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