mirror of
https://github.com/davidhalter/jedi.git
synced 2026-05-24 17:28:36 +08:00
Fix missing inference for typing.Type[typing.TypeVar] (#1448)
* Add Type[TypeVar] support * Completion tests for typing.Type[typing.TypeVar]
This commit is contained in:
committed by
Dave Halter
parent
facd21afc6
commit
761f0828c7
@@ -14,7 +14,8 @@ from jedi.inference.cache import inference_state_method_cache
|
|||||||
from jedi.inference.base_value import ValueSet, NO_VALUES
|
from jedi.inference.base_value import ValueSet, NO_VALUES
|
||||||
from jedi.inference.gradual.typing import TypeVar, LazyGenericClass, \
|
from jedi.inference.gradual.typing import TypeVar, LazyGenericClass, \
|
||||||
AbstractAnnotatedClass
|
AbstractAnnotatedClass
|
||||||
from jedi.inference.gradual.typing import GenericClass
|
from jedi.inference.gradual.typing import GenericClass, \
|
||||||
|
TypingClassValueWithIndex
|
||||||
from jedi.inference.helpers import is_string
|
from jedi.inference.helpers import is_string
|
||||||
from jedi.inference.compiled import builtin_from_name
|
from jedi.inference.compiled import builtin_from_name
|
||||||
from jedi.inference.param import get_executed_param_names
|
from jedi.inference.param import get_executed_param_names
|
||||||
@@ -270,7 +271,6 @@ def infer_type_vars_for_execution(function, arguments, annotation_dict):
|
|||||||
annotation_variable_results,
|
annotation_variable_results,
|
||||||
_infer_type_vars(ann, actual_value_set),
|
_infer_type_vars(ann, actual_value_set),
|
||||||
)
|
)
|
||||||
|
|
||||||
return annotation_variable_results
|
return annotation_variable_results
|
||||||
|
|
||||||
|
|
||||||
@@ -283,7 +283,7 @@ def _merge_type_var_dicts(base_dict, new_dict):
|
|||||||
base_dict[type_var_name] = values
|
base_dict[type_var_name] = values
|
||||||
|
|
||||||
|
|
||||||
def _infer_type_vars(annotation_value, value_set):
|
def _infer_type_vars(annotation_value, value_set, is_class_value=False):
|
||||||
"""
|
"""
|
||||||
This function tries to find information about undefined type vars and
|
This function tries to find information about undefined type vars and
|
||||||
returns a dict from type var name to value set.
|
returns a dict from type var name to value set.
|
||||||
@@ -298,7 +298,23 @@ def _infer_type_vars(annotation_value, value_set):
|
|||||||
"""
|
"""
|
||||||
type_var_dict = {}
|
type_var_dict = {}
|
||||||
if isinstance(annotation_value, TypeVar):
|
if isinstance(annotation_value, TypeVar):
|
||||||
return {annotation_value.py__name__(): value_set.py__class__()}
|
if not is_class_value:
|
||||||
|
return {annotation_value.py__name__(): value_set.py__class__()}
|
||||||
|
return {annotation_value.py__name__(): value_set}
|
||||||
|
elif isinstance(annotation_value, TypingClassValueWithIndex):
|
||||||
|
name = annotation_value.py__name__()
|
||||||
|
if name == 'Type':
|
||||||
|
given = annotation_value.get_generics()
|
||||||
|
if given:
|
||||||
|
for nested_annotation_value in given[0]:
|
||||||
|
_merge_type_var_dicts(
|
||||||
|
type_var_dict,
|
||||||
|
_infer_type_vars(
|
||||||
|
nested_annotation_value,
|
||||||
|
value_set,
|
||||||
|
is_class_value=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
elif isinstance(annotation_value, LazyGenericClass):
|
elif isinstance(annotation_value, LazyGenericClass):
|
||||||
name = annotation_value.py__name__()
|
name = annotation_value.py__name__()
|
||||||
if name == 'Iterable':
|
if name == 'Iterable':
|
||||||
|
|||||||
@@ -219,7 +219,10 @@ class _TypingClassMixin(ClassMixin):
|
|||||||
|
|
||||||
|
|
||||||
class TypingClassValueWithIndex(_TypingClassMixin, TypingValueWithIndex):
|
class TypingClassValueWithIndex(_TypingClassMixin, TypingValueWithIndex):
|
||||||
pass
|
|
||||||
|
@inference_state_method_cache()
|
||||||
|
def get_generics(self):
|
||||||
|
return list(_iter_over_arguments(self._index_value, self._context_of_index))
|
||||||
|
|
||||||
|
|
||||||
class TypingClassValue(_TypingClassMixin, TypingValue):
|
class TypingClassValue(_TypingClassMixin, TypingValue):
|
||||||
|
|||||||
@@ -363,6 +363,17 @@ in_out1(str())
|
|||||||
#?
|
#?
|
||||||
in_out1()
|
in_out1()
|
||||||
|
|
||||||
|
def type_in_out1(x: typing.Type[TYPE_VARX]) -> TYPE_VARX: ...
|
||||||
|
|
||||||
|
#? int()
|
||||||
|
type_in_out1(int)
|
||||||
|
#? str()
|
||||||
|
type_in_out1(str)
|
||||||
|
#? float()
|
||||||
|
type_in_out1(float)
|
||||||
|
#?
|
||||||
|
type_in_out1()
|
||||||
|
|
||||||
def in_out2(x: TYPE_VAR_CONSTRAINTSX) -> TYPE_VAR_CONSTRAINTSX: ...
|
def in_out2(x: TYPE_VAR_CONSTRAINTSX) -> TYPE_VAR_CONSTRAINTSX: ...
|
||||||
|
|
||||||
#? int()
|
#? int()
|
||||||
@@ -377,6 +388,18 @@ in_out2()
|
|||||||
#? float()
|
#? float()
|
||||||
in_out2(1.0)
|
in_out2(1.0)
|
||||||
|
|
||||||
|
def type_in_out2(x: typing.Type[TYPE_VAR_CONSTRAINTSX]) -> TYPE_VAR_CONSTRAINTSX: ...
|
||||||
|
|
||||||
|
#? int()
|
||||||
|
type_in_out2(int)
|
||||||
|
#? str()
|
||||||
|
type_in_out2(str)
|
||||||
|
#? str() int()
|
||||||
|
type_in_out2()
|
||||||
|
# TODO this should actually be str() int(), because of the constraints.
|
||||||
|
#? float()
|
||||||
|
type_in_out2(float)
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# TYPE_CHECKING
|
# TYPE_CHECKING
|
||||||
# -------------------------
|
# -------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user