python / python/typing_extensions

Starred unpack does not equal `Unpack` in Python 3.11

Open
#485 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
583
Forks
146
Avg merge
10h 11m
Merged PRs (30d)
5

Description

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)

https://github.com/python/typing_extensions/blob/17d3a37635bad3902c4e913a48d969cbebfb08c3/src/typing_extensions.py#L2473

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?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/typing_extensions.py around line 2473 and reproduce the Python 3.11 equality examples from the issue. Review the proposed equality, subclassing, monkey-patching, and documentation alternatives, then establish which behavior the maintainers want; done means the chosen behavior or limitation is documented and verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.