Skip to content

Commit

Permalink
Do not forget that a TypedDict was wrapped in Unpack after a `nam…
Browse files Browse the repository at this point in the history
…e-defined` error occurred. (#17226)

Do not set the `unpacked_kwargs` attribute of `CallableType` to False
when visiting a callable of which the `Unpack` wrapper of a `TypedDict`
has already been removed.

Fixes #17225
  • Loading branch information
tyralla authored Jun 5, 2024
1 parent ddcf90d commit 6bdd854
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
2 changes: 1 addition & 1 deletion mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,7 @@ def visit_parameters(self, t: Parameters) -> Type:
def visit_callable_type(self, t: CallableType, nested: bool = True) -> Type:
# Every Callable can bind its own type variables, if they're not in the outer scope
with self.tvar_scope_frame():
unpacked_kwargs = False
unpacked_kwargs = t.unpack_kwargs
if self.defining_alias:
variables = t.variables
else:
Expand Down
38 changes: 38 additions & 0 deletions test-data/unit/check-typeddict.test
Original file line number Diff line number Diff line change
Expand Up @@ -3487,3 +3487,41 @@ class A(Generic[T]):
return self.a(x=1)
[typing fixtures/typing-full.pyi]
[builtins fixtures/tuple.pyi]

[case testNameUndefinedErrorDoesNotLoseUnpackedKWArgsInformation]
from typing import overload
from typing_extensions import TypedDict, Unpack

class TD(TypedDict, total=False):
x: int
y: str

@overload
def f(self, *, x: int) -> None: ...
@overload
def f(self, *, y: str) -> None: ...
def f(self, **kwargs: Unpack[TD]) -> None:
z # E: Name "z" is not defined

@overload
def g(self, *, x: float) -> None: ...
@overload
def g(self, *, y: str) -> None: ...
def g(self, **kwargs: Unpack[TD]) -> None: # E: Overloaded function implementation does not accept all possible arguments of signature 1
z # E: Name "z" is not defined

class A:
def f(self, *, x: int) -> None: ...
def g(self, *, x: float) -> None: ...
class B(A):
def f(self, **kwargs: Unpack[TD]) -> None:
z # E: Name "z" is not defined
def g(self, **kwargs: Unpack[TD]) -> None: # E: Signature of "g" incompatible with supertype "A" \
# N: Superclass: \
# N: def g(self, *, x: float) -> None \
# N: Subclass: \
# N: def g(*, x: int = ..., y: str = ...) -> None
z # E: Name "z" is not defined
reveal_type(B.f) # N: Revealed type is "def (self: __main__.B, **kwargs: Unpack[TypedDict('__main__.TD', {'x'?: builtins.int, 'y'?: builtins.str})])"
B().f(x=1.0) # E: Argument "x" to "f" of "B" has incompatible type "float"; expected "int"
[builtins fixtures/primitives.pyi]

0 comments on commit 6bdd854

Please sign in to comment.