Skip to content

Commit

Permalink
Fix issues related to primer output
Browse files Browse the repository at this point in the history
  • Loading branch information
kreathon committed May 11, 2024
1 parent 8bebb70 commit 2aef4f3
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 45 deletions.
31 changes: 6 additions & 25 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5787,7 +5787,6 @@ def find_isinstance_check_helper(self, node: Expression) -> tuple[TypeMap, TypeM
self.lookup_type(expr),
[TypeRange(node.callee.type_is, is_upper_bound=False)],
expr,
ignore_type_params=False,
),
)
elif isinstance(node, ComparisonExpr):
Expand Down Expand Up @@ -7161,17 +7160,11 @@ def conditional_types_with_intersection(
type_ranges: list[TypeRange] | None,
ctx: Context,
default: None = None,
ignore_type_params: bool = True,
) -> tuple[Type | None, Type | None]: ...

@overload
def conditional_types_with_intersection(
self,
expr_type: Type,
type_ranges: list[TypeRange] | None,
ctx: Context,
default: Type,
ignore_type_params: bool = True,
self, expr_type: Type, type_ranges: list[TypeRange] | None, ctx: Context, default: Type
) -> tuple[Type, Type]: ...

def conditional_types_with_intersection(
Expand All @@ -7180,9 +7173,8 @@ def conditional_types_with_intersection(
type_ranges: list[TypeRange] | None,
ctx: Context,
default: Type | None = None,
ignore_type_params: bool = True,
) -> tuple[Type | None, Type | None]:
initial_types = conditional_types(expr_type, type_ranges, default, ignore_type_params)
initial_types = conditional_types(expr_type, type_ranges, default)
# For some reason, doing "yes_map, no_map = conditional_types_to_typemaps(...)"
# doesn't work: mypyc will decide that 'yes_map' is of type None if we try.
yes_type: Type | None = initial_types[0]
Expand Down Expand Up @@ -7430,27 +7422,18 @@ def visit_type_var(self, t: TypeVarType) -> None:

@overload
def conditional_types(
current_type: Type,
proposed_type_ranges: list[TypeRange] | None,
default: None = None,
ignore_type_params: bool = True,
current_type: Type, proposed_type_ranges: list[TypeRange] | None, default: None = None
) -> tuple[Type | None, Type | None]: ...


@overload
def conditional_types(
current_type: Type,
proposed_type_ranges: list[TypeRange] | None,
default: Type,
ignore_type_params: bool = True,
current_type: Type, proposed_type_ranges: list[TypeRange] | None, default: Type
) -> tuple[Type, Type]: ...


def conditional_types(
current_type: Type,
proposed_type_ranges: list[TypeRange] | None,
default: Type | None = None,
ignore_type_params: bool = True,
current_type: Type, proposed_type_ranges: list[TypeRange] | None, default: Type | None = None
) -> tuple[Type | None, Type | None]:
"""Takes in the current type and a proposed type of an expression.
Expand Down Expand Up @@ -7494,9 +7477,7 @@ def conditional_types(
if not type_range.is_upper_bound
]
)
remaining_type = restrict_subtype_away(
current_type, proposed_precise_type, ignore_type_params=ignore_type_params
)
remaining_type = restrict_subtype_away(current_type, proposed_precise_type)
return proposed_type, remaining_type
else:
# An isinstance check, but we don't understand the type
Expand Down
31 changes: 11 additions & 20 deletions mypy/subtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1910,49 +1910,40 @@ def try_restrict_literal_union(t: UnionType, s: Type) -> list[Type] | None:
return new_items


def restrict_subtype_away(t: Type, s: Type, ignore_type_params: bool = True) -> Type:
"""Return t minus s for runtime type assertions and TypeIs[].
def restrict_subtype_away(t: Type, s: Type) -> Type:
"""Return t minus s for runtime type assertions.
If we can't determine a precise result, return a supertype of the
ideal result (just t is a valid result).
This is used for type inference of runtime type checks such as
isinstance() or TypeIs[]. Currently, this just removes elements
of a union type.
isinstance(). Currently, this just removes elements of a union type.
"""
p_t = get_proper_type(t)
if isinstance(p_t, UnionType):
new_items = try_restrict_literal_union(p_t, s)
if new_items is None:
new_items = [
restrict_subtype_away(item, s, ignore_type_params=ignore_type_params)
restrict_subtype_away(item, s)
for item in p_t.relevant_items()
if (
isinstance(get_proper_type(item), AnyType)
or not covers_type(item, s, ignore_type_params)
)
if not covers_at_runtime(item, s)
]
return UnionType.make_union(new_items)
elif covers_type(t, s, ignore_type_params):
elif covers_at_runtime(t, s):
return UninhabitedType()
else:
return t


def covers_type(item: Type, supertype: Type, ignore_type_params: bool = True) -> bool:
"""Checks if item is covered by supertype."""
def covers_at_runtime(item: Type, supertype: Type) -> bool:
"""Will isinstance(item, supertype) always return True at runtime?"""
item = get_proper_type(item)
supertype = get_proper_type(supertype)

if not ignore_type_params:
return is_proper_subtype(item, supertype, ignore_promotions=True)
if isinstance(item, AnyType):
return False

# The following code is used for isinstance(), where ignore the type
# params is important (since this happens at runtime)
supertype = erase_type(supertype)
if is_proper_subtype(
erase_type(item), supertype, ignore_promotions=True, erase_instances=True
):
if is_subtype(item, supertype, ignore_promotions=True):
return True
if isinstance(supertype, Instance):
if supertype.type.is_protocol:
Expand Down
12 changes: 12 additions & 0 deletions test-data/unit/check-typeis.test
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,18 @@ class C:
def is_float(self, a: object) -> TypeIs[float]: pass
[builtins fixtures/tuple.pyi]

[case testTypeIsAwaitableAny]
from typing_extensions import TypeIs
from typing import Any, Awaitable, TypeVar, Union
T = TypeVar('T')
def is_awaitable(val: object) -> TypeIs[Awaitable[Any]]: pass
def main(a: Union[Awaitable[T], T]) -> None:
if is_awaitable(a):
reveal_type(a) # N: Revealed type is "Union[typing.Awaitable[T`-1], typing.Awaitable[Any]]"
else:
reveal_type(a) # N: Revealed type is "T`-1"
[builtins fixtures/tuple.pyi]

[case testTypeIsCrossModule]
import guard
from points import Point
Expand Down

0 comments on commit 2aef4f3

Please sign in to comment.