Skip to content

feat(api): give check_preconditions the fact's own arguments - #1988

Open
maisim wants to merge 1 commit into
pyinfra-dev:3.xfrom
maisim:feat/check-preconditions-kwargs
Open

maisim wants to merge 1 commit into
pyinfra-dev:3.xfrom
maisim:feat/check-preconditions-kwargs

Conversation

@maisim

@maisim maisim commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

check_preconditions(self, state, host) is called on a bare cls() instance, while the arguments the fact was asked about stay in fact_kwargs. A fact that takes parameters therefore cannot use it: it has no way to tell which project, host or pool it is being asked about, which is what a precondition needs in order to check anything.

The arguments now go with the call, named as the fact's command declares them. self is dropped first — getcallargs collects it alongside them, and _make_command drops it the same way before calling command.

Nothing changes for a fact whose command takes no parameters: it is called with no keyword arguments, which is what ZfsPools' implementation already expects.

Worth having because the case it serves is a common one: a fact that reads a resource an earlier operation of the same deploy creates — a project, a pool, a namespace. pyinfra gathers facts before it runs any operation, so at that point the resource is not there yet; the fact's command fails, state.fail_hosts() drops the host, and the deploy is over before it ran anything. Silencing that during the prepare phase is exactly what check_preconditions is for, and it was out of reach for a fact with a parameter.

  • Pull request is based on the default branch (3.x at this time)
  • Pull request includes tests for any new/updated operations/facts
  • Pull request includes documentation for any new/updated operations/facts
  • Tests pass (see scripts/dev-test.sh)
  • Type checking & code style passes (see scripts/dev-lint.sh)
  • Pull request title follows the
    conventional commits format

`check_preconditions(self, state, host)` is called on a bare `cls()` instance, while the arguments
the fact was asked about stay in `fact_kwargs`. A fact that takes parameters therefore cannot use it:
it has no way to tell which project, host or pool it is being asked about, which is what a
precondition needs in order to check anything.

The arguments now go with the call, named as the fact's `command` declares them. `self` is dropped
first — `getcallargs` collects it alongside them, and `_make_command` drops it the same way before
calling `command`.

The signature ends in `*args, **kwargs`, as `requires_command`'s does, so an implementation may
declare only what it needs: `(self, state, host)` stays valid, which is what the one existing
implementation already writes, and `(self, state, host, pool=None)` becomes possible for a fact that
depends on its own parameters. Naming the arguments explicitly would have forced every
implementation, present and future, to accept a parameter it ignores.

Worth having because the case it serves is a common one: a fact that reads a resource an earlier
operation of the same deploy creates — a project, a pool, a namespace. pyinfra gathers facts before
it runs any operation, so at that point the resource is not there yet; the fact's command fails,
`state.fail_hosts()` drops the host, and the deploy is over before it ran anything. Silencing that
during the prepare phase is exactly what `check_preconditions` is for, and it was out of reach for a
fact with a parameter.
@maisim
maisim force-pushed the feat/check-preconditions-kwargs branch from 385fd0b to eec3b9d Compare October 3, 2026 14:34
@wowi42 wowi42 added new feature API API mode specific issues. labels Oct 3, 2026

This branch has not been deployed

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

Labels

API API mode specific issues. new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants