python / python/mypy

Lenient TypeVarTuple checking when number of dimensions is unknown

Open
#18,665 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

feature needs discussion priority-0-high topic-pep-646
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Currently this generates an error:

from typing import Any

class C[*Ts, S]:
    pass

a = C[int, str]()
a = C[*tuple[Any, ...], str]()  # Error

This is the output:

error: Incompatible types in assignment (expression has type "C[*tuple[Any, ...], str]", variable has type "C[int, str]")

However, this doesn't generate an error:

from typing import Any

class C[*Ts, S]:
    pass

a = C[int, str]()
a = C[*tuple[Any, ...]]()  # No error

I'd argue that the first example shouldn't generate an error either. One possible rule would be to allow this as long as some substitution of the *tuple[Any, ...] part would match the target type.

We could possibly also generalize the matching of unknown-length TypeVarTuple type arguments when the unknown-length part has a non-Any tuple item type. This could reduce apparent false positives. Example:

from typing import Any

class C[*Ts, S]:
    pass

a = C[int, int]()
a = C[*tuple[int, ...]]()  # No error?

This would only change the behavior of variadic generics. Variable-length tuples would continue to behave as they behave currently, i.e. tuple[int, ...] wouldn't be assignable to tuple[int, int]. The tuple behavior has been around for a very long time, so it doesn't make sense to change it, but variadic generics are a relatively new and untested feature.

The primary motivation is help with NumPy and libraries that provide multidimensional array-like types.

Proper subtype checks should continue to work as they work currently, since we can't safely simplify say C[int] | C[*tuple[Any, ...]].

cc @ilevkivskyi who I chatted about this recently

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 by running the two TypeVarTuple examples from the issue through mypy and compare their current diagnostics. Investigate the variadic-generic compatibility and subtype-checking paths, then add coverage for the proposed Any and non-Any unknown-length cases while preserving existing variable-length tuple behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.