Skip to content

Commit 3a82a78

Browse files
committed
add --sys-paths to include new paths of sys.path
1 parent 76e4550 commit 3a82a78

File tree

6 files changed

+54
-13
lines changed

6 files changed

+54
-13
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,11 @@ Details:
373373

374374
# Changelogs
375375

376+
- 2021.04.11
377+
- add `--sys-paths` to include new paths of sys.path
378+
- support TEMP/HOME/SELF prefix, separated by commas
379+
- sometimes be used for separating pyz code from requirements
380+
- requirements often be installed by `pip install xxx -t $SOME_PATH`
376381
- 2021.04.01
377382
- use `ensurepip` instead of install `pip` while running with `lazy-install`
378383
- `unzip_path` has been set to `SELF/zipapps_cache` by default when `lazy_install` is `True`

test_utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,21 @@ def test_create_app_function():
440440
assert stdout_output.count(b'zipapps_cache') == 2, stdout_output.count(
441441
b'zipapps_cache')
442442

443+
# test sys_path
444+
_clean_paths()
445+
# pip install by given --target
446+
args = [
447+
sys.executable, '-m', 'pip', 'install', 'bottle', '-t', './bottle_env'
448+
]
449+
subprocess.Popen(args=args).wait()
450+
mock_requirement = Path('_requirements.txt')
451+
mock_requirement.write_text('bottle')
452+
old_file = create_app(sys_paths='SELF/bottle_env')
453+
output = subprocess.check_output([
454+
sys.executable, 'app.pyz', '-c', "import bottle;print(bottle.__file__)"
455+
]).decode()
456+
assert 'bottle_env' in output
457+
443458

444459
def main():
445460
"""

zipapps/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
from .main import create_app
33
from .activate_zipapps import activate
44
__all__ = ['create_app', 'activate']
5-
__version__ = '2021.04.01'
5+
__version__ = '2021.04.11'

zipapps/__main__.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def main():
156156
default='',
157157
dest='env_paths',
158158
help='Default --zipapps arg if it is not given while running.'
159-
' Support TEMP/HOME/SELF prefix.')
159+
' Support TEMP/HOME/SELF prefix, separated by commas.')
160160
parser.add_argument(
161161
'--delay',
162162
'-d',
@@ -167,6 +167,14 @@ def main():
167167
dest='lazy_install',
168168
help='Install packages with pip while running, which means '
169169
'requirements will not be install into pyz file.')
170+
parser.add_argument('--sys-paths',
171+
'--sys-path',
172+
'--py-path',
173+
'--python-path',
174+
default='',
175+
dest='sys_paths',
176+
help='Paths be insert to sys.path[-1] while running.'
177+
' Support TEMP/HOME/SELF prefix, separated by commas.')
170178
if len(sys.argv) == 1:
171179
return parser.print_help()
172180
args, pip_args = parser.parse_known_args()
@@ -187,6 +195,7 @@ def main():
187195
build_id=args.build_id,
188196
env_paths=args.env_paths,
189197
lazy_install=args.lazy_install,
198+
sys_paths=args.sys_paths,
190199
)
191200

192201

zipapps/ensure_zipapps_template.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ def prepare_path():
3434
"""Template code for zipapps entry point. Run with current PYTHONPATH"""
3535
# PYTHONPATH=./app.pyz
3636
zip_file_path = Path(__file__).parent.absolute()
37-
python_path_list = [str(zip_file_path)]
37+
_zipapps_python_path_list = [str(zip_file_path)]
3838
unzip = os.environ.get('ZIPAPPS_UNZIP') or r'''{unzip}'''
3939
if unzip:
4040
_cache_folder = os.environ.get('ZIPAPPS_CACHE') or os.environ.get(
4141
'UNZIP_PATH') or r'''{unzip_path}'''
4242

4343
_cache_folder_path = ensure_path(_cache_folder)
4444
_cache_folder_path = _cache_folder_path / zip_file_path.stem
45-
_cache_folder_abs_path = str(_cache_folder_path.absolute())
46-
python_path_list.insert(0, _cache_folder_abs_path)
45+
_cache_folder_path_str = str(_cache_folder_path.absolute())
46+
_zipapps_python_path_list.insert(0, _cache_folder_path_str)
4747
ts_file_name = '_zip_time_{ts}'
4848
if not (_cache_folder_path / ts_file_name).is_file():
4949
# check timestamp difference by file name, need to refresh _cache_folder
@@ -57,7 +57,7 @@ def prepare_path():
5757
file_dir_name = os.path.splitext(
5858
member.filename.split('/')[0])[0]
5959
if unzip == '*' or member.filename in _need_unzip_names or file_dir_name in _need_unzip_names:
60-
zf.extract(member, path=_cache_folder_abs_path)
60+
zf.extract(member, path=_cache_folder_path_str)
6161
# lazy pip install
6262
lazy_pip_dir = _cache_folder_path / r'''{LAZY_PIP_DIR_NAME}'''
6363
if lazy_pip_dir.is_dir():
@@ -69,23 +69,31 @@ def prepare_path():
6969
import subprocess
7070
shell_args = [
7171
sys.executable, '-m', 'pip', 'install', '--target',
72-
_cache_folder_abs_path
72+
_cache_folder_path_str
7373
] + {pip_args_repr}
7474
with subprocess.Popen(shell_args,
75-
cwd=_cache_folder_abs_path) as proc:
75+
cwd=_cache_folder_path_str) as proc:
7676
proc.wait()
7777
sep = ';' if sys.platform == 'win32' else ':'
7878
ignore_system_python_path = {ignore_system_python_path}
79+
_new_sys_paths = r'''{sys_paths}'''.strip()
80+
if _new_sys_paths:
81+
new_sys_paths = [str(ensure_path(p)) for p in _new_sys_paths.split(',')]
82+
else:
83+
new_sys_paths = []
7984
if ignore_system_python_path:
8085
sys.path.clear()
8186
# env of Popen is not valid for win32 platform, use os.environ instead.
82-
os.environ['PYTHONPATH'] = sep.join(python_path_list)
87+
_new_paths = _zipapps_python_path_list + new_sys_paths
8388
else:
84-
os.environ['PYTHONPATH'] = sep.join(python_path_list) + sep + (
85-
os.environ.get('PYTHONPATH') or '')
89+
_old_path = os.environ.get('PYTHONPATH') or ''
90+
_new_paths = _zipapps_python_path_list + [_old_path] + new_sys_paths
91+
os.environ['PYTHONPATH'] = sep.join(_new_paths)
8692
# let the dir path first
87-
paths = [path for path in python_path_list if path not in sys.path]
88-
sys.path = paths + sys.path
93+
zipapps_paths = [
94+
path for path in _zipapps_python_path_list if path not in sys.path
95+
]
96+
sys.path = zipapps_paths + sys.path + new_sys_paths
8997

9098

9199
prepare_path()

zipapps/main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def prepare_entry(
6161
ts='None',
6262
env_paths: str = '',
6363
pip_args: list = None,
64+
sys_paths: str = '',
6465
):
6566
unzip_names = set(unzip.split(',')) if unzip else set()
6667
warning_names: typing.Dict[str, dict] = {}
@@ -114,6 +115,7 @@ def prepare_entry(
114115
'env_paths': env_paths,
115116
'LAZY_PIP_DIR_NAME': Config.LAZY_PIP_DIR_NAME,
116117
'pip_args_repr': repr(pip_args),
118+
'sys_paths': sys_paths,
117119
}
118120
code = get_data('zipapps', '_entry_point.py').decode('u8')
119121
(cache_path / '__main__.py').write_text(code.format(**kwargs))
@@ -214,6 +216,7 @@ def create_app(
214216
build_id: str = '',
215217
env_paths: str = '',
216218
lazy_install: bool = False,
219+
sys_paths: str = '',
217220
):
218221
tmp_dir: tempfile.TemporaryDirectory = None
219222
try:
@@ -269,6 +272,7 @@ def create_app(
269272
ts=set_timestamp(_cache_path),
270273
env_paths=env_paths,
271274
pip_args=pip_args,
275+
sys_paths=sys_paths,
272276
)
273277
if compiled:
274278
if not unzip:

0 commit comments

Comments
 (0)