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

Starred unpack does not equal Unpack in Python 3.11 #485

Open
Daraan opened this issue Oct 11, 2024 · 1 comment
Open

Starred unpack does not equal Unpack in Python 3.11 #485

Daraan opened this issue Oct 11, 2024 · 1 comment

Comments

@Daraan
Copy link
Contributor

Daraan commented Oct 11, 2024

Equivalence between typing and typing_extensions is something I do not expect, however I think the following example is an exception as the non-equivalence comes as a surprise:

# python 3.11
import typing
from typing_extensions import Unpack, TypeVarTuple, get_type_hints
Ts = TypeVarTuple("Ts")

def foo(*x: *Ts): ...

print(get_type_hints(foo)['x'] == Unpack[Ts])  # <--- False
print(get_type_hints(foo)['x'] == typing.Unpack[Ts])  # <--- True

# or minimal example:
print(next(iter(Ts)) == Unpack[Ts])  # False

Why does this happen?

The 3.11+ backport of TypeVarTuple returns a patched instance tvt = typing.TypeVarTuple, which in turn will unpack to typing.Unpack[Ts] when __iter__ is used. (Unpack is backported until 3.11)

tvt = typing.TypeVarTuple(name)

Possible Fixes

  1. Likely bad idea: overwrite tvt.__iter__ to return typing_extensions.Unpack; might cause same problem at other places.

  2. Add __eq__ to typing_extensions.Unpack to equal with typing.Unpack. BUT, this will only be valid for the left-hand-side.

    print(Unpack[Ts] == get_type_hints(foo)['x'])  # <--- True
    print(get_type_hints(foo)['x'] == Unpack[Ts])  # <--- False

    Fix for the right-hand-side:
    a) typing_extensions._UnpackAlias must inherit from typing._UnpackGenericAlias for right-hand side priority.
    b) add typing._UnpackGenericAlias.__eq__ via monkey-patch

    Sideeffects: All Unpack and *-unpacks will be equivalent

  3. do not fix, but add a limitation/warning to the documentation that in 3.11

    typing_extensions.Unpack[Ts] != *Ts == typing.Unpack[Ts]  # pseudocode

I already have the necessary code for 2.a, but I am not sure what your stance is on this. Should equality be introduced, and if so is subclassing acceptable?

@JelleZijlstra
Copy link
Member

I think I'd prefer not to introduce any changes here. I'd prefer to discourage people from relying on equality of derived typing objects; instead introduce introspection APIs (get_origin() etc.) to decompose the objects to see if they are structurally equal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants