Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions e2e/cases/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ include("//multi-project-hub:setup.MODULE.bazel")
include("//oci:setup.MODULE.bazel")
include("//pbs-cc-toolchain:setup.MODULE.bazel")
include("//pth-namespace-547:setup.MODULE.bazel")
include("//pycross-distutils-probe:setup.MODULE.bazel")
include("//pycross-patches:setup.MODULE.bazel")
include("//pycross-pure-python:setup.MODULE.bazel")
include("//pycross-setuptools:setup.MODULE.bazel")
include("//pytest-anyio-plugin:setup.MODULE.bazel")
include("//pytest-main-867:setup.MODULE.bazel")
include("//pytest-mock-530:setup.MODULE.bazel")
Expand Down
18 changes: 18 additions & 0 deletions e2e/cases/pycross-distutils-probe/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Ported from rules_pycross tests/e2e/build_setuptools's distutils probe.
# See __test__.py for what the probe asserts.

load("@aspect_rules_py//py:defs.bzl", "py_test")

py_test(
name = "test",
srcs = ["__test__.py"],
data = ["@aspect_rules_py//uv/private/pep517_whl:build_helper.py"],
dep_group = "pycross_distutils_probe",
main = "__test__.py",
python_version = "3.12",
deps = [
"@pypi_pycross_distutils_probe//build",
"@pypi_pycross_distutils_probe//setuptools",
"@pypi_pycross_distutils_probe//wheel",
],
)
108 changes: 108 additions & 0 deletions e2e/cases/pycross-distutils-probe/__test__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""Drive build_helper.py against rules_pycross's distutils probe sdist.

Ported from rules_pycross tests/e2e/build_setuptools (`distutils_probe/`,
`build_distutils_probe_sdist.py`, `test_distutils_probe.py`). The sdist's
`build_py` command shells out to a *fresh* interpreter and imports
`distutils.util`; on Python 3.12+ that only resolves when setuptools'
`_distutils_hack` is reachable from the child. A build action that leaks a
stale `PYTHONPATH`/`PYTHONHOME` — exactly what rule.bzl's
`_INHERITED_PYTHON_ENV` filter strips — poisons the child while the parent
backend keeps working, so the failure is invisible to a plain "does it
build" check.

Structured like `uv-sdist-mpicc`: the sdist is assembled in-process and
build_helper.py runs as a subprocess with a minimal env (bare PATH, no
PYTHON* variables), so nothing is fetched from the network and nothing
leaks in from the test's own environment.
"""

import os
import subprocess
import sys
import tarfile
import tempfile
import textwrap

PYPROJECT = textwrap.dedent(
"""\
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
"""
)

SETUP_PY = textwrap.dedent(
"""\
import subprocess
import sys

from setuptools import setup
from setuptools.command.build_py import build_py as _build_py


class build_py(_build_py):
def run(self):
subprocess.check_call([sys.executable, "-c", "from distutils.util import byte_compile"])
super().run()


setup(
name="distutils_probe",
version="0.1",
packages=["distutils_probe_pkg"],
cmdclass={"build_py": build_py},
)
"""
)


def find_build_helper() -> str:
srcdir = os.environ["TEST_SRCDIR"]
for root, _, files in os.walk(srcdir, followlinks=True):
if "build_helper.py" in files and root.endswith(os.path.join("uv", "private", "pep517_whl")):
return os.path.join(root, "build_helper.py")
raise AssertionError("build_helper.py not found under TEST_SRCDIR")


def make_sdist(workdir: str) -> str:
pkgdir = os.path.join(workdir, "distutils_probe-0.1")
os.makedirs(os.path.join(pkgdir, "distutils_probe_pkg"))
with open(os.path.join(pkgdir, "pyproject.toml"), "w") as f:
f.write(PYPROJECT)
with open(os.path.join(pkgdir, "setup.py"), "w") as f:
f.write(SETUP_PY)
with open(os.path.join(pkgdir, "distutils_probe_pkg", "__init__.py"), "w") as f:
f.write("")
sdist = os.path.join(workdir, "distutils_probe-0.1.tar.gz")
with tarfile.open(sdist, "w:gz") as tar:
tar.add(pkgdir, arcname="distutils_probe-0.1")
return sdist


def main() -> None:
helper = find_build_helper()
tmp = tempfile.mkdtemp(dir=os.environ.get("TEST_TMPDIR"))
sdist = make_sdist(tmp)
outdir = os.path.join(tmp, "out")

result = subprocess.run(
[sys.executable, helper, "--validate-anyarch", sdist, outdir],
capture_output=True,
text=True,
env={
"PATH": os.pathsep.join(["/usr/bin", "/bin"]),
"HOME": os.environ.get("TEST_TMPDIR", "/tmp"),
},
)
if result.returncode != 0:
raise AssertionError(
"build_helper failed:\nstdout:\n{}\nstderr:\n{}".format(result.stdout, result.stderr)
)

wheels = [f for f in os.listdir(outdir) if f.endswith(".whl")]
assert wheels, "no wheel produced"
print("OK: {}".format(wheels))


if __name__ == "__main__":
main()
9 changes: 9 additions & 0 deletions e2e/cases/pycross-distutils-probe/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[project]
name = "pycross_distutils_probe"
version = "0.0.0"
requires-python = ">=3.11"
dependencies = [
"build",
"setuptools",
"wheel",
]
22 changes: 22 additions & 0 deletions e2e/cases/pycross-distutils-probe/setup.MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Port of rules_pycross's `tests/e2e/build_setuptools` distutils probe.

rules_pycross ships a synthetic sdist whose `build_py` command shells out to a
fresh interpreter and imports `distutils.util`, guarding against a build
environment that leaves the backend's child processes unable to find distutils
(`SETUPTOOLS_USE_DISTUTILS`, a stale `PYTHONPATH`, or a stripped `PATH`).
rule.bzl filters `PYTHONHOME`/`PYTHONPATH`/`PYTHONPLATLIBDIR` out of the
action env for exactly this reason, so the probe is worth keeping.

Driven the same way as `uv-sdist-mpicc`: the test invokes build_helper.py
directly against a sdist it builds in-process, so no lockfile entry or
network fetch is involved.
"""

uv = use_extension("@aspect_rules_py//uv:extensions.bzl", "uv")
uv.declare_hub(hub_name = "pypi_pycross_distutils_probe")
uv.project(
hub_name = "pypi_pycross_distutils_probe",
lock = "//pycross-distutils-probe:uv.lock",
pyproject = "//pycross-distutils-probe:pyproject.toml",
)
use_repo(uv, "pypi_pycross_distutils_probe")
82 changes: 82 additions & 0 deletions e2e/cases/pycross-distutils-probe/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions e2e/cases/pycross-patches/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Ported from rules_pycross tests/e2e/patches_and_hooks.
#
# `PATCHED` comes from the pre-build patch (applied to the sdist source tree
# before the PEP 517 backend runs), `POST_PATCHED` from the post-install patch
# (applied to the unpacked wheel). The post-install hunk's context includes the
# pre-build hunk's line, so the two must apply in that order.

load("@aspect_rules_py//py:defs.bzl", "py_test")

exports_files([
"patches/setproctitle-prebuild.patch",
"patches/setproctitle-postinstall.patch",
])

py_test(
name = "test_setproctitle_patched",
srcs = ["test_setproctitle_patched.py"],
dep_group = "pycross_patches",
main = "test_setproctitle_patched.py",
python_version = "3.12",
deps = ["@pypi_pycross_patches//setproctitle"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
--- a/lib/python3.12/site-packages/setproctitle/__init__.py
+++ b/lib/python3.12/site-packages/setproctitle/__init__.py
@@ -56,3 +56,4 @@
if sys.platform == "darwin":
getproctitle()
PATCHED = True
+POST_PATCHED = True
7 changes: 7 additions & 0 deletions e2e/cases/pycross-patches/patches/setproctitle-prebuild.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
--- a/pkg/setproctitle/__init__.py 2026-06-04 13:22:25.044466888 +0000
+++ b/pkg/setproctitle/__init__.py 2026-06-04 13:23:03.082422796 +0000
@@ -55,3 +55,4 @@
# by fork() on macOS (see #113).
if sys.platform == "darwin":
getproctitle()
+PATCHED = True
13 changes: 13 additions & 0 deletions e2e/cases/pycross-patches/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[project]
name = "pycross_patches"
version = "0.0.0"
requires-python = ">=3.11"
dependencies = [
"build",
"setuptools",
"wheel",
"setproctitle==1.3.2",
]

[tool.uv]
no-binary-package = ["setproctitle"]
46 changes: 46 additions & 0 deletions e2e/cases/pycross-patches/setup.MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Port of rules_pycross's `tests/e2e/patches_and_hooks` workspace.

setproctitle is forced to build from its sdist with both patch phases applied:
a pre-build patch that lands in the source tree before the PEP 517 backend
runs, and a post-install patch that rewrites the already-unpacked wheel. The
two patches stack — the post-install hunk carries the pre-build patch's
`PATCHED = True` line as context, so it only applies when the phases ran in
order and an ordering regression fails the build itself, not just the
runtime test.

The post-install patch is written against the installed venv layout
(`lib/python<X.Y>/site-packages/...`): rules_py applies post-install patches
with `patch -d` rooted at the install tree, unlike rules_pycross's
wheel-relative paths.

Uses its own hub: the patched setproctitle must not be shared with
`pycross-setuptools`, which builds the same version unpatched.

Not ported: rules_pycross's `pre_build_hooks` / `post_build_hooks` /
`path_tools` / `site_hooks` and its `repair_wheel` hook have no rules_py
equivalent. `uv.override_package(toolchains = ..., env = ...)` covers the
"inject something into the build environment" case those hooks serve; see
`uv-sdist-jdk-build`.
"""

uv = use_extension("@aspect_rules_py//uv:extensions.bzl", "uv")
uv.declare_hub(hub_name = "pypi_pycross_patches")
uv.project(
default_build_dependencies = [
"build",
"setuptools",
"wheel",
],
hub_name = "pypi_pycross_patches",
lock = "//pycross-patches:uv.lock",
pyproject = "//pycross-patches:pyproject.toml",
)
uv.override_package(
name = "setproctitle",
lock = "//pycross-patches:uv.lock",
post_install_patch_strip = 1,
post_install_patches = ["//pycross-patches:patches/setproctitle-postinstall.patch"],
pre_build_patch_strip = 1,
pre_build_patches = ["//pycross-patches:patches/setproctitle-prebuild.patch"],
)
use_repo(uv, "pypi_pycross_patches")
23 changes: 23 additions & 0 deletions e2e/cases/pycross-patches/test_setproctitle_patched.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Assert both patch phases reached the installed setproctitle.

Ported from rules_pycross tests/e2e/patches_and_hooks/tests/test_setproctitle.py.
`PATCHED` comes from the pre-build patch, `POST_PATCHED` from the post-install
patch. The upstream `SITE_HOOK_RAN` assertion is dropped: rules_py has no
`site_hooks` equivalent.
"""

import unittest

import setproctitle


class TestSetproctitle(unittest.TestCase):
def test_import(self) -> None:
title = setproctitle.getproctitle()
self.assertIsNotNone(title)
self.assertTrue(setproctitle.PATCHED)
self.assertTrue(setproctitle.POST_PATCHED)


if __name__ == "__main__":
unittest.main()
Loading
Loading