-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
[PEP 696] Fix swapping TypeVars with defaults. #19449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ilevkivskyi
merged 12 commits into
python:master
from
randolf-scholz:fix_typevar_default
Oct 27, 2025
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
510a89d
initial commit + revert debugging
randolf-scholz 4b34af1
added second test
randolf-scholz ee4dcc9
Merge branch 'python:master' into fix_typevar_default
randolf-scholz dc7f73a
Merge branch 'master' into fix_typevar_default
randolf-scholz 665d3ff
Merge branch 'master' into fix_typevar_default
randolf-scholz 70fbf96
Merge branch 'master' into fix_typevar_default
randolf-scholz 14ece7b
Merge branch 'master' into fix_typevar_default
randolf-scholz fd366cc
Merge branch 'master' into fix_typevar_default
randolf-scholz 76c0123
Merge branch 'master' into fix_typevar_default
randolf-scholz 1a3957a
Merge branch 'master' into fix_typevar_default
randolf-scholz 818175d
Merge branch 'master' into fix_typevar_default
randolf-scholz 8a088dc
Merge branch 'master' into fix_typevar_default
randolf-scholz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Types should be never modified in place. I know you didn't introduce it, but this should be fixed ASAP. (I think there is also a chance some of the problems you try to fix may be caused by this).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, with
copy_modifiedthen? If stuff should never be modified in place, it surprises me that the variables are not annotated asFinalin the first place.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, If I change this then now 2 tests fail:
testTypeVarDefaultsClassRecursive1andtestTypeVarDefaultsClassRecursiveMultipleFilesI noticed that
TypeVarType.__hash__is given byhash((self.id, self.upper_bound, tuple(self.values))), so changingdefaultdoes not change the hash.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. For historical reasons some types are constructed "gradually", so we can't make type attributes final. Maybe we will at some point, but that would be a big refactoring. For now, mypy contributors should remember a simple rule: types always new, symbols always original.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh well, it means there is another bug. TBH I am not sure if default should be part of the hash conceptually (and what it even means to have a type variable with same id, but a different default). IMO the support for type variable defaults may need to be re-implemented from scratch, as it is problematic on a conceptual level: regular default is not a property of an argument, it is a property of a function; same for type variables, their defaults are not property of type variable type itself, but of the function/class that uses them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the problem seems to be with getting the correct ID's. In the test case, we have
class D[T1=str, T2=T1].Modifying
repl.defaultin-place ensures that in theExpandTypeVisitor.variablesdictionary, the default of the dependent type variable gets updated to the new ID.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I don't understand why do we need to handle the defaults in
expand_typein the first place. As I explained, the default is not a property of a type variable, it is a property of a class/function, so the caller (e.g.applytypeetc) should always provide a complete type var -> replacement mapping. So thatexpand_type()should not be even allowed to look at the defaults.Yeah, I just looked at the original PR that added this logic #16878, it looks broken. The full complete mapping should be computed either in:
semanal/typeanalfor "static" application likex: C[int]applytypefor "dynamic" application likex = C[int]()before we even call
expand_type. I think the only right way to do it is this way.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure how to fix this at the moment, but given that this PR
Maybe this can still be merged as-is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The downside is that this is papering over the problem instead of fixing the real root cause. But anyway, if you feel strongly about this, I can merge this, it will not be much more work to axe this all later (and the tests are useful).