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
|
||||
)
|
||||
|
||||
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):
|
||||
index_class = TypingClassWithIndex
|
||||
|
||||
@@ -6,6 +6,7 @@ from typing import (
|
||||
Iterable,
|
||||
List,
|
||||
Mapping,
|
||||
Optional,
|
||||
Tuple,
|
||||
Type,
|
||||
TypeVar,
|
||||
@@ -19,7 +20,11 @@ T_co = TypeVar('T_co', covariant=True)
|
||||
V = TypeVar('V')
|
||||
|
||||
|
||||
just_float = 42. # type: float
|
||||
optional_float = 42. # type: Optional[float]
|
||||
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]]
|
||||
|
||||
# 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]]
|
||||
|
||||
# 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]:
|
||||
return [x() for x in the_list]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user