forked from VimPlug/jedi
Fix some issues with converting names, see #1466
This commit is contained in:
@@ -311,6 +311,13 @@ class CompiledName(AbstractNameDefinition):
|
||||
return None
|
||||
return parent_qualified_names + (self.string_name,)
|
||||
|
||||
def get_defining_qualified_value(self):
|
||||
context = self.parent_context
|
||||
if context.is_module() or context.is_class():
|
||||
return self.parent_context.get_value() # Might be None
|
||||
|
||||
return None
|
||||
|
||||
def __repr__(self):
|
||||
try:
|
||||
name = self.parent_context.name # __name__ is not defined all the time
|
||||
|
||||
@@ -133,6 +133,9 @@ class AbstractContext(object):
|
||||
def py__name__(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_value(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return None
|
||||
@@ -200,6 +203,9 @@ class ValueContext(AbstractContext):
|
||||
def py__doc__(self):
|
||||
return self._value.py__doc__()
|
||||
|
||||
def get_value(self):
|
||||
return self._value
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.__class__.__name__, self._value)
|
||||
|
||||
@@ -226,6 +232,7 @@ class TreeContextMixin(object):
|
||||
self.inference_state, parent_context.parent_context, class_value)
|
||||
func = value.BoundMethod(
|
||||
instance=instance,
|
||||
class_context=class_value.as_context(),
|
||||
function=func
|
||||
)
|
||||
return func
|
||||
@@ -365,6 +372,9 @@ class CompForContext(TreeContextMixin, AbstractContext):
|
||||
def get_filters(self, until_position=None, origin_scope=None):
|
||||
yield ParserTreeFilter(self)
|
||||
|
||||
def get_value(self):
|
||||
return None
|
||||
|
||||
def py__name__(self):
|
||||
return '<comprehension context>'
|
||||
|
||||
|
||||
@@ -135,9 +135,7 @@ class AbstractTreeName(AbstractNameDefinition):
|
||||
if self.is_import():
|
||||
raise 1
|
||||
elif self.parent_context:
|
||||
values = self.parent_context.name.infer()
|
||||
if len(values) == 1:
|
||||
return next(iter(values))
|
||||
return self.parent_context.get_value() # Might be None
|
||||
return None
|
||||
|
||||
def goto(self):
|
||||
@@ -240,6 +238,12 @@ class ValueNameMixin(object):
|
||||
return self._value.as_context()
|
||||
return super(ValueNameMixin, self).get_root_context()
|
||||
|
||||
def get_defining_qualified_value(self):
|
||||
context = self.parent_context
|
||||
if context.is_module() or context.is_class():
|
||||
return self.parent_context.get_value() # Might be None
|
||||
return None
|
||||
|
||||
@property
|
||||
def api_type(self):
|
||||
return self._value.api_type
|
||||
|
||||
@@ -11,7 +11,7 @@ from jedi.inference.signature import TreeSignature
|
||||
from jedi.inference.filters import ParserTreeFilter, FunctionExecutionFilter, \
|
||||
AnonymousFunctionExecutionFilter
|
||||
from jedi.inference.names import ValueName, AbstractNameDefinition, \
|
||||
AnonymousParamName, ParamName
|
||||
AnonymousParamName, ParamName, NameWrapper
|
||||
from jedi.inference.base_value import ContextualizedNode, NO_VALUES, \
|
||||
ValueSet, TreeValue, ValueWrapper
|
||||
from jedi.inference.lazy_value import LazyKnownValues, LazyKnownValue, \
|
||||
@@ -68,7 +68,7 @@ class FunctionMixin(object):
|
||||
if instance is None:
|
||||
# Calling the Foo.bar results in the original bar function.
|
||||
return ValueSet([self])
|
||||
return ValueSet([BoundMethod(instance, self)])
|
||||
return ValueSet([BoundMethod(instance, class_value.as_context(), self)])
|
||||
|
||||
def get_param_names(self):
|
||||
return [AnonymousParamName(self, param.name)
|
||||
@@ -141,6 +141,15 @@ class FunctionValue(use_metaclass(CachedMetaClass, FunctionMixin, FunctionAndCla
|
||||
return [self]
|
||||
|
||||
|
||||
class FunctionNameInClass(NameWrapper):
|
||||
def __init__(self, class_context, name):
|
||||
super(FunctionNameInClass, self).__init__(name)
|
||||
self._class_context = class_context
|
||||
|
||||
def get_defining_qualified_value(self):
|
||||
return self._class_context.get_value() # Might be None.
|
||||
|
||||
|
||||
class MethodValue(FunctionValue):
|
||||
def __init__(self, inference_state, class_context, *args, **kwargs):
|
||||
super(MethodValue, self).__init__(inference_state, *args, **kwargs)
|
||||
@@ -157,6 +166,10 @@ class MethodValue(FunctionValue):
|
||||
return None
|
||||
return names + (self.py__name__(),)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return FunctionNameInClass(self.class_context, super(MethodValue, self).name)
|
||||
|
||||
|
||||
class BaseFunctionExecutionContext(ValueContext, TreeContextMixin):
|
||||
def is_function_execution(self):
|
||||
|
||||
@@ -17,7 +17,7 @@ from jedi.inference.cache import inference_state_method_cache
|
||||
from jedi.inference.arguments import ValuesArguments, TreeArgumentsWrapper
|
||||
from jedi.inference.value.function import \
|
||||
FunctionValue, FunctionMixin, OverloadedFunctionValue, \
|
||||
BaseFunctionExecutionContext, FunctionExecutionContext
|
||||
BaseFunctionExecutionContext, FunctionExecutionContext, FunctionNameInClass
|
||||
from jedi.inference.value.klass import ClassFilter
|
||||
from jedi.inference.value.dynamic_arrays import get_dynamic_array_instance
|
||||
from jedi.parser_utils import function_is_staticmethod, function_is_classmethod
|
||||
@@ -211,7 +211,7 @@ class _BaseTreeInstance(AbstractInstanceValue):
|
||||
new = search_ancestor(new, 'funcdef', 'classdef')
|
||||
if class_context.tree_node is new:
|
||||
func = FunctionValue.from_context(class_context, func_node)
|
||||
bound_method = BoundMethod(self, func)
|
||||
bound_method = BoundMethod(self, class_context, func)
|
||||
if func_node.name.value == '__init__':
|
||||
context = bound_method.as_context(self._arguments)
|
||||
else:
|
||||
@@ -343,7 +343,7 @@ class TreeInstance(_BaseTreeInstance):
|
||||
# First check if the signature even matches, if not we don't
|
||||
# need to infer anything.
|
||||
continue
|
||||
bound_method = BoundMethod(self, signature.value)
|
||||
bound_method = BoundMethod(self, self.class_value.as_context(), signature.value)
|
||||
all_annotations = py__annotations__(signature.value.tree_node)
|
||||
type_var_dict = infer_type_vars_for_execution(bound_method, args, all_annotations)
|
||||
if type_var_dict:
|
||||
@@ -446,13 +446,21 @@ class CompiledInstanceClassFilter(AbstractFilter):
|
||||
|
||||
|
||||
class BoundMethod(FunctionMixin, ValueWrapper):
|
||||
def __init__(self, instance, function):
|
||||
def __init__(self, instance, class_context, function):
|
||||
super(BoundMethod, self).__init__(function)
|
||||
self.instance = instance
|
||||
self._class_context = class_context
|
||||
|
||||
def is_bound_method(self):
|
||||
return True
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return FunctionNameInClass(
|
||||
self._class_context,
|
||||
super(BoundMethod, self).name
|
||||
)
|
||||
|
||||
def py__class__(self):
|
||||
c, = values_from_qualified_names(self.inference_state, u'types', u'MethodType')
|
||||
return c
|
||||
@@ -477,7 +485,7 @@ class BoundMethod(FunctionMixin, ValueWrapper):
|
||||
|
||||
def get_signature_functions(self):
|
||||
return [
|
||||
BoundMethod(self.instance, f)
|
||||
BoundMethod(self.instance, self._class_context, f)
|
||||
for f in self._wrapped_value.get_signature_functions()
|
||||
]
|
||||
|
||||
|
||||
@@ -74,8 +74,7 @@ class ClassName(TreeNameDefinition):
|
||||
else:
|
||||
yield result_value
|
||||
|
||||
@property
|
||||
def defining_qualified_value(self):
|
||||
def get_defining_qualified_value(self):
|
||||
return self._class_value
|
||||
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ def _assert_is_same(d1, d2):
|
||||
'from collections import Counter; Counter',
|
||||
'from collections import Counter; Counter()',
|
||||
'from collections import Counter; Counter.most_common',
|
||||
'from collections import Counter; Counter().most_common',
|
||||
])
|
||||
def test_goto_stubs_on_itself(Script, code, type_):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user