1
0
forked from VimPlug/jedi

Fix issues with sys.path modifications that directly assign the sys.path or use the slicing notation.

This commit is contained in:
Dave Halter
2014-12-10 19:18:53 +01:00
parent 5af665abd8
commit 897c4cded6

View File

@@ -45,7 +45,7 @@ def _execute_code(module_path, code):
return []
def _paths_from_assignment(evaluator, statement):
def _paths_from_assignment(evaluator, expr_stmt):
"""
Extracts the assigned strings from an assignment that looks as follows::
@@ -56,18 +56,31 @@ def _paths_from_assignment(evaluator, statement):
because it will only affect Jedi in very random situations and by adding
more paths than necessary, it usually benefits the general user.
"""
for exp_list, operator in statement.assignment_details:
if len(exp_list) != 1 or not isinstance(exp_list[0], pr.Call):
for assignee, operator in zip(expr_stmt.children[::2], expr_stmt.children[1::2]):
try:
assert operator in ['=', '+=']
assert pr.is_node(assignee, 'power') and len(assignee.children) > 1
c = assignee.children
assert c[0].type == 'name' and c[0].value == 'sys'
trailer = c[1]
assert trailer.children[0] == '.' and trailer.children[1].value == 'path'
# TODO Essentially we're not checking details on sys.path
# manipulation. Both assigment of the sys.path and changing/adding
# parts of the sys.path are the same: They get added to the current
# sys.path.
"""
execution = c[2]
assert execution.children[0] == '['
subscript = execution.children[1]
assert subscript.type == 'subscript'
assert ':' in subscript.children
"""
except AssertionError:
continue
if exp_list[0].names() != ['sys', 'path']:
continue
# TODO at this point we ignore all ways what could be assigned to
# sys.path or an execution of it. Here we could do way more
# complicated checks.
from jedi.evaluate.iterable import get_iterator_types
from jedi.evaluate.precedence import is_string
for val in get_iterator_types(evaluator.eval_statement(statement)):
for val in get_iterator_types(evaluator.eval_statement(expr_stmt)):
if is_string(val):
yield val.obj
@@ -93,14 +106,15 @@ def _paths_from_list_modifications(module_path, trailer1, trailer2):
def _check_module(evaluator, module):
def get_sys_path_powers(names):
for power in [p.parent.parent for p in names]:
for name in names:
power = name.parent.parent
if pr.is_node(power, 'power'):
c = power.children
if isinstance(c[0], pr.Name) and c[0].value == 'sys' \
and pr.is_node(c[1], 'trailer'):
n = c[1].children[1]
if isinstance(n, pr.Name) and n.value == 'path':
yield power
yield name, power
sys_path = list(get_sys_path()) # copy
try:
@@ -108,11 +122,11 @@ def _check_module(evaluator, module):
except KeyError:
pass
else:
for power in get_sys_path_powers(possible_names):
for name, power in get_sys_path_powers(possible_names):
stmt = name.get_definition()
if len(power.children) >= 4:
sys_path.extend(_paths_from_list_modifications(module.path, *power.children[2:4]))
elif hasattr(power, 'assignment_details') \
and len(stmt.assignment_details) == 1:
elif name.get_definition().type == 'expr_stmt':
sys_path.extend(_paths_from_assignment(evaluator, stmt))
return sys_path