From cc136a28797e0bc92c7b6f016f5d9c7be4ec64e8 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Fri, 27 Dec 2019 18:58:50 +0100 Subject: [PATCH] Self manipulations are now more correct, fixes #1392 --- jedi/inference/value/instance.py | 19 +++++++------ test/completion/inheritance.py | 49 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/jedi/inference/value/instance.py b/jedi/inference/value/instance.py index a6b6931a..aa6b7290 100644 --- a/jedi/inference/value/instance.py +++ b/jedi/inference/value/instance.py @@ -560,17 +560,18 @@ class SelfAttributeFilter(ClassFilter): if name.is_definition() and self._access_possible(name, from_instance=True): # TODO filter non-self assignments instead of this bad # filter. - if self._is_in_right_scope(name): + if self._is_in_right_scope(trailer.parent.children[0], name): yield name - def _is_in_right_scope(self, name): - base = name - hit_funcdef = False - while True: - base = search_ancestor(base, 'funcdef', 'classdef', 'lambdef') - if base is self._parser_scope: - return hit_funcdef - hit_funcdef = True + def _is_in_right_scope(self, self_name, name): + self_context = self._node_context.create_context(self_name) + names = self_context.goto(self_name, position=self_name.start_pos) + return any( + n.api_type == 'param' + and n.tree_name.get_definition().position_index == 0 + and n.parent_context.tree_node is self._parser_scope + for n in names + ) def _convert_names(self, names): return [SelfName(self._instance, self._node_context, name) for name in names] diff --git a/test/completion/inheritance.py b/test/completion/inheritance.py index 73e3ed92..f7619a04 100644 --- a/test/completion/inheritance.py +++ b/test/completion/inheritance.py @@ -25,3 +25,52 @@ class Sub(Super): #! 8 ['class Inner'] def Inner(self): pass + +# ----------------- +# Finding self +# ----------------- + +class Test1: + class Test2: + def __init__(self): + self.foo_nested = 0 + #? ['foo_nested'] + self.foo_ + #? + self.foo_here + + def __init__(self, self2): + self.foo_here = 3 + #? ['foo_here', 'foo_in_func'] + self.foo_ + #? int() + self.foo_here + #? + self.foo_nested + #? + self.foo_not_on_self + #? float() + self.foo_in_func + self2.foo_on_second = '' + + def closure(): + self.foo_in_func = 4. + + def bar(self): + self = 3 + self.foo_not_on_self = 3 + + +class SubTest(Test1): + def __init__(self): + self.foo_sub_class = list + + def bar(self): + #? ['foo_here', 'foo_in_func', 'foo_sub_class'] + self.foo_ + #? int() + self.foo_here + #? + self.foo_nested + #? + self.foo_not_on_self