From 06d2119f513157b33c1c6ab66dfa51b6c9889db9 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 4 Sep 2019 00:53:46 +0200 Subject: [PATCH] Make sure a self variable is only defined in a function not outside --- jedi/inference/names.py | 1 - jedi/inference/param.py | 1 + jedi/inference/value/instance.py | 26 ++++++++++++++++++-------- test/completion/classes.py | 5 +++++ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/jedi/inference/names.py b/jedi/inference/names.py index c11d11ab..6b923bf6 100644 --- a/jedi/inference/names.py +++ b/jedi/inference/names.py @@ -331,7 +331,6 @@ class SimpleParamName(X): values = super(SimpleParamName, self).infer() if values: return values - # TODO private access from jedi.inference.dynamic_params import dynamic_param_lookup param = self._get_param_node() values = dynamic_param_lookup(self.function_value, param.position_index) diff --git a/jedi/inference/param.py b/jedi/inference/param.py index fb2bc479..6205fed1 100644 --- a/jedi/inference/param.py +++ b/jedi/inference/param.py @@ -66,6 +66,7 @@ def get_executed_param_names_and_issues(function_value, arguments): ) else: issues.append(None) + debug.warning('non-public warning: %s', m) issues = [] # List[Optional[analysis issue]] result_params = [] diff --git a/jedi/inference/value/instance.py b/jedi/inference/value/instance.py index 35439477..5a658318 100644 --- a/jedi/inference/value/instance.py +++ b/jedi/inference/value/instance.py @@ -1,5 +1,7 @@ from abc import abstractproperty +from parso.python.tree import search_ancestor + from jedi import debug from jedi import settings from jedi.inference import compiled @@ -484,10 +486,7 @@ class SelfName(TreeNameDefinition): @property def parent_context(self): - return self._instance.create_instance_context( - self.class_context, - self.tree_name - ) + return self._instance.create_instance_context(self.class_context, self.tree_name) class LazyInstanceClassName(object): @@ -548,9 +547,9 @@ class SelfAttributeFilter(ClassFilter): self._instance = instance def _filter(self, names): - names = self._filter_self_names(names) start, end = self._parser_scope.start_pos, self._parser_scope.end_pos - return [n for n in names if start < n.start_pos < end] + names = [n for n in names if start < n.start_pos < end] + return self._filter_self_names(names) def _filter_self_names(self, names): for name in names: @@ -559,8 +558,19 @@ class SelfAttributeFilter(ClassFilter): and len(trailer.parent.children) == 2 \ and trailer.children[0] == '.': if name.is_definition() and self._access_possible(name, from_instance=True): - # TODO filter non-self assignments. - yield name + # TODO filter non-self assignments instead of this bad + # filter. + if self._is_in_right_scope(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 _convert_names(self, names): return [SelfName(self._instance, self._node_context, name) for name in names] diff --git a/test/completion/classes.py b/test/completion/classes.py index 6ab4031b..33b749c8 100644 --- a/test/completion/classes.py +++ b/test/completion/classes.py @@ -31,6 +31,7 @@ second = 1 second = "" class TestClass(object): var_class = TestClass(1) + self.pseudo_var = 3 def __init__(self2, first_param, second_param, third=1.0): self2.var_inst = first_param @@ -85,6 +86,10 @@ TestClass.var inst.var_local #? [] TestClass.var_local. +#? +TestClass.pseudo_var +#? +TestClass().pseudo_var #? int() TestClass().ret(1)