@@ -209,6 +209,11 @@ def __init__(
209209 self .allow_tuple_literal = allow_tuple_literal
210210 # Positive if we are analyzing arguments of another (outer) type
211211 self .nesting_level = 0
212+ # Should we allow new type syntax when targeting older Python versions
213+ # like 'list[int]' or 'X | Y' (allowed in stubs and with `__future__` import)?
214+ self .always_allow_new_syntax = self .api .is_stub_file or self .api .is_future_flag_set (
215+ "annotations"
216+ )
212217 # Should we accept unbound type variables? This is currently used for class bases,
213218 # and alias right hand sides (before they are analyzed as type aliases).
214219 self .allow_unbound_tvars = allow_unbound_tvars
@@ -292,7 +297,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
292297 if (
293298 fullname in get_nongen_builtins (self .options .python_version )
294299 and t .args
295- and not self .api . always_allow_new_syntax
300+ and not self .always_allow_new_syntax
296301 ):
297302 self .fail (
298303 no_subscript_builtin_alias (fullname , propose_alt = not self .defining_alias ), t
@@ -509,7 +514,10 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Typ
509514 code = codes .VALID_TYPE ,
510515 )
511516 return AnyType (TypeOfAny .from_error )
512- elif self .api .check_pep585_name (fullname , "tuple" ):
517+ elif fullname == "typing.Tuple" or (
518+ fullname == "builtins.tuple"
519+ and (self .always_allow_new_syntax or self .options .python_version >= (3 , 9 ))
520+ ):
513521 # Tuple is special because it is involved in builtin import cycle
514522 # and may be not ready when used.
515523 sym = self .api .lookup_fully_qualified_or_none ("builtins.tuple" )
@@ -542,7 +550,10 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Typ
542550 return make_optional_type (item )
543551 elif fullname == "typing.Callable" :
544552 return self .analyze_callable_type (t )
545- elif self .api .check_pep585_name (fullname , "type" ):
553+ elif fullname == "typing.Type" or (
554+ fullname == "builtins.type"
555+ and (self .always_allow_new_syntax or self .options .python_version >= (3 , 9 ))
556+ ):
546557 if len (t .args ) == 0 :
547558 if fullname == "typing.Type" :
548559 any_type = self .get_omitted_any (t )
@@ -1092,7 +1103,7 @@ def visit_union_type(self, t: UnionType) -> Type:
10921103 if (
10931104 t .uses_pep604_syntax is True
10941105 and t .is_evaluated is True
1095- and not self .api . always_allow_new_syntax
1106+ and not self .always_allow_new_syntax
10961107 and not self .options .python_version >= (3 , 10 )
10971108 ):
10981109 self .fail ("X | Y syntax for unions requires Python 3.10" , t , code = codes .SYNTAX )
0 commit comments