Skip to content

Allow type checkers to infer more precise types for tuples#2194

Open
davidhalter wants to merge 4 commits intopython:mainfrom
davidhalter:zuban-update
Open

Allow type checkers to infer more precise types for tuples#2194
davidhalter wants to merge 4 commits intopython:mainfrom
davidhalter:zuban-update

Conversation

@davidhalter
Copy link
Contributor

This is consisent with the latest changes where f(1) could either be an int or a Literal[1]

    def f[T](x: T) -> T: ...
    assert_type(f(1), int)
    # or
    assert_type(f(1), Literal[1])

The same is possible with tuples:

    def f[*Ts](*x: *Ts) -> tuple[*Ts]: ...
    assert_type(f(1), tuple[int])
    # or
    assert_type(f(1), tuple[Literal[1]])

Mypy fails the test generics_typevartuple_callable.py now, because it doesn't error on any of the assert_type below:

def func3(*args: * tuple[int, *Ts, T]) -> tuple[T, *Ts]:
    raise NotImplementedError

assert_type(func3(1, "", 3j, 3.4), tuple[float, str, complex])  # E[fun3]
assert_type(func3(1, "", 3j, 3.4), tuple[float, Literal[''], complex])  # E[fun3]

This is also how Zuban used to work, but I think it's better to be precise here and it should probably fail one of the two (like Eric suggested in #2178 (comment)).

Ran the automated tests again. A few changes:

  • Zuban's passes a test again (due to assert_type changes)
  • Picked up a pyrefly upgrade that fixes a test

This is consisent with the latest changes where f(1) could either be an
int or a Literal[1]

    def f[T](x: T) -> T: ...
    assert_type(f(1), int)
    # or
    assert_type(f(1), Literal[1])

The same is possible with tuples:

    def f[*Ts](*x: *Ts) -> tuple[*Ts]: ...
    assert_type(f(1), tuple[int])
    # or
    assert_type(f(1), tuple[Literal[1]])


assert_type(args_to_tuple(1, "a"), tuple[int, str])
assert_type(args_to_tuple(1, "a"), tuple[int, str]) # E[args_to_tuple]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid the two options, could we put this in a function that takes args of type int and str? Then tuple[int, str] would be unambiguously right.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Jelle, that's a really good idea, it also feels more readable this way for people that are not used to the special # E[...] comments.

I pushed this. This makes Mypy pass generics_typevartuple_callable.py again and doesn't really change anything other than Zuban passing the tests with its latest release.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I weakly prefer the version prior to c1ffe96. The new version could pass even if the type checker completely fails to solve the TypeVarTuple and just falls back to *tuple[Any, ...] for its inference of *Ts. The version with the # E[] tagged errors was precise

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't think about that. That's obviously a problem. I'm happy to revert...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant something like this:

def func(x: int, y: str):
    assert_type(args_to_tuple(x, y), tuple[int, str])

I agree the current version is worse.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JelleZijlstra's version there works for me, yes!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlexWaygood @JelleZijlstra Thank you for the good feedback. Kind of stupid of me to not think of this in the first place. I think the change is now completely uncontroversial.

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this makes sense to me, thanks!

@AlexWaygood AlexWaygood added the topic: conformance tests Issues with the conformance test suite label Feb 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic: conformance tests Issues with the conformance test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants