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:
@@ -45,7 +45,7 @@ def _execute_code(module_path, code):
|
|||||||
return []
|
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::
|
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
|
because it will only affect Jedi in very random situations and by adding
|
||||||
more paths than necessary, it usually benefits the general user.
|
more paths than necessary, it usually benefits the general user.
|
||||||
"""
|
"""
|
||||||
for exp_list, operator in statement.assignment_details:
|
for assignee, operator in zip(expr_stmt.children[::2], expr_stmt.children[1::2]):
|
||||||
if len(exp_list) != 1 or not isinstance(exp_list[0], pr.Call):
|
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
|
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.iterable import get_iterator_types
|
||||||
from jedi.evaluate.precedence import is_string
|
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):
|
if is_string(val):
|
||||||
yield val.obj
|
yield val.obj
|
||||||
|
|
||||||
@@ -93,14 +106,15 @@ def _paths_from_list_modifications(module_path, trailer1, trailer2):
|
|||||||
|
|
||||||
def _check_module(evaluator, module):
|
def _check_module(evaluator, module):
|
||||||
def get_sys_path_powers(names):
|
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'):
|
if pr.is_node(power, 'power'):
|
||||||
c = power.children
|
c = power.children
|
||||||
if isinstance(c[0], pr.Name) and c[0].value == 'sys' \
|
if isinstance(c[0], pr.Name) and c[0].value == 'sys' \
|
||||||
and pr.is_node(c[1], 'trailer'):
|
and pr.is_node(c[1], 'trailer'):
|
||||||
n = c[1].children[1]
|
n = c[1].children[1]
|
||||||
if isinstance(n, pr.Name) and n.value == 'path':
|
if isinstance(n, pr.Name) and n.value == 'path':
|
||||||
yield power
|
yield name, power
|
||||||
|
|
||||||
sys_path = list(get_sys_path()) # copy
|
sys_path = list(get_sys_path()) # copy
|
||||||
try:
|
try:
|
||||||
@@ -108,11 +122,11 @@ def _check_module(evaluator, module):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
else:
|
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:
|
if len(power.children) >= 4:
|
||||||
sys_path.extend(_paths_from_list_modifications(module.path, *power.children[2:4]))
|
sys_path.extend(_paths_from_list_modifications(module.path, *power.children[2:4]))
|
||||||
elif hasattr(power, 'assignment_details') \
|
elif name.get_definition().type == 'expr_stmt':
|
||||||
and len(stmt.assignment_details) == 1:
|
|
||||||
sys_path.extend(_paths_from_assignment(evaluator, stmt))
|
sys_path.extend(_paths_from_assignment(evaluator, stmt))
|
||||||
return sys_path
|
return sys_path
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user