Skip to content

feat: provide the backend collection loops in the loader#78

Merged
henryiii merged 1 commit into
mainfrom
feat/backend-collection-loops
Jul 2, 2026
Merged

feat: provide the backend collection loops in the loader#78
henryiii merged 1 commit into
mainfrom
feat/backend-collection-loops

Conversation

@henryiii

@henryiii henryiii commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🤖 AI text below 🤖

Prompted by scikit-build/scikit-build-core#1433: the first real consumer of the dynamic_wheel hook had to write the collection loop itself, including validation rules our docs only stated in prose. The reference implementation should provide these loops so backends don't each re-derive spec rules.

Changes

  • loader.py: two new public functions, replacing the copy-paste snippets on the backend-authors page:
    • get_requires_for_dynamic_metadata(entries) -> list[str] — extra build requirements, collected in entry order, for the backend's PEP 517 get_requires_for_build_* hooks.
    • dynamic_wheel_fields(entries) -> set[str] — the METADATA 2.2 pass, now enforcing the rules the old doc snippet lacked: reported field names are validated against ALL_FIELDS, version: True raises, and unmentioned fields default to not dynamic.
  • Semantics change vs. the old snippet: same-field reports from multiple providers combine with OR (any True wins) rather than last-wins dict.update. Contributions to a field merge, so one dynamic part makes the merged value dynamic; PEP 643 permits over-marking but not under-marking. (Issue to align scikit-build-core to follow.)
  • Docs: backend_authors.md calls the real functions; the full loops (with validation) move to backend_authors_reimplement.md as the copyable reference; plugin_authors.md notes dynamic_wheel may run on a fresh instance, so it cannot rely on state stashed by dynamic_metadata/build_state (it only receives settings by design).
  • Tests (written first, confirmed failing without the fix): collection with hook-less providers skipped, the OR case, unknown-field rejection, and the version rule; these replace the old test that hand-rolled the loop.

The new functions appear in the API reference automatically via the existing automodule directive.

Add get_requires_for_dynamic_metadata(entries) and
dynamic_wheel_fields(entries) to loader.py, replacing the copy-paste
snippets on the backend-authors page. dynamic_wheel_fields enforces the
spec rules the snippet only stated in prose: unknown fields are
rejected, 'version' may never be dynamic, and unmentioned fields
default to not dynamic.

Same-field reports from multiple providers combine with OR rather than
last-wins: contributions to a field merge, so one dynamic part makes
the merged value dynamic, and PEP 643 only permits over-marking.

The full loops (with validation) move to the reimplement page, and the
plugin-author docs note dynamic_wheel may run on a fresh instance.

Assisted-by: ClaudeCode:claude-fable-5
henryiii added a commit to scikit-build/scikit-build-core that referenced this pull request Jul 2, 2026
dynamic_wheel_fields merged provider reports with dict.update, so when
two [[tool.dynamic-metadata]] entries reported the same field the last
one won -- a later {"dependencies": False} could retract an earlier
{"dependencies": True}. Since a list/table field's merged value can
change if any contributing provider's part may, reports must combine
with OR (any True wins); over-marking Dynamic is allowed, under-marking
violates PEP 643. Validation now runs on each fragment as it is
collected, so a masked {"version": True} raises instead of being
silently dropped. Aligns with scikit-build/dynamic-metadata#78.

Closes #1436

Assisted-by: ClaudeCode:claude-opus-4.8
@henryiii henryiii merged commit e802fe1 into main Jul 2, 2026
11 checks passed
@henryiii henryiii deleted the feat/backend-collection-loops branch July 2, 2026 18:47
@henryiii henryiii mentioned this pull request Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant