Skip to content

Starred unpack does not equal Unpack in Python 3.11 #485

Open
@Daraan

Description

@Daraan

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions