From 197c2f642bd0177ffc0c62758b0229e0cca0ebce Mon Sep 17 00:00:00 2001 From: David Halter Date: Mon, 22 Oct 2012 17:22:44 +0200 Subject: [PATCH] fixed some evil bugs in the import mechanism and even worse: In helpers.fast_parent_copy. --- jedi/builtin.py | 2 +- jedi/evaluate.py | 2 +- jedi/helpers.py | 17 ++++++++++++----- jedi/imports.py | 6 +++--- jedi/modules.py | 2 +- jedi/parsing.py | 3 +-- test/regression.py | 13 +++++++------ 7 files changed, 26 insertions(+), 19 deletions(-) diff --git a/jedi/builtin.py b/jedi/builtin.py index b5d9b31b..7f00dd3c 100644 --- a/jedi/builtin.py +++ b/jedi/builtin.py @@ -90,7 +90,7 @@ class Parser(CachedModule): name = name.rpartition('.')[0] # cut file type (normally .so) super(Parser, self).__init__(path=path, name=name) - self.sys_path = sys_path + self.sys_path = list(sys_path) self._module = None @property diff --git a/jedi/evaluate.py b/jedi/evaluate.py index 9f6b8c48..9f1cfebf 100644 --- a/jedi/evaluate.py +++ b/jedi/evaluate.py @@ -589,7 +589,7 @@ class Execution(Executable): for param in self.base.params[start_offset:]: # The value and key can both be null. There, the defaults apply. # args / kwargs will just be empty arrays / dicts, respectively. - # Wrong value count is just ignored. If you try to test cases which + # Wrong value count is just ignored. If you try to test cases that # are not allowed in Python, Jedi will maybe not show any # completions. key, value = next(var_arg_iterator, (None, None)) diff --git a/jedi/helpers.py b/jedi/helpers.py index b93bf60f..4d096049 100644 --- a/jedi/helpers.py +++ b/jedi/helpers.py @@ -58,7 +58,7 @@ class RecursionDecorator(object): result = [] n = self.current while n: - result.append(n.stmt) + result.insert(0, n.stmt) n = n.parent return result @@ -157,19 +157,26 @@ def fast_parent_copy(obj): continue if isinstance(value, list): new_obj.__dict__[key] = list_rec(value) - elif isinstance(value, parsing.Simple): + elif isinstance(value, (parsing.Simple, parsing.Call)): new_obj.__dict__[key] = recursion(value) - if obj.parent is not None: + # replace parent (first try _parent and then parent) + if hasattr(obj, '_parent') and obj._parent is not None: + try: + new_obj._parent = weakref.ref(new_elements[obj._parent()]) + except KeyError: + pass + elif obj.parent is not None: try: new_obj.parent = weakref.ref(new_elements[obj.parent()]) except KeyError: pass - if hasattr(obj, 'parent_stmt') and obj.parent_stmt is not None: + # replace parent_stmt + if hasattr(obj, '_parent_stmt') and obj._parent_stmt is not None: p = obj.parent_stmt() try: - new_obj.parent_stmt = weakref.ref(new_elements[p]) + new_obj._parent_stmt = weakref.ref(new_elements[p]) except KeyError: pass diff --git a/jedi/imports.py b/jedi/imports.py index deb21ac9..2b36c1a6 100644 --- a/jedi/imports.py +++ b/jedi/imports.py @@ -200,10 +200,10 @@ class ImportPath(object): return i if self.file_path: - sys_path_mod = self.sys_path_with_modifications() + sys_path_mod = list(self.sys_path_with_modifications()) sys_path_mod.insert(0, self.file_path) else: - sys_path_mod = builtin.module_find_path + sys_path_mod = list(builtin.module_find_path) current_namespace = None # now execute those paths @@ -218,7 +218,7 @@ class ImportPath(object): raise ModuleNotFound( 'The module you searched has not been found') - sys_path_mod.pop(0) + sys_path_mod.pop(0) # TODO why is this here? path = current_namespace[1] is_package_directory = current_namespace[2][2] == imp.PKG_DIRECTORY diff --git a/jedi/modules.py b/jedi/modules.py index 15b51039..c0918bb9 100644 --- a/jedi/modules.py +++ b/jedi/modules.py @@ -234,7 +234,7 @@ def sys_path_with_modifications(module): try: possible_stmts = module.used_names['path'] except KeyError: - return list(builtin.module_find_path) + return builtin.module_find_path sys_path = list(builtin.module_find_path) # copy for p in possible_stmts: diff --git a/jedi/parsing.py b/jedi/parsing.py index 6fa1ff12..162754b4 100644 --- a/jedi/parsing.py +++ b/jedi/parsing.py @@ -687,8 +687,7 @@ class Statement(Simple): if self._assignment_calls_calculated: return self._assignment_calls self._assignment_details = [] - result = Array(self.start_pos, Array.NOARRAY, self) - top = result + top = result = Array(self.start_pos, Array.NOARRAY, self) level = 0 is_chain = False close_brackets = False diff --git a/test/regression.py b/test/regression.py index bc4cb391..77c6a5a1 100755 --- a/test/regression.py +++ b/test/regression.py @@ -13,8 +13,7 @@ import api #api.set_debug_function(api.debug.print_to_stdout) - -class TestRegression(unittest.TestCase): +class Base(unittest.TestCase): def get_def(self, src, pos): script = api.Script(src, pos[0], pos[1], None) return script.get_definition() @@ -31,6 +30,7 @@ class TestRegression(unittest.TestCase): script = api.Script(src, pos[0], pos[1], '') return script.get_in_function_call() +class TestRegression(Base): def test_part_parser(self): """ test the get_in_function_call speedups """ s = '\n' * 100 + 'abs(' @@ -192,12 +192,13 @@ class TestRegression(unittest.TestCase): assert len(api.Script(s, 1, 15, '/').get_definition()) == 1 assert len(api.Script(s, 1, 10, '/').get_definition()) == 1 -class TestSpeed(unittest.TestCase): +class TestSpeed(Base): def test_os_path_join(self): """ named import - jedi-vim issue #8 """ - s = "join" - assert len(api.Script(s, 1, 15, '/').get_definition()) == 1 - assert len(api.Script(s, 1, 10, '/').get_definition()) == 1 + s = "from posixpath import join; join('', '')." + #api.set_debug_function(api.debug.print_to_stdout) + assert len(self.complete(s)) > 10 # is a str completion + #api.set_debug_function(None) if __name__ == '__main__':