Skip to content

Commit

Permalink
Fix type analysis for typing.Unpack (#15228)
Browse files Browse the repository at this point in the history
We were checking only for `typing_extensions.Unpack`, which breaks code
when checking at 3.11+ even if importing `typing_extensions` because its
just a re-export from `typing`.

These basic pythoneval tests also assert that the feature at least
somewhat works with the real stubs - otherwise up until now we had
basically no coverage of that, and were relying on the fake typing stubs
to be close enough to the real thing.
  • Loading branch information
jhance authored May 17, 2023
1 parent ce2c918 commit 905c2cb
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
12 changes: 11 additions & 1 deletion mypy/test/testpythoneval.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,17 @@ def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None

m = re.search("# flags: (.*)$", "\n".join(testcase.input), re.MULTILINE)
if m:
mypy_cmdline.extend(m.group(1).split())
additional_flags = m.group(1).split()
for flag in additional_flags:
if flag.startswith("--python-version="):
targetted_python_version = flag.split("=")[1]
targetted_major, targetted_minor = targetted_python_version.split(".")
if (int(targetted_major), int(targetted_minor)) > (
sys.version_info.major,
sys.version_info.minor,
):
return
mypy_cmdline.extend(additional_flags)

# Write the program to a file.
program = "_" + testcase.name + ".py"
Expand Down
2 changes: 1 addition & 1 deletion mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ def analyze_callable_args(
# Potentially a unpack.
sym = self.lookup_qualified(arg.name, arg)
if sym is not None:
if sym.fullname == "typing_extensions.Unpack":
if sym.fullname in ("typing_extensions.Unpack", "typing.Unpack"):
if found_unpack:
self.fail("Callables can only have a single unpack", arg)
found_unpack = True
Expand Down
25 changes: 25 additions & 0 deletions test-data/unit/pythoneval.test
Original file line number Diff line number Diff line change
Expand Up @@ -1986,3 +1986,28 @@ def good9(foo1: Foo[Concatenate[int, P]], foo2: Foo[[int, str, bytes]], *args: P

[out]
_testStrictEqualitywithParamSpec.py:11: error: Non-overlapping equality check (left operand type: "Foo[[int]]", right operand type: "Bar[[int]]")

[case testTypeVarTuple]
# flags: --enable-incomplete-feature=TypeVarTuple --enable-incomplete-feature=Unpack --python-version=3.11
from typing import Any, Callable, Unpack, TypeVarTuple

Ts = TypeVarTuple("Ts")

def foo(callback: Callable[[], Any]) -> None:
call(callback)

def call(callback: Callable[[Unpack[Ts]], Any], *args: Unpack[Ts]) -> Any:
...

[case testTypeVarTupleTypingExtensions]
# flags: --enable-incomplete-feature=TypeVarTuple --enable-incomplete-feature=Unpack
from typing_extensions import Unpack, TypeVarTuple
from typing import Any, Callable

Ts = TypeVarTuple("Ts")

def foo(callback: Callable[[], Any]) -> None:
call(callback)

def call(callback: Callable[[Unpack[Ts]], Any], *args: Unpack[Ts]) -> Any:
...

0 comments on commit 905c2cb

Please sign in to comment.