From f5f35b0048cf62dea5ae7623953946737fb48986 Mon Sep 17 00:00:00 2001 From: Hana Joo Date: Tue, 22 Apr 2025 08:54:06 -0700 Subject: [PATCH] Implements the INTRINSIC_TYPEALIAS bytecode. This feature is part of PEP 695, which allows builtin type aliases that are syntactically unambiguous with the existing way to create type aliases. This is only one part of the support, there are more features to come involving type parameters. PiperOrigin-RevId: 750210604 --- pytype/tests/test_annotations.py | 7 +++++++ pytype/tests/test_typing1.py | 11 +++++++++++ pytype/vm.py | 27 ++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/pytype/tests/test_annotations.py b/pytype/tests/test_annotations.py index f7f9a8ac1..aade2dcd6 100644 --- a/pytype/tests/test_annotations.py +++ b/pytype/tests/test_annotations.py @@ -1139,6 +1139,13 @@ def test_forward_reference_in_type_alias(self): Z = List[int] """) + @test_utils.skipBeforePy((3, 12), "type aliases are new in 3.12") + def test_use_builtin_type_alias(self): + self.Check(""" + type MyType = list[str] + using_mytype: MyType = ['foo', 'bar'] + """) + def test_fully_quoted_annotation(self): self.Check(""" from typing import Optional diff --git a/pytype/tests/test_typing1.py b/pytype/tests/test_typing1.py index a7b234ebc..09b5da485 100644 --- a/pytype/tests/test_typing1.py +++ b/pytype/tests/test_typing1.py @@ -103,6 +103,17 @@ def test_generate_type_alias(self): """, ) + @test_utils.skipBeforePy((3, 12), "type aliases are new in 3.12") + def test_generate_type_alias_312(self): + ty = self.Infer(""" + type MyType = list[str] + """) + self.assertTypesMatchPytd( + ty, + # TODO: b/412616662 - Generate type MyType = list[str] instead. + "MyType = list[str]", + ) + def test_protocol(self): self.Check(""" from typing_extensions import Protocol diff --git a/pytype/vm.py b/pytype/vm.py index 87cc22b7b..fc04e9a97 100644 --- a/pytype/vm.py +++ b/pytype/vm.py @@ -3871,7 +3871,32 @@ def byte_INTRINSIC_SUBSCRIPT_GENERIC(self, state): return state def byte_INTRINSIC_TYPEALIAS(self, state): - # TODO: b/350910471 - Implement to support PEP 695 + """This intrinsic creates a type alias and puts the result on the stack.""" + # https://docs.python.org/3.12/library/dis.html states: + # The argument is a tuple of the type alias’s name, type parameters, + # and value. There's no need to use the name because there's a STORE_NAME + # opcode following the call to this intrinsic. + state, param = state.pop() + # TODO: b/412616662 - For pytd generation, it's better to generate type + # aliases as `type MyType = int`, because the type alias is not callable + # if we do Mytype(), thus there should be a diagnostic when you try to call + # a type alias. For now, we generate `type MyType = int` as `MyType = int` + # because the machinery to make a distinction is not in place yet. + # TODO: b/350910471 - support the use of typevar + _, typevar, funcv = param.data[0].pyval + args = function.Args( + posargs=(), + namedargs={}, + starargs=None, + starstarargs=None, + ) + _, ret = function.call_function( + self.ctx, + state.node, + funcv, + args=args, + ) + state = state.push(ret) return state def byte_INTRINSIC_2_INVALID(self, state):