Skip to content

Commit

Permalink
Fix ParamSpec constraint for types as callable
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 committed Nov 19, 2022
1 parent e814c47 commit 9773e70
Show file tree
Hide file tree
Showing 2 changed files with 24 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
23 changes: 23 additions & 0 deletions test-data/unit/check-parameter-specification.test
Original file line number Diff line number Diff line change
Expand Up @@ -1296,3 +1296,26 @@ 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]
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(None), KwArg(None)], SomeClass]" \
# E: Argument 2 to "func" has incompatible type "Callable[[bool], SomeClass]"; expected "Callable[[VarArg(None), KwArg(None)], SomeClass]"
[builtins fixtures/paramspec.pyi]

0 comments on commit 9773e70

Please sign in to comment.