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

@@ -179,17 +179,18 @@ class ImportPath(object):
debug.dbg('search_module', string, self.file_path)
# Override the sys.path. It works only good that way.
# Injecting the path directly into `find_module` did not work.
sys.path, temp = builtin.module_find_path, sys.path
sys.path, temp = sys_path_mod, sys.path
try:
i = imp.find_module(string)
except:
except ImportError:
sys.path = temp
raise
sys.path = temp
return i
sys_path_mod = self.sys_path_with_modifications()
current_namespace = None
builtin.module_find_path.insert(0, self.file_path)
sys_path_mod.insert(0, self.file_path)
# now execute those paths
rest = []
for i, s in enumerate(self.import_path):
@@ -202,7 +203,7 @@ class ImportPath(object):
raise ModuleNotFound(
'The module you searched has not been found')
builtin.module_find_path.pop(0)
sys_path_mod.pop(0)
path = current_namespace[1]
is_package_directory = current_namespace[2][2] == imp.PKG_DIRECTORY

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

View File

@@ -18,5 +18,8 @@ import evaluate
#? ['goto']
evaluate.goto
#? ['pylab_']
import pylab_
#? ['jedi_']
import jedi_
#? ['el']
jedi_.el

View File

@@ -3,9 +3,10 @@ import os
import sys
import re
import traceback
from os.path import abspath, dirname
os.chdir(os.path.dirname(os.path.abspath(__file__)) + '/..')
sys.path.append('.')
sys.path.append(abspath(dirname(abspath(__file__)) + '/..'))
os.chdir(dirname(abspath(__file__)) + '/..')
from _compatibility import unicode, BytesIO, reduce, literal_eval, is_py25