1
0
forked from VimPlug/jedi

Fix some issues with converting names, see #1466

This commit is contained in:
Dave Halter
2020-01-07 10:59:15 +01:00
parent a17b56f260
commit fdb5071bec
7 changed files with 54 additions and 12 deletions

View File

@@ -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

View File

@@ -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>'

View File

@@ -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

View File

@@ -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):

View File

@@ -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()
]

View File

@@ -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

View File

@@ -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_):
"""