Skip to content

Commit

Permalink
Merge subtype visitors (#13303)
Browse files Browse the repository at this point in the history
Fixes #3297

This removes a significant chunk of code duplication. This is not a pure refactor, there were some cases when one of the visitors (mostly non-proper one) was more correct and/or complete. In few corner cases, where it was hard to decide, I merged behavior with `if` checks.
  • Loading branch information
ilevkivskyi authored Aug 3, 2022
1 parent d2063d2 commit d27bff6
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 494 deletions.
23 changes: 14 additions & 9 deletions mypy/meet.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@ def _type_object_overlap(left: Type, right: Type) -> bool:
"""Special cases for type object types overlaps."""
# TODO: these checks are a bit in gray area, adjust if they cause problems.
left, right = get_proper_types((left, right))
# 1. Type[C] vs Callable[..., C], where the latter is class object.
if isinstance(left, TypeType) and isinstance(right, CallableType) and right.is_type_obj():
# 1. Type[C] vs Callable[..., C] overlap even if the latter is not class object.
if isinstance(left, TypeType) and isinstance(right, CallableType):
return _is_overlapping_types(left.item, right.ret_type)
# 2. Type[C] vs Meta, where Meta is a metaclass for C.
if isinstance(left, TypeType) and isinstance(right, Instance):
Expand All @@ -381,13 +381,18 @@ def _type_object_overlap(left: Type, right: Type) -> bool:
return _type_object_overlap(left, right) or _type_object_overlap(right, left)

if isinstance(left, CallableType) and isinstance(right, CallableType):
return is_callable_compatible(
left,
right,
is_compat=_is_overlapping_types,
ignore_pos_arg_names=True,
allow_partial_overlap=True,
)

def _callable_overlap(left: CallableType, right: CallableType) -> bool:
return is_callable_compatible(
left,
right,
is_compat=_is_overlapping_types,
ignore_pos_arg_names=True,
allow_partial_overlap=True,
)

# Compare both directions to handle type objects.
return _callable_overlap(left, right) or _callable_overlap(right, left)
elif isinstance(left, CallableType):
left = left.fallback
elif isinstance(right, CallableType):
Expand Down
Loading

0 comments on commit d27bff6

Please sign in to comment.