Skip to content

Commit

Permalink
Deduplicate iterable logic (#16006)
Browse files Browse the repository at this point in the history
This e.g. makes sure both code paths receive my fix in #15688
  • Loading branch information
hauntsaninja authored Sep 1, 2023
1 parent 2a6d9cb commit d440490
Showing 1 changed file with 12 additions and 23 deletions.
35 changes: 12 additions & 23 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -4653,42 +4652,32 @@ 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
) -> 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]

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(...).
Expand Down

0 comments on commit d440490

Please sign in to comment.