diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index 32a596ec..3b5ca4f7 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -106,7 +106,8 @@ class NameFinder(object): else: check = flow_analysis.break_check(self._evaluator, name_list_scope, - er.wrap(self._evaluator, scope)) + er.wrap(self._evaluator, scope), + self.scope) if check is not flow_analysis.UNREACHABLE: result.append(name) if check is flow_analysis.REACHABLE: diff --git a/jedi/evaluate/flow_analysis.py b/jedi/evaluate/flow_analysis.py index e4d93fc0..0183a069 100644 --- a/jedi/evaluate/flow_analysis.py +++ b/jedi/evaluate/flow_analysis.py @@ -32,11 +32,21 @@ UNREACHABLE = Status(False, 'unreachable') UNSURE = Status(None, 'unsure') -def break_check(evaluator, base_scope, element_scope): +def break_check(evaluator, base_scope, element_scope, origin_scope=None): from jedi.evaluate.representation import wrap base_scope = wrap(evaluator, base_scope) element_scope = wrap(evaluator, element_scope) + # Direct parents get resolved, we filter scopes that are separate branches. + # This makes sense for autocompletion and static analysis. For actual + # Python it doesn't matter, because we're talking about potentially + # unreachable code. + s = origin_scope + while s is not None: + if element_scope == s: + return REACHABLE + s = s.parent + reachable = REACHABLE if isinstance(element_scope, Flow): if element_scope.command == 'else': diff --git a/test/completion/flow_analysis.py b/test/completion/flow_analysis.py index 42afa6dc..4674555c 100644 --- a/test/completion/flow_analysis.py +++ b/test/completion/flow_analysis.py @@ -182,3 +182,26 @@ isinst(1.0) isinst(False) #? int() isinst('') + +# ----------------- +# flows that are not reachable should be able to access parent scopes. +# ----------------- + +foobar = '' + +if 0: + within_flow = 1.0 + #? float() + within_flow + #? str() + foobar + if 0: + nested = 1 + #? int() + nested + #? float() + within_flow + #? str() + foobar + #? + nested diff --git a/test/test_api/test_call_signatures.py b/test/test_api/test_call_signatures.py index 862b57a8..edf12dbc 100644 --- a/test/test_api/test_call_signatures.py +++ b/test/test_api/test_call_signatures.py @@ -207,7 +207,7 @@ def test_signature_is_definition(): # Now compare all the attributes that a CallSignature must also have. for attr_name in dir(definition): dont_scan = ['defined_names', 'line_nr', 'start_pos', 'documentation', - 'doc', 'parent'] + 'doc', 'parent', 'goto_assignments'] if attr_name.startswith('_') or attr_name in dont_scan: continue attribute = getattr(definition, attr_name)