Skip to content

Commit b0b25b3

Browse files
committed
add version checks
1 parent 37ee432 commit b0b25b3

2 files changed

Lines changed: 52 additions & 3 deletions

File tree

mypy/nativeparse.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
read_str as read_str_bare,
3030
)
3131

32-
from mypy import message_registry, nodes, types
32+
from mypy import defaults, message_registry, nodes, types
3333
from mypy.cache import (
3434
DICT_STR_GEN,
3535
END_TAG,
@@ -167,8 +167,9 @@
167167

168168

169169
class State:
170-
def __init__(self, options: Options) -> None:
170+
def __init__(self, options: Options, is_stub: bool = False) -> None:
171171
self.options = options
172+
self.is_stub = is_stub
172173
self.errors: list[ParseError] = []
173174
self.num_funcs = 0
174175

@@ -180,6 +181,28 @@ def add_error(
180181
{"line": line, "column": column, "message": message, "blocker": blocker, "code": code}
181182
)
182183

184+
def check_min_version(
185+
self,
186+
feature: str,
187+
min_version: tuple[int, int],
188+
line: int,
189+
column: int,
190+
) -> None:
191+
"""Report a non blocker syntax error if the target Python feature is older than min_version."""
192+
if self.is_stub:
193+
target = max(self.options.python_version, defaults.PYTHON3_VERSION)
194+
else:
195+
target = self.options.python_version
196+
if target < min_version:
197+
self.add_error(
198+
f"{feature} are only supported in Python "
199+
f"{min_version[0]}.{min_version[1]} and greater",
200+
line,
201+
column,
202+
blocker=False,
203+
code="syntax",
204+
)
205+
183206

184207
def native_parse(
185208
filename: str,
@@ -607,6 +630,13 @@ def read_parameters(state: State, data: ReadBuffer) -> tuple[list[Argument], boo
607630
return arguments, has_ann
608631

609632

633+
def check_type_param_defaults(
634+
state: State, type_params: list[TypeParam], line: int, column: int
635+
) -> None:
636+
if any(p.default is not None for p in type_params):
637+
state.check_min_version("Type parameter defaults", (3, 13), line, column)
638+
639+
610640
def read_type_params(state: State, data: ReadBuffer) -> list[TypeParam]:
611641
"""Read type parameters (PEP 695 generics)."""
612642
type_params: list[TypeParam] = []
@@ -680,6 +710,11 @@ def read_func_def(state: State, data: ReadBuffer) -> FuncDef:
680710
if is_async:
681711
func_def.is_coroutine = True
682712
read_loc(data, func_def)
713+
if type_params:
714+
state.check_min_version(
715+
"Type parameter lists", (3, 12), func_def.line, func_def.column
716+
)
717+
check_type_param_defaults(state, type_params, func_def.line, func_def.column)
683718
if typ:
684719
typ.line = func_def.line
685720
typ.column = func_def.column
@@ -727,6 +762,11 @@ def read_class_def(state: State, data: ReadBuffer) -> ClassDef:
727762
)
728763
class_def.decorators = decorators
729764
read_loc(data, class_def)
765+
if type_params:
766+
state.check_min_version(
767+
"Type parameter lists", (3, 12), class_def.line, class_def.column
768+
)
769+
check_type_param_defaults(state, type_params, class_def.line, class_def.column)
730770
expect_end_tag(data)
731771
return class_def
732772

@@ -781,6 +821,10 @@ def read_type_alias_stmt(state: State, data: ReadBuffer) -> TypeAliasStmt:
781821

782822
stmt = TypeAliasStmt(name, type_params, lambda_expr)
783823
read_loc(data, stmt)
824+
state.check_min_version(
825+
'"type" statements', (3, 12), stmt.line, stmt.column
826+
)
827+
check_type_param_defaults(state, type_params, stmt.line, stmt.column)
784828
expect_end_tag(data)
785829
return stmt
786830

@@ -832,6 +876,10 @@ def read_try_stmt(state: State, data: ReadBuffer) -> TryStmt:
832876
stmt = TryStmt(body, vars_list, types_list, handlers, else_body, finally_body)
833877
stmt.is_star = is_star
834878
read_loc(data, stmt)
879+
if is_star:
880+
state.check_min_version("Exception groups", (3, 11), stmt.line, stmt.column)
881+
if state.options.python_version < (3, 11):
882+
stmt.is_star = False
835883
expect_end_tag(data)
836884
return stmt
837885

@@ -1474,6 +1522,7 @@ def read_expression(state: State, data: ReadBuffer) -> Expression:
14741522
titems.append(s)
14751523
expr = TemplateStrExpr(titems)
14761524
read_loc(data, expr)
1525+
state.check_min_version("t-strings", (3, 14), expr.line, expr.column)
14771526
expect_end_tag(data)
14781527
return expr
14791528
elif tag == nodes.LAMBDA_EXPR:

mypy/parse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def load_from_raw(
7171
"""
7272
from mypy.nativeparse import State, deserialize_imports, read_statements
7373

74-
state = State(options)
74+
state = State(options, is_stub=fnam.endswith(".pyi"))
7575
if imports_only:
7676
defs = []
7777
else:

0 commit comments

Comments
 (0)