-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
launch.py
91 lines (75 loc) · 1.94 KB
/
launch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import textwrap
import os
import subprocess
import sys
import signal
import glob
import itertools
class PathReader:
@staticmethod
def _read_file(filename):
root = os.path.dirname(filename)
return (
os.path.join(root, path.rstrip())
for path in open(filename)
if path.strip()
and not path.startswith('#')
and not path.startswith('import ')
)
@classmethod
def _read(cls, target):
"""
As .pth files aren't honored except in site dirs,
read the paths indicated by them.
"""
pth_files = glob.glob(os.path.join(target, '*.pth'))
file_items = map(cls._read_file, pth_files)
return itertools.chain.from_iterable(file_items)
def _inject_sitecustomize(target):
"""
Create a sitecustomize file in the target that will install
the target as a sitedir.
Only needed on Python 3.2 and earlier to workaround #1.
"""
if sys.version_info > (3, 3):
return
hook = textwrap.dedent("""
import site
site.addsitedir({target!r})
""").lstrip().format(**locals())
sc_fn = os.path.join(target, 'sitecustomize.py')
with open(sc_fn, 'w') as strm:
strm.write(hook)
def _build_env(target):
"""
Prepend target and .pth references in target to PYTHONPATH
"""
env = dict(os.environ)
suffix = env.get('PYTHONPATH')
prefix = target,
items = itertools.chain(
prefix,
PathReader._read(target),
(suffix,) if suffix else (),
)
joined = os.pathsep.join(items)
env['PYTHONPATH'] = joined
return env
def _setup_env(target):
_inject_sitecustomize(target)
return _build_env(target)
def with_path(target, params):
"""
Launch Python with target on the path and params
"""
def null_handler(signum, frame):
pass
signal.signal(signal.SIGINT, null_handler)
cmd = [sys.executable] + params
return subprocess.Popen(cmd, env=_setup_env(target)).wait()
def with_path_overlay(target, params):
"""
Overlay Python with target on the path and params
"""
cmd = [sys.executable] + params
os.execve(sys.executable, cmd, _setup_env(target))