sys path modifications working not only on imports, but on everything

This commit is contained in:
David Halter
2012-09-14 04:03:32 +02:00
parent 9a2ec13230
commit 444e4fd466
4 changed files with 56 additions and 45 deletions

View File

@@ -181,58 +181,64 @@ class ModuleWithCursor(Module):
def sys_path_with_modifications(module):
def execute_code(code):
c = "import os; from os.path import *; result=%s"
variables = {}
variables = {'__file__': module.path}
try:
exec_function(c % code, variables)
except Exception:
debug.warning('sys path detected, but failed to evaluate')
return None
try:
return os.path.abspath(variables['result'])
except KeyError:
return None
def check_module(module):
try:
possible_stmts = module.used_names['path']
except KeyError:
return builtin.module_find_path
sys_path = list(builtin.module_find_path) # copy
for p in possible_stmts:
try:
call = p.get_assignment_calls().get_only_subelement()
except AttributeError:
continue
n = call.name
if not isinstance(n, parsing.Name) or len(n.names) != 3:
continue
if n.names[:2] != ('sys', 'path'):
continue
array_cmd = n.names[2]
if call.execution is None:
continue
exe = call.execution
if not (array_cmd == 'insert' and len(exe) == 2 \
or array_cmd == 'append' and len(exe) == 1):
continue
if array_cmd == 'insert':
exe_type, exe.type = exe.type, parsing.Array.NOARRAY
exe_pop = exe.values.pop(0)
res = execute_code(exe.get_code())
if res is not None:
sys_path.insert(0, res)
exe.type = exe_type
exe.values.insert(0, exe_pop)
elif array_cmd == 'append':
res = execute_code(exe.get_code())
if res is not None:
sys_path.append(res)
return sys_path
curdir = os.path.abspath(os.curdir)
try:
os.chdir(os.path.dirname(module.path))
except OSError:
pass
sys_path = list(builtin.module_find_path) # copy
try:
possible_stmts = module.used_names['path']
except KeyError:
return []
for p in possible_stmts:
try:
call = p.get_assignment_calls().get_only_subelement()
except AttributeError:
continue
n = call.name
if not isinstance(n, parsing.Name) or len(n.names) != 3:
continue
if n.names[:2] != ('sys', 'path'):
continue
array_cmd = n.names[2]
if call.execution is None:
continue
exe = call.execution
if not (array_cmd == 'insert' and len(exe) == 2 \
or array_cmd == 'append' and len(exe) == 1):
continue
if array_cmd == 'insert':
exe_type, exe.type = exe.type, parsing.Array.NOARRAY
exe_pop = exe.values.pop(0)
res = execute_code(exe.get_code())
if res:
sys_path.insert(0, res)
exe.type = exe_type
exe.values.insert(0, exe_pop)
elif array_cmd == 'append':
res = execute_code(exe.get_code())
if res:
sys_path.append(res)
result = check_module(module)
# cleanup, back to old directory
os.chdir(curdir)
return sys_path
return result