diff --git a/mypy/newsemanal/semanal.py b/mypy/newsemanal/semanal.py index 2602c3460ccf..947fb921e23b 100644 --- a/mypy/newsemanal/semanal.py +++ b/mypy/newsemanal/semanal.py @@ -71,7 +71,7 @@ IntExpr, FloatExpr, UnicodeExpr, TempNode, OverloadPart, PlaceholderNode, COVARIANT, CONTRAVARIANT, INVARIANT, nongen_builtins, get_member_expr_fullname, REVEAL_TYPE, - REVEAL_LOCALS, is_final_node, TypedDictExpr + REVEAL_LOCALS, is_final_node, TypedDictExpr, type_aliases_target_versions ) from mypy.tvar_scope import TypeVarScope from mypy.typevars import fill_typevars @@ -3840,6 +3840,9 @@ def add_builtin_aliases(self, tree: MypyFile) -> None: """ assert tree.fullname() == 'typing' for alias, target_name in type_aliases.items(): + if type_aliases_target_versions[alias] > self.options.python_version: + # This alias is not available on this Python version. + continue name = alias.split('.')[-1] if name in tree.names and not isinstance(tree.names[name].node, PlaceholderNode): continue @@ -3863,7 +3866,10 @@ def add_builtin_aliases(self, tree: MypyFile) -> None: self.mark_incomplete(name, tree) else: # Test fixtures may be missing some builtin classes, which is okay. - pass + # Kill the placeholder if there is one. + if name in tree.names: + assert isinstance(tree.names[name].node, PlaceholderNode) + del tree.names[name] def lookup_fully_qualified(self, name: str) -> SymbolTableNode: """Lookup a fully qualified name. diff --git a/mypy/nodes.py b/mypy/nodes.py index b1ae7e59f523..33cbda418115 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -111,6 +111,19 @@ def get_column(self) -> int: 'typing.Deque': 'collections.deque', } # type: Final +# This keeps track of the oldest supported Python version where the corresponding +# alias _target_ is available. +type_aliases_target_versions = { + 'typing.List': (2, 7), + 'typing.Dict': (2, 7), + 'typing.Set': (2, 7), + 'typing.FrozenSet': (2, 7), + 'typing.ChainMap': (3, 3), + 'typing.Counter': (2, 7), + 'typing.DefaultDict': (2, 7), + 'typing.Deque': (2, 7), +} # type: Final + reverse_builtin_aliases = { 'builtins.list': 'typing.List', 'builtins.dict': 'typing.Dict',