Actually build the zipapp
@@ -20,6 +20,7 @@ from typing import (
Union,
)
from unittest.mock import patch
+from zipfile import ZipFile
import pytest
@@ -32,6 +33,7 @@ from _pytest.config import Config
from _pytest.config.argparsing import Parser
from setuptools.wheel import Wheel
+from pip import __file__ as pip_location
from pip._internal.cli.main import main as pip_entry_point
from pip._internal.locations import _USE_SYSCONFIG
from pip._internal.utils.temp_dir import global_tempdir_manager
@@ -529,6 +531,35 @@ def script_factory(
return factory
+ZIPAPP_MAIN = """\
+#!/usr/bin/env python
+
+import os
+import runpy
+import sys
+
+lib = os.path.join(os.path.dirname(__file__), "lib")
+sys.path.insert(0, lib)
+
+runpy.run_module("pip", run_name="__main__")
+"""
+
+def make_zipapp_from_pip(zipapp_name: Path) -> None:
+ pip_dir = Path(pip_location).parent
+ with zipapp_name.open("wb") as zipapp_file:
+ zipapp_file.write(b"#!/usr/bin/env python\n")
+ with ZipFile(zipapp_file, "w") as zipapp:
+ for pip_file in pip_dir.rglob("*"):
+ if pip_file.suffix == ".pyc":
+ continue
+ if pip_file.name == "__pycache__":
+ continue
+ rel_name = pip_file.relative_to(pip_dir.parent)
+ zipapp.write(pip_file, arcname=f"lib/{rel_name}")
+ zipapp.writestr("__main__.py", ZIPAPP_MAIN)
+
+
+
@pytest.fixture(scope="session")
def zipapp(request: pytest.FixtureRequest, tmpdir_factory: pytest.TempPathFactory) -> Optional[str]:
"""
@@ -542,13 +573,7 @@ def zipapp(request: pytest.FixtureRequest, tmpdir_factory: pytest.TempPathFactor
temp_location = tmpdir_factory.mktemp("zipapp")
pyz_file = temp_location / "pip.pyz"
- # What we want to do here is `pip wheel --wheel-dir temp_location <source_dir>`
- # and then build a zipapp from that wheel.
- # TODO: Remove hard coded file
- za = "pip-22.2.dev0.pyz"
- import warnings
- warnings.warn(f"Copying {za} to {pyz_file}")
- shutil.copyfile(za, pyz_file)
+ make_zipapp_from_pip(pyz_file)
return str(pyz_file)
