forked from VimPlug/jedi
Add support for generic optional parameters (#1559)
* Add support for generic optional parameters * Tests for passing non-optional arguments to optional parameters * Remove now-redundant is_class_value handling This parameter has since been removed from infer_type_vars methods, much simplifying the code.
This commit is contained in:
@@ -145,6 +145,24 @@ class TypingClassWithIndex(BaseTypingClassWithGenerics):
|
|||||||
generics_manager
|
generics_manager
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def infer_type_vars(self, value_set):
|
||||||
|
annotation_generics = self.get_generics()
|
||||||
|
|
||||||
|
if not annotation_generics:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
annotation_name = self.py__name__()
|
||||||
|
if annotation_name == 'Optional':
|
||||||
|
# Optional[T] is equivalent to Union[T, None]. In Jedi unions
|
||||||
|
# are represented by members within a ValueSet, so we extract
|
||||||
|
# the T from the Optional[T] by removing the None value.
|
||||||
|
none = builtin_from_name(self.inference_state, u'None')
|
||||||
|
return annotation_generics[0].infer_type_vars(
|
||||||
|
value_set.filter(lambda x: x != none),
|
||||||
|
)
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
class ProxyTypingValue(BaseTypingValue):
|
class ProxyTypingValue(BaseTypingValue):
|
||||||
index_class = TypingClassWithIndex
|
index_class = TypingClassWithIndex
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from typing import (
|
|||||||
Iterable,
|
Iterable,
|
||||||
List,
|
List,
|
||||||
Mapping,
|
Mapping,
|
||||||
|
Optional,
|
||||||
Tuple,
|
Tuple,
|
||||||
Type,
|
Type,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
@@ -19,7 +20,11 @@ T_co = TypeVar('T_co', covariant=True)
|
|||||||
V = TypeVar('V')
|
V = TypeVar('V')
|
||||||
|
|
||||||
|
|
||||||
|
just_float = 42. # type: float
|
||||||
|
optional_float = 42. # type: Optional[float]
|
||||||
list_of_ints = [42] # type: List[int]
|
list_of_ints = [42] # type: List[int]
|
||||||
|
list_of_floats = [42.] # type: List[float]
|
||||||
|
list_of_optional_floats = [x or None for x in list_of_floats] # type: List[Optional[float]]
|
||||||
list_of_ints_and_strs = [42, 'abc'] # type: List[Union[int, str]]
|
list_of_ints_and_strs = [42, 'abc'] # type: List[Union[int, str]]
|
||||||
|
|
||||||
# Test that simple parameters are handled
|
# Test that simple parameters are handled
|
||||||
@@ -47,6 +52,50 @@ for z in list_t_to_list_t(list_of_ints_and_strs):
|
|||||||
list_of_int_type = [int] # type: List[Type[int]]
|
list_of_int_type = [int] # type: List[Type[int]]
|
||||||
|
|
||||||
# Test that nested parameters are handled
|
# Test that nested parameters are handled
|
||||||
|
def list_optional_t_to_list_t(the_list: List[Optional[T]]) -> List[T]:
|
||||||
|
return [x for x in the_list if x is not None]
|
||||||
|
|
||||||
|
|
||||||
|
for xa in list_optional_t_to_list_t(list_of_optional_floats):
|
||||||
|
#? float()
|
||||||
|
xa
|
||||||
|
|
||||||
|
# Under covariance rules this is strictly incorrect (because List is mutable,
|
||||||
|
# the function would be allowed to put `None`s into our List[float], which would
|
||||||
|
# be bad), however we don't expect jedi to enforce that.
|
||||||
|
for xa1 in list_optional_t_to_list_t(list_of_floats):
|
||||||
|
#? float()
|
||||||
|
xa1
|
||||||
|
|
||||||
|
|
||||||
|
def optional_t_to_list_t(x: Optional[T]) -> List[T]:
|
||||||
|
return [x] if x is not None else []
|
||||||
|
|
||||||
|
|
||||||
|
for xb in optional_t_to_list_t(optional_float):
|
||||||
|
#? float()
|
||||||
|
xb
|
||||||
|
|
||||||
|
|
||||||
|
for xb2 in optional_t_to_list_t(just_float):
|
||||||
|
#? float()
|
||||||
|
xb2
|
||||||
|
|
||||||
|
|
||||||
|
def optional_list_t_to_list_t(x: Optional[List[T]]) -> List[T]:
|
||||||
|
return x if x is not None else []
|
||||||
|
|
||||||
|
|
||||||
|
optional_list_float = None # type: Optional[List[float]]
|
||||||
|
for xc in optional_list_t_to_list_t(optional_list_float):
|
||||||
|
#? float()
|
||||||
|
xc
|
||||||
|
|
||||||
|
for xc2 in optional_list_t_to_list_t(list_of_floats):
|
||||||
|
#? float()
|
||||||
|
xc2
|
||||||
|
|
||||||
|
|
||||||
def list_type_t_to_list_t(the_list: List[Type[T]]) -> List[T]:
|
def list_type_t_to_list_t(the_list: List[Type[T]]) -> List[T]:
|
||||||
return [x() for x in the_list]
|
return [x() for x in the_list]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user