mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-16 02:27:06 +08:00
Fix an issue with type vars
This commit is contained in:
@@ -159,7 +159,7 @@ class AnonymousArguments(AbstractArguments):
|
||||
execution_context.evaluator,
|
||||
execution_context,
|
||||
execution_context.tree_node
|
||||
)
|
||||
), []
|
||||
|
||||
def __repr__(self):
|
||||
return '%s()' % self.__class__.__name__
|
||||
|
||||
@@ -27,6 +27,9 @@ class InstanceExecutedParam(object):
|
||||
def infer(self):
|
||||
return ContextSet(self._instance)
|
||||
|
||||
def matches_signature(self):
|
||||
return True
|
||||
|
||||
|
||||
class AnonymousInstanceArguments(AnonymousArguments):
|
||||
def __init__(self, instance):
|
||||
@@ -42,14 +45,14 @@ class AnonymousInstanceArguments(AnonymousArguments):
|
||||
if len(tree_params) == 1:
|
||||
# If the only param is self, we don't need to try to find
|
||||
# executions of this function, we have all the params already.
|
||||
return [self_param]
|
||||
return [self_param], []
|
||||
executed_params = list(search_params(
|
||||
execution_context.evaluator,
|
||||
execution_context,
|
||||
execution_context.tree_node
|
||||
))
|
||||
executed_params[0] = self_param
|
||||
return [], executed_params
|
||||
return executed_params, []
|
||||
|
||||
|
||||
class AbstractInstanceContext(Context):
|
||||
@@ -263,7 +266,7 @@ class TreeInstance(AbstractInstanceContext):
|
||||
|
||||
@evaluator_method_cache()
|
||||
def get_annotated_class_object(self):
|
||||
from jedi.evaluate.pep0484 import define_type_vars_for_execution
|
||||
from jedi.evaluate import pep0484
|
||||
|
||||
for func in self._get_annotation_init_functions():
|
||||
# Just take the first result, it should always be one, because we
|
||||
@@ -274,13 +277,12 @@ class TreeInstance(AbstractInstanceContext):
|
||||
# First check if the signature even matches, if not we don't
|
||||
# need to infer anything.
|
||||
continue
|
||||
context_set = define_type_vars_for_execution(
|
||||
ContextSet(self.class_context),
|
||||
execution,
|
||||
self.class_context.list_type_vars()
|
||||
|
||||
all_annotations = pep0484.py__annotations__(execution.tree_node)
|
||||
return pep0484.define_type_vars(
|
||||
self.class_context,
|
||||
pep0484.infer_type_vars_for_execution(execution, all_annotations),
|
||||
)
|
||||
if context_set:
|
||||
return next(iter(context_set))
|
||||
return self.class_context
|
||||
|
||||
def _get_annotation_init_functions(self):
|
||||
|
||||
@@ -261,11 +261,9 @@ class ClassContext(use_metaclass(CachedMetaClass, TreeContext)):
|
||||
return self.name.string_name
|
||||
|
||||
def py__getitem__(self, index_context_set, contextualized_node):
|
||||
from jedi.evaluate.context.typing import TypingClassMixin, AnnotatedClass
|
||||
#from pprint import pprint
|
||||
for cls in py__mro__(self):
|
||||
if isinstance(cls, TypingClassMixin):
|
||||
# TODO get the right classes.
|
||||
from jedi.evaluate.context.typing import AnnotatedClass
|
||||
if not index_context_set:
|
||||
return ContextSet(self)
|
||||
return ContextSet.from_iterable(
|
||||
AnnotatedClass(
|
||||
self.evaluator,
|
||||
@@ -276,5 +274,3 @@ class ClassContext(use_metaclass(CachedMetaClass, TreeContext)):
|
||||
)
|
||||
for index_context in index_context_set
|
||||
)
|
||||
|
||||
return super(ClassContext, self).py__getitem__(index_context_set, contextualized_node)
|
||||
|
||||
@@ -406,7 +406,7 @@ class TypeVar(_BaseTypingContext):
|
||||
return ContextSet.from_sets(
|
||||
l.infer() for l in self._constraints_lazy_contexts
|
||||
)
|
||||
debug.warning('Tried to infer the TypeVar %r without a given type', self._var_name)
|
||||
debug.warning('Tried to infer the TypeVar %s without a given type', self._var_name)
|
||||
return NO_CONTEXTS
|
||||
|
||||
@property
|
||||
|
||||
@@ -69,7 +69,7 @@ def get_executed_params_and_issues(execution_context, var_args):
|
||||
_add_argument_issue(
|
||||
default_param_context,
|
||||
'type-error-too-many-arguments',
|
||||
lazy_context,
|
||||
argument,
|
||||
message=m
|
||||
)
|
||||
)
|
||||
|
||||
@@ -221,23 +221,34 @@ def infer_return_types(function_execution_context):
|
||||
if not unknown_type_vars:
|
||||
return context.eval_node(annotation).execute_annotation()
|
||||
|
||||
return define_type_vars_for_execution(
|
||||
context.eval_node(annotation),
|
||||
function_execution_context,
|
||||
unknown_type_vars,
|
||||
annotations_contexts = context.eval_node(annotation)
|
||||
type_var_dict = infer_type_vars_for_execution(function_execution_context, all_annotations)
|
||||
|
||||
def remap_type_vars(context, type_var_dict):
|
||||
"""
|
||||
The TypeVars in the resulting classes have sometimes different names
|
||||
and we need to check for that, e.g. a signature can be:
|
||||
|
||||
def iter(iterable: Iterable[_T]) -> Iterator[_T]: ...
|
||||
|
||||
However, the iterator is defined as Iterator[_T_co], which means it has
|
||||
a different type var name.
|
||||
"""
|
||||
if isinstance(context, ClassContext):
|
||||
return {
|
||||
to.py__name__(): type_var_dict.get(from_.py__name__(), NO_CONTEXTS)
|
||||
for from_, to in zip(unknown_type_vars, context.list_type_vars())
|
||||
}
|
||||
return type_var_dict
|
||||
return ContextSet.from_iterable(
|
||||
define_type_vars(
|
||||
annotation_context,
|
||||
remap_type_vars(annotation_context, type_var_dict),
|
||||
) for annotation_context in annotations_contexts
|
||||
).execute_annotation()
|
||||
|
||||
|
||||
def define_type_vars_for_execution(to_define_contexts, execution_context,
|
||||
unknown_type_vars):
|
||||
all_annotations = py__annotations__(execution_context.tree_node)
|
||||
return _define_type_vars(
|
||||
to_define_contexts,
|
||||
_infer_type_vars_for_execution(execution_context, all_annotations),
|
||||
)
|
||||
|
||||
|
||||
def _infer_type_vars_for_execution(execution_context, annotation_dict):
|
||||
def infer_type_vars_for_execution(execution_context, annotation_dict):
|
||||
"""
|
||||
Some functions use type vars that are not defined by the class, but rather
|
||||
only defined in the function. See for example `iter`. In those cases we
|
||||
@@ -277,26 +288,19 @@ def _infer_type_vars_for_execution(execution_context, annotation_dict):
|
||||
return annotation_variable_results
|
||||
|
||||
|
||||
def _define_type_vars(annotation_contexts, type_var_dict):
|
||||
def define_type_vars(annotation_context, type_var_dict):
|
||||
def remap_type_vars(cls):
|
||||
for type_var in cls.list_type_vars():
|
||||
yield type_var_dict.get(type_var.py__name__(), NO_CONTEXTS)
|
||||
|
||||
if not type_var_dict:
|
||||
return annotation_contexts
|
||||
|
||||
context_set = ContextSet()
|
||||
for annotation_context in annotation_contexts:
|
||||
if isinstance(annotation_context, ClassContext):
|
||||
context_set |= ContextSet.from_iterable([
|
||||
AnnotatedSubClass(
|
||||
if type_var_dict and isinstance(annotation_context, ClassContext):
|
||||
return AnnotatedSubClass(
|
||||
annotation_context.evaluator,
|
||||
annotation_context.parent_context,
|
||||
annotation_context.tree_node,
|
||||
given_types=tuple(remap_type_vars(annotation_context))
|
||||
)
|
||||
])
|
||||
return context_set
|
||||
return annotation_context
|
||||
|
||||
|
||||
def _merge_type_var_dicts(base_dict, new_dict):
|
||||
|
||||
@@ -273,9 +273,9 @@ d.values()[0]
|
||||
x, = d.values()
|
||||
#? int() str()
|
||||
x
|
||||
#? int()
|
||||
#? int() str()
|
||||
d['a']
|
||||
#? int() None
|
||||
#? int() str() None
|
||||
d.get('a')
|
||||
|
||||
# -----------------
|
||||
|
||||
Reference in New Issue
Block a user