Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions pytype/matcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -1198,14 +1198,18 @@ def _match_subst_against_subst(
type_param_map[t],
old_subst.copy(t=b1.AssignToNewVariable(self._node)),
)
else:
# If t isn't a TypeVar here it should be a ParamSpec
elif t in self._paramspecs:
assert t in self._paramspecs
new_var = self.ctx.program.NewVariable()
new_var.PasteBindingWithNewData(
b2, self.ctx.convert.get_maybe_abstract_instance(b2.data)
)
has_error = False
else:
new_var = self.ctx.program.NewVariable()
# Here' it's possibly a ParamSpec but the callpath to this code
# somehow does not assign to the self._paramspecs list.
has_error = False
# If new_subst contains a TypeVar that is mutually exclusive with t,
# then we can ignore this error because it is legal for t to not be
# present in new_subst.
Expand Down
19 changes: 19 additions & 0 deletions pytype/tests/test_paramspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,25 @@ def f(x: int, y) -> Any: ...
""",
)

def test_paramspec_in_callable_as_param_not_fail(self):
self.Check("""
from typing import ParamSpec, Callable

_P = ParamSpec("_P")
CallbleWithParamSpec = Callable[_P, None]

class A:
def __init__(self, callable_1: CallbleWithParamSpec, callable_2: CallbleWithParamSpec):
pass

class B(A):
def __init__(self, callable_1: CallbleWithParamSpec, callable_2: CallbleWithParamSpec):
super().__init__(
callable_1,
callable_2,
)
""")


class ContextlibTest(test_base.BaseTest):
"""Test some more complex uses of contextlib."""
Expand Down
Loading