From 2aa133722e76f5517a7f68771e2ef212f3d73817 Mon Sep 17 00:00:00 2001 From: Hugues Bruant Date: Mon, 24 Jan 2022 00:35:46 -0800 Subject: [PATCH] address review comments and misc cleanups --- mypy/meet.py | 21 +++++++++------------ mypy/sametypes.py | 4 ++-- mypy/subtypes.py | 4 ++-- mypy/typeops.py | 6 +++--- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/mypy/meet.py b/mypy/meet.py index 49a84f7d53070..f4b91ae8a5b71 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -143,18 +143,15 @@ def is_enum_overlapping_union(x: ProperType, y: ProperType) -> bool: return ( isinstance(x, Instance) and x.type.is_enum and isinstance(y, UnionType) and - all(isinstance(z, LiteralType) and z.fallback.type == x.type # type: ignore[misc] - for z in y.items) + all(x.type == p.fallback.type + for p in (get_proper_type(z) for z in y.relevant_items()) + if isinstance(p, LiteralType)) ) def is_literal_in_union(x: ProperType, y: ProperType) -> bool: - return ( - isinstance(x, LiteralType) and isinstance(y, UnionType) and any( - isinstance(z, LiteralType) and z == x # type: ignore[misc] - for z in y.items - ) - ) + return (isinstance(x, LiteralType) and isinstance(y, UnionType) and + any(x == get_proper_type(z) for z in y.items)) def is_overlapping_types(left: Type, @@ -223,10 +220,10 @@ def _is_overlapping_types(left: Type, right: Type) -> bool: # and crucially, we want to do that *fast* in case the enum is large # so we do it before expanding variants below to avoid O(n**2) behavior if ( - is_enum_overlapping_union(left, right) or - is_enum_overlapping_union(right, left) or - is_literal_in_union(left, right) or - is_literal_in_union(right, left) + is_enum_overlapping_union(left, right) + or is_enum_overlapping_union(right, left) + or is_literal_in_union(left, right) + or is_literal_in_union(right, left) ): return True diff --git a/mypy/sametypes.py b/mypy/sametypes.py index a3a7cc98a98ba..8721472862e71 100644 --- a/mypy/sametypes.py +++ b/mypy/sametypes.py @@ -147,9 +147,9 @@ def visit_union_type(self, left: UnionType) -> bool: def _extract_literals(u: UnionType) -> Tuple[Set[LiteralType], List[Type]]: lit: Set[LiteralType] = set() rem: List[Type] = [] - for i in u.items: + for i in u.relevant_items(): + i = get_proper_type(i) if is_simple_literal(i): - assert isinstance(i, LiteralType) # type: ignore[misc] lit.add(i) else: rem.append(i) diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 21b8fbc79d806..e40c1ed88493c 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -501,9 +501,9 @@ def visit_union_type(self, left: UnionType) -> bool: if isinstance(self.right, Instance): literal_types: Set[Instance] = set() # avoid redundant check for union of literals - for item in left.items: + for item in left.relevant_items(): + item = get_proper_type(item) if mypy.typeops.is_simple_literal(item): - assert isinstance(item, LiteralType) # type: ignore[misc] if item.fallback in literal_types: continue literal_types.add(item.fallback) diff --git a/mypy/typeops.py b/mypy/typeops.py index 0558cf283963c..60f432211dd75 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -6,7 +6,7 @@ """ from typing import cast, Optional, List, Sequence, Set, Iterable, TypeVar, Dict, Tuple, Any -from typing_extensions import Type as TypingType +from typing_extensions import Type as TypingType, TypeGuard import itertools import sys @@ -294,13 +294,13 @@ def callable_corresponding_argument(typ: CallableType, return by_name if by_name is not None else by_pos -def is_simple_literal(t: Type) -> bool: +def is_simple_literal(t: ProperType) -> TypeGuard[LiteralType]: """ Whether a type is a simple enough literal to allow for fast Union simplification For now this means enum or string """ - return isinstance(t, LiteralType) and ( # type: ignore[misc] + return isinstance(t, LiteralType) and ( t.fallback.type.is_enum or t.fallback.type.fullname == 'builtins.str' )