Skip to content
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

Better handling of Any/object in variadic generics #18643

Merged
merged 5 commits into from
Feb 12, 2025

Conversation

ilevkivskyi
Copy link
Member

@ilevkivskyi ilevkivskyi commented Feb 9, 2025

Fixes #18407
Fixes #17184
Fixes #16567

There are three things here:

  • Allow erased variadic callables with non-empty prefix to be supertypes of the non-erased ones. This relaxes a bit callable subtyping in general, but IMO this makes sense, people who want to be strict should simply use *args: object instead. An alternative would be to track erased variadic callables explicitly, which is ugly and fragile.
  • Add important missing case in subtypes.py for *Ts w.r.t. Any/object that handles similar situations for variadic instances and tuples (here however there is nothing special about Any vs object).
  • I also fix inconsistency in join uncovered by the above two.

The changes in expandtype.py are no-op, I just noticed potential danger while playing with this, so wanted to highlight it with comments for the future.

This comment has been minimized.

@ilevkivskyi
Copy link
Member Author

Hm, this exposed an inconsistency in instance vs type variable join. Let me try a principled first, but if there will be fallout, I will limit it to the variadic cases only.

@ilevkivskyi
Copy link
Member Author

Actually, after all I decided not to open this can of worms, let's limit the fix for uncovered inconsistency to variadic generics.

This comment has been minimized.

This comment has been minimized.

@ilevkivskyi
Copy link
Member Author

Pinging on review here, if there are no objections I will be merging this soon.

Copy link
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, another 3 bugs fixed! I didn't try to fully understand every single thing, but looks good overall. Left a minor suggestion about test coverage.

def join(x: T, y: T) -> T: ...
def test(xs: tuple[Unpack[Ts]], xsi: tuple[int, Unpack[Ts]]) -> None:
a: tuple[Any, ...]
reveal_type(join(xs, a)) # N: Revealed type is "builtins.tuple[Any, ...]"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also try the opposite argument order (join(a, xs)) here and below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, added symmetric check for each pair.

Copy link
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

@ilevkivskyi ilevkivskyi merged commit 2831eb1 into python:master Feb 12, 2025
18 checks passed
@ilevkivskyi ilevkivskyi deleted the norm-tvt-erasure branch February 12, 2025 19:49
ericmarkmartin pushed a commit to ericmarkmartin/mypy that referenced this pull request Feb 19, 2025
Fixes python#18407
Fixes python#17184
Fixes python#16567

There are three things here:
* Allow erased variadic callables with non-empty prefix to be supertypes
of the non-erased ones. This relaxes a bit callable subtyping in
general, but IMO this makes sense, people who want to be strict should
simply use `*args: object` instead. An alternative would be to track
erased variadic callables explicitly, which is ugly and fragile.
* Add important missing case in `subtypes.py` for `*Ts` w.r.t.
`Any`/`object` that handles similar situations for variadic instances
and tuples (here however there is nothing special about `Any` vs
`object`).
* I also fix inconsistency in join uncovered by the above two.

The changes in `expandtype.py` are no-op, I just noticed potential
danger while playing with this, so wanted to highlight it with comments
for the future.
ericmarkmartin pushed a commit to ericmarkmartin/mypy that referenced this pull request Feb 19, 2025
Fixes python#18407
Fixes python#17184
Fixes python#16567

There are three things here:
* Allow erased variadic callables with non-empty prefix to be supertypes
of the non-erased ones. This relaxes a bit callable subtyping in
general, but IMO this makes sense, people who want to be strict should
simply use `*args: object` instead. An alternative would be to track
erased variadic callables explicitly, which is ugly and fragile.
* Add important missing case in `subtypes.py` for `*Ts` w.r.t.
`Any`/`object` that handles similar situations for variadic instances
and tuples (here however there is nothing special about `Any` vs
`object`).
* I also fix inconsistency in join uncovered by the above two.

The changes in `expandtype.py` are no-op, I just noticed potential
danger while playing with this, so wanted to highlight it with comments
for the future.
x612skm pushed a commit to x612skm/mypy-dev that referenced this pull request Feb 24, 2025
Fixes python#18407
Fixes python#17184
Fixes python#16567

There are three things here:
* Allow erased variadic callables with non-empty prefix to be supertypes
of the non-erased ones. This relaxes a bit callable subtyping in
general, but IMO this makes sense, people who want to be strict should
simply use `*args: object` instead. An alternative would be to track
erased variadic callables explicitly, which is ugly and fragile.
* Add important missing case in `subtypes.py` for `*Ts` w.r.t.
`Any`/`object` that handles similar situations for variadic instances
and tuples (here however there is nothing special about `Any` vs
`object`).
* I also fix inconsistency in join uncovered by the above two.

The changes in `expandtype.py` are no-op, I just noticed potential
danger while playing with this, so wanted to highlight it with comments
for the future.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants