Skip to content

Commit

Permalink
refactor: delegate to uv's built-in packaging and dependency handling
Browse files Browse the repository at this point in the history
Fixes #151
  • Loading branch information
paveldikov committed Feb 19, 2025
1 parent 53e0631 commit 8fb3dae
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 3 deletions.
19 changes: 17 additions & 2 deletions src/tox_uv/_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import itertools
import logging
from collections import defaultdict
from collections.abc import Sequence
Expand All @@ -16,6 +17,8 @@
from tox.tox_env.python.pip.req_file import PythonDeps
from uv import find_uv_bin

from ._package_types import UvFromDirEditablePackage, UvFromDirPackage

if TYPE_CHECKING:
from tox.config.main import Config
from tox.tox_env.package import PathPackage
Expand Down Expand Up @@ -94,7 +97,7 @@ def install(self, arguments: Any, section: str, of_type: str) -> None: # noqa:
_LOGGER.warning("uv cannot install %r", arguments) # pragma: no cover
raise SystemExit(1) # pragma: no cover

def _install_list_of_deps( # noqa: C901
def _install_list_of_deps( # noqa: C901, PLR0912
self,
arguments: Sequence[
Requirement | WheelPackage | SdistPackage | EditableLegacyPackage | EditablePackage | PathPackage
Expand All @@ -114,6 +117,12 @@ def _install_list_of_deps( # noqa: C901
elif isinstance(arg, EditableLegacyPackage):
groups["req"].extend(str(i) for i in arg.deps)
groups["dev_pkg"].append(str(arg.path))
elif isinstance(arg, UvFromDirPackage):
extras_suffix = f"[{','.join(arg.extras)}]" if arg.extras else ""
groups["pkg_from_dir"].append(f"{arg.path}{extras_suffix}")
elif isinstance(arg, UvFromDirEditablePackage):
extras_suffix = f"[{','.join(arg.extras)}]" if arg.extras else ""
groups["dev_pkg_from_dir"].append(f"{arg.path}{extras_suffix}")
else: # pragma: no branch
_LOGGER.warning("uv install %r", arg) # pragma: no cover
raise SystemExit(1) # pragma: no cover
Expand All @@ -129,7 +138,13 @@ def _install_list_of_deps( # noqa: C901
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", "--no-deps"]
install_args = ["--reinstall"]
if groups["pkg_from_dir"]:
self._execute_installer(install_args + groups["pkg_from_dir"], of_type)
if groups["dev_pkg_from_dir"]:
requirements = list(itertools.chain.from_iterable(("-e", entry) for entry in groups["dev_pkg_from_dir"]))
self._execute_installer(install_args + requirements, of_type)
install_args.append("--no-deps")
if groups["pkg"]:
self._execute_installer(install_args + groups["pkg"], of_type)
if groups["dev_pkg"]:
Expand Down
19 changes: 19 additions & 0 deletions src/tox_uv/_package.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from tox.tox_env.python.virtual_env.package.cmd_builder import VenvCmdBuilder
from tox.tox_env.python.virtual_env.package.pyproject import Pep517VenvPackager

if TYPE_CHECKING:
from tox.config.sets import EnvConfigSet
from tox.tox_env.package import Package

from ._package_types import UvFromDirEditablePackage, UvFromDirPackage
from ._venv import UvVenv


Expand All @@ -11,6 +18,18 @@ class UvVenvPep517Packager(Pep517VenvPackager, UvVenv):
def id() -> str:
return "uv-venv-pep-517"

def perform_packaging(self, for_env: EnvConfigSet) -> list[Package]:
of_type: str = for_env["package"]
types = {
"from-dir": UvFromDirPackage,
"from-dir-editable": UvFromDirEditablePackage,
}
if of_type not in types:
return super().perform_packaging(for_env)

extras: list[str] = for_env["extras"]
return [types[of_type](self.core["tox_root"], extras)]


class UvVenvCmdBuilder(VenvCmdBuilder, UvVenv):
@staticmethod
Expand Down
31 changes: 31 additions & 0 deletions src/tox_uv/_package_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from tox.tox_env.python.package import PythonPathPackageWithDeps

if TYPE_CHECKING:
import pathlib
from collections.abc import Sequence


class UvFromDirPackage(PythonPathPackageWithDeps):
"""Package to be built and installed by uv directly."""

def __init__(self, path: pathlib.Path, extras: Sequence[str]) -> None:
super().__init__(path, ())
self.extras = extras


class UvFromDirEditablePackage(PythonPathPackageWithDeps):
"""Package to be built and editably installed by uv directly."""

def __init__(self, path: pathlib.Path, extras: Sequence[str]) -> None:
super().__init__(path, ())
self.extras = extras


__all__ = [
"UvFromDirEditablePackage",
"UvFromDirPackage",
]
4 changes: 4 additions & 0 deletions src/tox_uv/_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def default_pkg_type(self) -> str:
return "skip"
return super().default_pkg_type

@property
def _package_types(self) -> tuple[str, ...]:
return (*super()._package_types, "from-dir", "from-dir-editable")


__all__ = [
"UvVenvRunner",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_tox_uv_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def test_uv_package_use_default_from_file(tox_project: ToxProjectCreator) -> Non


@pytest.mark.parametrize("with_dash", [True, False], ids=["name_dash", "name_underscore"])
@pytest.mark.parametrize("package", ["sdist", "wheel", "editable"])
@pytest.mark.parametrize("package", ["sdist", "wheel", "editable", "from-dir", "from-dir-editable"])
def test_uv_package_artifact(
tox_project: ToxProjectCreator, package: str, demo_pkg_inline: Path, with_dash: bool
) -> None:
Expand Down

0 comments on commit 8fb3dae

Please sign in to comment.