Skip to content

Commit 6bbc8c5

Browse files
septatrixmsullivan
andauthored
Add typing.OrderedDict to type_aliases (#9389)
Co-authored-by: Michael Sullivan <[email protected]>
1 parent e145ba8 commit 6bbc8c5

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

mypy/nodes.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,12 @@ def get_column(self) -> int:
114114
'typing.Counter': 'collections.Counter',
115115
'typing.DefaultDict': 'collections.defaultdict',
116116
'typing.Deque': 'collections.deque',
117+
'typing.OrderedDict': 'collections.OrderedDict',
117118
} # type: Final
118119

119120
# This keeps track of the oldest supported Python version where the corresponding
120-
# alias _target_ is available.
121-
type_aliases_target_versions = {
121+
# alias source is available.
122+
type_aliases_source_versions = {
122123
'typing.List': (2, 7),
123124
'typing.Dict': (2, 7),
124125
'typing.Set': (2, 7),
@@ -127,6 +128,7 @@ def get_column(self) -> int:
127128
'typing.Counter': (2, 7),
128129
'typing.DefaultDict': (2, 7),
129130
'typing.Deque': (2, 7),
131+
'typing.OrderedDict': (3, 7),
130132
} # type: Final
131133

132134
reverse_builtin_aliases = {
@@ -139,6 +141,8 @@ def get_column(self) -> int:
139141
nongen_builtins = {'builtins.tuple': 'typing.Tuple',
140142
'builtins.enumerate': ''} # type: Final
141143
nongen_builtins.update((name, alias) for alias, name in type_aliases.items())
144+
# Drop OrderedDict from this for backward compatibility
145+
del nongen_builtins['collections.OrderedDict']
142146

143147
RUNTIME_PROTOCOL_DECOS = ('typing.runtime_checkable',
144148
'typing_extensions.runtime',

mypy/semanal.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
IntExpr, FloatExpr, UnicodeExpr, TempNode, OverloadPart,
7575
PlaceholderNode, COVARIANT, CONTRAVARIANT, INVARIANT,
7676
nongen_builtins, get_member_expr_fullname, REVEAL_TYPE,
77-
REVEAL_LOCALS, is_final_node, TypedDictExpr, type_aliases_target_versions,
77+
REVEAL_LOCALS, is_final_node, TypedDictExpr, type_aliases_source_versions,
7878
EnumCallExpr, RUNTIME_PROTOCOL_DECOS, FakeExpression, Statement, AssignmentExpr,
7979
ParamSpecExpr
8080
)
@@ -307,12 +307,27 @@ def prepare_typing_namespace(self, file_node: MypyFile) -> None:
307307
308308
They will be replaced with real aliases when corresponding targets are ready.
309309
"""
310-
for stmt in file_node.defs.copy():
311-
if (isinstance(stmt, AssignmentStmt) and len(stmt.lvalues) == 1 and
312-
isinstance(stmt.lvalues[0], NameExpr)):
313-
# Assignment to a simple name, remove it if it is a dummy alias.
314-
if 'typing.' + stmt.lvalues[0].name in type_aliases:
315-
file_node.defs.remove(stmt)
310+
# This is all pretty unfortunate. typeshed now has a
311+
# sys.version_info check for OrderedDict, and we shouldn't
312+
# take it out, because it is correct and a typechecker should
313+
# use that as a source of truth. But instead we rummage
314+
# through IfStmts to remove the info first. (I tried to
315+
# remove this whole machinery and ran into issues with the
316+
# builtins/typing import cycle.)
317+
def helper(defs: List[Statement]) -> None:
318+
for stmt in defs.copy():
319+
if isinstance(stmt, IfStmt):
320+
for body in stmt.body:
321+
helper(body.body)
322+
if stmt.else_body:
323+
helper(stmt.else_body.body)
324+
if (isinstance(stmt, AssignmentStmt) and len(stmt.lvalues) == 1 and
325+
isinstance(stmt.lvalues[0], NameExpr)):
326+
# Assignment to a simple name, remove it if it is a dummy alias.
327+
if 'typing.' + stmt.lvalues[0].name in type_aliases:
328+
defs.remove(stmt)
329+
330+
helper(file_node.defs)
316331

317332
def prepare_builtins_namespace(self, file_node: MypyFile) -> None:
318333
"""Add certain special-cased definitions to the builtins module.
@@ -430,7 +445,7 @@ def add_builtin_aliases(self, tree: MypyFile) -> None:
430445
"""
431446
assert tree.fullname == 'typing'
432447
for alias, target_name in type_aliases.items():
433-
if type_aliases_target_versions[alias] > self.options.python_version:
448+
if type_aliases_source_versions[alias] > self.options.python_version:
434449
# This alias is not available on this Python version.
435450
continue
436451
name = alias.split('.')[-1]

0 commit comments

Comments
 (0)