diff --git a/jedi/api/interpreter.py b/jedi/api/interpreter.py index 2511b144..90375676 100644 --- a/jedi/api/interpreter.py +++ b/jedi/api/interpreter.py @@ -4,6 +4,7 @@ TODO Some parts of this module are still not well documented. import inspect import re import sys +import copy from jedi._compatibility import builtins from jedi import debug @@ -31,7 +32,7 @@ class MixedModule(object): # 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 = helpers.deep_ast_copy(parser_module) + self._parser_module = copy.deepcopy(parser_module) for child in self._parser_module.children: child.parent = self diff --git a/jedi/api/keywords.py b/jedi/api/keywords.py index 5af80d12..365cb20c 100644 --- a/jedi/api/keywords.py +++ b/jedi/api/keywords.py @@ -67,6 +67,8 @@ keywords_only_valid_as_leaf = ( class Keyword(object): + type = 'completion_keyword' + def __init__(self, evaluator, name, pos): self.name = FakeName(name, self, pos) self.start_pos = pos diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index b9787f4c..0e6b2986 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -109,15 +109,18 @@ class Evaluator(object): self.execution_recursion_detector = recursion.ExecutionRecursionDetector(self) def wrap(self, element): - if isinstance(element, tree.Class): + if isinstance(element, (er.Wrapper, er.InstanceElement, + er.ModuleWrapper, er.FunctionExecution, er.Instance, compiled.CompiledObject)) or element is None: + # TODO this is so ugly, please refactor. + return element + + if element.type == 'classdef': return er.Class(self, element) - elif isinstance(element, tree.Function): - if isinstance(element, tree.Lambda): - return er.LambdaWrapper(self, element) - else: - return er.Function(self, element) - elif isinstance(element, (tree.Module)) \ - and not isinstance(element, er.ModuleWrapper): + elif element.type == 'funcdef': + return er.Function(self, element) + elif element.type == 'lambda': + return er.LambdaWrapper(self, element) + elif element.type == 'file_input': return er.ModuleWrapper(self, element) else: return element diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index 0ded2dfa..554e9871 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -560,6 +560,10 @@ def global_names_dict_generator(evaluator, scope, position): for names_dict in scope.names_dicts(True): yield names_dict, position if hasattr(scope, 'resets_positions'): + # TODO This is so ugly, seriously. However there's + # currently no good way of influencing + # global_names_dict_generator when it comes to certain + # objects. position = None if scope.type == 'funcdef': # The position should be reset if the current scope is a function. diff --git a/test/test_api/test_interpreter.py b/test/test_api/test_interpreter.py index ae98e81c..7b744d22 100644 --- a/test/test_api/test_interpreter.py +++ b/test/test_api/test_interpreter.py @@ -34,7 +34,6 @@ def test_builtin_details(): var = get_completion('variable', locals()) f = get_completion('func', locals()) m = get_completion('keyword', locals()) - print(cls._definition.type) assert cls.type == 'class' assert var.type == 'instance' assert f.type == 'function'