diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 7750c244..618bf1ba 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -392,9 +392,13 @@ class Interpreter(Script): super(Interpreter, self).__init__(source, **kwds) self.namespaces = namespaces - def _get_module_node(self): + def _get_module(self): parser_module = super(Interpreter, self)._get_module_node() - return interpreter.MixedModule(self._evaluator, parser_module, self.namespaces) + return interpreter.MixedModuleContext( + self._evaluator, + parser_module, + self.namespaces + ) def defined_names(source, path=None, encoding='utf-8'): diff --git a/jedi/api/interpreter.py b/jedi/api/interpreter.py index 8e1063fe..c73913b0 100644 --- a/jedi/api/interpreter.py +++ b/jedi/api/interpreter.py @@ -7,61 +7,41 @@ from jedi.cache import underscore_memoization from jedi.evaluate import helpers from jedi.evaluate.representation import ModuleContext from jedi.evaluate.compiled import mixed +from jedi.evaluate.context import Context -class MixedModule(object): +class MixedModuleContext(Context): resets_positions = True type = 'mixed_module' - def __init__(self, evaluator, parser_module, namespaces): - self._evaluator = evaluator + def __init__(self, evaluator, tree_module, namespaces): + self.evaluator = evaluator self._namespaces = namespaces self._namespace_objects = [type('jedi_namespace', (), n) for n in namespaces] - self._wrapped_module = ModuleContext(evaluator, parser_module) - # Usually we are dealing with very small code sizes when it comes to - # interpreter modules. In this case we just copy the whole syntax tree - # to be able to modify it. - self._parser_module = copy.deepcopy(parser_module) + self._module_context = ModuleContext(evaluator, tree_module) + self.tree_node = tree_module - for child in self._parser_module.children: - child.parent = self + def get_node(self): + return self.tree_node def names_dicts(self, search_global): - for names_dict in self._wrapped_module.names_dicts(search_global): + for names_dict in self._module_context.names_dicts(search_global): yield names_dict for namespace_obj in self._namespace_objects: - m = mixed.MixedObject(self._evaluator, namespace_obj, self._parser_module.name) + m = mixed.MixedObject(self.evaluator, namespace_obj, self.tree_node.name) for names_dict in m.names_dicts(False): yield names_dict + def get_filters(self, *args, **kwargs): + for filter in self._module_context.get_filters(*args, **kwargs): + yield filter + + for namespace_obj in self._namespace_objects: + m = mixed.MixedObject(self.evaluator, namespace_obj, self.tree_node.name) + for filter in m.get_filters(*args, **kwargs): + yield filter + def __getattr__(self, name): - return getattr(self._parser_module, name) - - -class LazyName(helpers.FakeName): - def __init__(self, evaluator, module, name, value): - super(LazyName, self).__init__(name) - self._module = module - self._evaluator = evaluator - self._value = value - self._name = name - - def is_definition(self): - return True - - @property - @underscore_memoization - def parent(self): - """ - Creating fake statements for the interpreter. - - Here we are trying to link back to Python code, if possible. This means - we try to find the python module for a name (not the builtin). - """ - return mixed.create(self._evaluator, self._value) - - @parent.setter - def parent(self, value): - """Needed because the super class tries to set parent.""" + return getattr(self._module_context, name)