• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 25405422172

05 May 2026 10:18PM UTC coverage: 92.879% (-0.07%) from 92.944%
25405422172

Pull #23319

github

web-flow
Merge c82d0f333 into e8b784f89
Pull Request #23319: [pants_ng] Scaffolding for a pants_ng mode.

25 of 76 new or added lines in 9 files covered. (32.89%)

209 existing lines in 15 files now uncovered.

92234 of 99306 relevant lines covered (92.88%)

4.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.18
/src/python/pants/backend/python/subsystems/uv.py
1
# Copyright 2026 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
12✔
5

6
import os
12✔
7
from dataclasses import dataclass
12✔
8
from typing import ClassVar
12✔
9

10
from pants.core.util_rules.external_tool import (
12✔
11
    TemplatedExternalTool,
12
    download_external_tool,
13
)
14
from pants.engine.fs import Digest
12✔
15
from pants.engine.internals.native_engine import FrozenDict
12✔
16
from pants.engine.platform import Platform
12✔
17
from pants.engine.rules import collect_rules, rule
12✔
18
from pants.option.option_types import StrListOption
12✔
19
from pants.option.subsystem import Subsystem
12✔
20
from pants.util.memo import memoized_property
12✔
21
from pants.util.ordered_set import OrderedSet
12✔
22
from pants.util.strutil import softwrap
12✔
23

24

25
class Uv(TemplatedExternalTool):
12✔
26
    options_scope = "uv"
12✔
27
    name = "uv"
12✔
28
    help = "The uv Python package manager (https://github.com/astral-sh/uv)."
12✔
29

30
    default_version = "0.11.6"
12✔
31
    default_known_versions = [
12✔
32
        "0.11.6|macos_arm64 |4b69a4e366ec38cd5f305707de95e12951181c448679a00dce2a78868dfc9f5b|20807020",
33
        "0.11.6|linux_x86_64|aa342a53abe42364093506d7704214d2cdca30b916843e520bc67759a5d20132|24460747",
34
        "0.11.6|linux_arm64 |d14ebd6f200047264152daaf97b8bd36c7885a5033e9e8bba8366cb0049c0d00|22576913",
35
    ]
36
    version_constraints = ">=0.7.4,<1.0"
12✔
37

38
    default_url_template = (
12✔
39
        "https://github.com/astral-sh/uv/releases/download/{version}/uv-{platform}.tar.gz"
40
    )
41
    default_url_platform_mapping = {
12✔
42
        "linux_arm64": "aarch64-unknown-linux-musl",
43
        "linux_x86_64": "x86_64-unknown-linux-musl",
44
        "macos_arm64": "aarch64-apple-darwin",
45
    }
46

47
    def generate_exe(self, plat: Platform) -> str:
12✔
48
        platform = self.default_url_platform_mapping[plat.value]
2✔
49
        return f"./uv-{platform}/uv"
2✔
50

51
    class EnvironmentAware(Subsystem.EnvironmentAware):
12✔
52
        env_vars_used_by_options = ("PATH",)
12✔
53

54
        _executable_search_paths = StrListOption(
12✔
55
            default=["<PATH>"],
56
            help=softwrap(
57
                """
58
                The PATH value that will be used by the uv subprocess and any subprocesses it
59
                spawns.
60

61
                The special string `"<PATH>"` will expand to the contents of the PATH env var.
62
                """
63
            ),
64
            advanced=True,
65
            metavar="<binary-paths>",
66
        )
67

68
        @memoized_property
12✔
69
        def path(self) -> tuple[str, ...]:
12✔
70
            def iter_path_entries():
2✔
71
                for entry in self._executable_search_paths:
2✔
72
                    if entry == "<PATH>":
2✔
73
                        path = self._options_env.get("PATH")
2✔
74
                        if path:
2✔
75
                            yield from path.split(os.pathsep)
2✔
76
                    else:
UNCOV
77
                        yield entry
×
78

79
            return tuple(OrderedSet(iter_path_entries()))
2✔
80

81

82
@dataclass(frozen=True)
12✔
83
class DownloadedUv:
12✔
84
    digest: Digest
12✔
85
    exe: str
12✔
86

87
    # The relpath to the named_cache inside the sandbox.
88
    cache_dir: ClassVar[str] = ".cache/uv_cache/"
12✔
89

90
    # Initial command line args for all invocations of this uv.
91
    # Callers will want to add further args for specific invocations.
92
    def args(self) -> tuple[str, ...]:
12✔
93
        return (
2✔
94
            self.exe,
95
            # --no-config suppresses user and host config discovery.
96
            "--no-config",
97
            # --config-file forces use of our generated uv.toml instead.
98
            "--config-file=uv.toml",
99
            f"--cache-dir={self.cache_dir}",
100
        )
101

102
    @classmethod
12✔
103
    def append_only_caches(cls) -> FrozenDict[str, str]:
12✔
104
        return FrozenDict({"uv_cache": cls.cache_dir})
2✔
105

106

107
@rule
12✔
108
async def download_uv_binary(uv: Uv, platform: Platform) -> DownloadedUv:
12✔
109
    downloaded = await download_external_tool(uv.get_request(platform))
2✔
110
    return DownloadedUv(
2✔
111
        digest=downloaded.digest,
112
        exe=downloaded.exe,
113
    )
114

115

116
def rules():
12✔
117
    return collect_rules()
12✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc