From 1f15ee8bc7e34d745dbbd73611f003e5d189af32 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Fri, 6 Jan 2017 00:08:01 +0100 Subject: [PATCH] Fix an issue with contexts. --- jedi/evaluate/filters.py | 21 +++++++++++++++------ jedi/evaluate/instance.py | 2 +- jedi/evaluate/iterable.py | 2 +- jedi/evaluate/representation.py | 26 +++++++++++++++++--------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/jedi/evaluate/filters.py b/jedi/evaluate/filters.py index ef390915..33b8c567 100644 --- a/jedi/evaluate/filters.py +++ b/jedi/evaluate/filters.py @@ -165,9 +165,18 @@ class AbstractUsedNamesFilter(AbstractFilter): class ParserTreeFilter(AbstractUsedNamesFilter): - def __init__(self, evaluator, context, parser_scope, until_position=None, - origin_scope=None, ): - super(ParserTreeFilter, self).__init__(context, parser_scope) + def __init__(self, evaluator, context, node_context=None, until_position=None, + origin_scope=None): + """ + node_context is an option to specify a second context for use cases + like the class mro where the parent class of a new name would be the + context, but for some type inference it's important to have a local + context of the other classes. + """ + if node_context is None: + node_context = context + super(ParserTreeFilter, self).__init__(context, node_context.tree_node) + self._node_context = node_context self._origin_scope = origin_scope self._until_position = until_position @@ -188,7 +197,7 @@ class ParserTreeFilter(AbstractUsedNamesFilter): def _check_flows(self, names): for name in sorted(names, key=lambda name: name.start_pos, reverse=True): check = flow_analysis.reachability_check( - self.context, self._parser_scope, name, self._origin_scope + self._node_context, self._parser_scope, name, self._origin_scope ) if check is not flow_analysis.UNREACHABLE: yield name @@ -200,12 +209,12 @@ class ParserTreeFilter(AbstractUsedNamesFilter): class FunctionExecutionFilter(ParserTreeFilter): param_name = ParamName - def __init__(self, evaluator, context, parser_scope, + def __init__(self, evaluator, context, node_context=None, until_position=None, origin_scope=None): super(FunctionExecutionFilter, self).__init__( evaluator, context, - parser_scope, + node_context, until_position, origin_scope ) diff --git a/jedi/evaluate/instance.py b/jedi/evaluate/instance.py index e8fa5b90..5a41d86f 100644 --- a/jedi/evaluate/instance.py +++ b/jedi/evaluate/instance.py @@ -322,7 +322,7 @@ class InstanceClassFilter(filters.ParserTreeFilter): super(InstanceClassFilter, self).__init__( evaluator=evaluator, context=context, - parser_scope=class_context.tree_node, + node_context=class_context, origin_scope=origin_scope ) self._class_context = class_context diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 40127f83..2552a6a1 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -190,7 +190,7 @@ class CompForContext(context.TreeContext): return self.tree_node def get_filters(self, search_global, until_position=None, origin_scope=None): - yield ParserTreeFilter(self.evaluator, self, self.tree_node) + yield ParserTreeFilter(self.evaluator, self) class Comprehension(AbstractSequence): diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index f438e22a..7f5aa187 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -166,16 +166,20 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext)): def get_filters(self, search_global, until_position=None, origin_scope=None, is_instance=False): if search_global: - yield ParserTreeFilter(self.evaluator, self, self.tree_node, until_position, origin_scope=origin_scope) + yield ParserTreeFilter( + self.evaluator, + context=self, + until_position=until_position, + origin_scope=origin_scope + ) else: for scope in self.py__mro__(): - print(scope) if isinstance(scope, compiled.CompiledObject): for filter in scope.get_filters(is_instance=is_instance): yield filter else: yield ClassFilter( - self.evaluator, self, scope.tree_node, + self.evaluator, self, node_context=scope, origin_scope=origin_scope) def is_class(self): @@ -225,7 +229,12 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext)): def get_filters(self, search_global, until_position=None, origin_scope=None): if search_global: - yield ParserTreeFilter(self.evaluator, self, self.tree_node, until_position, origin_scope=origin_scope) + yield ParserTreeFilter( + self.evaluator, + context=self, + until_position=until_position, + origin_scope=origin_scope + ) else: scope = self.py__class__() for filter in scope.get_filters(search_global=False, origin_scope=origin_scope): @@ -372,8 +381,8 @@ class FunctionExecutionContext(Executed): yield result def get_filters(self, search_global, until_position=None, origin_scope=None): - yield self.function_execution_filter(self.evaluator, self, self.tree_node, - until_position, + yield self.function_execution_filter(self.evaluator, self, + until_position=until_position, origin_scope=origin_scope) @memoize_default(default=NO_DEFAULT) @@ -419,9 +428,8 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext)): def get_filters(self, search_global, until_position=None, origin_scope=None): yield ParserTreeFilter( self.evaluator, - self, - self.tree_node, - until_position, + context=self, + until_position=until_position, origin_scope=origin_scope ) yield GlobalNameFilter(self, self.tree_node)