Skip to content

Commit 442ecca

Browse files
committed
SubtypeVisitor: treat ParamSpec as if it was a covariant TypeVar
1 parent 7af46ce commit 442ecca

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

mypy/subtypes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ def visit_instance(self, left: Instance) -> bool:
277277
if isinstance(tvar, TypeVarType):
278278
if not self.check_type_parameter(lefta, righta, tvar.variance):
279279
nominal = False
280+
elif isinstance(tvar, ParamSpecType):
281+
if not self.check_type_parameter(lefta, righta, COVARIANT):
282+
nominal = False
280283
else:
281284
if not is_equivalent(lefta, righta):
282285
nominal = False

test-data/unit/check-parameter-specification.test

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,26 @@ with f() as x:
416416
pass
417417
[builtins fixtures/dict.pyi]
418418
[typing fixtures/typing-full.pyi]
419+
420+
[case testDecoratingClassesThatUseParamSpec]
421+
from typing import Generic, TypeVar, Callable, Any
422+
from typing_extensions import ParamSpec
423+
424+
_P = ParamSpec("_P")
425+
_T = TypeVar("_T")
426+
_F = TypeVar("_F", bound=Callable[..., Any])
427+
428+
def f(x: _F) -> _F: ...
429+
430+
@f # Should be ok
431+
class OnlyParamSpec(Generic[_P]):
432+
pass
433+
434+
@f # Should be ok
435+
class MixedWithTypeVar1(Generic[_P, _T]):
436+
pass
437+
438+
@f # Should be ok
439+
class MixedWithTypeVar2(Generic[_T, _P]):
440+
pass
441+
[builtins fixtures/dict.pyi]

0 commit comments

Comments
 (0)