Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork3.1k
Fix Type Comparison Edge Cases#20277
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
George-Ogden commentedNov 20, 2025
I don't quite understand what I should do with |
A5rocks left a comment
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'm not familiar with this part of mypy (this is the first time I sawTypeRange!), so my comments may be wrong. Initial pass through though.
I'm not sure about the bigger picture here, it feels somewhat hacky to rely ontype(x) == Y logic to handletype(x) == type(y). I don't have any better ideas though.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
This comment has been minimized.
This comment has been minimized.
Uh oh!
There was an error while loading.Please reload this page.
tyralla commentedNov 21, 2025
Thanks for the PR! Also, just a short remark/question without any deep knowledge of the matter: If I understand#20275 correctly, calling |
George-Ogden commentedNov 21, 2025
@tyralla: Let me know if this makes it clear or if any of that doesn't make sense. |
A5rocks commentedNov 22, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Huh, then couldn't we get rid of any special casing for looking for specifically I imagine it's a bit strange (e.g. (I guess the flaw is actually that we need to know the relevant name to know what to narrow. Maybe that's why we don't do that) |
tyralla commentedNov 22, 2025
I never really thought about type narrowing with If I look at this example: classX:x=1classY:y=1classZ(X,Y): ...z=Z()x:X=zy:Y=zifxisy:x.y+y.x# error: "X" has no attribute "y"# error: "Y" has no attribute "x I ask myself if Mypy should not handle it like: ifisinstance(x,type(y))andisinstance(y,type(x)):x.y+y.x Which could eventually easily be implemented with the help of |
George-Ogden commentedNov 22, 2025
I had a look at this and I've modified the implementation to allow this kind of checking. It just needs a bit of cleaning up. |
George-Ogden commentedNov 23, 2025
This cannot be directly handled here because classX:x=1classY:y=1classZ(X,Y): ...z=Z()x:X=zy:Y=ziftype(x)istype(y):# instead of x is yx.y+y.x |
George-Ogden commentedNov 23, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
|
George-Ogden commentedNov 23, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Diff frommypy_primer, showing the effect of this PR on open source code: pandas (https://github.com/pandas-dev/pandas)+ pandas/core/arrays/base.py:1502: error: Redundant cast to "ExtensionArray" [redundant-cast]ibis (https://github.com/ibis-project/ibis)- ibis/common/patterns.py:658: error: "Pattern" has no attribute "type" [attr-defined]- ibis/common/patterns.py:934: error: "Pattern" has no attribute "patterns" [attr-defined]jax (https://github.com/google/jax)+ jax/_src/interpreters/partial_eval.py:96: error: Unused "type: ignore" comment [unused-ignore]+ jax/_src/interpreters/partial_eval.py:99: error: No overload variant of "get" of "dict" matches argument types "int | DArray | Tracer | Var | DBIdx | InDBIdx | OutDBIdx", "int | DArray | Tracer | Var | DBIdx | InDBIdx | OutDBIdx" [call-overload]+ jax/_src/interpreters/partial_eval.py:99: note: Possible overload variants:+ jax/_src/interpreters/partial_eval.py:99: note: def get(self, Name, None = ..., /) -> DBIdx | None+ jax/_src/interpreters/partial_eval.py:99: note: def get(self, Name, DBIdx, /) -> DBIdx+ jax/_src/interpreters/partial_eval.py:99: note: def [_T] get(self, Name, _T, /) -> DBIdx | _T+ jax/_src/interpreters/batching.py:231: error: Unused "type: ignore" comment [unused-ignore]+ jax/_src/interpreters/batching.py:232: error: Unused "type: ignore" comment [unused-ignore]+ jax/_src/interpreters/batching.py:234: error: No overload variant of "get" of "dict" matches argument types "int | DArray | Tracer | Var | DBIdx | InDBIdx | OutDBIdx", "int | DArray | Tracer | Var | DBIdx | InDBIdx | OutDBIdx" [call-overload]+ jax/_src/interpreters/batching.py:234: note: Possible overload variants:+ jax/_src/interpreters/batching.py:234: note: def get(self, Name, None = ..., /) -> DBIdx | None+ jax/_src/interpreters/batching.py:234: note: def get(self, Name, DBIdx, /) -> DBIdx+ jax/_src/interpreters/batching.py:234: note: def [_T] get(self, Name, _T, /) -> DBIdx | _T+ jax/_src/interpreters/batching.py:258: error: Unused "type: ignore" comment [unused-ignore]rotki (https://github.com/rotki/rotki)+ rotkehlchen/history/events/structures/base.py:161: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:162: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:163: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:164: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:165: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:166: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:167: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:168: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:169: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:170: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:171: error: Unused "type: ignore" comment [unused-ignore]+ rotkehlchen/history/events/structures/base.py:172: error: Unused "type: ignore" comment [unused-ignore]pip (https://github.com/pypa/pip)+ src/pip/_internal/utils/misc.py:551: error: Redundant cast to "HiddenText" [redundant-cast] |
Fixes#20275 and#20041
This code snippet fails to type-check before this PR:
But type-checks afterwards.
This is done by finding a least type as the upper bound when the equality succeeds.