Skip to content

feat: add get_build_system_dependencies global hook point#1271

Open
vshawrh wants to merge 1 commit into
python-wheel-build:mainfrom
vshawrh:feat/global-build-deps-hook
Open

feat: add get_build_system_dependencies global hook point#1271
vshawrh wants to merge 1 commit into
python-wheel-build:mainfrom
vshawrh:feat/global-build-deps-hook

Conversation

@vshawrh

@vshawrh vshawrh commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds get_build_system_dependencies as a new global hook point in fromager.hooks. This lets downstream projects register hooks that post-process build-system dependencies for all packages, without needing per-package plugins.

Motivation: In the AIPCC/fondue builder we have 22+ identical per-package plugins that exist solely to cap setuptools for packages whose setup.py uses removed APIs (pkg_resources, dry_run). With this hook point, we can replace all of them with a single global hook.

Changes

  • src/fromager/hooks.py: Added get_build_system_dependencies to GLOBAL_HOOK_NAMES and implemented run_get_build_system_dependencies_hooks() which chains hooks so each receives the (possibly modified) requirements list from the previous one.
  • src/fromager/dependencies.py: After overrides.find_and_invoke() returns build-system deps and before _filter_requirements(), the global hooks are now called to allow post-processing.
  • tests/test_hooks.py: Tests for the new hook: basic invocation, chaining behavior, no-op when no hooks registered, exception propagation.
  • tests/test_dependencies.py: Integration test verifying get_build_system_dependencies() calls the global hooks.

Hook signature

def get_build_system_dependencies(
    *,
    ctx: context.WorkContext,
    req: Requirement,
    sdist_root_dir: pathlib.Path,
    build_dir: pathlib.Path,
    requirements: list[str],
) -> list[str]:
    ...

Registered via entry points under fromager.hooks:

[project.entry-points."fromager.hooks"]
get_build_system_dependencies = "my_package.hooks:get_build_system_dependencies"

How it fits

The hook runs after per-package overrides (overrides.find_and_invoke) and before marker filtering (_filter_requirements). This means per-package plugins still take full precedence, and global hooks only augment the result.

Closes #1263

Allow downstream projects to register global hooks that post-process
build-system dependencies for all packages. Hooks are chained so
multiple can compose. This enables use cases like auto-capping
setuptools without per-package plugins.

Closes python-wheel-build#1263

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Vikash Shaw <vshaw@redhat.com>
@vshawrh
vshawrh requested a review from a team as a code owner July 24, 2026 15:23
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a global get_build_system_dependencies hook and runner that chains registered plugin results. Build-system dependency resolution now invokes this hook after initial resolution and before filtering and writing requirements. Tests cover argument forwarding, hook chaining, empty hook registration, exception propagation, and end-to-end integration with dependency resolution.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The change adds the requested global hook, chains it, and invokes it after per-package overrides before filtering.
Out of Scope Changes check ✅ Passed The PR stays focused on the new hook, integration, and tests; no unrelated changes are evident.
Title check ✅ Passed The title clearly summarizes the main change: adding a new global hook point for build-system dependencies.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the new hook, integration, and tests.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mergify mergify Bot added the ci label Jul 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_dependencies.py`:
- Around line 432-434: Strengthen the assertions in the dependency hook test
around the returned results so they verify a setuptools requirement excludes
version 82, rather than only checking that setuptools is present. Preserve the
existing requirements argument assertion and ensure the new check would fail if
the hook discarded the returned setuptools constraint.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4fdc1ee4-6f73-4d81-b707-e30713142a59

📥 Commits

Reviewing files that changed from the base of the PR and between d249228 and 2ffbe2d.

📒 Files selected for processing (4)
  • src/fromager/dependencies.py
  • src/fromager/hooks.py
  • tests/test_dependencies.py
  • tests/test_hooks.py

Comment on lines +432 to +434
names = set(r.name for r in results)
assert "setuptools" in names
assert called_with["requirements"] == ["setuptools>=40.0"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert that the hook’s returned constraint affects the result.

"setuptools" is already present before the hook runs, so this passes even if setuptools<82 is discarded. Assert that at least one returned setuptools requirement excludes version 82.

Suggested assertion
     names = set(r.name for r in results)
     assert "setuptools" in names
+    assert any(
+        r.name == "setuptools" and Version("82") not in r.specifier
+        for r in results
+    )
     assert called_with["requirements"] == ["setuptools>=40.0"]

As per path instructions, “Verify test actually tests the intended behavior.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
names = set(r.name for r in results)
assert "setuptools" in names
assert called_with["requirements"] == ["setuptools>=40.0"]
names = set(r.name for r in results)
assert "setuptools" in names
assert any(
r.name == "setuptools" and Version("82") not in r.specifier
for r in results
)
assert called_with["requirements"] == ["setuptools>=40.0"]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_dependencies.py` around lines 432 - 434, Strengthen the assertions
in the dependency hook test around the returned results so they verify a
setuptools requirement excludes version 82, rather than only checking that
setuptools is present. Preserve the existing requirements argument assertion and
ensure the new check would fail if the hook discarded the returned setuptools
constraint.

Source: Path instructions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add global hook point for get_build_system_dependencies

1 participant