diff --git a/docs/changelog/1779.bugfix.rst b/docs/changelog/1779.bugfix.rst new file mode 100644 index 000000000..c8d6286f6 --- /dev/null +++ b/docs/changelog/1779.bugfix.rst @@ -0,0 +1 @@ +Fix pinning seed packages via ``app-data`` seeder raised ``Invalid Requirement`` - by :user:`gaborbernat`. diff --git a/src/virtualenv/seed/embed/wheels/acquire.py b/src/virtualenv/seed/embed/wheels/acquire.py index 7f8730237..72ab4a626 100644 --- a/src/virtualenv/seed/embed/wheels/acquire.py +++ b/src/virtualenv/seed/embed/wheels/acquire.py @@ -129,7 +129,7 @@ def _get_wheels(from_folder, packages): def download_wheel(packages, for_py_version, to_folder, app_data): - to_download = list(p if v is None else "{}={}".format(p, v) for p, v in packages.items()) + to_download = list(p if v is None else "{}=={}".format(p, v) for p, v in packages.items()) logging.debug("download wheels %s", to_download) cmd = [ sys.executable, diff --git a/src/virtualenv/util/path/_pathlib/via_os_path.py b/src/virtualenv/util/path/_pathlib/via_os_path.py index 31c6c315c..3afbe3504 100644 --- a/src/virtualenv/util/path/_pathlib/via_os_path.py +++ b/src/virtualenv/util/path/_pathlib/via_os_path.py @@ -111,9 +111,9 @@ def open(self, mode="r"): def parents(self): result = [] parts = self.parts - for i in range(len(parts)): + for i in range(len(parts) - 1): result.append(Path(os.sep.join(parts[0 : i + 1]))) - return result + return result[::-1] def unlink(self): os.remove(self._path) diff --git a/tests/conftest.py b/tests/conftest.py index b4dd8dca7..d8ad9b4db 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -212,36 +212,25 @@ def finish(): class EnableCoverage(object): _COV_FILE = Path(coverage.__file__) - _COV_SITE_PACKAGES = _COV_FILE.parents[1] - _ROOT_COV_FILES_AND_FOLDERS = [i for i in _COV_SITE_PACKAGES.iterdir() if i.name.startswith("coverage")] - _SUBPROCESS_TRIGGER_PTH_NAME = "coverage-virtual-sub.pth" + _ROOT_COV_FILES_AND_FOLDERS = [i for i in _COV_FILE.parents[1].iterdir() if i.name.startswith("coverage")] def __init__(self, link): self.link = link self.targets = [] - self.cov_pth = self._COV_SITE_PACKAGES / self._SUBPROCESS_TRIGGER_PTH_NAME def __enter__(self, creator): - assert not self.cov_pth.exists() site_packages = creator.purelib - p_th = site_packages / self._SUBPROCESS_TRIGGER_PTH_NAME - - if not str(p_th).startswith(str(self._COV_SITE_PACKAGES)): - p_th.write_text("import coverage; coverage.process_startup()") - self.targets.append((p_th, p_th.unlink)) - for entry in self._ROOT_COV_FILES_AND_FOLDERS: - target = site_packages / entry.name - if not target.exists(): - clean = self.link(entry, target) - self.targets.append((target, clean)) + for entry in self._ROOT_COV_FILES_AND_FOLDERS: + target = site_packages / entry.name + if not target.exists(): + clean = self.link(entry, target) + self.targets.append((target, clean)) return self def __exit__(self, exc_type, exc_val, exc_tb): - assert self._COV_FILE.exists() for target, clean in self.targets: if target.exists(): clean() - assert not self.cov_pth.exists() assert self._COV_FILE.exists() diff --git a/tests/integration/test_run_int.py b/tests/integration/test_run_int.py new file mode 100644 index 000000000..bf818bafb --- /dev/null +++ b/tests/integration/test_run_int.py @@ -0,0 +1,19 @@ +from __future__ import absolute_import, unicode_literals + +from virtualenv import cli_run +from virtualenv.util.six import ensure_text +from virtualenv.util.subprocess import run_cmd + + +def test_app_data_pinning(tmp_path): + result = cli_run([ensure_text(str(tmp_path)), "--pip", "19.3.1", "--activators", "", "--seeder", "app-data"]) + code, out, err = run_cmd([str(result.creator.script("pip")), "list", "--disable-pip-version-check"]) + assert not code + assert not err + for line in out.splitlines(): + parts = line.split() + if parts and parts[0] == "pip": + assert parts[1] == "19.3.1" + break + else: + assert not out diff --git a/tests/unit/create/test_creator.py b/tests/unit/create/test_creator.py index 3174d4533..969e57335 100644 --- a/tests/unit/create/test_creator.py +++ b/tests/unit/create/test_creator.py @@ -395,7 +395,6 @@ def test_create_long_path(current_fastest, tmp_path): subprocess.check_call([str(result.creator.script("pip")), "--version"]) -@pytest.mark.timeout(timeout=60) @pytest.mark.parametrize("creator", set(PythonInfo.current_system().creators().key_to_class) - {"builtin"}) def test_create_distutils_cfg(creator, tmp_path, monkeypatch): result = cli_run([ensure_text(str(tmp_path / "venv")), "--activators", "", "--creator", creator])