From e371b670f5124790c4f7cd49a3e8878c49e15d34 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Thu, 22 Sep 2016 18:26:09 +0200 Subject: [PATCH] Remove a comprehension hack in the parser that would have made the diff parsers world hell. --- jedi/evaluate/finder.py | 10 +++++++++- jedi/parser/__init__.py | 5 ----- jedi/parser/fast.py | 6 +++++- jedi/settings.py | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index b9d9609d..d7f8be09 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -58,6 +58,13 @@ def filter_after_position(names, position, origin=None): return names_new +def is_comprehension_name(name, origin): + definition = name.get_definition() + # TODO This is really hacky. It just compares the two definitions. This + # fails tests and is in general just a temporary way. + return definition.type == 'comp_for' and origin.get_definition().type != definition.type + + def filter_definition_names(names, origin, position=None): """ Filter names that are actual definitions in a scope. Names that are just @@ -73,7 +80,8 @@ def filter_definition_names(names, origin, position=None): if not (isinstance(scope, er.FunctionExecution) and isinstance(scope.base, er.LambdaWrapper)): names = filter_after_position(names, position, origin) - names = [name for name in names if name.is_definition()] + names = [name for name in names + if name.is_definition() and not is_comprehension_name(name, origin)] # Private name mangling (compile.c) disallows access on names # preceeded by two underscores `__` if used outside of the class. Names diff --git a/jedi/parser/__init__.py b/jedi/parser/__init__.py index 5d724e9e..6b60dffd 100644 --- a/jedi/parser/__init__.py +++ b/jedi/parser/__init__.py @@ -193,11 +193,6 @@ class Parser(object): arr = self._scope_names_stack[-1].setdefault(n.value, []) arr.append(n) new_node.names_dict = scope_names - elif isinstance(new_node, pt.CompFor): - # The name definitions of comprehenions shouldn't be part of the - # current scope. They are part of the comprehension scope. - for n in new_node.get_defined_names(): - self._scope_names_stack[-1][n.value].remove(n) return new_node def convert_leaf(self, grammar, type, value, prefix, start_pos): diff --git a/jedi/parser/fast.py b/jedi/parser/fast.py index 569d5735..c6a72abe 100644 --- a/jedi/parser/fast.py +++ b/jedi/parser/fast.py @@ -173,6 +173,7 @@ class DiffParser(object): self._old_module = self._new_module assert self._new_module.end_pos[0] == line_length + return self._new_module def _copy_from_old_parser(self, line_offset, until_line_old, until_line_new): @@ -225,6 +226,9 @@ class DiffParser(object): self._update_positions(nodes, line_offset) parent = self._insert_nodes(nodes) self._update_names_dict(parent, nodes) + self._copied_ranges.append( + (nodes[0].start_pos[0], _get_last_line(nodes[-1])) + ) # We have copied as much as possible (but definitely not too # much). Therefore we just parse the rest. # We might not reach the end, because there's a statement @@ -469,7 +473,7 @@ class DiffParser(object): for key, names in self._old_module.used_names.items(): for name in names: if name.start_pos[0] in copied_line_numbers: - new_used_names.setdefault(key, []).add(name) + new_used_names.setdefault(key, []).append(name) # Add an endmarker. last_leaf = self._new_module.last_leaf() diff --git a/jedi/settings.py b/jedi/settings.py index 13dcfd45..b5e15759 100644 --- a/jedi/settings.py +++ b/jedi/settings.py @@ -130,7 +130,7 @@ On Linux, if environment variable ``$XDG_CACHE_HOME`` is set, # parser # ---------------- -fast_parser = True +fast_parser = False """ Use the fast parser. This means that reparsing is only being done if something has been changed e.g. to a function. If this happens, only the