parent
bce50a487f
commit
16509d52e6
@ -1 +1 @@
|
||||
SOURCES/virtualenv-20.20.0.tar.gz
|
||||
SOURCES/virtualenv-20.21.1.tar.gz
|
||||
|
@ -1 +1 @@
|
||||
9a444e4de87a9944222a1bde643f0a4ae8bd3e57 SOURCES/virtualenv-20.20.0.tar.gz
|
||||
ee10bef35332c6d7a9c9c82e11c5e5d081ddbdbd SOURCES/virtualenv-20.21.1.tar.gz
|
||||
|
@ -0,0 +1,339 @@
|
||||
From 42e0698087f061d1d7db6fcb9469302bda5d44ca Mon Sep 17 00:00:00 2001
|
||||
From: chrysle <fritzihab@posteo.de>
|
||||
Date: Fri, 28 Apr 2023 01:36:03 +0200
|
||||
Subject: [PATCH] 3.12 support and no setuptools/wheel on 3.12+ (#2558)
|
||||
|
||||
Cherry-picked from fd93dd79be89b21e6e9d43ca2dd1b02b811f6d6f
|
||||
---
|
||||
docs/changelog/2487.feature.rst | 6 +++++
|
||||
docs/changelog/2558.feature.rst | 1 +
|
||||
docs/render_cli.py | 10 +------
|
||||
docs/user_guide.rst | 5 ++--
|
||||
src/virtualenv/activation/python/__init__.py | 3 ++-
|
||||
src/virtualenv/seed/embed/base_embed.py | 11 +++++---
|
||||
src/virtualenv/util/path/_sync.py | 4 ++-
|
||||
tests/unit/config/test___main__.py | 2 +-
|
||||
tests/unit/create/test_creator.py | 26 ++++++++++++++++---
|
||||
tests/unit/discovery/py_info/test_py_info.py | 2 +-
|
||||
tests/unit/discovery/windows/conftest.py | 2 +-
|
||||
tests/unit/seed/embed/test_base_embed.py | 12 +++++++++
|
||||
.../embed/test_bootstrap_link_via_app_data.py | 4 +--
|
||||
.../unit/seed/wheels/test_periodic_update.py | 17 ++++++++++--
|
||||
14 files changed, 79 insertions(+), 26 deletions(-)
|
||||
create mode 100644 docs/changelog/2487.feature.rst
|
||||
create mode 100644 docs/changelog/2558.feature.rst
|
||||
|
||||
diff --git a/docs/changelog/2487.feature.rst b/docs/changelog/2487.feature.rst
|
||||
new file mode 100644
|
||||
index 0000000..12cc896
|
||||
--- /dev/null
|
||||
+++ b/docs/changelog/2487.feature.rst
|
||||
@@ -0,0 +1,6 @@
|
||||
+Do not install ``wheel`` and ``setuptools`` seed packages for Python 3.12+. To restore the old behaviour use:
|
||||
+
|
||||
+- for ``wheel`` use ``VIRTUALENV_WHEEL=bundle`` environment variable or ``--wheel=bundle`` CLI flag,
|
||||
+- for ``setuptools`` use ``VIRTUALENV_SETUPTOOLS=bundle`` environment variable or ``--setuptools=bundle`` CLI flag.
|
||||
+
|
||||
+By :user:`chrysle`.
|
||||
diff --git a/docs/changelog/2558.feature.rst b/docs/changelog/2558.feature.rst
|
||||
new file mode 100644
|
||||
index 0000000..58b627a
|
||||
--- /dev/null
|
||||
+++ b/docs/changelog/2558.feature.rst
|
||||
@@ -0,0 +1 @@
|
||||
+3.12 support - by :user:`gaborbernat`.
|
||||
diff --git a/src/virtualenv/activation/python/__init__.py b/src/virtualenv/activation/python/__init__.py
|
||||
index eb83504..a49444b 100644
|
||||
--- a/src/virtualenv/activation/python/__init__.py
|
||||
+++ b/src/virtualenv/activation/python/__init__.py
|
||||
@@ -12,10 +12,11 @@ class PythonActivator(ViaTemplateActivator):
|
||||
def replacements(self, creator, dest_folder):
|
||||
replacements = super().replacements(creator, dest_folder)
|
||||
lib_folders = OrderedDict((os.path.relpath(str(i), str(dest_folder)), None) for i in creator.libs)
|
||||
+ lib_folders = os.pathsep.join(lib_folders.keys()).replace("\\", "\\\\") # escape Windows path characters
|
||||
win_py2 = creator.interpreter.platform == "win32" and creator.interpreter.version_info.major == 2
|
||||
replacements.update(
|
||||
{
|
||||
- "__LIB_FOLDERS__": os.pathsep.join(lib_folders.keys()),
|
||||
+ "__LIB_FOLDERS__": lib_folders,
|
||||
"__DECODE_PATH__": ("yes" if win_py2 else ""),
|
||||
},
|
||||
)
|
||||
diff --git a/src/virtualenv/seed/embed/base_embed.py b/src/virtualenv/seed/embed/base_embed.py
|
||||
index f29110b..6782d6f 100644
|
||||
--- a/src/virtualenv/seed/embed/base_embed.py
|
||||
+++ b/src/virtualenv/seed/embed/base_embed.py
|
||||
@@ -39,7 +39,7 @@ class BaseEmbed(Seeder, metaclass=ABCMeta):
|
||||
return {
|
||||
distribution: getattr(self, f"{distribution}_version")
|
||||
for distribution in self.distributions()
|
||||
- if getattr(self, f"no_{distribution}") is False
|
||||
+ if getattr(self, f"no_{distribution}") is False and getattr(self, f"{distribution}_version") != "none"
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@@ -69,11 +69,13 @@ class BaseEmbed(Seeder, metaclass=ABCMeta):
|
||||
default=[],
|
||||
)
|
||||
for distribution, default in cls.distributions().items():
|
||||
+ if interpreter.version_info[:2] >= (3, 12) and distribution in {"wheel", "setuptools"}:
|
||||
+ default = "none"
|
||||
parser.add_argument(
|
||||
f"--{distribution}",
|
||||
dest=distribution,
|
||||
metavar="version",
|
||||
- help=f"version of {distribution} to install as seed: embed, bundle or exact version",
|
||||
+ help=f"version of {distribution} to install as seed: embed, bundle, none or exact version",
|
||||
default=default,
|
||||
)
|
||||
for distribution in cls.distributions():
|
||||
@@ -101,7 +103,10 @@ class BaseEmbed(Seeder, metaclass=ABCMeta):
|
||||
for distribution in self.distributions():
|
||||
if getattr(self, f"no_{distribution}"):
|
||||
continue
|
||||
- ver = f"={getattr(self, f'{distribution}_version', None) or 'latest'}"
|
||||
+ version = getattr(self, f"{distribution}_version", None)
|
||||
+ if version == "none":
|
||||
+ continue
|
||||
+ ver = f"={version or 'latest'}"
|
||||
result += f" {distribution}{ver},"
|
||||
return result[:-1] + ")"
|
||||
|
||||
diff --git a/src/virtualenv/util/path/_sync.py b/src/virtualenv/util/path/_sync.py
|
||||
index 604379d..b0af1eb 100644
|
||||
--- a/src/virtualenv/util/path/_sync.py
|
||||
+++ b/src/virtualenv/util/path/_sync.py
|
||||
@@ -1,6 +1,7 @@
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
+import sys
|
||||
from stat import S_IWUSR
|
||||
|
||||
|
||||
@@ -56,7 +57,8 @@ def safe_delete(dest):
|
||||
else:
|
||||
raise
|
||||
|
||||
- shutil.rmtree(str(dest), ignore_errors=True, onerror=onerror)
|
||||
+ kwargs = {"onexc" if sys.version_info >= (3, 12) else "onerror": onerror}
|
||||
+ shutil.rmtree(str(dest), ignore_errors=True, **kwargs)
|
||||
|
||||
|
||||
class _Debug:
|
||||
diff --git a/tests/unit/config/test___main__.py b/tests/unit/config/test___main__.py
|
||||
index 62228c9..d22ef7e 100644
|
||||
--- a/tests/unit/config/test___main__.py
|
||||
+++ b/tests/unit/config/test___main__.py
|
||||
@@ -58,7 +58,7 @@ def test_fail_with_traceback(raise_on_session_done, tmp_path, capsys):
|
||||
|
||||
@pytest.mark.usefixtures("session_app_data")
|
||||
def test_session_report_full(tmp_path, capsys):
|
||||
- run_with_catch([str(tmp_path)])
|
||||
+ run_with_catch([str(tmp_path), "--setuptools", "bundle", "--wheel", "bundle"])
|
||||
out, err = capsys.readouterr()
|
||||
assert err == ""
|
||||
lines = out.splitlines()
|
||||
diff --git a/tests/unit/create/test_creator.py b/tests/unit/create/test_creator.py
|
||||
index 0ec6d62..8b9d688 100644
|
||||
--- a/tests/unit/create/test_creator.py
|
||||
+++ b/tests/unit/create/test_creator.py
|
||||
@@ -412,7 +412,19 @@ def test_create_long_path(tmp_path):
|
||||
@pytest.mark.parametrize("creator", sorted(set(PythonInfo.current_system().creators().key_to_class) - {"builtin"}))
|
||||
@pytest.mark.usefixtures("session_app_data")
|
||||
def test_create_distutils_cfg(creator, tmp_path, monkeypatch):
|
||||
- result = cli_run([str(tmp_path / "venv"), "--activators", "", "--creator", creator])
|
||||
+ result = cli_run(
|
||||
+ [
|
||||
+ str(tmp_path / "venv"),
|
||||
+ "--activators",
|
||||
+ "",
|
||||
+ "--creator",
|
||||
+ creator,
|
||||
+ "--setuptools",
|
||||
+ "bundle",
|
||||
+ "--wheel",
|
||||
+ "bundle",
|
||||
+ ],
|
||||
+ )
|
||||
|
||||
app = Path(__file__).parent / "console_app"
|
||||
dest = tmp_path / "console_app"
|
||||
@@ -465,7 +477,9 @@ def list_files(path):
|
||||
|
||||
def test_zip_importer_can_import_setuptools(tmp_path):
|
||||
"""We're patching the loaders so might fail on r/o loaders, such as zipimporter on CPython<3.8"""
|
||||
- result = cli_run([str(tmp_path / "venv"), "--activators", "", "--no-pip", "--no-wheel", "--copies"])
|
||||
+ result = cli_run(
|
||||
+ [str(tmp_path / "venv"), "--activators", "", "--no-pip", "--no-wheel", "--copies", "--setuptools", "bundle"],
|
||||
+ )
|
||||
zip_path = tmp_path / "site-packages.zip"
|
||||
with zipfile.ZipFile(str(zip_path), "w", zipfile.ZIP_DEFLATED) as zip_handler:
|
||||
lib = str(result.creator.purelib)
|
||||
@@ -499,6 +513,7 @@ def test_no_preimport_threading(tmp_path):
|
||||
out = subprocess.check_output(
|
||||
[str(session.creator.exe), "-c", r"import sys; print('\n'.join(sorted(sys.modules)))"],
|
||||
text=True,
|
||||
+ encoding="utf-8",
|
||||
)
|
||||
imported = set(out.splitlines())
|
||||
assert "threading" not in imported
|
||||
@@ -515,6 +530,7 @@ def test_pth_in_site_vs_python_path(tmp_path):
|
||||
out = subprocess.check_output(
|
||||
[str(session.creator.exe), "-c", r"import sys; print(sys.testpth)"],
|
||||
text=True,
|
||||
+ encoding="utf-8",
|
||||
)
|
||||
assert out == "ok\n"
|
||||
# same with $PYTHONPATH pointing to site_packages
|
||||
@@ -527,6 +543,7 @@ def test_pth_in_site_vs_python_path(tmp_path):
|
||||
[str(session.creator.exe), "-c", r"import sys; print(sys.testpth)"],
|
||||
text=True,
|
||||
env=env,
|
||||
+ encoding="utf-8",
|
||||
)
|
||||
assert out == "ok\n"
|
||||
|
||||
@@ -540,6 +557,7 @@ def test_getsitepackages_system_site(tmp_path):
|
||||
out = subprocess.check_output(
|
||||
[str(session.creator.exe), "-c", r"import site; print(site.getsitepackages())"],
|
||||
text=True,
|
||||
+ encoding="utf-8",
|
||||
)
|
||||
site_packages = ast.literal_eval(out)
|
||||
|
||||
@@ -554,6 +572,7 @@ def test_getsitepackages_system_site(tmp_path):
|
||||
out = subprocess.check_output(
|
||||
[str(session.creator.exe), "-c", r"import site; print(site.getsitepackages())"],
|
||||
text=True,
|
||||
+ encoding="utf-8",
|
||||
)
|
||||
site_packages = [str(Path(i).resolve()) for i in ast.literal_eval(out)]
|
||||
|
||||
@@ -579,6 +598,7 @@ def test_get_site_packages(tmp_path):
|
||||
out = subprocess.check_output(
|
||||
[str(session.creator.exe), "-c", r"import site; print(site.getsitepackages())"],
|
||||
text=True,
|
||||
+ encoding="utf-8",
|
||||
)
|
||||
site_packages = ast.literal_eval(out)
|
||||
|
||||
@@ -617,7 +637,7 @@ def test_python_path(monkeypatch, tmp_path, python_path_on):
|
||||
if flag:
|
||||
cmd.append(flag)
|
||||
cmd.extend(["-c", "import json; import sys; print(json.dumps(sys.path))"])
|
||||
- return [i if case_sensitive else i.lower() for i in json.loads(subprocess.check_output(cmd))]
|
||||
+ return [i if case_sensitive else i.lower() for i in json.loads(subprocess.check_output(cmd, encoding="utf-8"))]
|
||||
|
||||
monkeypatch.delenv("PYTHONPATH", raising=False)
|
||||
base = _get_sys_path()
|
||||
diff --git a/tests/unit/discovery/py_info/test_py_info.py b/tests/unit/discovery/py_info/test_py_info.py
|
||||
index 24b129c..f3fdb7e 100644
|
||||
--- a/tests/unit/discovery/py_info/test_py_info.py
|
||||
+++ b/tests/unit/discovery/py_info/test_py_info.py
|
||||
@@ -289,7 +289,7 @@ def test_discover_exe_on_path_non_spec_name_not_match(mocker):
|
||||
assert CURRENT.satisfies(spec, impl_must_match=True) is False
|
||||
|
||||
|
||||
-@pytest.mark.skipif(IS_PYPY, reason="setuptools distutil1s patching does not work")
|
||||
+@pytest.mark.skipif(IS_PYPY, reason="setuptools distutils patching does not work")
|
||||
def test_py_info_setuptools():
|
||||
from setuptools.dist import Distribution
|
||||
|
||||
diff --git a/tests/unit/discovery/windows/conftest.py b/tests/unit/discovery/windows/conftest.py
|
||||
index 58da626..94f14da 100644
|
||||
--- a/tests/unit/discovery/windows/conftest.py
|
||||
+++ b/tests/unit/discovery/windows/conftest.py
|
||||
@@ -9,7 +9,7 @@ def _mock_registry(mocker):
|
||||
from virtualenv.discovery.windows.pep514 import winreg
|
||||
|
||||
loc, glob = {}, {}
|
||||
- mock_value_str = (Path(__file__).parent / "winreg-mock-values.py").read_text()
|
||||
+ mock_value_str = (Path(__file__).parent / "winreg-mock-values.py").read_text(encoding="utf-8")
|
||||
exec(mock_value_str, glob, loc)
|
||||
enum_collect = loc["enum_collect"]
|
||||
value_collect = loc["value_collect"]
|
||||
diff --git a/tests/unit/seed/embed/test_base_embed.py b/tests/unit/seed/embed/test_base_embed.py
|
||||
index 3344c74..ef2f829 100644
|
||||
--- a/tests/unit/seed/embed/test_base_embed.py
|
||||
+++ b/tests/unit/seed/embed/test_base_embed.py
|
||||
@@ -1,3 +1,5 @@
|
||||
+import sys
|
||||
+
|
||||
import pytest
|
||||
|
||||
from virtualenv.run import session_via_cli
|
||||
@@ -10,3 +12,13 @@ from virtualenv.run import session_via_cli
|
||||
def test_download_cli_flag(args, download, tmp_path):
|
||||
session = session_via_cli(args + [str(tmp_path)])
|
||||
assert session.seeder.download is download
|
||||
+
|
||||
+
|
||||
+def test_embed_wheel_versions(tmp_path):
|
||||
+ session = session_via_cli([str(tmp_path)])
|
||||
+ expected = (
|
||||
+ {"pip": "bundle"}
|
||||
+ if sys.version_info[:2] >= (3, 12)
|
||||
+ else {"pip": "bundle", "setuptools": "bundle", "wheel": "bundle"}
|
||||
+ )
|
||||
+ assert session.seeder.distribution_to_versions() == expected
|
||||
diff --git a/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py b/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
|
||||
index 2c8c3e8..015686d 100644
|
||||
--- a/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
|
||||
+++ b/tests/unit/seed/embed/test_bootstrap_link_via_app_data.py
|
||||
@@ -203,7 +203,7 @@ def test_populated_read_only_cache_and_copied_app_data(tmp_path, current_fastest
|
||||
@pytest.mark.parametrize("pkg", ["pip", "setuptools", "wheel"])
|
||||
@pytest.mark.usefixtures("session_app_data", "current_fastest", "coverage_env")
|
||||
def test_base_bootstrap_link_via_app_data_no(tmp_path, pkg):
|
||||
- create_cmd = [str(tmp_path), "--seeder", "app-data", f"--no-{pkg}"]
|
||||
+ create_cmd = [str(tmp_path), "--seeder", "app-data", f"--no-{pkg}", "--wheel", "bundle", "--setuptools", "bundle"]
|
||||
result = cli_run(create_cmd)
|
||||
assert not (result.creator.purelib / pkg).exists()
|
||||
for key in {"pip", "setuptools", "wheel"} - {pkg}:
|
||||
@@ -231,7 +231,7 @@ def _run_parallel_threads(tmp_path):
|
||||
|
||||
def _run(name):
|
||||
try:
|
||||
- cli_run(["--seeder", "app-data", str(tmp_path / name), "--no-pip", "--no-setuptools"])
|
||||
+ cli_run(["--seeder", "app-data", str(tmp_path / name), "--no-pip", "--no-setuptools", "--wheel", "bundle"])
|
||||
except Exception as exception:
|
||||
as_str = str(exception)
|
||||
exceptions.append(as_str)
|
||||
diff --git a/tests/unit/seed/wheels/test_periodic_update.py b/tests/unit/seed/wheels/test_periodic_update.py
|
||||
index e7794f5..c36a983 100644
|
||||
--- a/tests/unit/seed/wheels/test_periodic_update.py
|
||||
+++ b/tests/unit/seed/wheels/test_periodic_update.py
|
||||
@@ -66,7 +66,7 @@ def test_manual_upgrade(session_app_data, caplog, mocker, for_py_version):
|
||||
|
||||
@pytest.mark.usefixtures("session_app_data")
|
||||
def test_pick_periodic_update(tmp_path, mocker, for_py_version):
|
||||
- embed, current = get_embed_wheel("setuptools", "3.5"), get_embed_wheel("setuptools", for_py_version)
|
||||
+ embed, current = get_embed_wheel("setuptools", "3.6"), get_embed_wheel("setuptools", for_py_version)
|
||||
mocker.patch("virtualenv.seed.wheels.bundle.load_embed_wheel", return_value=embed)
|
||||
completed = datetime.now() - timedelta(days=29)
|
||||
u_log = UpdateLog(
|
||||
@@ -77,7 +77,20 @@ def test_pick_periodic_update(tmp_path, mocker, for_py_version):
|
||||
)
|
||||
read_dict = mocker.patch("virtualenv.app_data.via_disk_folder.JSONStoreDisk.read", return_value=u_log.to_dict())
|
||||
|
||||
- result = cli_run([str(tmp_path), "--activators", "", "--no-periodic-update", "--no-wheel", "--no-pip"])
|
||||
+ result = cli_run(
|
||||
+ [
|
||||
+ str(tmp_path),
|
||||
+ "--activators",
|
||||
+ "",
|
||||
+ "--no-periodic-update",
|
||||
+ "--no-wheel",
|
||||
+ "--no-pip",
|
||||
+ "--setuptools",
|
||||
+ "bundle",
|
||||
+ "--wheel",
|
||||
+ "bundle",
|
||||
+ ],
|
||||
+ )
|
||||
|
||||
assert read_dict.call_count == 1
|
||||
installed = [i.name for i in result.creator.purelib.iterdir() if i.suffix == ".dist-info"]
|
||||
--
|
||||
2.40.0
|
||||
|
@ -0,0 +1,70 @@
|
||||
From fc8e412fa8fe524ab3f112f02e865aa42608388b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jakub=20Kul=C3=ADk?= <Kulikjak@gmail.com>
|
||||
Date: Thu, 27 Apr 2023 18:52:38 +0200
|
||||
Subject: [PATCH] prevent PermissionError when using venv creator on some
|
||||
systems (#2543)
|
||||
|
||||
Cherry-picked from 0597a2f8ab32705b86a25dbd1d42fd30c3033061
|
||||
---
|
||||
docs/changelog/2543.bugfix.rst | 2 ++
|
||||
src/virtualenv/activation/via_template.py | 4 ++++
|
||||
tests/unit/create/test_creator.py | 22 ++++++++++++++++++++++
|
||||
3 files changed, 28 insertions(+)
|
||||
create mode 100644 docs/changelog/2543.bugfix.rst
|
||||
|
||||
diff --git a/docs/changelog/2543.bugfix.rst b/docs/changelog/2543.bugfix.rst
|
||||
new file mode 100644
|
||||
index 0000000..5f0d6ca
|
||||
--- /dev/null
|
||||
+++ b/docs/changelog/2543.bugfix.rst
|
||||
@@ -0,0 +1,2 @@
|
||||
+Prevent ``PermissionError`` when using venv creator on systems that deliver files without user write
|
||||
+permission - by :user:`kulikjak`.
|
||||
diff --git a/src/virtualenv/activation/via_template.py b/src/virtualenv/activation/via_template.py
|
||||
index 069d52e..cc9dbda 100644
|
||||
--- a/src/virtualenv/activation/via_template.py
|
||||
+++ b/src/virtualenv/activation/via_template.py
|
||||
@@ -41,6 +41,10 @@ class ViaTemplateActivator(Activator, metaclass=ABCMeta):
|
||||
for template in templates:
|
||||
text = self.instantiate_template(replacements, template, creator)
|
||||
dest = to_folder / self.as_name(template)
|
||||
+ # remove the file if it already exists - this prevents permission
|
||||
+ # errors when the dest is not writable
|
||||
+ if dest.exists():
|
||||
+ dest.unlink()
|
||||
# use write_bytes to avoid platform specific line normalization (\n -> \r\n)
|
||||
dest.write_bytes(text.encode("utf-8"))
|
||||
generated.append(dest)
|
||||
diff --git a/tests/unit/create/test_creator.py b/tests/unit/create/test_creator.py
|
||||
index ea61ed0..0ec6d62 100644
|
||||
--- a/tests/unit/create/test_creator.py
|
||||
+++ b/tests/unit/create/test_creator.py
|
||||
@@ -690,3 +690,25 @@ def test_py_pyc_missing(tmp_path, mocker, py, pyc):
|
||||
|
||||
pyc_at = Python2.from_stdlib(Python2.mappings(CURRENT), "osc.py")[1](result.creator, Path("os.pyc"))
|
||||
assert pyc_at.exists() is pyc
|
||||
+
|
||||
+
|
||||
+# Make sure that the venv creator works on systems where vendor-delivered files
|
||||
+# (specifically venv scripts delivered with Python itself) are not writable.
|
||||
+#
|
||||
+# https://github.com/pypa/virtualenv/issues/2419
|
||||
+@pytest.mark.skipif("venv" not in CURRENT_CREATORS, reason="test needs venv creator")
|
||||
+def test_venv_creator_without_write_perms(tmp_path, mocker):
|
||||
+ from virtualenv.run.session import Session
|
||||
+
|
||||
+ prev = Session._create
|
||||
+
|
||||
+ def func(self):
|
||||
+ prev(self)
|
||||
+ scripts_dir = self.creator.dest / "bin"
|
||||
+ for script in scripts_dir.glob("*ctivate*"):
|
||||
+ script.chmod(stat.S_IREAD | stat.S_IRGRP | stat.S_IROTH)
|
||||
+
|
||||
+ mocker.patch("virtualenv.run.session.Session._create", side_effect=func, autospec=True)
|
||||
+
|
||||
+ cmd = [str(tmp_path), "--seeder", "app-data", "--without-pip", "--creator", "venv"]
|
||||
+ cli_run(cmd)
|
||||
--
|
||||
2.40.0
|
||||
|
Loading…
Reference in new issue