From b0b25b3320fa7d20e1ab5dd1e9e3d38ab05af280 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Mon, 25 May 2026 03:44:54 -0400 Subject: [PATCH 1/7] add version checks --- mypy/nativeparse.py | 53 +++++++++++++++++++++++++++++++++++++++++++-- mypy/parse.py | 2 +- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/mypy/nativeparse.py b/mypy/nativeparse.py index 414426580fa7..cfef0defff7a 100644 --- a/mypy/nativeparse.py +++ b/mypy/nativeparse.py @@ -29,7 +29,7 @@ read_str as read_str_bare, ) -from mypy import message_registry, nodes, types +from mypy import defaults, message_registry, nodes, types from mypy.cache import ( DICT_STR_GEN, END_TAG, @@ -167,8 +167,9 @@ class State: - def __init__(self, options: Options) -> None: + def __init__(self, options: Options, is_stub: bool = False) -> None: self.options = options + self.is_stub = is_stub self.errors: list[ParseError] = [] self.num_funcs = 0 @@ -180,6 +181,28 @@ def add_error( {"line": line, "column": column, "message": message, "blocker": blocker, "code": code} ) + def check_min_version( + self, + feature: str, + min_version: tuple[int, int], + line: int, + column: int, + ) -> None: + """Report a non blocker syntax error if the target Python feature is older than min_version.""" + if self.is_stub: + target = max(self.options.python_version, defaults.PYTHON3_VERSION) + else: + target = self.options.python_version + if target < min_version: + self.add_error( + f"{feature} are only supported in Python " + f"{min_version[0]}.{min_version[1]} and greater", + line, + column, + blocker=False, + code="syntax", + ) + def native_parse( filename: str, @@ -607,6 +630,13 @@ def read_parameters(state: State, data: ReadBuffer) -> tuple[list[Argument], boo return arguments, has_ann +def check_type_param_defaults( + state: State, type_params: list[TypeParam], line: int, column: int +) -> None: + if any(p.default is not None for p in type_params): + state.check_min_version("Type parameter defaults", (3, 13), line, column) + + def read_type_params(state: State, data: ReadBuffer) -> list[TypeParam]: """Read type parameters (PEP 695 generics).""" type_params: list[TypeParam] = [] @@ -680,6 +710,11 @@ def read_func_def(state: State, data: ReadBuffer) -> FuncDef: if is_async: func_def.is_coroutine = True read_loc(data, func_def) + if type_params: + state.check_min_version( + "Type parameter lists", (3, 12), func_def.line, func_def.column + ) + check_type_param_defaults(state, type_params, func_def.line, func_def.column) if typ: typ.line = func_def.line typ.column = func_def.column @@ -727,6 +762,11 @@ def read_class_def(state: State, data: ReadBuffer) -> ClassDef: ) class_def.decorators = decorators read_loc(data, class_def) + if type_params: + state.check_min_version( + "Type parameter lists", (3, 12), class_def.line, class_def.column + ) + check_type_param_defaults(state, type_params, class_def.line, class_def.column) expect_end_tag(data) return class_def @@ -781,6 +821,10 @@ def read_type_alias_stmt(state: State, data: ReadBuffer) -> TypeAliasStmt: stmt = TypeAliasStmt(name, type_params, lambda_expr) read_loc(data, stmt) + state.check_min_version( + '"type" statements', (3, 12), stmt.line, stmt.column + ) + check_type_param_defaults(state, type_params, stmt.line, stmt.column) expect_end_tag(data) return stmt @@ -832,6 +876,10 @@ def read_try_stmt(state: State, data: ReadBuffer) -> TryStmt: stmt = TryStmt(body, vars_list, types_list, handlers, else_body, finally_body) stmt.is_star = is_star read_loc(data, stmt) + if is_star: + state.check_min_version("Exception groups", (3, 11), stmt.line, stmt.column) + if state.options.python_version < (3, 11): + stmt.is_star = False expect_end_tag(data) return stmt @@ -1474,6 +1522,7 @@ def read_expression(state: State, data: ReadBuffer) -> Expression: titems.append(s) expr = TemplateStrExpr(titems) read_loc(data, expr) + state.check_min_version("t-strings", (3, 14), expr.line, expr.column) expect_end_tag(data) return expr elif tag == nodes.LAMBDA_EXPR: diff --git a/mypy/parse.py b/mypy/parse.py index a8fb5542a704..47e2f95f0f30 100644 --- a/mypy/parse.py +++ b/mypy/parse.py @@ -71,7 +71,7 @@ def load_from_raw( """ from mypy.nativeparse import State, deserialize_imports, read_statements - state = State(options) + state = State(options, is_stub=fnam.endswith(".pyi")) if imports_only: defs = [] else: From 3a8407e954151772e1b3437f0eaa3011161e2858 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Mon, 25 May 2026 04:23:59 -0400 Subject: [PATCH 2/7] stub check update --- mypy/nativeparse.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mypy/nativeparse.py b/mypy/nativeparse.py index cfef0defff7a..2003f0620a63 100644 --- a/mypy/nativeparse.py +++ b/mypy/nativeparse.py @@ -29,7 +29,7 @@ read_str as read_str_bare, ) -from mypy import defaults, message_registry, nodes, types +from mypy import message_registry, nodes, types from mypy.cache import ( DICT_STR_GEN, END_TAG, @@ -190,10 +190,8 @@ def check_min_version( ) -> None: """Report a non blocker syntax error if the target Python feature is older than min_version.""" if self.is_stub: - target = max(self.options.python_version, defaults.PYTHON3_VERSION) - else: - target = self.options.python_version - if target < min_version: + return + if self.options.python_version < min_version: self.add_error( f"{feature} are only supported in Python " f"{min_version[0]}.{min_version[1]} and greater", From c8851c007e9be793fd27aeda8f79af7abfee6678 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 08:26:03 +0000 Subject: [PATCH 3/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/nativeparse.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/mypy/nativeparse.py b/mypy/nativeparse.py index 2003f0620a63..a5c91ca4bf3b 100644 --- a/mypy/nativeparse.py +++ b/mypy/nativeparse.py @@ -182,11 +182,7 @@ def add_error( ) def check_min_version( - self, - feature: str, - min_version: tuple[int, int], - line: int, - column: int, + self, feature: str, min_version: tuple[int, int], line: int, column: int ) -> None: """Report a non blocker syntax error if the target Python feature is older than min_version.""" if self.is_stub: @@ -709,9 +705,7 @@ def read_func_def(state: State, data: ReadBuffer) -> FuncDef: func_def.is_coroutine = True read_loc(data, func_def) if type_params: - state.check_min_version( - "Type parameter lists", (3, 12), func_def.line, func_def.column - ) + state.check_min_version("Type parameter lists", (3, 12), func_def.line, func_def.column) check_type_param_defaults(state, type_params, func_def.line, func_def.column) if typ: typ.line = func_def.line @@ -761,9 +755,7 @@ def read_class_def(state: State, data: ReadBuffer) -> ClassDef: class_def.decorators = decorators read_loc(data, class_def) if type_params: - state.check_min_version( - "Type parameter lists", (3, 12), class_def.line, class_def.column - ) + state.check_min_version("Type parameter lists", (3, 12), class_def.line, class_def.column) check_type_param_defaults(state, type_params, class_def.line, class_def.column) expect_end_tag(data) return class_def @@ -819,9 +811,7 @@ def read_type_alias_stmt(state: State, data: ReadBuffer) -> TypeAliasStmt: stmt = TypeAliasStmt(name, type_params, lambda_expr) read_loc(data, stmt) - state.check_min_version( - '"type" statements', (3, 12), stmt.line, stmt.column - ) + state.check_min_version('"type" statements', (3, 12), stmt.line, stmt.column) check_type_param_defaults(state, type_params, stmt.line, stmt.column) expect_end_tag(data) return stmt From 0b00e61a80fb43ccb37844c041f3418c0ff6303b Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Thu, 28 May 2026 02:57:15 -0400 Subject: [PATCH 4/7] enforce tstrings in stubs and update messaging --- mypy/nativeparse.py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/mypy/nativeparse.py b/mypy/nativeparse.py index a5c91ca4bf3b..fa9bdebab11f 100644 --- a/mypy/nativeparse.py +++ b/mypy/nativeparse.py @@ -182,15 +182,22 @@ def add_error( ) def check_min_version( - self, feature: str, min_version: tuple[int, int], line: int, column: int + self, + feature: str, + min_version: tuple[int, int], + line: int, + column: int, + *, + enforce_in_stubs: bool = False, ) -> None: """Report a non blocker syntax error if the target Python feature is older than min_version.""" - if self.is_stub: + if self.is_stub and not enforce_in_stubs: return if self.options.python_version < min_version: + curr = self.options.python_version self.add_error( - f"{feature} are only supported in Python " - f"{min_version[0]}.{min_version[1]} and greater", + f"{feature}: requires Python {min_version[0]}.{min_version[1]} or newer " + f"(current target: Python {curr[0]}.{curr[1]})", line, column, blocker=False, @@ -705,7 +712,9 @@ def read_func_def(state: State, data: ReadBuffer) -> FuncDef: func_def.is_coroutine = True read_loc(data, func_def) if type_params: - state.check_min_version("Type parameter lists", (3, 12), func_def.line, func_def.column) + state.check_min_version( + "Improved type parameter syntax", (3, 12), func_def.line, func_def.column + ) check_type_param_defaults(state, type_params, func_def.line, func_def.column) if typ: typ.line = func_def.line @@ -755,7 +764,9 @@ def read_class_def(state: State, data: ReadBuffer) -> ClassDef: class_def.decorators = decorators read_loc(data, class_def) if type_params: - state.check_min_version("Type parameter lists", (3, 12), class_def.line, class_def.column) + state.check_min_version( + "Improved type parameter syntax", (3, 12), class_def.line, class_def.column + ) check_type_param_defaults(state, type_params, class_def.line, class_def.column) expect_end_tag(data) return class_def @@ -1003,6 +1014,10 @@ def read_type(state: State, data: ReadBuffer) -> Type: from_star_syntax = read_bool(data) unpack = UnpackType(inner_type, from_star_syntax=from_star_syntax) read_loc(data, unpack) + if from_star_syntax: + state.check_min_version( + "Star unpack syntax", (3, 11), unpack.line, unpack.column + ) expect_end_tag(data) return unpack elif tag == types.CALL_TYPE: @@ -1510,7 +1525,9 @@ def read_expression(state: State, data: ReadBuffer) -> Expression: titems.append(s) expr = TemplateStrExpr(titems) read_loc(data, expr) - state.check_min_version("t-strings", (3, 14), expr.line, expr.column) + state.check_min_version( + "t-strings", (3, 14), expr.line, expr.column, enforce_in_stubs=True + ) expect_end_tag(data) return expr elif tag == nodes.LAMBDA_EXPR: From 60d8f7c365f328bf19b670ded2658f1a90c275cd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 07:01:18 +0000 Subject: [PATCH 5/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/nativeparse.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mypy/nativeparse.py b/mypy/nativeparse.py index fa9bdebab11f..d5af1c8c6ec8 100644 --- a/mypy/nativeparse.py +++ b/mypy/nativeparse.py @@ -1015,9 +1015,7 @@ def read_type(state: State, data: ReadBuffer) -> Type: unpack = UnpackType(inner_type, from_star_syntax=from_star_syntax) read_loc(data, unpack) if from_star_syntax: - state.check_min_version( - "Star unpack syntax", (3, 11), unpack.line, unpack.column - ) + state.check_min_version("Star unpack syntax", (3, 11), unpack.line, unpack.column) expect_end_tag(data) return unpack elif tag == types.CALL_TYPE: From 303fa4f4dcafdfe25e100e837d43eb73de40de10 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Thu, 28 May 2026 04:24:43 -0400 Subject: [PATCH 6/7] add tests --- test-data/unit/check-typevar-tuple.test | 4 ++++ test-data/unit/check-varargs.test | 1 + test-data/unit/native-parser.test | 18 ++++++++++++++---- test-data/unit/pythoneval.test | 25 +++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test index 8d3f3cd80531..c5c1643cf0b0 100644 --- a/test-data/unit/check-typevar-tuple.test +++ b/test-data/unit/check-typevar-tuple.test @@ -578,6 +578,7 @@ reveal_type(b) # N: Revealed type is "def (*Any) -> builtins.int" [builtins fixtures/tuple.pyi] [case testTypeVarTuplePep646CallableNewSyntax] +# flags: --python-version 3.11 from typing import Callable, Generic, Tuple from typing_extensions import ParamSpec @@ -2155,6 +2156,7 @@ def f(x: int | None): [builtins fixtures/tuple.pyi] [case testJoinOfVariadicTupleCallablesNoCrash] +# flags: --python-version 3.11 from typing import Callable, Tuple f: Callable[[int, *Tuple[str, ...], int], None] @@ -2608,6 +2610,7 @@ def test(xs: tuple[Unpack[Ts]], xsi: tuple[int, Unpack[Ts]]) -> None: [builtins fixtures/tuple.pyi] [case testTypeVarTupleInferAgainstAnyCallableSuffix] +# flags: --python-version 3.11 from typing import Any, Callable, TypeVar, TypeVarTuple Ts = TypeVarTuple("Ts") @@ -2620,6 +2623,7 @@ reveal_type(deco(untyped)) # N: Revealed type is "def (*Any) -> Any" [builtins fixtures/tuple.pyi] [case testNoCrashOnNonNormalUnpackInCallable] +# flags: --python-version 3.11 from typing import Callable, Unpack, TypeVar T = TypeVar("T") diff --git a/test-data/unit/check-varargs.test b/test-data/unit/check-varargs.test index 172e57cf1a4b..4de3d649c068 100644 --- a/test-data/unit/check-varargs.test +++ b/test-data/unit/check-varargs.test @@ -1116,6 +1116,7 @@ class D: [builtins fixtures/dict.pyi] [case testUnpackInCallableType] +# flags: --python-version 3.11 from typing import Callable, TypedDict from typing_extensions import Unpack diff --git a/test-data/unit/native-parser.test b/test-data/unit/native-parser.test index 8962875a9cf2..5e44978e0e5a 100644 --- a/test-data/unit/native-parser.test +++ b/test-data/unit/native-parser.test @@ -1300,12 +1300,12 @@ try: except* ValueError: y [out] +1:0: error: Exception groups: requires Python 3.11 or newer (current target: Python 3.10) MypyFile:1( TryStmt:1( Block:2( ExpressionStmt:2( NameExpr(x))) - * NameExpr(ValueError) Block:4( ExpressionStmt:4( @@ -1317,12 +1317,12 @@ try: except* Exception as e: y [out] +1:0: error: Exception groups: requires Python 3.11 or newer (current target: Python 3.10) MypyFile:1( TryStmt:1( Block:2( ExpressionStmt:2( NameExpr(x))) - * NameExpr(Exception) NameExpr(e) Block:4( @@ -1337,12 +1337,12 @@ except* ValueError: except* KeyError as e: z [out] +1:0: error: Exception groups: requires Python 3.11 or newer (current target: Python 3.10) MypyFile:1( TryStmt:1( Block:2( ExpressionStmt:2( NameExpr(x))) - * NameExpr(ValueError) Block:4( ExpressionStmt:4( @@ -1363,12 +1363,12 @@ else: finally: w [out] +1:0: error: Exception groups: requires Python 3.11 or newer (current target: Python 3.10) MypyFile:1( TryStmt:1( Block:2( ExpressionStmt:2( NameExpr(x))) - * NameExpr(ValueError) Block:4( ExpressionStmt:4( @@ -2022,6 +2022,7 @@ MypyFile:1( def f(*args: *Ts) -> None: pass [out] +1:13: error: Star unpack syntax: requires Python 3.11 or newer (current target: Python 3.10) MypyFile:1( FuncDef:1( f @@ -2034,6 +2035,7 @@ MypyFile:1( [case testUnpackTypeInTuple] x: tuple[int, *Ts, str] [out] +1:14: error: Star unpack syntax: requires Python 3.11 or newer (current target: Python 3.10) MypyFile:1( AssignmentStmt:1( NameExpr(x) @@ -3190,6 +3192,7 @@ MypyFile:1( # comment type A[T] = C[T] [out] +2:0: error: "type" statements: requires Python 3.12 or newer (current target: Python 3.10) MypyFile:1( TypeAliasStmt:2( NameExpr(A) @@ -3209,6 +3212,9 @@ def f[T](): pass def g[T: str](): pass def h[T: (int, str)](): pass [out] +3:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) +4:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) +5:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) MypyFile:1( FuncDef:3( f @@ -3239,6 +3245,8 @@ MypyFile:1( def f[**P](): pass class C[T: int, **P]: pass [out] +3:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) +4:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) MypyFile:1( FuncDef:3( f @@ -3261,6 +3269,8 @@ MypyFile:1( def f[*Ts](): pass class C[T: int, *Ts]: pass [out] +3:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) +4:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) MypyFile:1( FuncDef:3( f diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 659a8515455d..fa3001c3a482 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -2268,3 +2268,28 @@ _testNarrowingMappingAndAbstractSet.py:33: note: Revealed type is "dict[str, int _testNarrowingMappingAndAbstractSet.py:34: note: Revealed type is "set[str]" _testNarrowingMappingAndAbstractSet.py:38: note: Revealed type is "_collections_abc.dict_keys[str, int]" _testNarrowingMappingAndAbstractSet.py:39: note: Revealed type is "set[str]" + +[case testNativeParserTStringRequiresPython314] +# flags: --python-version=3.13 --native-parser --ignore-missing-imports +x = t"hello {1}" +[out] +_testNativeParserTStringRequiresPython314.py:2: error: T-strings: requires Python 3.14 or newer (current target: Python 3.13) + +[case testNativeParserTStringRequiresPython314InStub] +# flags: --python-version=3.13 --native-parser --ignore-missing-imports +import m +[file m.pyi] +x: object +def f() -> object: ... +y = t"hello {1}" +[out] +m.pyi:3: error: T-strings: requires Python 3.14 or newer (current target: Python 3.13) + +[case testNativeParserStarUnpackRequiresPython311] +# flags: --python-version=3.10 --native-parser +from typing_extensions import TypeVarTuple, Unpack +Ts = TypeVarTuple("Ts") +def f(x: tuple[Unpack[Ts]]) -> None: ... +def g(x: tuple[*Ts]) -> None: ... +[out] +_testNativeParserStarUnpackRequiresPython311.py:5: error: Star unpack syntax: requires Python 3.11 or newer (current target: Python 3.10) From faa7f42d51c8841459555f0581815c0752b98113 Mon Sep 17 00:00:00 2001 From: Kevin Kannammalil Date: Fri, 29 May 2026 01:22:51 -0400 Subject: [PATCH 7/7] refactor tests --- mypy/test/test_nativeparse.py | 8 +- test-data/unit/native-parser-python311.test | 108 ++++++++++ test-data/unit/native-parser-python312.test | 90 +++++++++ test-data/unit/native-parser.test | 211 -------------------- test-data/unit/pythoneval.test | 5 + 5 files changed, 210 insertions(+), 212 deletions(-) create mode 100644 test-data/unit/native-parser-python311.test create mode 100644 test-data/unit/native-parser-python312.test diff --git a/mypy/test/test_nativeparse.py b/mypy/test/test_nativeparse.py index e0a0da29166b..1e63f4abc299 100644 --- a/mypy/test/test_nativeparse.py +++ b/mypy/test/test_nativeparse.py @@ -52,7 +52,11 @@ class NativeParserSuite(DataSuite): required_out_section = True base_path = "." - files = ["native-parser.test"] if has_nativeparse else [] + files = ( + ["native-parser.test", "native-parser-python311.test", "native-parser-python312.test"] + if has_nativeparse + else [] + ) def run_case(self, testcase: DataDrivenTestCase) -> None: test_parser(testcase) @@ -77,6 +81,8 @@ def test_parser(testcase: DataDrivenTestCase) -> None: if testcase.file.endswith("python310.test"): options.python_version = (3, 10) + elif testcase.file.endswith("python311.test"): + options.python_version = (3, 11) elif testcase.file.endswith("python312.test"): options.python_version = (3, 12) elif testcase.file.endswith("python313.test"): diff --git a/test-data/unit/native-parser-python311.test b/test-data/unit/native-parser-python311.test new file mode 100644 index 000000000000..9a314715133a --- /dev/null +++ b/test-data/unit/native-parser-python311.test @@ -0,0 +1,108 @@ +[case testTryExceptStar] +try: + x +except* ValueError: + y +[out] +MypyFile:1( + TryStmt:1( + Block:2( + ExpressionStmt:2( + NameExpr(x))) + * + NameExpr(ValueError) + Block:4( + ExpressionStmt:4( + NameExpr(y))))) + +[case testTryExceptStarWithVar] +try: + x +except* Exception as e: + y +[out] +MypyFile:1( + TryStmt:1( + Block:2( + ExpressionStmt:2( + NameExpr(x))) + * + NameExpr(Exception) + NameExpr(e) + Block:4( + ExpressionStmt:4( + NameExpr(y))))) + +[case testTryMultipleExceptStar] +try: + x +except* ValueError: + y +except* KeyError as e: + z +[out] +MypyFile:1( + TryStmt:1( + Block:2( + ExpressionStmt:2( + NameExpr(x))) + * + NameExpr(ValueError) + Block:4( + ExpressionStmt:4( + NameExpr(y))) + NameExpr(KeyError) + NameExpr(e) + Block:6( + ExpressionStmt:6( + NameExpr(z))))) + +[case testTryExceptStarElseFinally] +try: + x +except* ValueError: + y +else: + z +finally: + w +[out] +MypyFile:1( + TryStmt:1( + Block:2( + ExpressionStmt:2( + NameExpr(x))) + * + NameExpr(ValueError) + Block:4( + ExpressionStmt:4( + NameExpr(y))) + Else( + ExpressionStmt:6( + NameExpr(z))) + Finally( + ExpressionStmt:8( + NameExpr(w))))) + +[case testUnpackTypeInSignature] +def f(*args: *Ts) -> None: + pass +[out] +MypyFile:1( + FuncDef:1( + f + def (*args: *Ts?) -> None? + VarArg( + Var(args)) + Block:2( + PassStmt:2()))) + +[case testUnpackTypeInTuple] +x: tuple[int, *Ts, str] +[out] +MypyFile:1( + AssignmentStmt:1( + NameExpr(x) + TempNode:1( + Any) + tuple?[int?, *Ts?, str?])) diff --git a/test-data/unit/native-parser-python312.test b/test-data/unit/native-parser-python312.test new file mode 100644 index 000000000000..2b1f9b42e0f7 --- /dev/null +++ b/test-data/unit/native-parser-python312.test @@ -0,0 +1,90 @@ +[case testPEP695TypeAlias] +# comment +type A[T] = C[T] +[out] +MypyFile:1( + TypeAliasStmt:2( + NameExpr(A) + TypeParam( + T) + LambdaExpr:2( + Block:-1( + ReturnStmt:2( + IndexExpr:2( + NameExpr(C) + NameExpr(T))))))) + +[case testPEP695GenericFunction] +# comment + +def f[T](): pass +def g[T: str](): pass +def h[T: (int, str)](): pass +[out] +MypyFile:1( + FuncDef:3( + f + TypeParam( + T) + Block:3( + PassStmt:3())) + FuncDef:4( + g + TypeParam( + T + str?) + Block:4( + PassStmt:4())) + FuncDef:5( + h + TypeParam( + T + Values( + int? + str?)) + Block:5( + PassStmt:5()))) + +[case testPEP695ParamSpec] +# comment + +def f[**P](): pass +class C[T: int, **P]: pass +[out] +MypyFile:1( + FuncDef:3( + f + TypeParam( + **P) + Block:3( + PassStmt:3())) + ClassDef:4( + C + TypeParam( + T + int?) + TypeParam( + **P) + PassStmt:4())) + +[case testPEP695TypeVarTuple] +# comment + +def f[*Ts](): pass +class C[T: int, *Ts]: pass +[out] +MypyFile:1( + FuncDef:3( + f + TypeParam( + *Ts) + Block:3( + PassStmt:3())) + ClassDef:4( + C + TypeParam( + T + int?) + TypeParam( + *Ts) + PassStmt:4())) diff --git a/test-data/unit/native-parser.test b/test-data/unit/native-parser.test index 5e44978e0e5a..abf653fc213c 100644 --- a/test-data/unit/native-parser.test +++ b/test-data/unit/native-parser.test @@ -1294,92 +1294,6 @@ MypyFile:1( ExpressionStmt:6( NameExpr(z))))) -[case testTryExceptStar] -try: - x -except* ValueError: - y -[out] -1:0: error: Exception groups: requires Python 3.11 or newer (current target: Python 3.10) -MypyFile:1( - TryStmt:1( - Block:2( - ExpressionStmt:2( - NameExpr(x))) - NameExpr(ValueError) - Block:4( - ExpressionStmt:4( - NameExpr(y))))) - -[case testTryExceptStarWithVar] -try: - x -except* Exception as e: - y -[out] -1:0: error: Exception groups: requires Python 3.11 or newer (current target: Python 3.10) -MypyFile:1( - TryStmt:1( - Block:2( - ExpressionStmt:2( - NameExpr(x))) - NameExpr(Exception) - NameExpr(e) - Block:4( - ExpressionStmt:4( - NameExpr(y))))) - -[case testTryMultipleExceptStar] -try: - x -except* ValueError: - y -except* KeyError as e: - z -[out] -1:0: error: Exception groups: requires Python 3.11 or newer (current target: Python 3.10) -MypyFile:1( - TryStmt:1( - Block:2( - ExpressionStmt:2( - NameExpr(x))) - NameExpr(ValueError) - Block:4( - ExpressionStmt:4( - NameExpr(y))) - NameExpr(KeyError) - NameExpr(e) - Block:6( - ExpressionStmt:6( - NameExpr(z))))) - -[case testTryExceptStarElseFinally] -try: - x -except* ValueError: - y -else: - z -finally: - w -[out] -1:0: error: Exception groups: requires Python 3.11 or newer (current target: Python 3.10) -MypyFile:1( - TryStmt:1( - Block:2( - ExpressionStmt:2( - NameExpr(x))) - NameExpr(ValueError) - Block:4( - ExpressionStmt:4( - NameExpr(y))) - Else( - ExpressionStmt:6( - NameExpr(z))) - Finally( - ExpressionStmt:8( - NameExpr(w))))) - [case testConditionalExprSimple] x if y else z [out] @@ -2018,32 +1932,6 @@ MypyFile:1( y)) PassStmt:5())) -[case testUnpackTypeInSignature] -def f(*args: *Ts) -> None: - pass -[out] -1:13: error: Star unpack syntax: requires Python 3.11 or newer (current target: Python 3.10) -MypyFile:1( - FuncDef:1( - f - def (*args: *Ts?) -> None? - VarArg( - Var(args)) - Block:2( - PassStmt:2()))) - -[case testUnpackTypeInTuple] -x: tuple[int, *Ts, str] -[out] -1:14: error: Star unpack syntax: requires Python 3.11 or newer (current target: Python 3.10) -MypyFile:1( - AssignmentStmt:1( - NameExpr(x) - TempNode:1( - Any) - tuple?[int?, *Ts?, str?])) - - [case testLiteralStringType] from typing import Literal x: Literal["hello"] @@ -3188,105 +3076,6 @@ MypyFile:1( Body( PassStmt:3()))) -[case testPEP695TypeAlias] -# comment -type A[T] = C[T] -[out] -2:0: error: "type" statements: requires Python 3.12 or newer (current target: Python 3.10) -MypyFile:1( - TypeAliasStmt:2( - NameExpr(A) - TypeParam( - T) - LambdaExpr:2( - Block:-1( - ReturnStmt:2( - IndexExpr:2( - NameExpr(C) - NameExpr(T))))))) - -[case testPEP695GenericFunction] -# comment - -def f[T](): pass -def g[T: str](): pass -def h[T: (int, str)](): pass -[out] -3:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) -4:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) -5:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) -MypyFile:1( - FuncDef:3( - f - TypeParam( - T) - Block:3( - PassStmt:3())) - FuncDef:4( - g - TypeParam( - T - str?) - Block:4( - PassStmt:4())) - FuncDef:5( - h - TypeParam( - T - Values( - int? - str?)) - Block:5( - PassStmt:5()))) - -[case testPEP695ParamSpec] -# comment - -def f[**P](): pass -class C[T: int, **P]: pass -[out] -3:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) -4:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) -MypyFile:1( - FuncDef:3( - f - TypeParam( - **P) - Block:3( - PassStmt:3())) - ClassDef:4( - C - TypeParam( - T - int?) - TypeParam( - **P) - PassStmt:4())) - -[case testPEP695TypeVarTuple] -# comment - -def f[*Ts](): pass -class C[T: int, *Ts]: pass -[out] -3:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) -4:0: error: Improved type parameter syntax: requires Python 3.12 or newer (current target: Python 3.10) -MypyFile:1( - FuncDef:3( - f - TypeParam( - *Ts) - Block:3( - PassStmt:3())) - ClassDef:4( - C - TypeParam( - T - int?) - TypeParam( - *Ts) - PassStmt:4())) - [case testTypeCommentLastLine] d = [ # Placeholder for items diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index fa3001c3a482..399003f02c7f 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -2272,8 +2272,10 @@ _testNarrowingMappingAndAbstractSet.py:39: note: Revealed type is "set[str]" [case testNativeParserTStringRequiresPython314] # flags: --python-version=3.13 --native-parser --ignore-missing-imports x = t"hello {1}" +reveal_type(x) [out] _testNativeParserTStringRequiresPython314.py:2: error: T-strings: requires Python 3.14 or newer (current target: Python 3.13) +_testNativeParserTStringRequiresPython314.py:3: note: Revealed type is "Any" [case testNativeParserTStringRequiresPython314InStub] # flags: --python-version=3.13 --native-parser --ignore-missing-imports @@ -2291,5 +2293,8 @@ from typing_extensions import TypeVarTuple, Unpack Ts = TypeVarTuple("Ts") def f(x: tuple[Unpack[Ts]]) -> None: ... def g(x: tuple[*Ts]) -> None: ... +reveal_type(g) +g((1, 2)) [out] _testNativeParserStarUnpackRequiresPython311.py:5: error: Star unpack syntax: requires Python 3.11 or newer (current target: Python 3.10) +_testNativeParserStarUnpackRequiresPython311.py:6: note: Revealed type is "def [Ts] (x: tuple[*Ts])"