From 4eed8d5135e6c2f04c7779354b262c86ae90d898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Wed, 4 Jan 2023 16:10:30 -0800 Subject: [PATCH] Fix devenv when package for env is wheel/editable (#2820) Resolves https://github.com/tox-dev/tox/issues/2815 --- docs/changelog/2815.bugfix.rst | 1 + src/tox/config/main.py | 4 ++++ src/tox/session/cmd/devenv.py | 16 ++++++++-------- tests/session/cmd/test_devenv.py | 9 ++++++--- 4 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 docs/changelog/2815.bugfix.rst diff --git a/docs/changelog/2815.bugfix.rst b/docs/changelog/2815.bugfix.rst new file mode 100644 index 000000000..2188b01e3 --- /dev/null +++ b/docs/changelog/2815.bugfix.rst @@ -0,0 +1 @@ +``devenv`` does not respect the specified path when the package is a wheel file - by :user:`gaborbernat`. diff --git a/src/tox/config/main.py b/src/tox/config/main.py index 00aaaed81..ce25bccf1 100644 --- a/src/tox/config/main.py +++ b/src/tox/config/main.py @@ -7,6 +7,7 @@ from tox.config.loader.api import Loader, OverrideMap +from .loader.memory import MemoryLoader from .loader.section import Section from .sets import ConfigSet, CoreConfigSet, EnvConfigSet from .source import Source @@ -41,6 +42,7 @@ def __init__( self._src = config_source self._key_to_conf_set: dict[tuple[str, str], ConfigSet] = OrderedDict() self._core_set: CoreConfigSet | None = None + self.memory_seed_loaders: defaultdict[str, list[MemoryLoader]] = defaultdict(list) def pos_args(self, to_path: Path | None) -> tuple[str, ...] | None: """ @@ -132,6 +134,8 @@ def get_section_config( except KeyError: conf_set = of_type(self, section, for_env) self._key_to_conf_set[key] = conf_set + if for_env is not None: + conf_set.loaders.extend(self.memory_seed_loaders.get(for_env, [])) for loader in self._src.get_loaders(section, base, self._overrides, conf_set): conf_set.loaders.append(loader) if loaders is not None: diff --git a/src/tox/session/cmd/devenv.py b/src/tox/session/cmd/devenv.py index ff98180ac..5ff28ad5d 100644 --- a/src/tox/session/cmd/devenv.py +++ b/src/tox/session/cmd/devenv.py @@ -17,31 +17,31 @@ def tox_add_option(parser: ToxParser) -> None: help_msg = "sets up a development environment at ENVDIR based on the tox configuration specified " our = parser.add_command("devenv", ["d"], help_msg, devenv) - our.add_argument("devenv_path", metavar="path", default=Path("venv").absolute(), nargs="?") + our.add_argument("devenv_path", metavar="path", default=Path("venv"), nargs="?", type=Path) register_env_select_flags(our, default=CliEnv("py"), multiple=False) env_run_create_flags(our, mode="devenv") def devenv(state: State) -> int: opt = state.conf.options + opt.devenv_path = opt.devenv_path.absolute() opt.skip_missing_interpreters = False # the target python must exist opt.no_test = False # do not run the test suite opt.package_only = False opt.install_pkg = None # no explicit packages to install opt.skip_pkg_install = False # always install a package in this case opt.no_test = True # do not run the test phase + loader = MemoryLoader( # these configuration values are loaded from in-memory always (no file conf) + usedevelop=True, # dev environments must be of type dev + env_dir=opt.devenv_path, # move it in source + ) + state.conf.memory_seed_loaders[list(opt.env)[0]].append(loader) state.envs.ensure_only_run_env_is_active() envs = list(state.envs.iter()) if len(envs) != 1: raise HandledError(f"exactly one target environment allowed in devenv mode but found {', '.join(envs)}") - loader = MemoryLoader( # these configuration values are loaded from in-memory always (no file conf) - usedevelop=True, # dev environments must be of type dev - env_dir=Path(opt.devenv_path), # move it in source - ) - tox_env = state.envs[envs[0]] - tox_env.conf.loaders.insert(0, loader) result = run_sequential(state) if result == 0: - logging.warning(f"created development environment under {tox_env.conf['env_dir']}") + logging.warning(f"created development environment under {opt.devenv_path}") return result diff --git a/tests/session/cmd/test_devenv.py b/tests/session/cmd/test_devenv.py index aba3e261a..de6a25379 100644 --- a/tests/session/cmd/test_devenv.py +++ b/tests/session/cmd/test_devenv.py @@ -6,15 +6,18 @@ def test_devenv_fail_multiple_target(tox_project: ToxProjectCreator) -> None: - outcome = tox_project({"tox.ini": ""}).run("d", "-e", "py39,py38") + outcome = tox_project({"tox.ini": ""}).run("d", "-e", "a,b") outcome.assert_failed() - msg = "ROOT: HandledError| exactly one target environment allowed in devenv mode but found py39, py38\n" + msg = "ROOT: HandledError| exactly one target environment allowed in devenv mode but found a, b\n" outcome.assert_out_err(msg, "") @pytest.mark.integration() def test_devenv_ok(tox_project: ToxProjectCreator, enable_pip_pypi_access: str | None) -> None: # noqa: U100 - content = {"setup.py": "from setuptools import setup\nsetup(name='demo', version='1.0')"} + content = { + "setup.py": "from setuptools import setup\nsetup(name='demo', version='1.0')", + "tox.ini": "[tox]\nenv_list = py\n[testenv]\nusedevelop = True", + } project = tox_project(content) outcome = project.run("d", "-e", "py")