Skip to content

Commit 37886c7

Browse files
authored
Always allow use of type[T] in stubs (#11863)
1 parent edbc248 commit 37886c7

File tree

3 files changed

+19
-20
lines changed

3 files changed

+19
-20
lines changed

Diff for: mypy/semanal.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -2631,7 +2631,6 @@ def analyze_alias(self, rvalue: Expression,
26312631
self.plugin,
26322632
self.options,
26332633
self.is_typeshed_stub_file,
2634-
allow_new_syntax=self.is_stub_file,
26352634
allow_placeholder=allow_placeholder,
26362635
in_dynamic_func=dynamic,
26372636
global_scope=global_scope)
@@ -5169,8 +5168,7 @@ def type_analyzer(self, *,
51695168
allow_tuple_literal=allow_tuple_literal,
51705169
report_invalid_types=report_invalid_types,
51715170
allow_placeholder=allow_placeholder,
5172-
allow_required=allow_required,
5173-
allow_new_syntax=self.is_stub_file)
5171+
allow_required=allow_required)
51745172
tpan.in_dynamic_func = bool(self.function_stack and self.function_stack[-1].is_dynamic())
51755173
tpan.global_scope = not self.type and not self.function_stack
51765174
return tpan

Diff for: mypy/typeanal.py

+15-17
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ def analyze_type_alias(node: Expression,
7070
plugin: Plugin,
7171
options: Options,
7272
is_typeshed_stub: bool,
73-
allow_new_syntax: bool = False,
7473
allow_placeholder: bool = False,
7574
in_dynamic_func: bool = False,
7675
global_scope: bool = True) -> Optional[Tuple[Type, Set[str]]]:
@@ -81,12 +80,12 @@ def analyze_type_alias(node: Expression,
8180
Return None otherwise. 'node' must have been semantically analyzed.
8281
"""
8382
try:
84-
type = expr_to_unanalyzed_type(node, options, allow_new_syntax)
83+
type = expr_to_unanalyzed_type(node, options, api.is_stub_file)
8584
except TypeTranslationError:
8685
api.fail('Invalid type alias: expression is not a valid type', node)
8786
return None
8887
analyzer = TypeAnalyser(api, tvar_scope, plugin, options, is_typeshed_stub,
89-
allow_new_syntax=allow_new_syntax, defining_alias=True,
88+
defining_alias=True,
9089
allow_placeholder=allow_placeholder)
9190
analyzer.in_dynamic_func = in_dynamic_func
9291
analyzer.global_scope = global_scope
@@ -127,7 +126,6 @@ def __init__(self,
127126
is_typeshed_stub: bool, *,
128127
defining_alias: bool = False,
129128
allow_tuple_literal: bool = False,
130-
allow_new_syntax: bool = False,
131129
allow_unbound_tvars: bool = False,
132130
allow_placeholder: bool = False,
133131
allow_required: bool = False,
@@ -144,8 +142,11 @@ def __init__(self,
144142
# Positive if we are analyzing arguments of another (outer) type
145143
self.nesting_level = 0
146144
# Should we allow new type syntax when targeting older Python versions
147-
# like 'list[int]' or 'X | Y' (allowed in stubs)?
148-
self.allow_new_syntax = allow_new_syntax
145+
# like 'list[int]' or 'X | Y' (allowed in stubs and with `__future__` import)?
146+
self.always_allow_new_syntax = (
147+
self.api.is_stub_file
148+
or self.api.is_future_flag_set('annotations')
149+
)
149150
# Should we accept unbound type variables (always OK in aliases)?
150151
self.allow_unbound_tvars = allow_unbound_tvars or defining_alias
151152
# If false, record incomplete ref if we generate PlaceholderType.
@@ -202,9 +203,8 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
202203
if hook is not None:
203204
return hook(AnalyzeTypeContext(t, t, self))
204205
if (fullname in get_nongen_builtins(self.options.python_version)
205-
and t.args and
206-
not self.allow_new_syntax and
207-
not self.api.is_future_flag_set("annotations")):
206+
and t.args
207+
and not self.always_allow_new_syntax):
208208
self.fail(no_subscript_builtin_alias(fullname,
209209
propose_alt=not self.defining_alias), t)
210210
tvar_def = self.tvar_scope.get_binding(sym)
@@ -291,9 +291,8 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt
291291
" in a variable annotation", t)
292292
return AnyType(TypeOfAny.from_error)
293293
elif (fullname == 'typing.Tuple' or
294-
(fullname == 'builtins.tuple' and (self.options.python_version >= (3, 9) or
295-
self.api.is_future_flag_set('annotations') or
296-
self.allow_new_syntax))):
294+
(fullname == 'builtins.tuple'
295+
and (self.always_allow_new_syntax or self.options.python_version >= (3, 9)))):
297296
# Tuple is special because it is involved in builtin import cycle
298297
# and may be not ready when used.
299298
sym = self.api.lookup_fully_qualified_or_none('builtins.tuple')
@@ -326,8 +325,8 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt
326325
elif fullname == 'typing.Callable':
327326
return self.analyze_callable_type(t)
328327
elif (fullname == 'typing.Type' or
329-
(fullname == 'builtins.type' and (self.options.python_version >= (3, 9) or
330-
self.api.is_future_flag_set('annotations')))):
328+
(fullname == 'builtins.type'
329+
and (self.always_allow_new_syntax or self.options.python_version >= (3, 9)))):
331330
if len(t.args) == 0:
332331
if fullname == 'typing.Type':
333332
any_type = self.get_omitted_any(t)
@@ -704,9 +703,8 @@ def visit_star_type(self, t: StarType) -> Type:
704703
def visit_union_type(self, t: UnionType) -> Type:
705704
if (t.uses_pep604_syntax is True
706705
and t.is_evaluated is True
707-
and self.api.is_stub_file is False
708-
and self.options.python_version < (3, 10)
709-
and self.api.is_future_flag_set('annotations') is False):
706+
and not self.always_allow_new_syntax
707+
and not self.options.python_version >= (3, 10)):
710708
self.fail("X | Y syntax for unions requires Python 3.10", t)
711709
return UnionType(self.anal_array(t.items), t.line)
712710

Diff for: test-data/unit/check-generic-alias.test

+3
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ b: B
273273
import m
274274
reveal_type(m.a) # N: Revealed type is "builtins.list[builtins.int]"
275275
reveal_type(m.b) # N: Revealed type is "builtins.list[builtins.list[builtins.int]]"
276+
m.C # has complex representation, ignored
277+
reveal_type(m.d) # N: Revealed type is "Type[builtins.str]"
276278

277279
[file m.pyi]
278280
A = list[int]
@@ -281,4 +283,5 @@ B = list[list[int]]
281283
b: B
282284
class C(list[int]):
283285
pass
286+
d: type[str]
284287
[builtins fixtures/list.pyi]

0 commit comments

Comments
 (0)