diff --git a/jedi/inference/base_value.py b/jedi/inference/base_value.py index 4b8fff05..a2346977 100644 --- a/jedi/inference/base_value.py +++ b/jedi/inference/base_value.py @@ -222,7 +222,11 @@ class Value(HelperValueMixin, BaseValue): # The root value knows if it's a stub or not. return self.parent_context.is_stub() + @memoize_method def as_context(self): + return self._as_context() + + def _as_context(self): raise NotImplementedError('Not all values need to be converted to contexts') diff --git a/jedi/inference/compiled/value.py b/jedi/inference/compiled/value.py index e9c5a7ca..07779b21 100644 --- a/jedi/inference/compiled/value.py +++ b/jedi/inference/compiled/value.py @@ -263,7 +263,7 @@ class CompiledObject(Value): def get_metaclasses(self): return NO_VALUES - def as_context(self): + def _as_context(self): return AbstractContext(self) diff --git a/jedi/inference/gradual/stub_value.py b/jedi/inference/gradual/stub_value.py index 54515848..1e41039b 100644 --- a/jedi/inference/gradual/stub_value.py +++ b/jedi/inference/gradual/stub_value.py @@ -59,7 +59,7 @@ class TypingModuleWrapper(StubModuleValue): for f in filters: yield f - def as_context(self): + def _as_context(self): return TypingModuleContext(self) diff --git a/jedi/inference/gradual/typing.py b/jedi/inference/gradual/typing.py index 72700281..483990bb 100644 --- a/jedi/inference/gradual/typing.py +++ b/jedi/inference/gradual/typing.py @@ -626,7 +626,7 @@ class AbstractAnnotatedClass(ClassMixin, ValueWrapper): generics=tuple(new_generics) )]) - def as_context(self): + def _as_context(self): return AnnotatedClassContext(self) def __repr__(self): diff --git a/jedi/inference/usages.py b/jedi/inference/usages.py index c0041ff8..fe5ef9a7 100644 --- a/jedi/inference/usages.py +++ b/jedi/inference/usages.py @@ -37,14 +37,17 @@ def _find_names(module_context, tree_name): def usages(module_context, tree_name): search_name = tree_name.value found_names = _find_names(module_context, tree_name) - modules = set(d.get_root_context() for d in found_names.values()) - modules = set(m for m in modules if m.is_module() and not m.is_compiled()) + module_contexts = set(d.get_root_context() for d in found_names.values()) + module_contexts = set(m for m in module_contexts if not m.is_compiled()) non_matching_usage_maps = {} inf = module_context.inference_state - for m in imports.get_modules_containing_name(inf, modules, search_name): - for name_leaf in m.tree_node.get_used_names().get(search_name, []): - new = _find_names(m, name_leaf) + potential_modules = imports.get_module_contexts_containing_name( + inf, module_contexts, search_name + ) + for module_context in potential_modules: + for name_leaf in module_context.tree_node.get_used_names().get(search_name, []): + new = _find_names(module_context, name_leaf) if any(tree_name in found_names for tree_name in new): found_names.update(new) for tree_name in new: diff --git a/jedi/inference/value/function.py b/jedi/inference/value/function.py index d0926b60..21133f31 100644 --- a/jedi/inference/value/function.py +++ b/jedi/inference/value/function.py @@ -93,7 +93,7 @@ class FunctionMixin(object): return FunctionExecutionContext(self, arguments) - def as_context(self): + def _as_context(self): return self.get_function_execution() def get_signatures(self): @@ -110,7 +110,7 @@ class FunctionValue(use_metaclass(CachedMetaClass, FunctionMixin, FunctionAndCla if context.is_class(): return MethodValue( context.inference_state, - context, + context._value, # TODO private access! parent_context=parent_context, tree_node=tree_node ) @@ -148,17 +148,17 @@ class FunctionValue(use_metaclass(CachedMetaClass, FunctionMixin, FunctionAndCla class MethodValue(FunctionValue): - def __init__(self, inference_state, class_context, *args, **kwargs): + def __init__(self, inference_state, class_value, *args, **kwargs): super(MethodValue, self).__init__(inference_state, *args, **kwargs) - self.class_context = class_context + self.class_value = class_value def get_default_param_context(self): - return self.class_context + return self.class_value 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_context.get_qualified_names() + names = self.class_value.get_qualified_names() if names is None: return None return names + (self.py__name__(),) diff --git a/jedi/inference/value/instance.py b/jedi/inference/value/instance.py index 69a80fbe..38e52297 100644 --- a/jedi/inference/value/instance.py +++ b/jedi/inference/value/instance.py @@ -198,33 +198,33 @@ class AbstractInstanceValue(Value): yield bound_method.get_function_execution(self.var_args) @inference_state_method_cache() - def create_instance_value(self, class_value, node): + def create_instance_context(self, class_context, node): if node.parent.type in ('funcdef', 'classdef'): node = node.parent scope = get_parent_scope(node) - if scope == class_value.tree_node: - return class_value + if scope == class_context.tree_node: + return class_context else: - parent_context = self.create_instance_value(class_value, scope) + parent_context = self.create_instance_context(class_context, scope) if scope.type == 'funcdef': func = FunctionValue.from_context( parent_context, scope, ) bound_method = BoundMethod(self, func) - if scope.name.value == '__init__' and parent_context == class_value: + if scope.name.value == '__init__' and parent_context == class_context: return bound_method.get_function_execution(self.var_args) else: return bound_method.get_function_execution() elif scope.type == 'classdef': - class_value = ClassValue(self.inference_state, parent_context, scope) - return class_value + class_context = ClassValue(self.inference_state, parent_context, scope) + return class_context.as_context() elif scope.type in ('comp_for', 'sync_comp_for'): # Comprehensions currently don't have a special scope in Jedi. - return self.create_instance_value(class_value, scope) + return self.create_instance_context(class_context, scope) else: raise NotImplementedError - return class_value + return class_context def get_signatures(self): call_funcs = self.py__getattribute__('__call__').py__get__(self, self.class_value) @@ -425,7 +425,10 @@ class SelfName(TreeNameDefinition): @property def parent_context(self): - return self._instance.create_instance_value(self.class_value, self.tree_name) + return self._instance.create_instance_context( + self.class_value.as_context(), + self.tree_name + ) class LazyInstanceClassName(object): diff --git a/jedi/inference/value/iterable.py b/jedi/inference/value/iterable.py index 8dd9c013..ee9e6269 100644 --- a/jedi/inference/value/iterable.py +++ b/jedi/inference/value/iterable.py @@ -674,8 +674,8 @@ def _check_array_additions(context, sequence): debug.dbg('Dynamic array search aborted.', color='MAGENTA') return NO_VALUES - def find_additions(value, arglist, add_name): - params = list(arguments.TreeArguments(value.inference_state, value, arglist).unpack()) + def find_additions(context, arglist, add_name): + params = list(arguments.TreeArguments(context.inference_state, context, arglist).unpack()) result = set() if add_name in ['insert']: params = params[1:] @@ -717,7 +717,6 @@ def _check_array_additions(context, sequence): or execution_trailer.children[1] == ')': continue - raise NotImplementedError random_context = context.create_context(name) with recursion.execution_allowed(context.inference_state, power) as allowed: @@ -783,8 +782,8 @@ class _ArrayInstance(HelperValueMixin): class Slice(object): - def __init__(self, value, start, stop, step): - self._value = value + def __init__(self, python_value, start, stop, step): + self._python_value = python_value self._slice_object = None # All of them are either a Precedence or None. self._start = start @@ -793,7 +792,7 @@ class Slice(object): def __getattr__(self, name): if self._slice_object is None: - value = compiled.builtin_from_name(self._value.inference_state, 'slice') + value = compiled.builtin_from_name(self._python_value.inference_state, 'slice') self._slice_object, = value.execute_with_values() return getattr(self._slice_object, name) @@ -807,7 +806,7 @@ class Slice(object): if element is None: return None - result = self._value.infer_node(element) + result = self._python_value.infer_node(element) if len(result) != 1: # For simplicity, we want slices to be clear defined with just # one type. Otherwise we will return an empty slice object. diff --git a/jedi/inference/value/klass.py b/jedi/inference/value/klass.py index cbbdd756..bd898d1d 100644 --- a/jedi/inference/value/klass.py +++ b/jedi/inference/value/klass.py @@ -225,7 +225,7 @@ class ClassMixin(object): init_funcs = self.py__call__().py__getattribute__('__init__') return [sig.bind(self) for sig in init_funcs.get_signatures()] - def as_context(self): + def _as_context(self): return ClassContext(self) diff --git a/jedi/inference/value/module.py b/jedi/inference/value/module.py index d965293a..3768523a 100644 --- a/jedi/inference/value/module.py +++ b/jedi/inference/value/module.py @@ -275,7 +275,7 @@ class ModuleValue(ModuleMixin, TreeValue): else: raise AttributeError('Only packages have __path__ attributes.') - def as_context(self): + def _as_context(self): return ModuleContext(self) def __repr__(self):