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
35 changes: 35 additions & 0 deletions pytype/tests/test_paramspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,41 @@ def f(x: Callable[P, int]) -> Callable[P, int]: ...
""",
)

@test_utils.skipBeforePy((3, 12), "PEP 695 - 3.12 feature")
def test_paramspec_in_type_alias_695(self):
ty = self.Infer("""
from typing import Callable
type Foo[T, **P] = Callable[P, T]
""")
self.assertTypesMatchPytd(
ty,
"""
from typing import Callable, ParamSpec
P = ParamSpec('P')
T = TypeVar('T')

Foo = Callable[P, T]
""",
)

@test_utils.skipBeforePy((3, 12), "PEP 695 - 3.12 feature")
def test_paramspec_in_function_def_695(self):
ty = self.Infer("""
from typing import Callable
def foo[T, **P](a: Callable[P, T]) -> Callable[P, T]:
return a
""")
self.assertTypesMatchPytd(
ty,
"""
from typing import Callable, ParamSpec
P = ParamSpec('P')
T = TypeVar('T')

def foo(a: Callable[P, T]) -> Callable[P, T]: ...
""",
)

def test_concatenate_in_def(self):
ty = self.Infer("""
from typing import Callable, Concatenate, ParamSpec
Expand Down
25 changes: 24 additions & 1 deletion pytype/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@ def _typings_type_var(self):
self.ctx.root_node
)

@functools.cached_property
def _typings_paramspec(self):
return typing_overlay.ParamSpec.make(self.ctx, None).to_variable(
self.ctx.root_node
)

def run_instruction(
self, op: opcodes.Opcode, state: frame_state.FrameState
) -> frame_state.FrameState:
Expand Down Expand Up @@ -3884,7 +3890,24 @@ def byte_INTRINSIC_TYPEVAR(self, state):
return state

def byte_INTRINSIC_PARAMSPEC(self, state):
# TODO: b/350910471 - Implement to support PEP 695
"""This intrinsic is a synonym to typing.ParamSpec."""
state, param = state.pop()
type_var_name = self.ctx.convert.constant_to_var(
param.data[0].pyval, node=state.node
)
args = function.Args(
posargs=(type_var_name,),
namedargs={},
starargs=None,
starstarargs=None,
)
_, ret = function.call_function(
self.ctx,
state.node,
self._typings_paramspec,
args=args,
)
state = state.push(ret)
return state

def byte_INTRINSIC_TYPEVARTUPLE(self, state):
Expand Down
Loading