diff --git a/pyproject.toml b/pyproject.toml index 266bd2e..ab307d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,6 +98,7 @@ lint.ignore = [ "D301", # Use `r"""` if any backslashes in a docstring "D401", # First line of docstring should be in imperative mood "DOC201", # no support for sphinx + "DOC501", # no support for sphinx https://github.com/astral-sh/ruff/issues/12520 "ISC001", # Conflict with formatter "S104", # Possible binding to all interface ] diff --git a/src/tox_uv/_installer.py b/src/tox_uv/_installer.py index b2ef47b..6d07809 100644 --- a/src/tox_uv/_installer.py +++ b/src/tox_uv/_installer.py @@ -33,6 +33,7 @@ class UvInstaller(Pip): def __init__(self, tox_env: Python, with_list_deps: bool = True) -> None: # noqa: FBT001, FBT002 self._with_list_deps = with_list_deps + self._pkg_manager = "uv" super().__init__(tox_env) def freeze_cmd(self) -> list[str]: @@ -67,6 +68,21 @@ def default_install_command(self, conf: Config, env_name: str | None) -> Command return Command(cmd) def post_process_install_command(self, cmd: Command) -> Command: + """Returns uv or pip based on current config. + + Returns: + A string, uv or pip currently. + Raises: + RuntimeError: if unexpected a data is found in config. + """ + install_cmd = cmd.args + # uv pip command does not have same option named for reinstall and we want to allow users that use original + # 'pip' in their install_command to still be able to make use of it. + if len(install_cmd) < 1 or not isinstance(install_cmd[0], str): # pragma: no cover + msg = f"Unable to determine install command. {install_cmd}" + raise RuntimeError(msg) + self._pkg_manager = "uv" if install_cmd[0].endswith("uv") else "pip" + install_command = cmd.args pip_pre: bool = self._env.conf["pip_pre"] uv_resolution: str = self._env.conf["uv_resolution"] @@ -74,7 +90,7 @@ def post_process_install_command(self, cmd: Command) -> Command: opts_at = install_command.index("{opts}") except ValueError: if pip_pre: - install_command.extend(("--prerelease", "allow")) + install_command.extend(("--prerelease", "allow") if self._pkg_manager == "uv" else ("--pre",)) if uv_resolution: install_command.extend(("--resolution", uv_resolution)) else: @@ -136,7 +152,7 @@ def _install_list_of_deps( # noqa: C901, PLR0912 new_deps = sorted(set(groups["req"]) - set(old or [])) if new_deps: # pragma: no branch self._execute_installer(new_deps, req_of_type) - install_args = ["--reinstall"] + install_args = ["--reinstall"] if self._pkg_manager == "uv" else ["--force-reinstall"] if groups["uv"]: self._execute_installer(install_args + groups["uv"], of_type) if groups["uv_editable"]: diff --git a/tests/test_tox_uv_installer.py b/tests/test_tox_uv_installer.py index 828dcff..4a137a8 100644 --- a/tests/test_tox_uv_installer.py +++ b/tests/test_tox_uv_installer.py @@ -36,6 +36,29 @@ def test_uv_install_with_pre(tox_project: ToxProjectCreator) -> None: result.assert_success() +def test_uv_install_with_pre_custom_install_cmd_using_original_pip(tox_project: ToxProjectCreator) -> None: + project = tox_project({ + "tox.ini": """ + [testenv] + deps = tomli + pip_pre = true + package = skip + uv_seed = true + commands = python -c 'import tomli' + + [testenv:a] + + [testenv:b] + install_command = python3 -m pip install {packages} + + [testenv:c] + install_command = uv pip install {packages} + """ + }) + result = project.run("r", "-v", "-e", "a,b,c") + result.assert_success() + + def test_uv_install_with_pre_custom_install_cmd(tox_project: ToxProjectCreator) -> None: project = tox_project({ "tox.ini": """