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

pantsbuild / pants / 18198316586

02 Oct 2025 03:50PM UTC coverage: 78.82% (-1.4%) from 80.265%
18198316586

push

github

web-flow
Bump serde from 1.0.226 to 1.0.228 in /src/rust (#22723)

Bumps [serde](https://github.com/serde-rs/serde) from 1.0.226 to
1.0.228.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/serde-rs/serde/releases">serde's
releases</a>.</em></p>
<blockquote>
<h2>v1.0.228</h2>
<ul>
<li>Allow building documentation with
<code>RUSTDOCFLAGS='--cfg=docsrs'</code> set for the whole dependency
graph (<a
href="https://redirect.github.com/serde-rs/serde/issues/2995">#2995</a>)</li>
</ul>
<h2>v1.0.227</h2>
<ul>
<li>Documentation improvements (<a
href="https://redirect.github.com/serde-rs/serde/issues/2991">#2991</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/serde-rs/serde/commit/a866b336f"><code>a866b33</code></a>
Release 1.0.228</li>
<li><a
href="https://github.com/serde-rs/serde/commit/5adc9e816"><code>5adc9e8</code></a>
Merge pull request <a
href="https://redirect.github.com/serde-rs/serde/issues/2995">#2995</a>
from dtolnay/rustdocflags</li>
<li><a
href="https://github.com/serde-rs/serde/commit/ab581789f"><code>ab58178</code></a>
Workaround for RUSTDOCFLAGS='--cfg=docsrs'</li>
<li><a
href="https://github.com/serde-rs/serde/commit/415d9fc56"><code>415d9fc</code></a>
Release 1.0.227</li>
<li><a
href="https://github.com/serde-rs/serde/commit/7c58427e1"><code>7c58427</code></a>
Merge pull request <a
href="https://redirect.github.com/serde-rs/serde/issues/2991">#2991</a>
from dtolnay/inlinecoredoc</li>
<li><a
href="https://github.com/serde-rs/serde/commit/9d3410e3f"><code>9d3410e</code></a>
Merge pull request <a
href="https://redirect.github.com/serde-rs/serde/issues/2992">#2992</a>
from dtolnay/inplaceseed</li>
<li><a
href="https://github.com/serde-rs/serde/commit/2fb6748bf1ff93... (continued)

73576 of 93347 relevant lines covered (78.82%)

2.9 hits per line

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

69.35
/src/python/pants/core/util_rules/adhoc_binaries.py
1
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
10✔
5

6
import os
10✔
7
import sys
10✔
8
from dataclasses import dataclass
10✔
9
from textwrap import dedent  # noqa: PNT20
10✔
10

11
from pants.core.environments.target_types import EnvironmentTarget
10✔
12
from pants.core.subsystems.python_bootstrap import PythonBootstrapSubsystem
10✔
13
from pants.core.util_rules.system_binaries import BashBinary, SystemBinariesSubsystem, TarBinary
10✔
14
from pants.engine.download_file import download_file
10✔
15
from pants.engine.fs import DownloadFile
10✔
16
from pants.engine.internals.native_engine import FileDigest
10✔
17
from pants.engine.platform import Platform
10✔
18
from pants.engine.process import Process, ProcessCacheScope, execute_process_or_raise
10✔
19
from pants.engine.rules import collect_rules, implicitly, rule
10✔
20
from pants.util.frozendict import FrozenDict
10✔
21
from pants.util.logging import LogLevel
10✔
22

23

24
@dataclass(frozen=True)
10✔
25
class PythonBuildStandaloneBinary:
10✔
26
    """A Python interpreter for use by `@rule` code as an alternative to BashBinary scripts.
27

28
    This interpreter is provided by Python Build Standalone https://gregoryszorc.com/docs/python-build-standalone/main/,
29
    which has a few caveats. Namely it doesn't play nicely with third-party sdists. Meaning Pants'
30
    scripts being run by Python Build Standalone should avoid third-party sdists.
31
    """
32

33
    _CACHE_DIRNAME = "python_build_standalone"
10✔
34
    _SYMLINK_DIRNAME = ".python-build-standalone"
10✔
35
    APPEND_ONLY_CACHES = FrozenDict({_CACHE_DIRNAME: _SYMLINK_DIRNAME})
10✔
36

37
    path: str  # The absolute path to a Python executable
10✔
38

39

40
# NB: These private types are solely so we can test the docker-path using the local
41
# environment.
42
class _PythonBuildStandaloneBinary(PythonBuildStandaloneBinary):
10✔
43
    pass
10✔
44

45

46
class _DownloadPythonBuildStandaloneBinaryRequest:
10✔
47
    pass
10✔
48

49

50
@rule(desc="Downloading Python for scripts", level=LogLevel.TRACE)
10✔
51
async def download_python_binary(
10✔
52
    _: _DownloadPythonBuildStandaloneBinaryRequest,
53
    platform: Platform,
54
    tar_binary: TarBinary,
55
    bash_binary: BashBinary,
56
    python_bootstrap: PythonBootstrapSubsystem,
57
    system_binaries_environment: SystemBinariesSubsystem.EnvironmentAware,
58
) -> _PythonBuildStandaloneBinary:
59
    url, fingerprint, bytelen = python_bootstrap.internal_python_build_standalone_info[
×
60
        platform.value
61
    ]
62

63
    filename = url.rsplit("/", 1)[-1]
×
64
    python_archive = await download_file(
×
65
        DownloadFile(
66
            url,
67
            FileDigest(
68
                fingerprint=fingerprint,
69
                serialized_bytes_length=bytelen,
70
            ),
71
        ),
72
        **implicitly(),
73
    )
74

75
    download_result = await execute_process_or_raise(
×
76
        **implicitly(
77
            Process(
78
                argv=[tar_binary.path, "-xvf", filename],
79
                input_digest=python_archive,
80
                env={"PATH": os.pathsep.join(system_binaries_environment.system_binary_paths)},
81
                description="Extract Pants' execution Python",
82
                level=LogLevel.DEBUG,
83
                output_directories=("python",),
84
            )
85
        )
86
    )
87

88
    installation_root = f"{PythonBuildStandaloneBinary._SYMLINK_DIRNAME}/{download_result.output_digest.fingerprint}"
×
89

90
    # NB: This is similar to what we do for every Python provider. We should refactor these into
91
    # some shared code to centralize the behavior.
92
    installation_script = dedent(
×
93
        f"""\
94
        if [ ! -f "{installation_root}/DONE" ]; then
95
            cp -r python "{installation_root}"
96
            touch "{installation_root}/DONE"
97
        fi
98
        echo "$(realpath "{installation_root}")/bin/python3"
99
    """
100
    )
101

102
    result = await execute_process_or_raise(
×
103
        **implicitly(
104
            Process(
105
                [bash_binary.path, "-c", installation_script],
106
                level=LogLevel.DEBUG,
107
                input_digest=download_result.output_digest,
108
                description="Install Python for Pants usage",
109
                env={"PATH": os.pathsep.join(system_binaries_environment.system_binary_paths)},
110
                append_only_caches=PythonBuildStandaloneBinary.APPEND_ONLY_CACHES,
111
                # Don't cache, we want this to always be run so that we can assume for the rest of the
112
                # session the named_cache destination for this Python is valid, as the Python ecosystem
113
                # mainly assumes absolute paths for Python interpreters.
114
                cache_scope=ProcessCacheScope.PER_SESSION,
115
            )
116
        )
117
    )
118

119
    return _PythonBuildStandaloneBinary(result.stdout.decode().splitlines()[-1].strip())
×
120

121

122
@rule
10✔
123
async def get_python_for_scripts(env_tgt: EnvironmentTarget) -> PythonBuildStandaloneBinary:
10✔
124
    if env_tgt.can_access_local_system_paths:
×
125
        return PythonBuildStandaloneBinary(sys.executable)
×
126

127
    result = await download_python_binary(
×
128
        _DownloadPythonBuildStandaloneBinaryRequest(), **implicitly()
129
    )
130

131
    return PythonBuildStandaloneBinary(result.path)
×
132

133

134
@dataclass(frozen=True)
10✔
135
class GunzipBinaryRequest:
10✔
136
    pass
10✔
137

138

139
@dataclass(frozen=True)
10✔
140
class GunzipBinary:
10✔
141
    python_binary: PythonBuildStandaloneBinary
10✔
142

143
    def extract_archive_argv(self, archive_path: str, extract_path: str) -> tuple[str, ...]:
10✔
144
        archive_name = os.path.basename(archive_path)
×
145
        dest_file_name = os.path.splitext(archive_name)[0]
×
146
        dest_path = os.path.join(extract_path, dest_file_name)
×
147
        script = dedent(
×
148
            f"""
149
            import gzip
150
            import shutil
151
            with gzip.GzipFile(filename={archive_path!r}, mode="rb") as source:
152
                with open({dest_path!r}, "wb") as dest:
153
                    shutil.copyfileobj(source, dest)
154
            """
155
        )
156
        return (self.python_binary.path, "-c", script)
×
157

158

159
@rule
10✔
160
async def find_gunzip(python_binary: PythonBuildStandaloneBinary) -> GunzipBinary:
10✔
161
    return GunzipBinary(python_binary)
×
162

163

164
@rule
10✔
165
async def find_gunzip_wrapper(_: GunzipBinaryRequest, gunzip: GunzipBinary) -> GunzipBinary:
10✔
166
    return gunzip
×
167

168

169
def rules():
10✔
170
    return collect_rules()
10✔
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