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
5 changes: 4 additions & 1 deletion .github/workflows/publish_tombstone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ jobs:

- name: Build the tombstone sdists
run: |
python3 -m pip install --upgrade build twine==6.0.1
# setuptools is explicit: the sdist builds with --no-isolation, and
# Python 3.12+ runners no longer ship setuptools, so the backend
# would otherwise be missing (BackendUnavailable, run 32309423898).
python3 -m pip install --upgrade build twine==6.0.1 setuptools
python3 -m autohands.tombstone --out dist-tombstone

- name: Check metadata
Expand Down
23 changes: 23 additions & 0 deletions autohands/tombstone.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
from __future__ import annotations

import argparse
import importlib.util
import shutil
import subprocess
import sys
Expand Down Expand Up @@ -251,6 +252,27 @@ def write_project(
return project_dir


def require_setuptools() -> None:
"""Fail early, and legibly, when the build backend is missing.

The sdist is built with `--no-isolation`, so setuptools has to be present in
this interpreter — and Python 3.12 dropped it from the default environment.
Without this check the failure surfaces as `BackendUnavailable: Cannot
import 'setuptools.build_meta'` from inside pyproject_hooks, which names
neither the cause nor the fix. A developer machine that happens to have
setuptools installed will not reproduce it, so the check has to be explicit
rather than left to whatever the environment happens to carry.
"""
if importlib.util.find_spec("setuptools") is None:
raise RuntimeError(
"setuptools is not installed in this interpreter, so the sdist cannot "
"be built. The build deliberately runs with --no-isolation so it "
"cannot silently reach the network for a backend; Python 3.12 and "
"later no longer ship setuptools by default. Install it first: "
"python3 -m pip install setuptools"
)


def build_sdist(
project_dir: Path,
out_dir: Path,
Expand All @@ -268,6 +290,7 @@ def build_sdist(
so "the newest tarball here" would happily hand back a sibling package's
sdist and verify *its* metadata instead.
"""
require_setuptools()
out_dir.mkdir(parents=True, exist_ok=True)
subprocess.run(
[
Expand Down
13 changes: 13 additions & 0 deletions tests/test_tombstone.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,19 @@ def _build_available():
)


def test_missing_setuptools_is_reported_before_the_build(tmp_path, monkeypatch):
"""`--no-isolation` means the backend must already be installed, and Python
3.12 dropped setuptools from the default environment. Left unchecked the
failure arrives as `BackendUnavailable: Cannot import
'setuptools.build_meta'` from inside pyproject_hooks, naming neither the
cause nor the fix — and a machine that happens to have setuptools will
never reproduce it (PyAutoHands run 32309423898)."""
monkeypatch.setattr(tombstone.importlib.util, "find_spec", lambda name: None)

with pytest.raises(RuntimeError, match="pip install setuptools"):
tombstone.build_sdist(tmp_path / "project", tmp_path / "dist", "autolens")


@requires_build
def test_built_sdist_declares_sub_floor_requires_python(tmp_path):
project = tombstone.write_project("autolens", tmp_path)
Expand Down
Loading