From 3f531e14ed5c6324d99e2e7fe956725a683265d7 Mon Sep 17 00:00:00 2001 From: STerliakov Date: Wed, 5 Feb 2025 01:49:19 +0100 Subject: [PATCH 1/6] Normalize tuple fallback to tuple[Any, ...] in constructor if it isn't special --- mypy/checker.py | 5 ----- mypy/types.py | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 999d75678aa4..066e929c5200 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -8484,11 +8484,6 @@ def visit_type_var(self, t: TypeVarType) -> bool: # multi-step type inference. return t.id.is_meta_var() - def visit_tuple_type(self, t: TupleType, /) -> bool: - # Exclude fallback to avoid bogus "need type annotation" errors - # TODO: Maybe erase plain tuples used as fallback in TupleType constructor? - return self.query_types(t.items) - class SetNothingToAny(TypeTranslator): """Replace all ambiguous Uninhabited types with Any (to avoid spurious extra errors).""" diff --git a/mypy/types.py b/mypy/types.py index f700be887116..76e4ad03ba27 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -2415,6 +2415,12 @@ def __init__( implicit: bool = False, ) -> None: super().__init__(line, column) + if fallback.type and fallback.type.fullname == "builtins.tuple": + assert len(fallback.args) == 1 + if not isinstance(fallback.args[0], AnyType): + fallback = fallback.copy_modified( + args=[AnyType(TypeOfAny.implementation_artifact)] + ) self.partial_fallback = fallback self.items = items self.implicit = implicit From 749f9560a247b0f55f471eb91dee1523d4e5bf7d Mon Sep 17 00:00:00 2001 From: STerliakov Date: Wed, 5 Feb 2025 02:51:20 +0100 Subject: [PATCH 2/6] Fix own typing --- mypy/types.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mypy/types.py b/mypy/types.py index 76e4ad03ba27..26c3e48365e0 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -2417,7 +2417,9 @@ def __init__( super().__init__(line, column) if fallback.type and fallback.type.fullname == "builtins.tuple": assert len(fallback.args) == 1 - if not isinstance(fallback.args[0], AnyType): + if not isinstance(fallback.args[0], ProperType) or not isinstance( + fallback.args[0], AnyType + ): fallback = fallback.copy_modified( args=[AnyType(TypeOfAny.implementation_artifact)] ) From a3bd40f1a40d0633c22a593e976bf5b1ebb6ad0e Mon Sep 17 00:00:00 2001 From: STerliakov Date: Wed, 5 Feb 2025 03:02:37 +0100 Subject: [PATCH 3/6] That should be special_form --- mypy/messages.py | 1 + mypy/types.py | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index 3beb287bcc21..6b061a379ff6 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -2008,6 +2008,7 @@ def untyped_decorated_function(self, typ: Type, context: Context) -> None: if isinstance(typ, AnyType): self.fail("Function is untyped after decorator transformation", context) else: + breakpoint() self.fail( f'Type of decorated function contains type "Any" ({format_type(typ, self.options)})', context, diff --git a/mypy/types.py b/mypy/types.py index 26c3e48365e0..7b65e9a80937 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -2420,9 +2420,7 @@ def __init__( if not isinstance(fallback.args[0], ProperType) or not isinstance( fallback.args[0], AnyType ): - fallback = fallback.copy_modified( - args=[AnyType(TypeOfAny.implementation_artifact)] - ) + fallback = fallback.copy_modified(args=[AnyType(TypeOfAny.special_form)]) self.partial_fallback = fallback self.items = items self.implicit = implicit From 25c13177b4e61545f1ae2a404be0daf77df45341 Mon Sep 17 00:00:00 2001 From: STerliakov Date: Wed, 5 Feb 2025 03:23:26 +0100 Subject: [PATCH 4/6] . --- mypy/messages.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mypy/messages.py b/mypy/messages.py index 6b061a379ff6..3beb287bcc21 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -2008,7 +2008,6 @@ def untyped_decorated_function(self, typ: Type, context: Context) -> None: if isinstance(typ, AnyType): self.fail("Function is untyped after decorator transformation", context) else: - breakpoint() self.fail( f'Type of decorated function contains type "Any" ({format_type(typ, self.options)})', context, From d3be6130ef33ae6a4d98cd6ba7df69494d0db173 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Sun, 9 Feb 2025 19:22:23 +0000 Subject: [PATCH 5/6] Add comment in mypy/types.py --- mypy/types.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mypy/types.py b/mypy/types.py index 7b65e9a80937..693a3edffc99 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -2416,6 +2416,8 @@ def __init__( ) -> None: super().__init__(line, column) if fallback.type and fallback.type.fullname == "builtins.tuple": + # We actively ignore type argument for plain tuple fallback, to avoid spurious errors, + # partial_fallback should never be used directly anyway, only via typeops.tuple_fallback(). assert len(fallback.args) == 1 if not isinstance(fallback.args[0], ProperType) or not isinstance( fallback.args[0], AnyType From 75b09ac809601b61d59c32ef9293db64fedd86d2 Mon Sep 17 00:00:00 2001 From: STerliakov Date: Mon, 10 Feb 2025 23:05:33 +0100 Subject: [PATCH 6/6] Revert to previous version, only remove TODO --- mypy/checker.py | 4 ++++ mypy/types.py | 8 -------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 066e929c5200..4c3f3f3315a3 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -8484,6 +8484,10 @@ def visit_type_var(self, t: TypeVarType) -> bool: # multi-step type inference. return t.id.is_meta_var() + def visit_tuple_type(self, t: TupleType, /) -> bool: + # Exclude fallback to avoid bogus "need type annotation" errors + return self.query_types(t.items) + class SetNothingToAny(TypeTranslator): """Replace all ambiguous Uninhabited types with Any (to avoid spurious extra errors).""" diff --git a/mypy/types.py b/mypy/types.py index 693a3edffc99..f700be887116 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -2415,14 +2415,6 @@ def __init__( implicit: bool = False, ) -> None: super().__init__(line, column) - if fallback.type and fallback.type.fullname == "builtins.tuple": - # We actively ignore type argument for plain tuple fallback, to avoid spurious errors, - # partial_fallback should never be used directly anyway, only via typeops.tuple_fallback(). - assert len(fallback.args) == 1 - if not isinstance(fallback.args[0], ProperType) or not isinstance( - fallback.args[0], AnyType - ): - fallback = fallback.copy_modified(args=[AnyType(TypeOfAny.special_form)]) self.partial_fallback = fallback self.items = items self.implicit = implicit