mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Fix class tests
This commit is contained in:
@@ -284,7 +284,7 @@ class Completion:
|
||||
cls = tree.search_ancestor(leaf, 'classdef')
|
||||
if isinstance(cls, (tree.Class, tree.Function)):
|
||||
# Complete the methods that are defined in the super classes.
|
||||
random_value = self._module_context.create_context(
|
||||
random_context = self._module_context.create_context(
|
||||
cls,
|
||||
node_is_value=True
|
||||
)
|
||||
@@ -294,7 +294,8 @@ class Completion:
|
||||
if cls.start_pos[1] >= leaf.start_pos[1]:
|
||||
return
|
||||
|
||||
filters = random_value.get_filters(is_instance=True)
|
||||
# TODO _value private access!
|
||||
filters = random_context._value.get_filters(is_instance=True)
|
||||
# The first dict is the dictionary of class itself.
|
||||
next(filters)
|
||||
for filter in filters:
|
||||
|
||||
@@ -349,13 +349,13 @@ class InferenceState(object):
|
||||
new_dotted.children[index - 1:] = []
|
||||
values = context.infer_node(new_dotted)
|
||||
return unite(
|
||||
value.py__getattribute__(name, name_value=value, is_goto=True)
|
||||
value.goto(name, name_value=value)
|
||||
for value in values
|
||||
)
|
||||
|
||||
if node_type == 'trailer' and par.children[0] == '.':
|
||||
values = helpers.infer_call_of_leaf(context, name, cut_own_trailer=True)
|
||||
return values.py__getattribute__(name, name_context=context, is_goto=True)
|
||||
return values.goto(name, name_context=context)
|
||||
else:
|
||||
stmt = tree.search_ancestor(
|
||||
name, 'expr_stmt', 'lambdef'
|
||||
@@ -391,8 +391,9 @@ class InferenceState(object):
|
||||
if is_funcdef:
|
||||
func = FunctionValue.from_context(parent_context, scope_node)
|
||||
if parent_context.is_class():
|
||||
# TODO _value private access!
|
||||
instance = AnonymousInstance(
|
||||
self, parent_context.parent_context, parent_context)
|
||||
self, parent_context.parent_context, parent_context._value)
|
||||
func = BoundMethod(
|
||||
instance=instance,
|
||||
function=func
|
||||
@@ -402,7 +403,7 @@ class InferenceState(object):
|
||||
return func.get_function_execution()
|
||||
return func
|
||||
elif scope_node.type == 'classdef':
|
||||
return ClassValue(self, parent_context, scope_node)
|
||||
return ClassValue(self, parent_context, scope_node).as_context()
|
||||
elif scope_node.type in ('comp_for', 'sync_comp_for'):
|
||||
if node.start_pos >= scope_node.children[-1].start_pos:
|
||||
return parent_context
|
||||
|
||||
@@ -71,6 +71,18 @@ class HelperValueMixin(object):
|
||||
filters = f.get_value_filters()
|
||||
return f.find(filters, attribute_lookup=True)
|
||||
|
||||
def goto(self, name_or_str, name_context=None, analysis_errors=True):
|
||||
"""
|
||||
:param position: Position of the last statement -> tuple of line, column
|
||||
"""
|
||||
if name_context is None:
|
||||
name_context = self
|
||||
from jedi.inference import finder
|
||||
f = finder.NameFinder(self.inference_state, self, name_context, name_or_str,
|
||||
analysis_errors=analysis_errors)
|
||||
filters = f.get_value_filters()
|
||||
return f.filter_name(filters)
|
||||
|
||||
def py__await__(self):
|
||||
await_value_set = self.py__getattribute__(u"__await__")
|
||||
if not await_value_set:
|
||||
@@ -403,9 +415,10 @@ class ValueSet(BaseValueSet):
|
||||
def execute_with_values(self, *args, **kwargs):
|
||||
return ValueSet.from_sets(c.execute_with_values(*args, **kwargs) for c in self._set)
|
||||
|
||||
def goto(self, *args, **kwargs):
|
||||
return reduce(add, [c.goto(*args, **kwargs) for c in self._set], [])
|
||||
|
||||
def py__getattribute__(self, *args, **kwargs):
|
||||
if kwargs.get('is_goto'):
|
||||
return reduce(add, [c.py__getattribute__(*args, **kwargs) for c in self._set], [])
|
||||
return ValueSet.from_sets(c.py__getattribute__(*args, **kwargs) for c in self._set)
|
||||
|
||||
def get_item(self, *args, **kwargs):
|
||||
@@ -422,9 +435,6 @@ class ValueSet(BaseValueSet):
|
||||
value_set |= method()
|
||||
return value_set
|
||||
|
||||
def as_context(self):
|
||||
return [v.as_context() for v in self._set]
|
||||
|
||||
def gather_annotation_classes(self):
|
||||
return ValueSet.from_sets([c.gather_annotation_classes() for c in self._set])
|
||||
|
||||
|
||||
@@ -72,6 +72,9 @@ class AbstractContext(object):
|
||||
def py__name__(self):
|
||||
return self._value.py__name__()
|
||||
|
||||
def get_qualified_names(self):
|
||||
return self._value.get_qualified_names()
|
||||
|
||||
def py__doc__(self):
|
||||
return self._value.py__doc__()
|
||||
|
||||
@@ -103,6 +106,7 @@ class ModuleContext(AbstractContext):
|
||||
def get_filters(self, until_position=None, origin_scope=None):
|
||||
filters = self._value.get_filters(origin_scope)
|
||||
# Skip the first filter and replace it.
|
||||
next(filters)
|
||||
yield MergedFilter(
|
||||
ParserTreeFilter(
|
||||
context=self,
|
||||
|
||||
@@ -169,11 +169,11 @@ def _infer_param(execution_context, param):
|
||||
|
||||
param_comment = params_comments[index]
|
||||
return _infer_annotation_string(
|
||||
execution_context.function_value.get_default_param_value(),
|
||||
execution_context.function_value.get_default_param_context(),
|
||||
param_comment
|
||||
)
|
||||
# Annotations are like default params and resolve in the same way.
|
||||
value = execution_context.function_value.get_default_param_value()
|
||||
value = execution_context.function_value.get_default_param_context()
|
||||
return infer_annotation(value, annotation)
|
||||
|
||||
|
||||
@@ -210,13 +210,13 @@ def infer_return_types(function_execution_context):
|
||||
return NO_VALUES
|
||||
|
||||
return _infer_annotation_string(
|
||||
function_execution_context.function_value.get_default_param_value(),
|
||||
function_execution_context.function_value.get_default_param_context(),
|
||||
match.group(1).strip()
|
||||
).execute_annotation()
|
||||
if annotation is None:
|
||||
return NO_VALUES
|
||||
|
||||
value = function_execution_context.function_value.get_default_param_value()
|
||||
value = function_execution_context.function_value.get_default_param_context()
|
||||
unknown_type_vars = list(find_unknown_type_vars(value, annotation))
|
||||
annotation_values = infer_annotation(value, annotation)
|
||||
if not unknown_type_vars:
|
||||
@@ -241,7 +241,7 @@ def infer_type_vars_for_execution(execution_context, annotation_dict):
|
||||
2. Infer type vars with the execution state we have.
|
||||
3. Return the union of all type vars that have been found.
|
||||
"""
|
||||
value = execution_context.function_value.get_default_param_value()
|
||||
value = execution_context.function_value.get_default_param_context()
|
||||
|
||||
annotation_variable_results = {}
|
||||
executed_params, _ = execution_context.get_executed_params_and_issues()
|
||||
|
||||
@@ -69,7 +69,7 @@ def _try_stub_to_python_names(names, prefer_stub_to_compiled=False):
|
||||
ignore_compiled=prefer_stub_to_compiled,
|
||||
)
|
||||
if values and name_list:
|
||||
new_names = values.py__getattribute__(name_list[-1], is_goto=True)
|
||||
new_names = values.goto(name_list[-1])
|
||||
for new_name in new_names:
|
||||
yield new_name
|
||||
if new_names:
|
||||
@@ -121,7 +121,7 @@ def _python_to_stub_names(names, fallback_to_python=False):
|
||||
for name in name_list[:-1]:
|
||||
stubs = stubs.py__getattribute__(name)
|
||||
if stubs and name_list:
|
||||
new_names = stubs.py__getattribute__(name_list[-1], is_goto=True)
|
||||
new_names = stubs.goto(name_list[-1])
|
||||
for new_name in new_names:
|
||||
yield new_name
|
||||
if new_names:
|
||||
|
||||
@@ -89,7 +89,7 @@ def get_executed_params_and_issues(execution_context, arguments):
|
||||
# Default params are part of the value where the function was defined.
|
||||
# This means that they might have access on class variables that the
|
||||
# function itself doesn't have.
|
||||
default_param_value = execution_context.function_value.get_default_param_value()
|
||||
default_param_context = execution_context.function_value.get_default_param_context()
|
||||
|
||||
for param in funcdef.get_params():
|
||||
param_dict[param.name.value] = param
|
||||
@@ -172,7 +172,7 @@ def get_executed_params_and_issues(execution_context, arguments):
|
||||
)
|
||||
)
|
||||
else:
|
||||
result_arg = LazyTreeValue(default_param_value, param.default)
|
||||
result_arg = LazyTreeValue(default_param_context, param.default)
|
||||
is_default = True
|
||||
else:
|
||||
result_arg = argument
|
||||
|
||||
@@ -93,6 +93,9 @@ class FunctionMixin(object):
|
||||
|
||||
return FunctionExecutionContext(self, arguments)
|
||||
|
||||
def as_context(self):
|
||||
return self.get_function_execution()
|
||||
|
||||
def get_signatures(self):
|
||||
return [TreeSignature(f) for f in self.get_signature_functions()]
|
||||
|
||||
@@ -137,7 +140,7 @@ class FunctionValue(use_metaclass(CachedMetaClass, FunctionMixin, FunctionAndCla
|
||||
c, = values_from_qualified_names(self.inference_state, u'types', u'FunctionType')
|
||||
return c
|
||||
|
||||
def get_default_param_value(self):
|
||||
def get_default_param_context(self):
|
||||
return self.parent_context
|
||||
|
||||
def get_signature_functions(self):
|
||||
@@ -145,17 +148,17 @@ class FunctionValue(use_metaclass(CachedMetaClass, FunctionMixin, FunctionAndCla
|
||||
|
||||
|
||||
class MethodValue(FunctionValue):
|
||||
def __init__(self, inference_state, class_value, *args, **kwargs):
|
||||
def __init__(self, inference_state, class_context, *args, **kwargs):
|
||||
super(MethodValue, self).__init__(inference_state, *args, **kwargs)
|
||||
self.class_value = class_value
|
||||
self.class_context = class_context
|
||||
|
||||
def get_default_param_value(self):
|
||||
return self.class_value
|
||||
def get_default_param_context(self):
|
||||
return self.class_context
|
||||
|
||||
def get_qualified_names(self):
|
||||
# Need to implement this, because the parent value of a method
|
||||
# value is not the class value but the module.
|
||||
names = self.class_value.get_qualified_names()
|
||||
names = self.class_context.get_qualified_names()
|
||||
if names is None:
|
||||
return None
|
||||
return names + (self.py__name__(),)
|
||||
|
||||
@@ -106,7 +106,7 @@ class ClassFilter(ParserTreeFilter):
|
||||
def _equals_origin_scope(self):
|
||||
node = self._origin_scope
|
||||
while node is not None:
|
||||
if node == self._parser_scope or node == self.value:
|
||||
if node == self._parser_scope or node == self.context:
|
||||
return True
|
||||
node = get_cached_parent_scope(self._used_names, node)
|
||||
return False
|
||||
|
||||
@@ -158,7 +158,7 @@ def _follow_param(inference_state, arguments, index):
|
||||
return lazy_value.infer()
|
||||
|
||||
|
||||
def argument_clinic(string, want_obj=False, want_value=False,
|
||||
def argument_clinic(string, want_obj=False, want_context=False,
|
||||
want_arguments=False, want_inference_state=False,
|
||||
want_callback=False):
|
||||
"""
|
||||
@@ -174,8 +174,8 @@ def argument_clinic(string, want_obj=False, want_value=False,
|
||||
assert not kwargs # Python 2...
|
||||
debug.dbg('builtin start %s' % obj, color='MAGENTA')
|
||||
result = NO_VALUES
|
||||
if want_value:
|
||||
kwargs['value'] = arguments.value
|
||||
if want_context:
|
||||
kwargs['context'] = arguments.context
|
||||
if want_obj:
|
||||
kwargs['obj'] = obj
|
||||
if want_inference_state:
|
||||
@@ -268,11 +268,11 @@ class SuperInstance(LazyValueWrapper):
|
||||
yield f
|
||||
|
||||
|
||||
@argument_clinic('[type[, obj]], /', want_value=True)
|
||||
def builtins_super(types, objects, value):
|
||||
if isinstance(value, FunctionExecutionContext):
|
||||
if isinstance(value.var_args, InstanceArguments):
|
||||
instance = value.var_args.instance
|
||||
@argument_clinic('[type[, obj]], /', want_context=True)
|
||||
def builtins_super(types, objects, context):
|
||||
if isinstance(context, FunctionExecutionContext):
|
||||
if isinstance(context.var_args, InstanceArguments):
|
||||
instance = context.var_args.instance
|
||||
# TODO if a class is given it doesn't have to be the direct super
|
||||
# class, it can be an anecestor from long ago.
|
||||
return ValueSet({SuperInstance(instance.inference_state, instance)})
|
||||
|
||||
@@ -231,9 +231,7 @@ class IntegrationTestCase(object):
|
||||
#if user_context._value.api_type == 'function':
|
||||
# user_context = user_context.get_function_execution()
|
||||
node.parent = user_context.tree_node
|
||||
results = convert_values(
|
||||
user_context.infer_node(node),
|
||||
)
|
||||
results = convert_values(user_context.infer_node(node))
|
||||
if not results:
|
||||
raise Exception('Could not resolve %s on line %s'
|
||||
% (match.string, self.line_nr - 1))
|
||||
|
||||
Reference in New Issue
Block a user