Skip to content

Commit

Permalink
Fix ParamSpec constraint for types as callable (#14153)
Browse files Browse the repository at this point in the history
Most types can be considered as callables, constructing the type itself.
When a constraint was created for a ParamSpec variable, the return type
would be set to NoneType, which conflicts with assumptions that
CallableType makes when it is the constructor of another type, crashing
mypy. This patch replaces the return type by UninhabitedType instead,
which stops CallableType from considering itself as a constructor.
  • Loading branch information
VincentVanlaer authored Nov 28, 2022
1 parent 365297c commit 19c7fd3
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
2 changes: 1 addition & 1 deletion mypy/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ def visit_callable_type(self, template: CallableType) -> list[Constraint]:
arg_types=cactual.arg_types[prefix_len:],
arg_kinds=cactual.arg_kinds[prefix_len:],
arg_names=cactual.arg_names[prefix_len:],
ret_type=NoneType(),
ret_type=UninhabitedType(),
),
)
)
Expand Down
24 changes: 24 additions & 0 deletions test-data/unit/check-parameter-specification.test
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,30 @@ class C(Generic[P]):
reveal_type(bar(C(fn=foo, x=1))) # N: Revealed type is "__main__.C[[x: builtins.int]]"
[builtins fixtures/paramspec.pyi]

[case testParamSpecClassConstructor]
# flags: --strict-optional
from typing import ParamSpec, Callable

P = ParamSpec("P")

class SomeClass:
def __init__(self, a: str) -> None:
pass

def func(t: Callable[P, SomeClass], val: Callable[P, SomeClass]) -> None:
pass

def constructor(a: str) -> SomeClass:
return SomeClass(a)

def wrong_constructor(a: bool) -> SomeClass:
return SomeClass("a")

func(SomeClass, constructor)
func(SomeClass, wrong_constructor) # E: Argument 1 to "func" has incompatible type "Type[SomeClass]"; expected "Callable[[VarArg(<nothing>), KwArg(<nothing>)], SomeClass]" \
# E: Argument 2 to "func" has incompatible type "Callable[[bool], SomeClass]"; expected "Callable[[VarArg(<nothing>), KwArg(<nothing>)], SomeClass]"
[builtins fixtures/paramspec.pyi]

[case testParamSpecInTypeAliasBasic]
from typing import ParamSpec, Callable

Expand Down

0 comments on commit 19c7fd3

Please sign in to comment.