From 48b75426ed32ff1aac8d30296a411798f60667eb Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Thu, 31 Aug 2023 02:37:35 -0700 Subject: [PATCH 1/2] Deduplicate iterable logic This e.g. makes sure both code paths receive my fix in #15688 --- mypy/checker.py | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index a44601b83e21..84c4cc351a63 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -4653,22 +4653,13 @@ def analyze_async_iterable_item_type(self, expr: Expression) -> tuple[Type, Type def analyze_iterable_item_type(self, expr: Expression) -> tuple[Type, Type]: """Analyse iterable expression and return iterator and iterator item types.""" - echk = self.expr_checker - iterable = get_proper_type(echk.accept(expr)) - iterator = echk.check_method_call_by_name("__iter__", iterable, [], [], expr)[0] - + iterator, iterable = self.analyze_iterable_item_type_without_expression( + self.expr_checker.accept(expr), context=expr + ) int_type = self.analyze_range_native_int_type(expr) if int_type: return iterator, int_type - - if ( - isinstance(iterable, TupleType) - and iterable.partial_fallback.type.fullname == "builtins.tuple" - ): - return iterator, tuple_fallback(iterable).args[0] - else: - # Non-tuple iterable. - return iterator, echk.check_method_call_by_name("__next__", iterator, [], [], expr)[0] + return iterator, iterable def analyze_iterable_item_type_without_expression( self, type: Type, context: Context @@ -4678,17 +4669,15 @@ def analyze_iterable_item_type_without_expression( iterable = get_proper_type(type) iterator = echk.check_method_call_by_name("__iter__", iterable, [], [], context)[0] - if isinstance(iterable, TupleType): - joined: Type = UninhabitedType() - for item in iterable.items: - joined = join_types(joined, item) - return iterator, joined + if ( + isinstance(iterable, TupleType) + and iterable.partial_fallback.type.fullname == "builtins.tuple" + ): + return iterator, tuple_fallback(iterable).args[0] else: # Non-tuple iterable. - return ( - iterator, - echk.check_method_call_by_name("__next__", iterator, [], [], context)[0], - ) + iterable = echk.check_method_call_by_name("__next__", iterator, [], [], context)[0] + return iterator, iterable def analyze_range_native_int_type(self, expr: Expression) -> Type | None: """Try to infer native int item type from arguments to range(...). From 49027d472f7d7eb5b6fd2f418a79a9856e27ae8a Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Thu, 31 Aug 2023 03:04:10 -0700 Subject: [PATCH 2/2] fixup --- mypy/checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index 84c4cc351a63..07ce5a3abde2 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -41,7 +41,6 @@ from mypy.errorcodes import TYPE_VAR, UNUSED_AWAITABLE, UNUSED_COROUTINE, ErrorCode from mypy.errors import Errors, ErrorWatcher, report_internal_error from mypy.expandtype import expand_self_type, expand_type, expand_type_by_instance -from mypy.join import join_types from mypy.literals import Key, extract_var_from_literal_hash, literal, literal_hash from mypy.maptype import map_instance_to_supertype from mypy.meet import is_overlapping_erased_types, is_overlapping_types @@ -4666,6 +4665,7 @@ def analyze_iterable_item_type_without_expression( ) -> tuple[Type, Type]: """Analyse iterable type and return iterator and iterator item types.""" echk = self.expr_checker + iterable: Type iterable = get_proper_type(type) iterator = echk.check_method_call_by_name("__iter__", iterable, [], [], context)[0]