-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Rework starargs with union argument #19651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
245cba3
f2d254c
df7b3f0
5e239a3
6cbb237
115bf00
08db3da
fac1e07
68bc671
e8dcf88
fe4289a
0139c12
109b4f3
0a6d757
e169d3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
|
||
from collections.abc import Sequence | ||
from typing import TYPE_CHECKING, Callable, cast | ||
from typing_extensions import NewType, TypeGuard | ||
from typing_extensions import NewType, TypeGuard, TypeIs | ||
|
||
from mypy import nodes | ||
from mypy.maptype import map_instance_to_supertype | ||
|
@@ -278,11 +278,12 @@ def expand_actual_type( | |
return original_actual | ||
|
||
def is_iterable(self, typ: Type) -> bool: | ||
"""Check if the type is an iterable, i.e. implements the Iterable Protocol.""" | ||
from mypy.subtypes import is_subtype | ||
|
||
return is_subtype(typ, self.context.iterable_type) | ||
|
||
def is_iterable_instance_type(self, typ: Type) -> TypeGuard[IterableType]: | ||
def is_iterable_instance_type(self, typ: Type) -> TypeIs[IterableType]: | ||
"""Check if the type is an Iterable[T].""" | ||
p_t = get_proper_type(typ) | ||
return isinstance(p_t, Instance) and p_t.type == self.context.iterable_type.type | ||
|
@@ -300,8 +301,6 @@ def _solve_as_iterable(self, typ: Type) -> IterableType | AnyType: | |
from mypy.nodes import ARG_POS | ||
from mypy.solve import solve_constraints | ||
|
||
iterable_kind = self.context.iterable_type.type | ||
|
||
# We first create an upcast function: | ||
# def [T] (Iterable[T]) -> Iterable[T]: ... | ||
# and then solve for T, given the input type as the argument. | ||
|
@@ -310,21 +309,20 @@ def _solve_as_iterable(self, typ: Type) -> IterableType | AnyType: | |
"T", | ||
TypeVarId(-1), | ||
values=[], | ||
upper_bound=AnyType(TypeOfAny.special_form), | ||
default=AnyType(TypeOfAny.special_form), | ||
upper_bound=AnyType(TypeOfAny.from_omitted_generics), | ||
default=AnyType(TypeOfAny.from_omitted_generics), | ||
) | ||
target = Instance(iterable_kind, [T]) | ||
|
||
target = self._make_iterable_instance_type(T) | ||
upcast_callable = CallableType( | ||
variables=[T], | ||
arg_types=[target], | ||
arg_kinds=[ARG_POS], | ||
arg_names=[None], | ||
ret_type=T, | ||
ret_type=target, | ||
fallback=self.context.function_type, | ||
) | ||
constraints = infer_constraints_for_callable( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can |
||
upcast_callable, [typ], [ARG_POS], [None], [[0]], context=self.context | ||
upcast_callable, [typ], [ARG_POS], [None], [[0]], self.context | ||
) | ||
|
||
(sol,), _ = solve_constraints([T], constraints) | ||
|
@@ -334,7 +332,11 @@ def _solve_as_iterable(self, typ: Type) -> IterableType | AnyType: | |
return self._make_iterable_instance_type(sol) | ||
|
||
def as_iterable_type(self, typ: Type) -> IterableType | AnyType: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we reuse logic from |
||
"""Reinterpret a type as Iterable[T], or return AnyType if not possible.""" | ||
"""Reinterpret a type as Iterable[T], or return AnyType if not possible. | ||
|
||
This function specially handles certain types like UnionType, TupleType, and UnpackType. | ||
Otherwise, the upcasting is performed using the solver. | ||
""" | ||
p_t = get_proper_type(typ) | ||
if self.is_iterable_instance_type(p_t) or isinstance(p_t, AnyType): | ||
return p_t | ||
|
@@ -386,8 +388,8 @@ def parse_star_args_type( | |
) -> TupleType | IterableType | ParamSpecType | AnyType: | ||
"""Parse the type of a ``*args`` argument. | ||
|
||
Returns one of TupleType, IterableType, ParamSpecType, | ||
or AnyType(TypeOfAny.from_error) if the type cannot be parsed or is invalid. | ||
Returns one of TupleType, IterableType, ParamSpecType or AnyType. | ||
Returns AnyType(TypeOfAny.from_error) if the type cannot be parsed or is invalid. | ||
""" | ||
p_t = get_proper_type(typ) | ||
if isinstance(p_t, (TupleType, ParamSpecType, AnyType)): | ||
|
Uh oh!
There was an error while loading. Please reload this page.