From 271e387ba7f8dd558765510bf525a5bdf3bfd9ad Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Fri, 9 Oct 2020 02:04:46 -0300 Subject: [PATCH 01/26] Allows builtins to be generic aliases (PEP 585) --- mypy/main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mypy/main.py b/mypy/main.py index 74758b40513e..f6cf61a792e8 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -81,6 +81,10 @@ def flush_errors(new_messages: List[str], serious: bool) -> None: f.write(msg + '\n') f.flush() + if options.python_version >= (3, 9): + from mypy.nodes import nongen_builtins + nongen_builtins.clear() + serious = False blockers = False res = None From 34726795a224528c9942cb8ba37258dd3efd49f1 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Fri, 9 Oct 2020 02:04:46 -0300 Subject: [PATCH 02/26] fix test testNoSubcriptionOfStdlibCollections --- test-data/unit/pythoneval.test | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index e3eaf8a00ff3..c401b57f8db9 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -854,6 +854,7 @@ _program.py:19: error: Dict entry 0 has incompatible type "str": "List[ _program.py:23: error: Invalid index type "str" for "MyDDict[Dict[_KT, _VT]]"; expected type "int" [case testNoSubcriptionOfStdlibCollections] +# flags: --python-version 3.6 import collections from collections import Counter from typing import TypeVar @@ -870,11 +871,11 @@ d[0] = 1 def f(d: collections.defaultdict[int, str]) -> None: ... [out] -_program.py:5: error: "defaultdict" is not subscriptable -_program.py:6: error: "Counter" is not subscriptable -_program.py:9: error: "defaultdict" is not subscriptable -_program.py:12: error: Invalid index type "int" for "defaultdict[str, int]"; expected type "str" -_program.py:14: error: "defaultdict" is not subscriptable, use "typing.DefaultDict" instead +_program.py:6: error: "defaultdict" is not subscriptable +_program.py:7: error: "Counter" is not subscriptable +_program.py:10: error: "defaultdict" is not subscriptable +_program.py:13: error: Invalid index type "int" for "defaultdict[str, int]"; expected type "str" +_program.py:15: error: "defaultdict" is not subscriptable, use "typing.DefaultDict" instead [case testCollectionsAliases] import typing as t From 1299956cf35573752cd19bbba2120d835e1b1aa7 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Fri, 9 Oct 2020 02:04:46 -0300 Subject: [PATCH 03/26] fix test testDisallowAnyGenericsBuiltinCollections --- test-data/unit/cmdline.test | 1 + 1 file changed, 1 insertion(+) diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test index 9d74bdc9a1be..a72bf9704b44 100644 --- a/test-data/unit/cmdline.test +++ b/test-data/unit/cmdline.test @@ -645,6 +645,7 @@ a.__pow__() # E: All overload variants of "__pow__" of "int" require at least on # cmd: mypy m.py [file mypy.ini] \[mypy] +python_version=3.6 \[mypy-m] disallow_any_generics = True From ca5c841c2e0edf7bf15a8ff1b880f62068410982 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Fri, 9 Oct 2020 02:04:46 -0300 Subject: [PATCH 04/26] Revert "Allows builtins to be generic aliases (PEP 585)" This reverts commit 22a4789d547121652c32de1ff25334ca6a9c3f0a. --- mypy/main.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mypy/main.py b/mypy/main.py index f6cf61a792e8..74758b40513e 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -81,10 +81,6 @@ def flush_errors(new_messages: List[str], serious: bool) -> None: f.write(msg + '\n') f.flush() - if options.python_version >= (3, 9): - from mypy.nodes import nongen_builtins - nongen_builtins.clear() - serious = False blockers = False res = None From dcfedebb72c752d6ede323da9dfd5089ca4d0612 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Fri, 9 Oct 2020 02:04:46 -0300 Subject: [PATCH 05/26] create get_nongen_builtins() to access nongen_builtins depending on python version (for pep585) --- mypy/nodes.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mypy/nodes.py b/mypy/nodes.py index dff1dd6c1072..f34f2daf9569 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -136,9 +136,13 @@ def get_column(self) -> int: 'builtins.frozenset': 'typing.FrozenSet', } # type: Final -nongen_builtins = {'builtins.tuple': 'typing.Tuple', +_nongen_builtins = {'builtins.tuple': 'typing.Tuple', 'builtins.enumerate': ''} # type: Final -nongen_builtins.update((name, alias) for alias, name in type_aliases.items()) +_nongen_builtins.update((name, alias) for alias, name in type_aliases.items()) + +def get_nongen_builtins(python_version): + # After 3.9 with pep585 generic builtins are allowed. + return _nongen_builtins if python_version < (3, 9) else {} RUNTIME_PROTOCOL_DECOS = ('typing.runtime_checkable', 'typing_extensions.runtime', From a9d099609722e677072a00d8843dd448b848d33e Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Fri, 9 Oct 2020 01:20:31 -0300 Subject: [PATCH 06/26] implements pep585 accepting generic builtins --- mypy/semanal.py | 11 ++++++----- mypy/typeanal.py | 30 +++++++++++++++++++----------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 2ea444bf4ab2..4c841a2bb260 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -73,7 +73,7 @@ YieldExpr, ExecStmt, BackquoteExpr, ImportBase, AwaitExpr, IntExpr, FloatExpr, UnicodeExpr, TempNode, OverloadPart, PlaceholderNode, COVARIANT, CONTRAVARIANT, INVARIANT, - nongen_builtins, get_member_expr_fullname, REVEAL_TYPE, + get_nongen_builtins, get_member_expr_fullname, REVEAL_TYPE, REVEAL_LOCALS, is_final_node, TypedDictExpr, type_aliases_target_versions, EnumCallExpr, RUNTIME_PROTOCOL_DECOS, FakeExpression, Statement, AssignmentExpr, ParamSpecExpr @@ -446,7 +446,7 @@ def add_builtin_aliases(self, tree: MypyFile) -> None: target = self.named_type_or_none(target_name, []) assert target is not None # Transform List to List[Any], etc. - fix_instance_types(target, self.fail, self.note) + fix_instance_types(target, self.fail, self.note, self.options.python_version) alias_node = TypeAlias(target, alias, line=-1, column=-1, # there is no context no_args=True, normalized=True) @@ -2566,7 +2566,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: # if the expected number of arguments is non-zero, so that aliases like A = List work. # However, eagerly expanding aliases like Text = str is a nice performance optimization. no_args = isinstance(res, Instance) and not res.args # type: ignore - fix_instance_types(res, self.fail, self.note) + fix_instance_types(res, self.fail, self.note, self.options.python_version) alias_node = TypeAlias(res, self.qualified_name(lvalue.name), s.line, s.column, alias_tvars=alias_tvars, no_args=no_args) if isinstance(s.rvalue, (IndexExpr, CallExpr)): # CallExpr is for `void = type(None)` @@ -3787,12 +3787,13 @@ def analyze_type_application(self, expr: IndexExpr) -> None: if isinstance(target, Instance): name = target.type.fullname if (alias.no_args and # this avoids bogus errors for already reported aliases - name in nongen_builtins and not alias.normalized): + name in get_nongen_builtins(self.options.python_version) and + not alias.normalized): self.fail(no_subscript_builtin_alias(name, propose_alt=False), expr) # ...or directly. else: n = self.lookup_type_node(base) - if n and n.fullname in nongen_builtins: + if n and n.fullname in get_nongen_builtins(self.options.python_version): self.fail(no_subscript_builtin_alias(n.fullname, propose_alt=False), expr) def analyze_type_application_args(self, expr: IndexExpr) -> Optional[List[Type]]: diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 7a7408d351e1..92a9bb962c13 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -21,7 +21,7 @@ from mypy.nodes import ( TypeInfo, Context, SymbolTableNode, Var, Expression, - nongen_builtins, check_arg_names, check_arg_kinds, ARG_POS, ARG_NAMED, + get_nongen_builtins, check_arg_names, check_arg_kinds, ARG_POS, ARG_NAMED, ARG_OPT, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2, TypeVarExpr, TypeVarLikeExpr, ParamSpecExpr, TypeAlias, PlaceholderNode, SYMBOL_FUNCBASE_TYPES, Decorator, MypyFile ) @@ -94,6 +94,8 @@ def analyze_type_alias(node: Expression, def no_subscript_builtin_alias(name: str, propose_alt: bool = True) -> str: msg = '"{}" is not subscriptable'.format(name.split('.')[-1]) + # This should never be called if the python_version is 3.9 or newer + nongen_builtins = get_nongen_builtins((3, 8)) replacement = nongen_builtins[name] if replacement and propose_alt: msg += ', use "{}" instead'.format(replacement) @@ -194,7 +196,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) hook = self.plugin.get_type_analyze_hook(fullname) if hook is not None: return hook(AnalyzeTypeContext(t, t, self)) - if (fullname in nongen_builtins + if (fullname in get_nongen_builtins(self.options.python_version) and t.args and not self.allow_unnormalized and not self.api.is_future_flag_set("annotations")): @@ -241,6 +243,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) self.fail, self.note, disallow_any=disallow_any, + python_version=self.options.python_version, use_generic_error=True, unexpanded_type=t) return res @@ -342,7 +345,7 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt def get_omitted_any(self, typ: Type, fullname: Optional[str] = None) -> AnyType: disallow_any = not self.is_typeshed_stub and self.options.disallow_any_generics - return get_omitted_any(disallow_any, self.fail, self.note, typ, fullname) + return get_omitted_any(disallow_any, self.fail, self.note, typ, self.options.python_version, fullname) def analyze_type_with_type_info( self, info: TypeInfo, args: Sequence[Type], ctx: Context) -> Type: @@ -364,7 +367,8 @@ def analyze_type_with_type_info( if len(instance.args) != len(info.type_vars) and not self.defining_alias: fix_instance(instance, self.fail, self.note, disallow_any=self.options.disallow_any_generics and - not self.is_typeshed_stub) + not self.is_typeshed_stub, + python_version=self.options.python_version) tup = info.tuple_type if tup is not None: @@ -970,9 +974,11 @@ def tuple_type(self, items: List[Type]) -> TupleType: def get_omitted_any(disallow_any: bool, fail: MsgCallback, note: MsgCallback, - orig_type: Type, fullname: Optional[str] = None, + orig_type: Type, python_version: Tuple[int, int], + fullname: Optional[str] = None, unexpanded_type: Optional[Type] = None) -> AnyType: if disallow_any: + nongen_builtins = get_nongen_builtins(python_version) if fullname in nongen_builtins: typ = orig_type # We use a dedicated error message for builtin generics (as the most common case). @@ -1010,7 +1016,8 @@ def get_omitted_any(disallow_any: bool, fail: MsgCallback, note: MsgCallback, def fix_instance(t: Instance, fail: MsgCallback, note: MsgCallback, - disallow_any: bool, use_generic_error: bool = False, + disallow_any: bool, python_version: Tuple[int, int], + use_generic_error: bool = False, unexpanded_type: Optional[Type] = None,) -> None: """Fix a malformed instance by replacing all type arguments with Any. @@ -1021,7 +1028,7 @@ def fix_instance(t: Instance, fail: MsgCallback, note: MsgCallback, fullname = None # type: Optional[str] else: fullname = t.type.fullname - any_type = get_omitted_any(disallow_any, fail, note, t, fullname, unexpanded_type) + any_type = get_omitted_any(disallow_any, fail, note, t, python_version, fullname, unexpanded_type) t.args = (any_type,) * len(t.type.type_vars) return # Invalid number of type parameters. @@ -1280,21 +1287,22 @@ def make_optional_type(t: Type) -> Type: return UnionType([t, NoneType()], t.line, t.column) -def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback) -> None: +def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int]) -> None: """Recursively fix all instance types (type argument count) in a given type. For example 'Union[Dict, List[str, int]]' will be transformed into 'Union[Dict[Any, Any], List[Any]]' in place. """ - t.accept(InstanceFixer(fail, note)) + t.accept(InstanceFixer(fail, note, python_version)) class InstanceFixer(TypeTraverserVisitor): - def __init__(self, fail: MsgCallback, note: MsgCallback) -> None: + def __init__(self, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int]) -> None: self.fail = fail self.note = note + self.python_version = python_version def visit_instance(self, typ: Instance) -> None: super().visit_instance(typ) if len(typ.args) != len(typ.type.type_vars): - fix_instance(typ, self.fail, self.note, disallow_any=False, use_generic_error=True) + fix_instance(typ, self.fail, self.note, disallow_any=False, python_version=self.python_version, use_generic_error=True) From 40b5aed0cd204506e56f6dd8d2f851e9fbb79dc2 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Wed, 14 Oct 2020 06:22:25 -0300 Subject: [PATCH 07/26] fix code style to mypy guidelines --- mypy/nodes.py | 6 ++++-- mypy/typeanal.py | 16 +++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/mypy/nodes.py b/mypy/nodes.py index f34f2daf9569..fed1033a5946 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -137,13 +137,15 @@ def get_column(self) -> int: } # type: Final _nongen_builtins = {'builtins.tuple': 'typing.Tuple', - 'builtins.enumerate': ''} # type: Final + 'builtins.enumerate': ''} # type: Final _nongen_builtins.update((name, alias) for alias, name in type_aliases.items()) -def get_nongen_builtins(python_version): + +def get_nongen_builtins(python_version: Tuple[int, int]) -> Dict[str, str]: # After 3.9 with pep585 generic builtins are allowed. return _nongen_builtins if python_version < (3, 9) else {} + RUNTIME_PROTOCOL_DECOS = ('typing.runtime_checkable', 'typing_extensions.runtime', 'typing_extensions.runtime_checkable') # type: Final diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 92a9bb962c13..dfd1217cda8f 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -345,7 +345,8 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt def get_omitted_any(self, typ: Type, fullname: Optional[str] = None) -> AnyType: disallow_any = not self.is_typeshed_stub and self.options.disallow_any_generics - return get_omitted_any(disallow_any, self.fail, self.note, typ, self.options.python_version, fullname) + return get_omitted_any(disallow_any, self.fail, self.note, typ, + self.options.python_version, fullname) def analyze_type_with_type_info( self, info: TypeInfo, args: Sequence[Type], ctx: Context) -> Type: @@ -1028,7 +1029,8 @@ def fix_instance(t: Instance, fail: MsgCallback, note: MsgCallback, fullname = None # type: Optional[str] else: fullname = t.type.fullname - any_type = get_omitted_any(disallow_any, fail, note, t, python_version, fullname, unexpanded_type) + any_type = get_omitted_any(disallow_any, fail, note, t, python_version, fullname, + unexpanded_type) t.args = (any_type,) * len(t.type.type_vars) return # Invalid number of type parameters. @@ -1287,7 +1289,8 @@ def make_optional_type(t: Type) -> Type: return UnionType([t, NoneType()], t.line, t.column) -def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int]) -> None: +def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback, + python_version: Tuple[int, int]) -> None: """Recursively fix all instance types (type argument count) in a given type. For example 'Union[Dict, List[str, int]]' will be transformed into @@ -1297,7 +1300,9 @@ def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback, python_ver class InstanceFixer(TypeTraverserVisitor): - def __init__(self, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int]) -> None: + def __init__( + self, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int] + ) -> None: self.fail = fail self.note = note self.python_version = python_version @@ -1305,4 +1310,5 @@ def __init__(self, fail: MsgCallback, note: MsgCallback, python_version: Tuple[i def visit_instance(self, typ: Instance) -> None: super().visit_instance(typ) if len(typ.args) != len(typ.type.type_vars): - fix_instance(typ, self.fail, self.note, disallow_any=False, python_version=self.python_version, use_generic_error=True) + fix_instance(typ, self.fail, self.note, disallow_any=False, + python_version=self.python_version, use_generic_error=True) From d4492aea4a2557269641fda6d8a5f94f9acf8500 Mon Sep 17 00:00:00 2001 From: cdce8p <30130371+cdce8p@users.noreply.github.com> Date: Sat, 17 Oct 2020 22:10:31 +0200 Subject: [PATCH 08/26] Added testcases for pep585ga --- mypy/test/testcheck.py | 1 + mypy/typeanal.py | 3 +- test-data/unit/check-generic-alias.test | 49 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 test-data/unit/check-generic-alias.test diff --git a/mypy/test/testcheck.py b/mypy/test/testcheck.py index 34d9b66da0c1..a81ed113a709 100644 --- a/mypy/test/testcheck.py +++ b/mypy/test/testcheck.py @@ -91,6 +91,7 @@ 'check-errorcodes.test', 'check-annotated.test', 'check-parameter-specification.test', + 'check-generic-alias.test', ] # Tests that use Python 3.8-only AST features (like expression-scoped ignores): diff --git a/mypy/typeanal.py b/mypy/typeanal.py index dfd1217cda8f..adf8f35a1e7c 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -308,7 +308,8 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt elif fullname == 'typing.Callable': return self.analyze_callable_type(t) elif (fullname == 'typing.Type' or - (fullname == 'builtins.type' and self.api.is_future_flag_set('annotations'))): + (fullname == 'builtins.type' and self.api.is_future_flag_set('annotations')) or + (fullname == 'builtins.type' and not self.options.python_version < (3, 9))): if len(t.args) == 0: if fullname == 'typing.Type': any_type = self.get_omitted_any(t) diff --git a/test-data/unit/check-generic-alias.test b/test-data/unit/check-generic-alias.test new file mode 100644 index 000000000000..c0b5a81fdc20 --- /dev/null +++ b/test-data/unit/check-generic-alias.test @@ -0,0 +1,49 @@ +-- Test cases for generic aliases + +[case testGenericAliasImportCollections] +# flags: --python-version 3.9 +from collections import defaultdict, OrderedDict, ChainMap, Counter, deque + +t1: defaultdict[int, int] +t2: OrderedDict[int, int] +t3: ChainMap[int, int] +t4: Counter[int] +t5: deque[int] + +[builtins fixtures/tuple.pyi] + +[case testGenericAliasImportCollectionsABC] +# flags: --python-version 3.9 +from collections.abc import Awaitable, Coroutine, Iterable, Iterator, Mapping + +t1: Awaitable +t2: Coroutine +t3: Iterable +t4: Iterator +t5: Mapping + +[builtins fixtures/tuple.pyi] + +[case testGenericAliasImportBuiltIns] +# flags: --python-version 3.9 + +t1: type[int] + +[builtins fixtures/list.pyi] +[builtins fixtures/dict.pyi] + +[case testGenericAliasImportBuiltInsSet] +# flags: --python-version 3.9 + +t1: set[int] + +[builtins fixtures/set.pyi] + +[case testGenericAliasImportRe] +# flags: --python-version 3.9 +from re import Pattern, Match + +t1: Pattern[str] +t2: Match[str] + +[builtins fixtures/tuple.pyi] From 14f2732b5391db1a5a3d1d35d3d1eab1a9206036 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sat, 24 Oct 2020 15:28:52 -0300 Subject: [PATCH 09/26] Allows builtins to be generic aliases (PEP 585) --- mypy/main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mypy/main.py b/mypy/main.py index 74758b40513e..f6cf61a792e8 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -81,6 +81,10 @@ def flush_errors(new_messages: List[str], serious: bool) -> None: f.write(msg + '\n') f.flush() + if options.python_version >= (3, 9): + from mypy.nodes import nongen_builtins + nongen_builtins.clear() + serious = False blockers = False res = None From 6e9341c232b0e350f18255726a073e959a6e38ed Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sat, 24 Oct 2020 15:28:52 -0300 Subject: [PATCH 10/26] fix test testNoSubcriptionOfStdlibCollections --- test-data/unit/pythoneval.test | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index e3eaf8a00ff3..c401b57f8db9 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -854,6 +854,7 @@ _program.py:19: error: Dict entry 0 has incompatible type "str": "List[ _program.py:23: error: Invalid index type "str" for "MyDDict[Dict[_KT, _VT]]"; expected type "int" [case testNoSubcriptionOfStdlibCollections] +# flags: --python-version 3.6 import collections from collections import Counter from typing import TypeVar @@ -870,11 +871,11 @@ d[0] = 1 def f(d: collections.defaultdict[int, str]) -> None: ... [out] -_program.py:5: error: "defaultdict" is not subscriptable -_program.py:6: error: "Counter" is not subscriptable -_program.py:9: error: "defaultdict" is not subscriptable -_program.py:12: error: Invalid index type "int" for "defaultdict[str, int]"; expected type "str" -_program.py:14: error: "defaultdict" is not subscriptable, use "typing.DefaultDict" instead +_program.py:6: error: "defaultdict" is not subscriptable +_program.py:7: error: "Counter" is not subscriptable +_program.py:10: error: "defaultdict" is not subscriptable +_program.py:13: error: Invalid index type "int" for "defaultdict[str, int]"; expected type "str" +_program.py:15: error: "defaultdict" is not subscriptable, use "typing.DefaultDict" instead [case testCollectionsAliases] import typing as t From f737ef77c009ddea3a85575de24c119613d861b4 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sat, 24 Oct 2020 15:28:52 -0300 Subject: [PATCH 11/26] fix test testDisallowAnyGenericsBuiltinCollections --- test-data/unit/cmdline.test | 1 + 1 file changed, 1 insertion(+) diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test index 541f63d10039..60c2e64d084f 100644 --- a/test-data/unit/cmdline.test +++ b/test-data/unit/cmdline.test @@ -663,6 +663,7 @@ a.__pow__() # E: All overload variants of "__pow__" of "int" require at least on # cmd: mypy m.py [file mypy.ini] \[mypy] +python_version=3.6 \[mypy-m] disallow_any_generics = True From 8d53899cc8d9865b7af39bec8f1209fb709e03ca Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sat, 24 Oct 2020 15:28:52 -0300 Subject: [PATCH 12/26] Revert "Allows builtins to be generic aliases (PEP 585)" This reverts commit 22a4789d547121652c32de1ff25334ca6a9c3f0a. --- mypy/main.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mypy/main.py b/mypy/main.py index f6cf61a792e8..74758b40513e 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -81,10 +81,6 @@ def flush_errors(new_messages: List[str], serious: bool) -> None: f.write(msg + '\n') f.flush() - if options.python_version >= (3, 9): - from mypy.nodes import nongen_builtins - nongen_builtins.clear() - serious = False blockers = False res = None From 8b7eb7eefa14d8872e924dfc11c91e35788e8687 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sat, 24 Oct 2020 15:27:14 -0300 Subject: [PATCH 13/26] create get_nongen_builtins() to access nongen_builtins depending on python version (for pep585) --- mypy/nodes.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mypy/nodes.py b/mypy/nodes.py index 992fd8a59f60..7a9f51ab2ce4 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -138,11 +138,15 @@ def get_column(self) -> int: 'builtins.frozenset': 'typing.FrozenSet', } # type: Final -nongen_builtins = {'builtins.tuple': 'typing.Tuple', +_nongen_builtins = {'builtins.tuple': 'typing.Tuple', 'builtins.enumerate': ''} # type: Final -nongen_builtins.update((name, alias) for alias, name in type_aliases.items()) +_nongen_builtins.update((name, alias) for alias, name in type_aliases.items()) # Drop OrderedDict from this for backward compatibility -del nongen_builtins['collections.OrderedDict'] +del _nongen_builtins['collections.OrderedDict'] + +def get_nongen_builtins(python_version): + # After 3.9 with pep585 generic builtins are allowed. + return _nongen_builtins if python_version < (3, 9) else {} RUNTIME_PROTOCOL_DECOS = ('typing.runtime_checkable', 'typing_extensions.runtime', From 6b9b7986f067a7366839701b604425f31ac05f68 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sat, 24 Oct 2020 15:27:14 -0300 Subject: [PATCH 14/26] implements pep585 accepting generic builtins --- mypy/semanal.py | 11 ++++++----- mypy/typeanal.py | 30 +++++++++++++++++++----------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index cf02e967242c..840c5effdb2e 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -73,7 +73,7 @@ YieldExpr, ExecStmt, BackquoteExpr, ImportBase, AwaitExpr, IntExpr, FloatExpr, UnicodeExpr, TempNode, OverloadPart, PlaceholderNode, COVARIANT, CONTRAVARIANT, INVARIANT, - nongen_builtins, get_member_expr_fullname, REVEAL_TYPE, + get_nongen_builtins, get_member_expr_fullname, REVEAL_TYPE, REVEAL_LOCALS, is_final_node, TypedDictExpr, type_aliases_source_versions, EnumCallExpr, RUNTIME_PROTOCOL_DECOS, FakeExpression, Statement, AssignmentExpr, ParamSpecExpr @@ -461,7 +461,7 @@ def add_builtin_aliases(self, tree: MypyFile) -> None: target = self.named_type_or_none(target_name, []) assert target is not None # Transform List to List[Any], etc. - fix_instance_types(target, self.fail, self.note) + fix_instance_types(target, self.fail, self.note, self.options.python_version) alias_node = TypeAlias(target, alias, line=-1, column=-1, # there is no context no_args=True, normalized=True) @@ -2585,7 +2585,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: # if the expected number of arguments is non-zero, so that aliases like A = List work. # However, eagerly expanding aliases like Text = str is a nice performance optimization. no_args = isinstance(res, Instance) and not res.args # type: ignore - fix_instance_types(res, self.fail, self.note) + fix_instance_types(res, self.fail, self.note, self.options.python_version) alias_node = TypeAlias(res, self.qualified_name(lvalue.name), s.line, s.column, alias_tvars=alias_tvars, no_args=no_args) if isinstance(s.rvalue, (IndexExpr, CallExpr)): # CallExpr is for `void = type(None)` @@ -3803,12 +3803,13 @@ def analyze_type_application(self, expr: IndexExpr) -> None: if isinstance(target, Instance): name = target.type.fullname if (alias.no_args and # this avoids bogus errors for already reported aliases - name in nongen_builtins and not alias.normalized): + name in get_nongen_builtins(self.options.python_version) and + not alias.normalized): self.fail(no_subscript_builtin_alias(name, propose_alt=False), expr) # ...or directly. else: n = self.lookup_type_node(base) - if n and n.fullname in nongen_builtins: + if n and n.fullname in get_nongen_builtins(self.options.python_version): self.fail(no_subscript_builtin_alias(n.fullname, propose_alt=False), expr) def analyze_type_application_args(self, expr: IndexExpr) -> Optional[List[Type]]: diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 7a7408d351e1..92a9bb962c13 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -21,7 +21,7 @@ from mypy.nodes import ( TypeInfo, Context, SymbolTableNode, Var, Expression, - nongen_builtins, check_arg_names, check_arg_kinds, ARG_POS, ARG_NAMED, + get_nongen_builtins, check_arg_names, check_arg_kinds, ARG_POS, ARG_NAMED, ARG_OPT, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2, TypeVarExpr, TypeVarLikeExpr, ParamSpecExpr, TypeAlias, PlaceholderNode, SYMBOL_FUNCBASE_TYPES, Decorator, MypyFile ) @@ -94,6 +94,8 @@ def analyze_type_alias(node: Expression, def no_subscript_builtin_alias(name: str, propose_alt: bool = True) -> str: msg = '"{}" is not subscriptable'.format(name.split('.')[-1]) + # This should never be called if the python_version is 3.9 or newer + nongen_builtins = get_nongen_builtins((3, 8)) replacement = nongen_builtins[name] if replacement and propose_alt: msg += ', use "{}" instead'.format(replacement) @@ -194,7 +196,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) hook = self.plugin.get_type_analyze_hook(fullname) if hook is not None: return hook(AnalyzeTypeContext(t, t, self)) - if (fullname in nongen_builtins + if (fullname in get_nongen_builtins(self.options.python_version) and t.args and not self.allow_unnormalized and not self.api.is_future_flag_set("annotations")): @@ -241,6 +243,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) self.fail, self.note, disallow_any=disallow_any, + python_version=self.options.python_version, use_generic_error=True, unexpanded_type=t) return res @@ -342,7 +345,7 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt def get_omitted_any(self, typ: Type, fullname: Optional[str] = None) -> AnyType: disallow_any = not self.is_typeshed_stub and self.options.disallow_any_generics - return get_omitted_any(disallow_any, self.fail, self.note, typ, fullname) + return get_omitted_any(disallow_any, self.fail, self.note, typ, self.options.python_version, fullname) def analyze_type_with_type_info( self, info: TypeInfo, args: Sequence[Type], ctx: Context) -> Type: @@ -364,7 +367,8 @@ def analyze_type_with_type_info( if len(instance.args) != len(info.type_vars) and not self.defining_alias: fix_instance(instance, self.fail, self.note, disallow_any=self.options.disallow_any_generics and - not self.is_typeshed_stub) + not self.is_typeshed_stub, + python_version=self.options.python_version) tup = info.tuple_type if tup is not None: @@ -970,9 +974,11 @@ def tuple_type(self, items: List[Type]) -> TupleType: def get_omitted_any(disallow_any: bool, fail: MsgCallback, note: MsgCallback, - orig_type: Type, fullname: Optional[str] = None, + orig_type: Type, python_version: Tuple[int, int], + fullname: Optional[str] = None, unexpanded_type: Optional[Type] = None) -> AnyType: if disallow_any: + nongen_builtins = get_nongen_builtins(python_version) if fullname in nongen_builtins: typ = orig_type # We use a dedicated error message for builtin generics (as the most common case). @@ -1010,7 +1016,8 @@ def get_omitted_any(disallow_any: bool, fail: MsgCallback, note: MsgCallback, def fix_instance(t: Instance, fail: MsgCallback, note: MsgCallback, - disallow_any: bool, use_generic_error: bool = False, + disallow_any: bool, python_version: Tuple[int, int], + use_generic_error: bool = False, unexpanded_type: Optional[Type] = None,) -> None: """Fix a malformed instance by replacing all type arguments with Any. @@ -1021,7 +1028,7 @@ def fix_instance(t: Instance, fail: MsgCallback, note: MsgCallback, fullname = None # type: Optional[str] else: fullname = t.type.fullname - any_type = get_omitted_any(disallow_any, fail, note, t, fullname, unexpanded_type) + any_type = get_omitted_any(disallow_any, fail, note, t, python_version, fullname, unexpanded_type) t.args = (any_type,) * len(t.type.type_vars) return # Invalid number of type parameters. @@ -1280,21 +1287,22 @@ def make_optional_type(t: Type) -> Type: return UnionType([t, NoneType()], t.line, t.column) -def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback) -> None: +def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int]) -> None: """Recursively fix all instance types (type argument count) in a given type. For example 'Union[Dict, List[str, int]]' will be transformed into 'Union[Dict[Any, Any], List[Any]]' in place. """ - t.accept(InstanceFixer(fail, note)) + t.accept(InstanceFixer(fail, note, python_version)) class InstanceFixer(TypeTraverserVisitor): - def __init__(self, fail: MsgCallback, note: MsgCallback) -> None: + def __init__(self, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int]) -> None: self.fail = fail self.note = note + self.python_version = python_version def visit_instance(self, typ: Instance) -> None: super().visit_instance(typ) if len(typ.args) != len(typ.type.type_vars): - fix_instance(typ, self.fail, self.note, disallow_any=False, use_generic_error=True) + fix_instance(typ, self.fail, self.note, disallow_any=False, python_version=self.python_version, use_generic_error=True) From 40b2da38c44f6c31297d558287bbc04b9c1e5a9c Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sat, 24 Oct 2020 15:27:14 -0300 Subject: [PATCH 15/26] fix code style to mypy guidelines --- mypy/nodes.py | 6 ++++-- mypy/typeanal.py | 16 +++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/mypy/nodes.py b/mypy/nodes.py index 7a9f51ab2ce4..0571788bf002 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -139,15 +139,17 @@ def get_column(self) -> int: } # type: Final _nongen_builtins = {'builtins.tuple': 'typing.Tuple', - 'builtins.enumerate': ''} # type: Final + 'builtins.enumerate': ''} # type: Final _nongen_builtins.update((name, alias) for alias, name in type_aliases.items()) # Drop OrderedDict from this for backward compatibility del _nongen_builtins['collections.OrderedDict'] -def get_nongen_builtins(python_version): + +def get_nongen_builtins(python_version: Tuple[int, int]) -> Dict[str, str]: # After 3.9 with pep585 generic builtins are allowed. return _nongen_builtins if python_version < (3, 9) else {} + RUNTIME_PROTOCOL_DECOS = ('typing.runtime_checkable', 'typing_extensions.runtime', 'typing_extensions.runtime_checkable') # type: Final diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 92a9bb962c13..dfd1217cda8f 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -345,7 +345,8 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt def get_omitted_any(self, typ: Type, fullname: Optional[str] = None) -> AnyType: disallow_any = not self.is_typeshed_stub and self.options.disallow_any_generics - return get_omitted_any(disallow_any, self.fail, self.note, typ, self.options.python_version, fullname) + return get_omitted_any(disallow_any, self.fail, self.note, typ, + self.options.python_version, fullname) def analyze_type_with_type_info( self, info: TypeInfo, args: Sequence[Type], ctx: Context) -> Type: @@ -1028,7 +1029,8 @@ def fix_instance(t: Instance, fail: MsgCallback, note: MsgCallback, fullname = None # type: Optional[str] else: fullname = t.type.fullname - any_type = get_omitted_any(disallow_any, fail, note, t, python_version, fullname, unexpanded_type) + any_type = get_omitted_any(disallow_any, fail, note, t, python_version, fullname, + unexpanded_type) t.args = (any_type,) * len(t.type.type_vars) return # Invalid number of type parameters. @@ -1287,7 +1289,8 @@ def make_optional_type(t: Type) -> Type: return UnionType([t, NoneType()], t.line, t.column) -def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int]) -> None: +def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback, + python_version: Tuple[int, int]) -> None: """Recursively fix all instance types (type argument count) in a given type. For example 'Union[Dict, List[str, int]]' will be transformed into @@ -1297,7 +1300,9 @@ def fix_instance_types(t: Type, fail: MsgCallback, note: MsgCallback, python_ver class InstanceFixer(TypeTraverserVisitor): - def __init__(self, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int]) -> None: + def __init__( + self, fail: MsgCallback, note: MsgCallback, python_version: Tuple[int, int] + ) -> None: self.fail = fail self.note = note self.python_version = python_version @@ -1305,4 +1310,5 @@ def __init__(self, fail: MsgCallback, note: MsgCallback, python_version: Tuple[i def visit_instance(self, typ: Instance) -> None: super().visit_instance(typ) if len(typ.args) != len(typ.type.type_vars): - fix_instance(typ, self.fail, self.note, disallow_any=False, python_version=self.python_version, use_generic_error=True) + fix_instance(typ, self.fail, self.note, disallow_any=False, + python_version=self.python_version, use_generic_error=True) From 90a5192aac42c78014148e2a893dc6968b554d43 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sat, 24 Oct 2020 21:12:32 -0300 Subject: [PATCH 16/26] Update test-data/unit/check-generic-alias.test Co-authored-by: cdce8p <30130371+cdce8p@users.noreply.github.com> --- test-data/unit/check-generic-alias.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test-data/unit/check-generic-alias.test b/test-data/unit/check-generic-alias.test index c0b5a81fdc20..4ea0fe4cc03c 100644 --- a/test-data/unit/check-generic-alias.test +++ b/test-data/unit/check-generic-alias.test @@ -28,6 +28,8 @@ t5: Mapping # flags: --python-version 3.9 t1: type[int] +t2: tuple[int, int] +t3: dict[int, str] [builtins fixtures/list.pyi] [builtins fixtures/dict.pyi] From 8dbd6ac6b9fbed998c73f342f7a51952c6cbbbee Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sat, 24 Oct 2020 21:23:19 -0300 Subject: [PATCH 17/26] @hauntsaninja suggestion --- mypy/typeanal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index adf8f35a1e7c..0cb453104616 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -308,8 +308,8 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt elif fullname == 'typing.Callable': return self.analyze_callable_type(t) elif (fullname == 'typing.Type' or - (fullname == 'builtins.type' and self.api.is_future_flag_set('annotations')) or - (fullname == 'builtins.type' and not self.options.python_version < (3, 9))): + (fullname == 'builtins.type' and (self.options.python_version >= (3, 9) or + self.api.is_future_flag_set('annotations')))): if len(t.args) == 0: if fullname == 'typing.Type': any_type = self.get_omitted_any(t) From 779dffd883c71a6893ec3a04a25c585db4ca1d8e Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sun, 25 Oct 2020 00:52:48 -0300 Subject: [PATCH 18/26] add tests cases for PEP 585 generic builtins --- test-data/unit/check-generic-alias.test | 254 +++++++++++++++++++++--- 1 file changed, 230 insertions(+), 24 deletions(-) diff --git a/test-data/unit/check-generic-alias.test b/test-data/unit/check-generic-alias.test index 4ea0fe4cc03c..e137c0c3ea25 100644 --- a/test-data/unit/check-generic-alias.test +++ b/test-data/unit/check-generic-alias.test @@ -1,46 +1,191 @@ -- Test cases for generic aliases -[case testGenericAliasImportCollections] -# flags: --python-version 3.9 -from collections import defaultdict, OrderedDict, ChainMap, Counter, deque -t1: defaultdict[int, int] -t2: OrderedDict[int, int] -t3: ChainMap[int, int] -t4: Counter[int] -t5: deque[int] -[builtins fixtures/tuple.pyi] +-- Non passing tests, tests the new generic aliases with old versions generating errors -[case testGenericAliasImportCollectionsABC] -# flags: --python-version 3.9 -from collections.abc import Awaitable, Coroutine, Iterable, Iterator, Mapping +[case testGenericBuiltinNonPassing] +# flags: --python-version 3.6 -t1: Awaitable -t2: Coroutine -t3: Iterable -t4: Iterator -t5: Mapping +t1: list +t2: list[int] # E: "list" is not subscriptable, use "typing.List" instead +t3: list[str] # E: "list" is not subscriptable, use "typing.List" instead -[builtins fixtures/tuple.pyi] +t4: tuple +t5: tuple[int] # E: "tuple" is not subscriptable, use "typing.Tuple" instead + +t6: dict = {} +t7: dict[int, str] # E: "dict" is not subscriptable, use "typing.Dict" instead + +[builtins fixtures/list.pyi] +[builtins fixtures/dict.pyi] + + +[case testGenericBuiltinSetNonPassing] +# flags: --python-version 3.6 + +t1: set +t2: set[int] # E: "set" is not subscriptable, use "typing.Set" instead + +[builtins fixtures/set.pyi] + + +[case testGenericBuiltinTypeNonPassing] +# flags: --python-version 3.6 -[case testGenericAliasImportBuiltIns] +t1: type +t2: type[int] # E: "type" expects no type arguments, but 1 given + +[builtins fixtures/set.pyi] + +[case testGenericBuiltinCollectionsNonPassing] +# flags: --python-version 3.6 +import builtins +import collections + +t01: collections.deque +t02: collections.deque[int] # E: "deque" is not subscriptable, use "typing.Deque" instead +t03: collections.defaultdict +t04: collections.defaultdict[int, str] # E: "defaultdict" is not subscriptable, use "typing.DefaultDict" instead +t05: collections.OrderedDict +t06: collections.OrderedDict[int, str] +t07: collections.Counter +t08: collections.Counter[int] # E: "Counter" is not subscriptable, use "typing.Counter" instead +t09: collections.ChainMap +t10: collections.ChainMap[int, str] # E: "ChainMap" is not subscriptable, use "typing.ChainMap" instead + +-- Testing with colletions.abc all of them works actually, so I'll just leave it + + + +-- ------------------------------------------------------- -- +-- Testing the builtins generic aliases defined in PEP 585 -- + + +[case testGenericAliasImportBuiltins] # flags: --python-version 3.9 +t1: list +t2: list[int] +t3: list[str] + +t4: tuple +t5: tuple[int] +t6: tuple[int, str] -t1: type[int] -t2: tuple[int, int] -t3: dict[int, str] +t7: dict +t8: dict[str, int] + +reveal_type(t1) # N: Revealed type is 'builtins.list[Any]' +reveal_type(t2) # N: Revealed type is 'builtins.list[builtins.int]' +reveal_type(t3) # N: Revealed type is 'builtins.list[builtins.str]' +reveal_type(t4) # N: Revealed type is 'builtins.tuple[Any]' +# reveal_type(t5) # Nx Revealed type is 'builtins.tuple[builtins.int]' +# reveal_type(t6) # Nx Revealed type is 'builtins.tuple[builtins.int, builtins.str]' +reveal_type(t7) # N: Revealed type is 'builtins.dict[Any, Any]' +reveal_type(t8) # N: Revealed type is 'builtins.dict[builtins.str, builtins.int]' [builtins fixtures/list.pyi] [builtins fixtures/dict.pyi] -[case testGenericAliasImportBuiltInsSet] + +[case testGenericAliasImportBuiltinsSet] # flags: --python-version 3.9 +t1: set +t2: set[int] +t3: set[str] -t1: set[int] +reveal_type(t1) # N: Revealed type is 'builtins.set[Any]' +reveal_type(t2) # N: Revealed type is 'builtins.set[builtins.int]' +reveal_type(t3) # N: Revealed type is 'builtins.set[builtins.str]' [builtins fixtures/set.pyi] + +[case testGenericAliasImportBuiltinsType] +# flags: --python-version 3.9 +t1: type +t2: type[int] +t3: type[str] + +reveal_type(t1) # N: Revealed type is 'builtins.type' +# reveal_type(t2) # N Revealed type is 'Type[builtins.int]' +# reveal_type(t3) # N Revealed type is 'Type[builtins.str]' + + +[case testGenericAliasImportCollections] +# flags: --python-version 3.9 +import collections + +t1: collections.deque[int] +t2: collections.defaultdict[int, str] +t3: collections.OrderedDict[int, str] +t4: collections.Counter[int] +t5: collections.ChainMap[int, str] + +reveal_type(t1) # N: Revealed type is 'collections.deque[builtins.int]' +reveal_type(t2) # N: Revealed type is 'collections.defaultdict[builtins.int, builtins.str]' +reveal_type(t3) # N: Revealed type is 'collections.OrderedDict[builtins.int, builtins.str]' +reveal_type(t4) # N: Revealed type is 'collections.Counter[builtins.int]' +reveal_type(t5) # N: Revealed type is 'collections.ChainMap[builtins.int, builtins.str]' + +[builtins fixtures/tuple.pyi] + + +[case testGenericAliasImportCollectionsABC] +# flags: --python-version 3.9 +import collections.abc + +t01: collections.abc.Awaitable[int] +t02: collections.abc.Coroutine[str, int, float] +t03: collections.abc.AsyncIterable[int] +t04: collections.abc.AsyncIterator[int] +t05: collections.abc.AsyncGenerator[int, float] +t06: collections.abc.Iterable[int] +t07: collections.abc.Iterator[int] +t08: collections.abc.Generator[int, float, str] +t09: collections.abc.Reversible[int] +t10: collections.abc.Container[int] +t11: collections.abc.Collection[int] +t12: collections.abc.Callable[[int], float] +t13: collections.abc.Set[int] +t14: collections.abc.MutableSet[int] +t15: collections.abc.Mapping[int, str] +t16: collections.abc.MutableMapping[int, str] +t17: collections.abc.Sequence[int] +t18: collections.abc.MutableSequence[int] +t19: collections.abc.ByteString +t20: collections.abc.MappingView[int, int] +t21: collections.abc.KeysView[int] +t22: collections.abc.ItemsView[int, str] +t23: collections.abc.ValuesView[str] + +# reveal_type(t01) # N +# reveal_type(t02) # N +# reveal_type(t03) # N +# reveal_type(t04) # N +# reveal_type(t05) # N +# reveal_type(t06) # N +# reveal_type(t07) # N +# reveal_type(t08) # N +# reveal_type(t09) # N +# reveal_type(t10) # N +# reveal_type(t11) # N +# reveal_type(t12) # N +# reveal_type(t13) # N +# reveal_type(t14) # N +# reveal_type(t15) # N +# reveal_type(t16) # N +# reveal_type(t17) # N +# reveal_type(t18) # N +# reveal_type(t19) # N +# reveal_type(t20) # N +# reveal_type(t21) # N +# reveal_type(t22) # N +# reveal_type(t23) # N + +[builtins fixtures/tuple.pyi] + + [case testGenericAliasImportRe] # flags: --python-version 3.9 from re import Pattern, Match @@ -49,3 +194,64 @@ t1: Pattern[str] t2: Match[str] [builtins fixtures/tuple.pyi] + + +[case testGenericBuiltinTupleTyping] +# flags: --python-version 3.6 +from typing import Tuple + +t01: Tuple = () +t02: Tuple[int] = (1, ) +t03: Tuple[int, str] = (1, 'a') +t04: Tuple[int, int] = (1, 2) +t05: Tuple[int, int, int] = (1, 2, 3) +t06: Tuple[int, int, int, int] = (1, 2, 3, 4) +t07: Tuple[int, int, int, int, int] = (1, 2, 3, 4, 5) +t08: Tuple[int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6) +t09: Tuple[int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7) +t10: Tuple[int, int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7, 8) +t11: Tuple[int, ...] +t12: Tuple[int, ...] = (1,) +t13: Tuple[int, ...] = (1, 2) +t14: Tuple[int, ...] = (1, 2, 3) +t15: Tuple[int, ...] = (1, 2, 3, 4) +t16: Tuple[int, ...] = (1, 2, 3, 4, 5) +t17: Tuple[int, ...] = (1, 2, 3, 4, 5, 6) +t18: Tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7) +t19: Tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8) + +[builtins fixtures/tuple.pyi] + + +[case testGenericBuiltinTuple] +# flags: --python-version 3.9 + +# t01: tuple = () +# t02: tuple[int] = (1, ) +# t03: tuple[int, str] = (1, 'a') +# t04: tuple[int, int] = (1, 2) +# t05: tuple[int, int, int] = (1, 2, 3) +# t06: tuple[int, int, int, int] = (1, 2, 3, 4) +# t07: tuple[int, int, int, int, int] = (1, 2, 3, 4, 5) +# t08: tuple[int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6) +# t09: tuple[int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7) +# t10: tuple[int, int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7, 8) + +[builtins fixtures/tuple.pyi] +[out] + +[case testGenericBuiltinTupleVariadic] +# flags: --python-version 3.9 + +# t11: tuple[int, ...] +# t12: tuple[int, ...] = (1,) +# t13: tuple[int, ...] = (1, 2) +# t14: tuple[int, ...] = (1, 2, 3) +# t15: tuple[int, ...] = (1, 2, 3, 4) +# t16: tuple[int, ...] = (1, 2, 3, 4, 5) +# t17: tuple[int, ...] = (1, 2, 3, 4, 5, 6) +# t18: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7) +# t19: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8) + +[builtins fixtures/tuple.pyi] +[out] \ No newline at end of file From 6d58555b59bf642d7643a1f7f0b967d2d0a2a034 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sun, 25 Oct 2020 01:23:01 -0300 Subject: [PATCH 19/26] add failing tests for PEP 585 to be investigated --- test-data/unit/check-generic-alias.test | 84 ++++++++++++------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/test-data/unit/check-generic-alias.test b/test-data/unit/check-generic-alias.test index e137c0c3ea25..2e36d2859aa4 100644 --- a/test-data/unit/check-generic-alias.test +++ b/test-data/unit/check-generic-alias.test @@ -159,29 +159,29 @@ t21: collections.abc.KeysView[int] t22: collections.abc.ItemsView[int, str] t23: collections.abc.ValuesView[str] -# reveal_type(t01) # N -# reveal_type(t02) # N -# reveal_type(t03) # N -# reveal_type(t04) # N -# reveal_type(t05) # N -# reveal_type(t06) # N -# reveal_type(t07) # N -# reveal_type(t08) # N -# reveal_type(t09) # N -# reveal_type(t10) # N -# reveal_type(t11) # N -# reveal_type(t12) # N -# reveal_type(t13) # N -# reveal_type(t14) # N -# reveal_type(t15) # N -# reveal_type(t16) # N -# reveal_type(t17) # N -# reveal_type(t18) # N -# reveal_type(t19) # N -# reveal_type(t20) # N -# reveal_type(t21) # N -# reveal_type(t22) # N -# reveal_type(t23) # N +reveal_type(t01) # N: Revealed type is 'collections.abc.Awaitable[builtins.int]' +reveal_type(t02) # N: Revealed type is 'collections.abc.Coroutine[builtins.str, builtins.int, builtins.float]' +reveal_type(t03) # N: Revealed type is 'collections.abc.AsyncIterable[builtins.int]' +reveal_type(t04) # N: Revealed type is 'collections.abc.AsyncIterator[builtins.int]' +reveal_type(t05) # N: Revealed type is 'collections.abc.AsyncGenerator[builtins.int, builtins.float]' +reveal_type(t06) # N: Revealed type is 'collections.abc.Iterable[builtins.int]' +reveal_type(t07) # N: Revealed type is 'collections.abc.Iterator[builtins.int]' +reveal_type(t08) # N: Revealed type is 'collections.abc.Generator[builtins.int, builtins.float, builtins.str]' +reveal_type(t09) # N: Revealed type is 'collections.abc.Reversible[builtins.int]' +reveal_type(t10) # N: Revealed type is 'collections.abc.Container[builtins.int]' +reveal_type(t11) # N: Revealed type is 'collections.abc.Collection[builtins.int]' +reveal_type(t12) # N: Revealed type is 'collections.abc.Callable[[builtins.int], builtins.float]' +reveal_type(t13) # N: Revealed type is 'collections.abc.Set[builtins.int]' +reveal_type(t14) # N: Revealed type is 'collections.abc.MutableSet[builtins.int]' +reveal_type(t15) # N: Revealed type is 'collections.abc.Mapping[builtins.int, builtins.str]' +reveal_type(t16) # N: Revealed type is 'collections.abc.MutableMapping[builtins.int, builtins.str]' +reveal_type(t17) # N: Revealed type is 'collections.abc.Sequence[builtins.int]' +reveal_type(t18) # N: Revealed type is 'collections.abc.MutableSequence[builtins.int]' +reveal_type(t19) # N: Revealed type is 'collections.abc.ByteString' +reveal_type(t20) # N: Revealed type is 'collections.abc.MappingView[builtins.int, builtins.int]' +reveal_type(t21) # N: Revealed type is 'collections.abc.KeysView[builtins.int]' +reveal_type(t22) # N: Revealed type is 'collections.abc.ItemsView[builtins.int, builtins.str]' +reveal_type(t23) # N: Revealed type is 'collections.abc.ValuesView[builtins.str]' [builtins fixtures/tuple.pyi] @@ -226,16 +226,16 @@ t19: Tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8) [case testGenericBuiltinTuple] # flags: --python-version 3.9 -# t01: tuple = () -# t02: tuple[int] = (1, ) -# t03: tuple[int, str] = (1, 'a') -# t04: tuple[int, int] = (1, 2) -# t05: tuple[int, int, int] = (1, 2, 3) -# t06: tuple[int, int, int, int] = (1, 2, 3, 4) -# t07: tuple[int, int, int, int, int] = (1, 2, 3, 4, 5) -# t08: tuple[int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6) -# t09: tuple[int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7) -# t10: tuple[int, int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7, 8) +t01: tuple = () +t02: tuple[int] = (1, ) +t03: tuple[int, str] = (1, 'a') +t04: tuple[int, int] = (1, 2) +t05: tuple[int, int, int] = (1, 2, 3) +t06: tuple[int, int, int, int] = (1, 2, 3, 4) +t07: tuple[int, int, int, int, int] = (1, 2, 3, 4, 5) +t08: tuple[int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6) +t09: tuple[int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7) +t10: tuple[int, int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7, 8) [builtins fixtures/tuple.pyi] [out] @@ -243,15 +243,15 @@ t19: Tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8) [case testGenericBuiltinTupleVariadic] # flags: --python-version 3.9 -# t11: tuple[int, ...] -# t12: tuple[int, ...] = (1,) -# t13: tuple[int, ...] = (1, 2) -# t14: tuple[int, ...] = (1, 2, 3) -# t15: tuple[int, ...] = (1, 2, 3, 4) -# t16: tuple[int, ...] = (1, 2, 3, 4, 5) -# t17: tuple[int, ...] = (1, 2, 3, 4, 5, 6) -# t18: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7) -# t19: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8) +t11: tuple[int, ...] +t12: tuple[int, ...] = (1,) +t13: tuple[int, ...] = (1, 2) +t14: tuple[int, ...] = (1, 2, 3) +t15: tuple[int, ...] = (1, 2, 3, 4) +t16: tuple[int, ...] = (1, 2, 3, 4, 5) +t17: tuple[int, ...] = (1, 2, 3, 4, 5, 6) +t18: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7) +t19: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8) [builtins fixtures/tuple.pyi] [out] \ No newline at end of file From c9ac0caac24263f29086a9d8beac8dd74c8b082a Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sun, 25 Oct 2020 02:21:54 -0300 Subject: [PATCH 20/26] fix `tuple[Any, ...]` case --- mypy/typeanal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 0cb453104616..4c2bd2f2b950 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -275,7 +275,7 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt self.fail("Final can be only used as an outermost qualifier" " in a variable annotation", t) return AnyType(TypeOfAny.from_error) - elif fullname == 'typing.Tuple': + elif fullname in ('typing.Tuple', 'builtins.tuple'): # Tuple is special because it is involved in builtin import cycle # and may be not ready when used. sym = self.api.lookup_fully_qualified_or_none('builtins.tuple') From eca2a1334319a2a158d07b59dcc99e47eac505ee Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sun, 25 Oct 2020 02:23:41 -0300 Subject: [PATCH 21/26] minor test impr. for tuple --- test-data/unit/check-generic-alias.test | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test-data/unit/check-generic-alias.test b/test-data/unit/check-generic-alias.test index 2e36d2859aa4..52967b326609 100644 --- a/test-data/unit/check-generic-alias.test +++ b/test-data/unit/check-generic-alias.test @@ -210,6 +210,7 @@ t07: Tuple[int, int, int, int, int] = (1, 2, 3, 4, 5) t08: Tuple[int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6) t09: Tuple[int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7) t10: Tuple[int, int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7, 8) + t11: Tuple[int, ...] t12: Tuple[int, ...] = (1,) t13: Tuple[int, ...] = (1, 2) @@ -237,12 +238,6 @@ t08: tuple[int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6) t09: tuple[int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7) t10: tuple[int, int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7, 8) -[builtins fixtures/tuple.pyi] -[out] - -[case testGenericBuiltinTupleVariadic] -# flags: --python-version 3.9 - t11: tuple[int, ...] t12: tuple[int, ...] = (1,) t13: tuple[int, ...] = (1, 2) @@ -253,5 +248,9 @@ t17: tuple[int, ...] = (1, 2, 3, 4, 5, 6) t18: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7) t19: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8) +from typing import Tuple + +t20: Tuple[int, ...] = t19 + [builtins fixtures/tuple.pyi] [out] \ No newline at end of file From 55dcbb5acc1ef85aefbdd06a6af2d6e81da37f43 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sun, 25 Oct 2020 18:21:38 -0300 Subject: [PATCH 22/26] Update mypy/typeanal.py Co-authored-by: cdce8p <30130371+cdce8p@users.noreply.github.com> --- mypy/typeanal.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 4c2bd2f2b950..d88701273948 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -275,7 +275,9 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt self.fail("Final can be only used as an outermost qualifier" " in a variable annotation", t) return AnyType(TypeOfAny.from_error) - elif fullname in ('typing.Tuple', 'builtins.tuple'): + elif (fullname == 'typing.Tuple' or + (fullname == 'builtins.tuple' and ( + self.options.python_version >= (3, 9) or self.api.is_future_flag_set('annotations')))): # Tuple is special because it is involved in builtin import cycle # and may be not ready when used. sym = self.api.lookup_fully_qualified_or_none('builtins.tuple') From c0d0989bfae25851324c74822859ea823a28e9ed Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sun, 25 Oct 2020 18:30:32 -0300 Subject: [PATCH 23/26] disable tests failing due reveal_type() --- test-data/unit/check-generic-alias.test | 47 +++++++++++++------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/test-data/unit/check-generic-alias.test b/test-data/unit/check-generic-alias.test index 52967b326609..0c63438aff86 100644 --- a/test-data/unit/check-generic-alias.test +++ b/test-data/unit/check-generic-alias.test @@ -159,29 +159,30 @@ t21: collections.abc.KeysView[int] t22: collections.abc.ItemsView[int, str] t23: collections.abc.ValuesView[str] -reveal_type(t01) # N: Revealed type is 'collections.abc.Awaitable[builtins.int]' -reveal_type(t02) # N: Revealed type is 'collections.abc.Coroutine[builtins.str, builtins.int, builtins.float]' -reveal_type(t03) # N: Revealed type is 'collections.abc.AsyncIterable[builtins.int]' -reveal_type(t04) # N: Revealed type is 'collections.abc.AsyncIterator[builtins.int]' -reveal_type(t05) # N: Revealed type is 'collections.abc.AsyncGenerator[builtins.int, builtins.float]' -reveal_type(t06) # N: Revealed type is 'collections.abc.Iterable[builtins.int]' -reveal_type(t07) # N: Revealed type is 'collections.abc.Iterator[builtins.int]' -reveal_type(t08) # N: Revealed type is 'collections.abc.Generator[builtins.int, builtins.float, builtins.str]' -reveal_type(t09) # N: Revealed type is 'collections.abc.Reversible[builtins.int]' -reveal_type(t10) # N: Revealed type is 'collections.abc.Container[builtins.int]' -reveal_type(t11) # N: Revealed type is 'collections.abc.Collection[builtins.int]' -reveal_type(t12) # N: Revealed type is 'collections.abc.Callable[[builtins.int], builtins.float]' -reveal_type(t13) # N: Revealed type is 'collections.abc.Set[builtins.int]' -reveal_type(t14) # N: Revealed type is 'collections.abc.MutableSet[builtins.int]' -reveal_type(t15) # N: Revealed type is 'collections.abc.Mapping[builtins.int, builtins.str]' -reveal_type(t16) # N: Revealed type is 'collections.abc.MutableMapping[builtins.int, builtins.str]' -reveal_type(t17) # N: Revealed type is 'collections.abc.Sequence[builtins.int]' -reveal_type(t18) # N: Revealed type is 'collections.abc.MutableSequence[builtins.int]' -reveal_type(t19) # N: Revealed type is 'collections.abc.ByteString' -reveal_type(t20) # N: Revealed type is 'collections.abc.MappingView[builtins.int, builtins.int]' -reveal_type(t21) # N: Revealed type is 'collections.abc.KeysView[builtins.int]' -reveal_type(t22) # N: Revealed type is 'collections.abc.ItemsView[builtins.int, builtins.str]' -reveal_type(t23) # N: Revealed type is 'collections.abc.ValuesView[builtins.str]' +-- DISABLED UNTIL FIX THE REVEAL_TYPE ISSUES (see #7907) +# reveal_type(t01) # Nx Revealed type is 'collections.abc.Awaitable[builtins.int]' +# reveal_type(t02) # Nx Revealed type is 'collections.abc.Coroutine[builtins.str, builtins.int, builtins.float]' +# reveal_type(t03) # Nx Revealed type is 'collections.abc.AsyncIterable[builtins.int]' +# reveal_type(t04) # Nx Revealed type is 'collections.abc.AsyncIterator[builtins.int]' +# reveal_type(t05) # Nx Revealed type is 'collections.abc.AsyncGenerator[builtins.int, builtins.float]' +# reveal_type(t06) # Nx Revealed type is 'collections.abc.Iterable[builtins.int]' +# reveal_type(t07) # Nx Revealed type is 'collections.abc.Iterator[builtins.int]' +# reveal_type(t08) # Nx Revealed type is 'collections.abc.Generator[builtins.int, builtins.float, builtins.str]' +# reveal_type(t09) # Nx Revealed type is 'collections.abc.Reversible[builtins.int]' +# reveal_type(t10) # Nx Revealed type is 'collections.abc.Container[builtins.int]' +# reveal_type(t11) # Nx Revealed type is 'collections.abc.Collection[builtins.int]' +# reveal_type(t12) # Nx Revealed type is 'collections.abc.Callable[[builtins.int], builtins.float]' +# reveal_type(t13) # Nx Revealed type is 'collections.abc.Set[builtins.int]' +# reveal_type(t14) # Nx Revealed type is 'collections.abc.MutableSet[builtins.int]' +# reveal_type(t15) # Nx Revealed type is 'collections.abc.Mapping[builtins.int, builtins.str]' +# reveal_type(t16) # Nx Revealed type is 'collections.abc.MutableMapping[builtins.int, builtins.str]' +# reveal_type(t17) # Nx Revealed type is 'collections.abc.Sequence[builtins.int]' +# reveal_type(t18) # Nx Revealed type is 'collections.abc.MutableSequence[builtins.int]' +# reveal_type(t19) # Nx Revealed type is 'collections.abc.ByteString' +# reveal_type(t20) # Nx Revealed type is 'collections.abc.MappingView[builtins.int, builtins.int]' +# reveal_type(t21) # Nx Revealed type is 'collections.abc.KeysView[builtins.int]' +# reveal_type(t22) # Nx Revealed type is 'collections.abc.ItemsView[builtins.int, builtins.str]' +# reveal_type(t23) # Nx Revealed type is 'collections.abc.ValuesView[builtins.str]' [builtins fixtures/tuple.pyi] From ab0e4cd3f97ae2f42dc12aabf0feddd1031d6893 Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Sun, 25 Oct 2020 19:28:14 -0300 Subject: [PATCH 24/26] fix style to pep8 --- mypy/typeanal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index d88701273948..5eb6f0576c0d 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -276,8 +276,8 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt " in a variable annotation", t) return AnyType(TypeOfAny.from_error) elif (fullname == 'typing.Tuple' or - (fullname == 'builtins.tuple' and ( - self.options.python_version >= (3, 9) or self.api.is_future_flag_set('annotations')))): + (fullname == 'builtins.tuple' and (self.options.python_version >= (3, 9) or + self.api.is_future_flag_set('annotations')))): # Tuple is special because it is involved in builtin import cycle # and may be not ready when used. sym = self.api.lookup_fully_qualified_or_none('builtins.tuple') From a81abc8ef7f6a2c5263b6c21af248ec71cc9401d Mon Sep 17 00:00:00 2001 From: Allan Daemon Date: Wed, 28 Oct 2020 21:18:05 -0300 Subject: [PATCH 25/26] Update test-data/unit/check-generic-alias.test Co-authored-by: Ethan Smith --- test-data/unit/check-generic-alias.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/unit/check-generic-alias.test b/test-data/unit/check-generic-alias.test index 0c63438aff86..b5e330eec37d 100644 --- a/test-data/unit/check-generic-alias.test +++ b/test-data/unit/check-generic-alias.test @@ -254,4 +254,4 @@ from typing import Tuple t20: Tuple[int, ...] = t19 [builtins fixtures/tuple.pyi] -[out] \ No newline at end of file +[out] From 0edf1233672117c4555759c5a91461a502ddce5d Mon Sep 17 00:00:00 2001 From: hauntsaninja <> Date: Thu, 26 Nov 2020 13:46:01 -0800 Subject: [PATCH 26/26] collate future annotations tests, simplify --- mypy/test/testcheck.py | 1 - test-data/unit/check-future.test | 24 ---- test-data/unit/check-generic-alias.test | 168 +++++++++++------------- 3 files changed, 76 insertions(+), 117 deletions(-) delete mode 100644 test-data/unit/check-future.test diff --git a/mypy/test/testcheck.py b/mypy/test/testcheck.py index 4a3bb1cf42ca..5dd8c3b286a9 100644 --- a/mypy/test/testcheck.py +++ b/mypy/test/testcheck.py @@ -65,7 +65,6 @@ 'check-selftype.test', 'check-python2.test', 'check-columns.test', - 'check-future.test', 'check-functions.test', 'check-tuples.test', 'check-expressions.test', diff --git a/test-data/unit/check-future.test b/test-data/unit/check-future.test deleted file mode 100644 index 9ccf4eaa3dd2..000000000000 --- a/test-data/unit/check-future.test +++ /dev/null @@ -1,24 +0,0 @@ --- Test cases for __future__ imports - -[case testFutureAnnotationsImportCollections] -# flags: --python-version 3.7 -from __future__ import annotations -from collections import defaultdict, ChainMap, Counter, deque - -t1: defaultdict[int, int] -t2: ChainMap[int, int] -t3: Counter[int] -t4: deque[int] - -[builtins fixtures/tuple.pyi] - -[case testFutureAnnotationsImportBuiltIns] -# flags: --python-version 3.7 -from __future__ import annotations - -t1: type[int] -t2: list[int] -t3: dict[int, int] -t4: tuple[int, str, int] - -[builtins fixtures/dict.pyi] diff --git a/test-data/unit/check-generic-alias.test b/test-data/unit/check-generic-alias.test index b5e330eec37d..e7a1354d85cb 100644 --- a/test-data/unit/check-generic-alias.test +++ b/test-data/unit/check-generic-alias.test @@ -1,46 +1,34 @@ -- Test cases for generic aliases - - --- Non passing tests, tests the new generic aliases with old versions generating errors - -[case testGenericBuiltinNonPassing] -# flags: --python-version 3.6 - +[case testGenericBuiltinWarning] +# flags: --python-version 3.7 t1: list t2: list[int] # E: "list" is not subscriptable, use "typing.List" instead t3: list[str] # E: "list" is not subscriptable, use "typing.List" instead t4: tuple t5: tuple[int] # E: "tuple" is not subscriptable, use "typing.Tuple" instead +t6: tuple[int, str] # E: "tuple" is not subscriptable, use "typing.Tuple" instead +t7: tuple[int, ...] # E: Unexpected '...' \ + # E: "tuple" is not subscriptable, use "typing.Tuple" instead -t6: dict = {} -t7: dict[int, str] # E: "dict" is not subscriptable, use "typing.Dict" instead +t8: dict = {} +t9: dict[int, str] # E: "dict" is not subscriptable, use "typing.Dict" instead -[builtins fixtures/list.pyi] +t10: type +t11: type[int] # E: "type" expects no type arguments, but 1 given [builtins fixtures/dict.pyi] -[case testGenericBuiltinSetNonPassing] -# flags: --python-version 3.6 - +[case testGenericBuiltinSetWarning] +# flags: --python-version 3.7 t1: set t2: set[int] # E: "set" is not subscriptable, use "typing.Set" instead - [builtins fixtures/set.pyi] -[case testGenericBuiltinTypeNonPassing] -# flags: --python-version 3.6 - -t1: type -t2: type[int] # E: "type" expects no type arguments, but 1 given - -[builtins fixtures/set.pyi] - -[case testGenericBuiltinCollectionsNonPassing] -# flags: --python-version 3.6 -import builtins +[case testGenericCollectionsWarning] +# flags: --python-version 3.7 import collections t01: collections.deque @@ -54,15 +42,46 @@ t08: collections.Counter[int] # E: "Counter" is not subscriptable, use "typing. t09: collections.ChainMap t10: collections.ChainMap[int, str] # E: "ChainMap" is not subscriptable, use "typing.ChainMap" instead --- Testing with colletions.abc all of them works actually, so I'll just leave it +[case testGenericBuiltinFutureAnnotations] +# flags: --python-version 3.7 +from __future__ import annotations +t1: list +t2: list[int] +t3: list[str] + +t4: tuple +t5: tuple[int] +t6: tuple[int, str] +t7: tuple[int, ...] + +t8: dict = {} +t9: dict[int, str] +t10: type +t11: type[int] +[builtins fixtures/dict.pyi] --- ------------------------------------------------------- -- --- Testing the builtins generic aliases defined in PEP 585 -- +[case testGenericCollectionsFutureAnnotations] +# flags: --python-version 3.7 +from __future__ import annotations +import collections -[case testGenericAliasImportBuiltins] +t01: collections.deque +t02: collections.deque[int] +t03: collections.defaultdict +t04: collections.defaultdict[int, str] +t05: collections.OrderedDict +t06: collections.OrderedDict[int, str] +t07: collections.Counter +t08: collections.Counter[int] +t09: collections.ChainMap +t10: collections.ChainMap[int, str] +[builtins fixtures/tuple.pyi] + + +[case testGenericAliasBuiltinsReveal] # flags: --python-version 3.9 t1: list t2: list[int] @@ -71,24 +90,31 @@ t3: list[str] t4: tuple t5: tuple[int] t6: tuple[int, str] +t7: tuple[int, ...] -t7: dict -t8: dict[str, int] +t8: dict = {} +t9: dict[int, str] + +t10: type +t11: type[int] reveal_type(t1) # N: Revealed type is 'builtins.list[Any]' reveal_type(t2) # N: Revealed type is 'builtins.list[builtins.int]' reveal_type(t3) # N: Revealed type is 'builtins.list[builtins.str]' reveal_type(t4) # N: Revealed type is 'builtins.tuple[Any]' -# reveal_type(t5) # Nx Revealed type is 'builtins.tuple[builtins.int]' -# reveal_type(t6) # Nx Revealed type is 'builtins.tuple[builtins.int, builtins.str]' -reveal_type(t7) # N: Revealed type is 'builtins.dict[Any, Any]' -reveal_type(t8) # N: Revealed type is 'builtins.dict[builtins.str, builtins.int]' - -[builtins fixtures/list.pyi] +# TODO: ideally these would reveal builtins.tuple +reveal_type(t5) # N: Revealed type is 'Tuple[builtins.int]' +reveal_type(t6) # N: Revealed type is 'Tuple[builtins.int, builtins.str]' +# TODO: this is incorrect, see #9522 +reveal_type(t7) # N: Revealed type is 'builtins.tuple[builtins.int]' +reveal_type(t8) # N: Revealed type is 'builtins.dict[Any, Any]' +reveal_type(t9) # N: Revealed type is 'builtins.dict[builtins.int, builtins.str]' +reveal_type(t10) # N: Revealed type is 'builtins.type' +reveal_type(t11) # N: Revealed type is 'Type[builtins.int]' [builtins fixtures/dict.pyi] -[case testGenericAliasImportBuiltinsSet] +[case testGenericAliasBuiltinsSetReveal] # flags: --python-version 3.9 t1: set t2: set[int] @@ -97,22 +123,10 @@ t3: set[str] reveal_type(t1) # N: Revealed type is 'builtins.set[Any]' reveal_type(t2) # N: Revealed type is 'builtins.set[builtins.int]' reveal_type(t3) # N: Revealed type is 'builtins.set[builtins.str]' - [builtins fixtures/set.pyi] -[case testGenericAliasImportBuiltinsType] -# flags: --python-version 3.9 -t1: type -t2: type[int] -t3: type[str] - -reveal_type(t1) # N: Revealed type is 'builtins.type' -# reveal_type(t2) # N Revealed type is 'Type[builtins.int]' -# reveal_type(t3) # N Revealed type is 'Type[builtins.str]' - - -[case testGenericAliasImportCollections] +[case testGenericAliasCollectionsReveal] # flags: --python-version 3.9 import collections @@ -127,11 +141,10 @@ reveal_type(t2) # N: Revealed type is 'collections.defaultdict[builtins.int, bu reveal_type(t3) # N: Revealed type is 'collections.OrderedDict[builtins.int, builtins.str]' reveal_type(t4) # N: Revealed type is 'collections.Counter[builtins.int]' reveal_type(t5) # N: Revealed type is 'collections.ChainMap[builtins.int, builtins.str]' - [builtins fixtures/tuple.pyi] -[case testGenericAliasImportCollectionsABC] +[case testGenericAliasCollectionsABCReveal] # flags: --python-version 3.9 import collections.abc @@ -159,7 +172,7 @@ t21: collections.abc.KeysView[int] t22: collections.abc.ItemsView[int, str] t23: collections.abc.ValuesView[str] --- DISABLED UNTIL FIX THE REVEAL_TYPE ISSUES (see #7907) +# TODO: these currently reveal the classes from typing, see #7907 # reveal_type(t01) # Nx Revealed type is 'collections.abc.Awaitable[builtins.int]' # reveal_type(t02) # Nx Revealed type is 'collections.abc.Coroutine[builtins.str, builtins.int, builtins.float]' # reveal_type(t03) # Nx Revealed type is 'collections.abc.AsyncIterable[builtins.int]' @@ -183,17 +196,14 @@ t23: collections.abc.ValuesView[str] # reveal_type(t21) # Nx Revealed type is 'collections.abc.KeysView[builtins.int]' # reveal_type(t22) # Nx Revealed type is 'collections.abc.ItemsView[builtins.int, builtins.str]' # reveal_type(t23) # Nx Revealed type is 'collections.abc.ValuesView[builtins.str]' - [builtins fixtures/tuple.pyi] [case testGenericAliasImportRe] # flags: --python-version 3.9 from re import Pattern, Match - t1: Pattern[str] t2: Match[str] - [builtins fixtures/tuple.pyi] @@ -206,22 +216,10 @@ t02: Tuple[int] = (1, ) t03: Tuple[int, str] = (1, 'a') t04: Tuple[int, int] = (1, 2) t05: Tuple[int, int, int] = (1, 2, 3) -t06: Tuple[int, int, int, int] = (1, 2, 3, 4) -t07: Tuple[int, int, int, int, int] = (1, 2, 3, 4, 5) -t08: Tuple[int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6) -t09: Tuple[int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7) -t10: Tuple[int, int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7, 8) - -t11: Tuple[int, ...] -t12: Tuple[int, ...] = (1,) -t13: Tuple[int, ...] = (1, 2) -t14: Tuple[int, ...] = (1, 2, 3) -t15: Tuple[int, ...] = (1, 2, 3, 4) -t16: Tuple[int, ...] = (1, 2, 3, 4, 5) -t17: Tuple[int, ...] = (1, 2, 3, 4, 5, 6) -t18: Tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7) -t19: Tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8) - +t06: Tuple[int, ...] +t07: Tuple[int, ...] = (1,) +t08: Tuple[int, ...] = (1, 2) +t09: Tuple[int, ...] = (1, 2, 3) [builtins fixtures/tuple.pyi] @@ -233,25 +231,11 @@ t02: tuple[int] = (1, ) t03: tuple[int, str] = (1, 'a') t04: tuple[int, int] = (1, 2) t05: tuple[int, int, int] = (1, 2, 3) -t06: tuple[int, int, int, int] = (1, 2, 3, 4) -t07: tuple[int, int, int, int, int] = (1, 2, 3, 4, 5) -t08: tuple[int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6) -t09: tuple[int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7) -t10: tuple[int, int, int, int, int, int, int, int] = (1, 2, 3, 4, 5, 6, 7, 8) - -t11: tuple[int, ...] -t12: tuple[int, ...] = (1,) -t13: tuple[int, ...] = (1, 2) -t14: tuple[int, ...] = (1, 2, 3) -t15: tuple[int, ...] = (1, 2, 3, 4) -t16: tuple[int, ...] = (1, 2, 3, 4, 5) -t17: tuple[int, ...] = (1, 2, 3, 4, 5, 6) -t18: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7) -t19: tuple[int, ...] = (1, 2, 3, 4, 5, 6, 7, 8) +t06: tuple[int, ...] +t07: tuple[int, ...] = (1,) +t08: tuple[int, ...] = (1, 2) +t09: tuple[int, ...] = (1, 2, 3) from typing import Tuple - -t20: Tuple[int, ...] = t19 - +t10: Tuple[int, ...] = t09 [builtins fixtures/tuple.pyi] -[out]