Allow better control over sys.path in subprocesses

Either add path to pyqtgraph, or copy entire path (anything else still requires manual effort)
This commit is contained in:
Luke Campagnola 2017-09-13 09:13:03 -07:00
parent 16781636bf
commit 5fb5858802
2 changed files with 25 additions and 8 deletions

View File

@ -13,16 +13,25 @@ if __name__ == '__main__':
#print "key:", ' '.join([str(ord(x)) for x in authkey])
path = opts.pop('path', None)
if path is not None:
## rewrite sys.path without assigning a new object--no idea who already has a reference to the existing list.
while len(sys.path) > 0:
sys.path.pop()
sys.path.extend(path)
if isinstance(path, str):
# if string, just insert this into the path
sys.path.insert(0, path)
else:
# if list, then replace the entire sys.path
## modify sys.path in place--no idea who already has a reference to the existing list.
while len(sys.path) > 0:
sys.path.pop()
sys.path.extend(path)
if opts.pop('pyside', False):
import PySide
targetStr = opts.pop('targetStr')
target = pickle.loads(targetStr) ## unpickling the target should import everything we need
try:
target = pickle.loads(targetStr) ## unpickling the target should import everything we need
except:
print("Current sys.path:", sys.path)
raise
target(**opts) ## Send all other options to the target function
sys.exit(0)

View File

@ -1,4 +1,4 @@
import subprocess, atexit, os, sys, time, random, socket, signal
import subprocess, atexit, os, sys, time, random, socket, signal, inspect
import multiprocessing.connection
try:
import cPickle as pickle
@ -50,7 +50,9 @@ class Process(RemoteEventHandler):
process to process requests from the parent process until it
is asked to quit. If you wish to specify a different target,
it must be picklable (bound methods are not).
copySysPath If True, copy the contents of sys.path to the remote process
copySysPath If True, copy the contents of sys.path to the remote process.
If False, then only the path required to import pyqtgraph is
added.
debug If True, print detailed information about communication
with the child process.
wrapStdout If True (default on windows) then stdout and stderr from the
@ -82,7 +84,13 @@ class Process(RemoteEventHandler):
port = l.address[1]
## start remote process, instruct it to run target function
sysPath = sys.path if copySysPath else None
if copySysPath:
sysPath = sys.path
else:
# what path do we need to make target importable?
mod = inspect.getmodule(target)
modroot = sys.modules[mod.__name__.split('.')[0]]
sysPath = os.path.abspath(os.path.join(os.path.dirname(modroot.__file__), '..'))
bootstrap = os.path.abspath(os.path.join(os.path.dirname(__file__), 'bootstrap.py'))
self.debugMsg('Starting child process (%s %s)' % (executable, bootstrap))