Skip to content

How to type hints for a genetic input tuple, with list[T] map to T #2063

Closed

Description

@baitian752
def func[T, *Ts1, *Ts2](values: tuple[*Ts1, list[T], *Ts2]) -> tuple[*Ts1, T, *Ts2]: ...

This is not valid as the document say:

However, note that at most one type variable tuple may appear in a single list of type arguments or type parameters

Activity

  1. added
    topic: featureDiscussions about new features for Python's type annotations
    on Aug 6, 2025
  2. RBerga06 commented on Aug 6, 2025

    @RBerga06

    I believe this is not yet supported because in some cases it can be ambiguous. Given:

    def func[T, *Ts1, *Ts2](values: tuple[*Ts1, list[T], *Ts2]) -> tuple[*Ts1, T, *Ts2]: ...

    what should type checkers reveal for the following code?

    y = func((5, [3], ["foo"], 3.14))
    reveal_type(y)

    There are two different options that are compatible with func's signature but are not consistent with each other:

    1. The type checker infers:

      • Ts1 = tuple[int]
      • T = int
      • Ts2 = tuple[list[str], float]
      • return type is tuple[int, int, list[str], float]
    2. The type checker infers:

      • Ts1 = tuple[int, list[int]]
      • T = str
      • Ts2 = tuple[float]
      • return type is tuple[int, list[int], str, float]

    Actually, because TypeVarTuples can also bind to empty tuples, I think this counterexample can be further simplified:

    z = func(([3], ["foo"]))
    reveal_type(z)  # `tuple[int, list[str]]` or `tuple[list[int], str]`?

    See the Python Typing specification for another example of ambiguity with TypeVarTuples.

  3. RBerga06 commented on Aug 6, 2025

    @RBerga06

    Maybe introducing TypeVarTuple bounds could allow for multiple TypeVarTuples in the same type argument list?

    def split_tuple[*Ts1: int, *Ts2: str](values: tuple[*Ts1, *Ts2]) -> tuple[tuple[*Ts1], tuple[*Ts2]]: ...
    
    class MyInt(int): ...
    class MyStr(str): ...
    
    w = split_tuple((MyInt(3), 14, MyStr("hey"), "there"))
    reveal_type(w)  # tuple[tuple[MyInt, int], tuple[MyStr, str]]

    I think this is not ambiguous, but note that I'm relying on the fact that it's impossible (at least in CPython) to construct an object that is both an instance of int and an instance of str.

  4. locked and limited conversation to collaborators on Aug 8, 2025
  5. converted this issue into a discussion #2064 on Aug 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: featureDiscussions about new features for Python's type annotations

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions