Skip to content

Commit

Permalink
expose and document programmatic API (#1592)
Browse files Browse the repository at this point in the history
Signed-off-by: Bernat Gabor <bgabor8@bloomberg.net>
  • Loading branch information
gaborbernat authored Feb 12, 2020
1 parent 80fe52f commit 77f0dd8
Show file tree
Hide file tree
Showing 19 changed files with 123 additions and 58 deletions.
1 change: 1 addition & 0 deletions docs/changelog/1585.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expose a programmatic API as ``from virtualenv import cli_run`` - by :user:`gaborbernat`.
2 changes: 2 additions & 0 deletions docs/changelog/1585.doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Document a programmatic API as ``from virtualenv import cli_run`` under :ref:`programmatic_api` -
by :user:`gaborbernat`.
2 changes: 1 addition & 1 deletion docs/render_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def build_rows(options):
names = option["name"]
default = option["default"]
if default is not None:
if isinstance(default, str) and default[0] == default[-1] and default[0] == '"':
if isinstance(default, str) and default and default[0] == default[-1] and default[0] == '"':
default = default[1:-1]
if default == SUPPRESS:
default = None
Expand Down
24 changes: 24 additions & 0 deletions docs/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,27 @@ also provisions a ``decativate`` command that will allow you to undo the operati
A longer explanation of this can be found within Allison Kaptur's 2013 blog post: `There's no magic: virtualenv
edition <https://www.recurse.com/blog/14-there-is-no-magic-virtualenv-edition>`_ explains how virtualenv uses bash and
Python and ``PATH`` and ``PYTHONHOME`` to isolate virtual environments' paths.

.. _programmatic_api:

Programmatic API
----------------

At the moment ``virtualenv`` offers only CLI level interface. If you want to trigger invocation of Python environments
from within Python you should be using the ``virtualenv.cli_run`` method; this takes an ``args`` argument where you can
pass the options the same way you would from the command line. The run will return a session object containing data
about the created virtual environment.

.. code-block:: python
from virtualenv import cli_run
cli_run(["venv"])
.. automodule:: virtualenv
:members:

.. currentmodule:: virtualenv.session

.. autoclass:: Session
:members:
6 changes: 5 additions & 1 deletion src/virtualenv/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from __future__ import absolute_import, unicode_literals

from .run import cli_run

This comment has been minimized.

Copy link
@zazaho

zazaho Feb 15, 2020

on my box this creates a circular import. If I move the import cli_run after the version import everything is fine.
Error message:
AttributeError: partially initialized module 'virtualenv' has no attribute 'version' (most likely due to a circular import)

This comment has been minimized.

Copy link
@gaborbernat

gaborbernat Feb 15, 2020

Author Contributor

That's strange, do you have the stack trace?

This comment has been minimized.

Copy link
@zazaho

zazaho Feb 15, 2020

i ran python setup.py build in the top level of the tar downloaded from pypi.

Traceback (most recent call last):
File "setup.py", line 3, in
setup()
File "/usr/lib/python3.8/site-packages/setuptools/init.py", line 144, in setup
return distutils.core.setup(**attrs)
File "/usr/lib64/python3.8/distutils/core.py", line 121, in setup
dist.parse_config_files()
File "/usr/lib/python3.8/site-packages/setuptools/dist.py", line 701, in parse_config_files
parse_configuration(self, self.command_options,
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 121, in parse_configuration
meta.parse()
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 426, in parse
section_parser_method(section_options)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 399, in parse_section
self[name] = value
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 184, in setitem
value = parser(value)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 515, in _parse_version
version = self._parse_attr(value, self.package_dir)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 349, in _parse_attr
module = import_module(module_name)
File "/usr/lib64/python3.8/importlib/init.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 1014, in _gcd_import
File "", line 991, in _find_and_load
File "", line 975, in _find_and_load_unlocked
File "", line 671, in _load_unlocked
File "", line 783, in exec_module
File "", line 219, in _call_with_frames_removed
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/init.py", line 3, in
from .run import cli_run
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/run/init.py", line 10, in
from .plugin.creators import CreatorSelector
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/run/plugin/creators.py", line 6, in
from virtualenv.create.via_global_ref.builtin.builtin_way import VirtualenvBuiltin
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/create/via_global_ref/builtin/builtin_way.py", line 7, in
from virtualenv.create.creator import Creator
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/create/creator.py", line 16, in
from virtualenv.discovery.cached_py_info import LogCmd
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/discovery/cached_py_info.py", line 27, in
_CACHE[Path(sys.executable)] = PythonInfo()
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/discovery/py_info.py", line 87, in init
self.distutils_install = {u(k): u(v) for k, v in self._distutils_install().items()}
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/discovery/py_info.py", line 113, in _distutils_install
d.parse_config_files()
File "/usr/lib/python3.8/site-packages/setuptools/dist.py", line 701, in parse_config_files
parse_configuration(self, self.command_options,
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 121, in parse_configuration
meta.parse()
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 426, in parse
section_parser_method(section_options)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 399, in parse_section
self[name] = value
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 184, in setitem
value = parser(value)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 515, in _parse_version
version = self._parse_attr(value, self.package_dir)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 350, in _parse_attr
value = getattr(module, attr_name)
AttributeError: partially initialized module 'virtualenv' has no attribute 'version' (most likely due to a circular import)
sacha@honeybox:/rpmbuild/STAGED/virtualenv-20.0.4$
sacha@honeybox:
/rpmbuild/STAGED/virtualenv-20.0.4$
sacha@honeybox:~/rpmbuild/STAGED/virtualenv-20.0.4$ python setup.py build
Traceback (most recent call last):
File "setup.py", line 3, in
setup()
File "/usr/lib/python3.8/site-packages/setuptools/init.py", line 144, in setup
return distutils.core.setup(**attrs)
File "/usr/lib64/python3.8/distutils/core.py", line 121, in setup
dist.parse_config_files()
File "/usr/lib/python3.8/site-packages/setuptools/dist.py", line 701, in parse_config_files
parse_configuration(self, self.command_options,
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 121, in parse_configuration
meta.parse()
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 426, in parse
section_parser_method(section_options)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 399, in parse_section
self[name] = value
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 184, in setitem
value = parser(value)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 515, in _parse_version
version = self._parse_attr(value, self.package_dir)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 349, in _parse_attr
module = import_module(module_name)
File "/usr/lib64/python3.8/importlib/init.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 1014, in _gcd_import
File "", line 991, in _find_and_load
File "", line 975, in _find_and_load_unlocked
File "", line 671, in _load_unlocked
File "", line 783, in exec_module
File "", line 219, in _call_with_frames_removed
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/init.py", line 3, in
from .run import cli_run
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/run/init.py", line 10, in
from .plugin.creators import CreatorSelector
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/run/plugin/creators.py", line 6, in
from virtualenv.create.via_global_ref.builtin.builtin_way import VirtualenvBuiltin
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/create/via_global_ref/builtin/builtin_way.py", line 7, in
from virtualenv.create.creator import Creator
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/create/creator.py", line 16, in
from virtualenv.discovery.cached_py_info import LogCmd
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/discovery/cached_py_info.py", line 27, in
_CACHE[Path(sys.executable)] = PythonInfo()
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/discovery/py_info.py", line 87, in init
self.distutils_install = {u(k): u(v) for k, v in self._distutils_install().items()}
File "/home/sacha/rpmbuild/STAGED/virtualenv-20.0.4/src/virtualenv/discovery/py_info.py", line 113, in _distutils_install
d.parse_config_files()
File "/usr/lib/python3.8/site-packages/setuptools/dist.py", line 701, in parse_config_files
parse_configuration(self, self.command_options,
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 121, in parse_configuration
meta.parse()
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 426, in parse
section_parser_method(section_options)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 399, in parse_section
self[name] = value
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 184, in setitem
value = parser(value)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 515, in _parse_version
version = self._parse_attr(value, self.package_dir)
File "/usr/lib/python3.8/site-packages/setuptools/config.py", line 350, in _parse_attr
value = getattr(module, attr_name)
AttributeError: partially initialized module 'virtualenv' has no attribute 'version' (most likely due to a circular import)

This comment has been minimized.

Copy link
@gaborbernat

gaborbernat Feb 15, 2020

Author Contributor

That's not supported, you should be using a tool that understands pep 517 and pep 518 like pip 19+🤷‍♀️ or ensure build dependencies are correct

from .version import __version__

__all__ = ("__version__", "run")
__all__ = (
"__version__",
"cli_run",
)
6 changes: 3 additions & 3 deletions src/virtualenv/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
def run(args=None, options=None):
start = datetime.now()
from virtualenv.error import ProcessCallFailed
from virtualenv.run import run_via_cli
from virtualenv.run import cli_run

if args is None:
args = sys.argv[1:]
try:
session = run_via_cli(args, options)
session = cli_run(args, options)
logging.warning(
"created virtual environment in %.0fms %s with seeder %s",
(datetime.now() - start).total_seconds() * 1000,
Expand All @@ -35,7 +35,7 @@ def run_with_catch(args=None):
try:
run(args, options)
except (KeyboardInterrupt, Exception) as exception:
if options.with_traceback:
if getattr(options, "with_traceback", False):
logging.shutdown() # force flush of log messages before the trace is printed
raise
else:
Expand Down
32 changes: 19 additions & 13 deletions src/virtualenv/config/ini.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

from .convert import convert

DEFAULT_CONFIG_FILE = default_config_dir() / "virtualenv.ini"


class IniConfig(object):
VIRTUALENV_CONFIG_FILE_ENV_VAR = six.ensure_str("VIRTUALENV_CONFIG_FILE")
Expand All @@ -24,18 +22,26 @@ class IniConfig(object):
def __init__(self):
config_file = os.environ.get(self.VIRTUALENV_CONFIG_FILE_ENV_VAR, None)
self.is_env_var = config_file is not None
self.config_file = Path(config_file) if config_file is not None else DEFAULT_CONFIG_FILE
self.config_file = Path(config_file) if config_file is not None else (default_config_dir() / "virtualenv.ini")
self._cache = {}
self.has_config_file = self.config_file.exists()
if self.has_config_file:
self.config_file = self.config_file.resolve()
self.config_parser = ConfigParser.ConfigParser()
try:
self._load()
self.has_virtualenv_section = self.config_parser.has_section(self.section)
except Exception as exception:
logging.error("failed to read config file %s because %r", config_file, exception)
self.has_config_file = None

exception = None
self.has_config_file = None
try:
self.has_config_file = self.config_file.exists()
except OSError as exc:
exception = exc
else:
if self.has_config_file:
self.config_file = self.config_file.resolve()
self.config_parser = ConfigParser.ConfigParser()
try:
self._load()
self.has_virtualenv_section = self.config_parser.has_section(self.section)
except Exception as exc:
exception = exc
if exception is not None:
logging.error("failed to read config file %s because %r", config_file, exception)

def _load(self):
with self.config_file.open("rt") as file_handler:
Expand Down
7 changes: 4 additions & 3 deletions src/virtualenv/run/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
from .plugin.seeders import SeederSelector


def run_via_cli(args, options=None):
"""Run the virtual environment creation via CLI arguments
def cli_run(args, options=None):
"""Create a virtual environment given some command line interface arguments
:param args: the command line arguments
:return: the creator used
:param options: passing in a ``argparse.Namespace`` object allows return of the parsed options
:return: the session object of the creation (its structure for now is experimental and might change on short notice)
"""
session = session_via_cli(args, options)
session.run()
Expand Down
37 changes: 32 additions & 5 deletions src/virtualenv/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,39 @@


class Session(object):
"""Represents a virtual environment creation session"""

def __init__(self, verbosity, interpreter, creator, seeder, activators):
self.verbosity = verbosity
self.interpreter = interpreter
self.creator = creator
self.seeder = seeder
self.activators = activators
self._verbosity = verbosity
self._interpreter = interpreter
self._creator = creator
self._seeder = seeder
self._activators = activators

@property
def verbosity(self):
"""The verbosity of the run"""
return self._verbosity

@property
def interpreter(self):
"""Create a virtual environment based on this reference interpreter"""
return self._interpreter

@property
def creator(self):
"""The creator used to build the virtual environment (must be compatible with the interpreter)"""
return self._creator

@property
def seeder(self):
"""The mechanism used to provide the seed packages (pip, setuptools, wheel)"""
return self._seeder

@property
def activators(self):
"""Activators used to generate activations scripts"""
return self._activators

def run(self):
self._create()
Expand Down
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ def ensure_py_info_cache_empty():


@pytest.fixture(autouse=True)
def ignore_global_config(tmp_path, mocker):
def ignore_global_config(tmp_path, mocker, monkeypatch):
mocker.patch("virtualenv.dirs._CFG_DIR", None)
mocker.patch("virtualenv.dirs.user_config_dir", return_value=tmp_path / "this-should-never-exist")
mocker.patch("virtualenv.dirs.user_config_dir", return_value=Path(str(tmp_path / "this-should-never-exist")))
yield


Expand Down
6 changes: 3 additions & 3 deletions tests/integration/test_zipapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import six

from virtualenv.discovery.py_info import PythonInfo
from virtualenv.run import run_via_cli
from virtualenv.run import cli_run
from virtualenv.util.path import Path

HERE = Path(__file__).parent
Expand All @@ -28,7 +28,7 @@ def zipapp_build_env(tmp_path_factory):
for version in range(8, 4, -1):
try:
# create a virtual environment which is also guaranteed to contain a recent enough pip (bundled)
session = run_via_cli(
session = cli_run(
["-vvv", "-p", "{}3.{}".format(impl, version), "--activators", "", str(create_env_path)]
)
exe = str(session.creator.exe)
Expand Down Expand Up @@ -61,7 +61,7 @@ def zipapp(zipapp_build_env, tmp_path_factory):
@pytest.fixture(scope="session")
def zipapp_test_env(tmp_path_factory):
base_path = tmp_path_factory.mktemp("zipapp-test")
session = run_via_cli(["-v", "--activators", "", "--without-pip", str(base_path / "env")])
session = cli_run(["-v", "--activators", "", "--without-pip", str(base_path / "env")])
yield session.creator.exe
shutil.rmtree(str(base_path))

Expand Down
4 changes: 2 additions & 2 deletions tests/unit/activation/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import six

from virtualenv.info import IS_PYPY, WIN_CPYTHON_2
from virtualenv.run import run_via_cli
from virtualenv.run import cli_run
from virtualenv.util.path import Path
from virtualenv.util.subprocess import Popen

Expand Down Expand Up @@ -207,7 +207,7 @@ def raise_on_non_source_class():
@pytest.fixture(scope="session")
def activation_python(tmp_path_factory, special_char_name, current_fastest):
dest = os.path.join(six.ensure_text(str(tmp_path_factory.mktemp("activation-tester-env"))), special_char_name)
session = run_via_cli(["--without-pip", dest, "--prompt", special_char_name, "--creator", current_fastest, "-vv"])
session = cli_run(["--without-pip", dest, "--prompt", special_char_name, "--creator", current_fastest, "-vv"])
pydoc_test = session.creator.purelib / "pydoc_test.py"
pydoc_test.write_text('"""This is pydoc_test.py"""')
yield session
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/create/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import pytest

from virtualenv.discovery.py_info import PythonInfo
from virtualenv.run import run_via_cli
from virtualenv.run import cli_run
from virtualenv.util.path import Path
from virtualenv.util.subprocess import Popen

Expand Down Expand Up @@ -45,7 +45,7 @@ def old_virtualenv(tmp_path_factory):
return CURRENT.executable
else:
env_for_old_virtualenv = tmp_path_factory.mktemp("env-for-old-virtualenv")
result = run_via_cli(["--no-download", "--activators", "", str(env_for_old_virtualenv)])
result = cli_run(["--no-download", "--activators", "", str(env_for_old_virtualenv)])
# noinspection PyBroadException
try:
process = Popen(
Expand Down
20 changes: 10 additions & 10 deletions tests/unit/create/test_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
import pytest
import six

from virtualenv.__main__ import run
from virtualenv.__main__ import run, run_with_catch
from virtualenv.create.creator import DEBUG_SCRIPT, Creator, get_env_debug_info
from virtualenv.discovery.builtin import get_interpreter
from virtualenv.discovery.py_info import PythonInfo
from virtualenv.info import IS_PYPY, fs_supports_symlink
from virtualenv.pyenv_cfg import PyEnvCfg
from virtualenv.run import run_via_cli, session_via_cli
from virtualenv.run import cli_run, session_via_cli
from virtualenv.util.path import Path

CURRENT = PythonInfo.current_system()
Expand All @@ -38,7 +38,7 @@ def test_os_path_sep_not_allowed(tmp_path, capsys, sep):

def _non_success_exit_code(capsys, target):
with pytest.raises(SystemExit) as context:
run_via_cli(args=[target])
run_with_catch(args=[target])
assert context.value.code != 0
out, err = capsys.readouterr()
assert not out, out
Expand Down Expand Up @@ -126,7 +126,7 @@ def test_create_no_seed(python, creator, isolated, system, coverage_env, special
]
if isolated == "global":
cmd.append("--system-site-packages")
result = run_via_cli(cmd)
result = cli_run(cmd)
coverage_env()
if IS_PYPY:
# pypy cleans up file descriptors periodically so our (many) subprocess calls impact file descriptor limits
Expand Down Expand Up @@ -202,7 +202,7 @@ def _session_via_cli(args, options=None):
@pytest.mark.skipif(not sys.version_info[0] == 2, reason="python 2 only tests")
def test_debug_bad_virtualenv(tmp_path):
cmd = [str(tmp_path), "--without-pip"]
result = run_via_cli(cmd)
result = cli_run(cmd)
# if the site.py is removed/altered the debug should fail as no one is around to fix the paths
site_py = result.creator.stdlib / "site.py"
site_py.unlink()
Expand All @@ -223,12 +223,12 @@ def test_create_clear_resets(tmp_path, creator, clear, caplog):
pytest.skip("venv without clear might fail")
marker = tmp_path / "magic"
cmd = [str(tmp_path), "--seeder", "app-data", "--without-pip", "--creator", creator, "-vvv"]
run_via_cli(cmd)
cli_run(cmd)

marker.write_text("") # if we a marker file this should be gone on a clear run, remain otherwise
assert marker.exists()

run_via_cli(cmd + (["--clear"] if clear else []))
cli_run(cmd + (["--clear"] if clear else []))
assert marker.exists() is not clear


Expand All @@ -239,7 +239,7 @@ def test_prompt_set(tmp_path, creator, prompt):
if prompt is not None:
cmd.extend(["--prompt", "magic"])

result = run_via_cli(cmd)
result = cli_run(cmd)
actual_prompt = tmp_path.name if prompt is None else prompt
cfg = PyEnvCfg.from_file(result.creator.pyenv_cfg.path)
if prompt is None:
Expand Down Expand Up @@ -276,7 +276,7 @@ def test_cross_major(cross_python, coverage_env, tmp_path, current_fastest):
"--creator",
current_fastest,
]
result = run_via_cli(cmd)
result = cli_run(cmd)
coverage_env()
env = PythonInfo.from_exe(str(result.creator.exe))
assert env.version_info.major != CURRENT.version_info.major
Expand Down Expand Up @@ -312,5 +312,5 @@ def test_create_long_path(current_fastest, tmp_path):
folder.mkdir(parents=True)

cmd = [str(folder)]
result = run_via_cli(cmd)
result = cli_run(cmd)
subprocess.check_call([str(result.creator.script("pip")), "--version"])
6 changes: 3 additions & 3 deletions tests/unit/create/test_interpreters.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
import pytest

from virtualenv.discovery.py_info import PythonInfo
from virtualenv.run import run_via_cli
from virtualenv.run import cli_run


@pytest.mark.slow
def test_failed_to_find_bad_spec():
of_id = uuid4().hex
with pytest.raises(RuntimeError) as context:
run_via_cli(["-p", of_id])
cli_run(["-p", of_id])
msg = repr(RuntimeError("failed to find interpreter for Builtin discover of python_spec={!r}".format(of_id)))
assert repr(context.value) == msg

Expand All @@ -22,7 +22,7 @@ def test_failed_to_find_bad_spec():
def test_failed_to_find_implementation(of_id, mocker):
mocker.patch("virtualenv.run.plugin.creators.CreatorSelector._OPTIONS", return_value={})
with pytest.raises(RuntimeError) as context:
run_via_cli(["-p", of_id])
cli_run(["-p", of_id])
assert repr(context.value) == repr(
RuntimeError("No virtualenv implementation for {}".format(PythonInfo.current_system()))
)
6 changes: 3 additions & 3 deletions tests/unit/seed/test_boostrap_link_via_app_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from virtualenv.discovery.py_info import PythonInfo
from virtualenv.info import fs_supports_symlink
from virtualenv.run import run_via_cli
from virtualenv.run import cli_run
from virtualenv.seed.embed.wheels import BUNDLE_SUPPORT
from virtualenv.seed.embed.wheels.acquire import BUNDLE_FOLDER
from virtualenv.util.subprocess import Popen
Expand Down Expand Up @@ -37,7 +37,7 @@ def test_base_bootstrap_link_via_app_data(tmp_path, coverage_env, current_fastes
]
if not copies:
create_cmd.append("--symlink-app-data")
result = run_via_cli(create_cmd)
result = cli_run(create_cmd)
coverage_env()
assert result

Expand Down Expand Up @@ -82,7 +82,7 @@ def test_base_bootstrap_link_via_app_data(tmp_path, coverage_env, current_fastes
assert setuptools not in files_post_first_uninstall

# check we can run it again and will work - checks both overwrite and reuse cache
result = run_via_cli(create_cmd)
result = cli_run(create_cmd)
coverage_env()
assert result
files_post_second_create = list(site_package.iterdir())
Expand Down
Loading

0 comments on commit 77f0dd8

Please sign in to comment.