Skip to content

Commit cbbca7e

Browse files
committed
add arg --ensure-pip
1 parent fe7fed6 commit cbbca7e

File tree

7 files changed

+57
-20
lines changed

7 files changed

+57
-20
lines changed

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ Package your python code (with requirements) into a standalone zip file.
77

88
Inspired by [shiv](https://github.com/linkedin/shiv) but unlike `shiv`
99

10-
1. zipapps may not unzip cache when without any C language-based library or dynamic modules(`.so/.pyd`), such as `requests`, `bottle`, or your own pure python code.
11-
2. cache path to unzip is `./zipapps_cache` by default, not the `HOME` path.
12-
3. the cache folders will be reused for the same app name, not like shiv to create many new versions and use much disk space.
13-
4. you can install requirements with `pip` while first running(not packaging) by lazy install mode, for cross-platform publishing and reducing your `.pyz` file size.
14-
5. combine multiple `venv.pyz` files for your code flexibly.
10+
1. `zipapps` may not create the cache folder while your package has no C language-based libraries or dynamic modules(`.so/.pyd`), such as `requests`, `bottle` or other pure python codes.
11+
2. The default cache path is `./zipapps_cache`, but not the `HOME` path.
12+
3. The cache folders will be reused for the `same app name`, not to create many new versions and use much disk space.
13+
4. You can install requirements with `pip` while first running(not packaging) by `lazy install` mode, for cross-platform publishing and reducing your `.pyz` file size.
14+
5. Using multiple `venv.pyz` files together.
15+
16+
[Changelog.md](https://github.com/ClericPy/zipapps/blob/master/changelog.md)
1517

1618
# What is the `.pyz`?
1719

@@ -397,7 +399,9 @@ Details:
397399
1. Default `--zipapps` arg if it is not given while running. Support TEMP/HOME/SELF prefix.
398400
16. `--delay, -d, --lazy-pip, --lazy-install, --lazy-pip-install`
399401
1. Install packages with pip while first running, which means requirements will not be install into pyz file.
400-
17. all the other (or `unknown`) args will be used by "pip install"
402+
17. `--ensure-pip`
403+
1. Add the ensurepip package to your pyz file, works for **embed-python**(windows) or other python versions without `pip` installed but `lazy-install` mode is enabled. [EXPERIMENTAL]
404+
18. all the other (or `unknown`) args will be used by "pip install"
401405
1. such as `-r requirements.txt`
402406
2. such as `bottle aiohttp`
403407
3. the `pip_args` arg of `zipapps.create_app`
@@ -440,5 +444,3 @@ Details:
440444
1. `import sys;sys.path.insert(0, 'app.pyz')` (without .so/.pyd)
441445
2. `python3 app.pyz script.py`
442446
7. Other usages need to be found, and enjoy yourself.
443-
444-
# [Changelog.md](https://github.com/ClericPy/zipapps/blob/master/changelog.md)

args.png

55.8 KB
Loading

args.svg

Lines changed: 1 addition & 0 deletions
Loading

changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
# Changelogs
33

4+
- 2021.04.29
5+
- add arg `--ensure-pip` for embed-python(windows) or other python versions which have no `pip` installed but `lazy-install` mode is enabled.
46
- 2021.04.24
57
- remove conflict command args with `pip`
68
- remove `--compile` arg, it will only work for `pip`

zipapps/__main__.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ def main():
161161
action='store_true',
162162
dest='lazy_install',
163163
help='Install packages with pip while running, which means '
164-
'requirements will not be install into pyz file. Default unzip path will be changed to `SELF/zipapps_cache`')
164+
'requirements will not be install into pyz file. Default unzip path will be changed to `SELF/zipapps_cache`'
165+
)
165166
parser.add_argument(
166167
'-pva',
167168
'--python-version-accuracy',
@@ -185,6 +186,13 @@ def main():
185186
dest='activate',
186187
help='Activate the given paths of zipapps app, '
187188
'only activate them but not run them, separated by commas.')
189+
parser.add_argument(
190+
'--ensure-pip',
191+
action='store_true',
192+
dest='ensure_pip',
193+
help='Add the ensurepip package to your pyz file, works for '
194+
'embed-python(windows) or other python versions without `pip`'
195+
' installed but `lazy-install` mode is enabled. [EXPERIMENTAL]')
188196
if len(sys.argv) == 1:
189197
return parser.print_help()
190198
args, pip_args = parser.parse_known_args()
@@ -212,6 +220,7 @@ def main():
212220
lazy_install=args.lazy_install,
213221
sys_paths=args.sys_paths,
214222
python_version_slice=int(args.python_version_slice),
223+
ensure_pip=args.ensure_pip,
215224
)
216225

217226

zipapps/ensure_zipapps_template.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,29 @@ def prepare_path():
9595
_pip_target.mkdir(parents=True, exist_ok=True)
9696
try:
9797
import pip
98+
shell_args = [
99+
sys.executable, '-m', 'pip', 'install', '--target',
100+
lazy_pip_dir_str
101+
] + pip_args
102+
import subprocess
103+
with subprocess.Popen(shell_args,
104+
cwd=_cache_folder_path_str,
105+
stdout=sys.stderr) as proc:
106+
proc.wait()
98107
except ImportError:
108+
# try installing pip
109+
cwd = os.getcwd()
110+
os.chdir(_cache_folder_path_str)
99111
import ensurepip
100-
ensurepip.bootstrap()
101-
import subprocess
102-
shell_args = [
103-
sys.executable, '-m', 'pip', 'install', '--target',
104-
lazy_pip_dir_str
105-
] + pip_args
106-
with subprocess.Popen(shell_args,
107-
cwd=_cache_folder_path_str,
108-
stdout=sys.stderr) as proc:
109-
proc.wait()
112+
assert ensurepip._bootstrap(root=lazy_pip_dir_str) == 0
113+
for _path in _pip_target.glob('**/pip/'):
114+
if _path.is_dir():
115+
sys.path.append(str(_path.parent.absolute()))
116+
break
117+
import pip
118+
args = ['install', '-t', lazy_pip_dir_str] + pip_args
119+
pip.main(args)
120+
os.chdir(cwd)
110121
# avoid duplicated installation
111122
(_pip_target / pip_args_md5).touch()
112123
sep = ';' if sys.platform == 'win32' else ':'

zipapps/main.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from pkgutil import get_data
1616
from zipfile import BadZipFile, ZipFile
1717

18-
__version__ = '2021.04.27'
18+
__version__ = '2021.04.29'
1919

2020

2121
class ZipApp(object):
@@ -47,6 +47,7 @@ def __init__(
4747
lazy_install: bool = False,
4848
sys_paths: str = '',
4949
python_version_slice: int = 2,
50+
ensure_pip: bool = False,
5051
):
5152
"""Zip your code.
5253
@@ -86,6 +87,8 @@ def __init__(
8687
:type sys_paths: str, optional
8788
:param python_version_slice: Only work for lazy-install mode, then `pip` target folders differ according to sys.version_info[:_slice], defaults to 2, which means 3.8.3 equals to 3.8.4 for same version accuracy 3.8, defaults to 2
8889
:type python_version_slice: int, optional
90+
:param ensure_pip: Add the ensurepip package to your pyz file, works for embed-python(windows) or other python versions without `pip` installed but `lazy-install` mode is enabled.
91+
:type includes: bool, optional
8992
"""
9093
self.includes = includes
9194
self.cache_path = cache_path
@@ -106,6 +109,7 @@ def __init__(
106109
self.lazy_install = lazy_install
107110
self.sys_paths = sys_paths
108111
self.python_version_slice = python_version_slice
112+
self.ensure_pip = ensure_pip
109113

110114
self._tmp_dir: tempfile.TemporaryDirectory = None
111115
self._build_success = False
@@ -142,6 +146,13 @@ def ensure_args(self):
142146
f'[INFO]: output path is `{self._output_path}`, you can reset it with the arg `output`.'
143147
)
144148

149+
def prepare_ensure_pip(self):
150+
if self.ensure_pip:
151+
import ensurepip
152+
ensurepip_dir_path = Path(ensurepip.__file__).parent
153+
shutil.copytree(str(ensurepip_dir_path.absolute()),
154+
self._cache_path / ensurepip_dir_path.name)
155+
145156
def build(self):
146157
self._log(
147158
f'{"=" * 10} Start building `{self._output_path}` with zipapps version <{__version__}> {"=" * 10}'
@@ -150,6 +161,7 @@ def build(self):
150161
if self.build_exists():
151162
return self._output_path
152163
self.prepare_includes()
164+
self.prepare_ensure_pip()
153165
self.prepare_pip()
154166
self.prepare_entry_point()
155167
if self.build_id_name:

0 commit comments

Comments
 (0)