Skip to content

fix: make fact conditions explicit and reject bare fact classes - #2064

Open
mvanhorn wants to merge 1 commit into
pyinfra-dev:3.xfrom
mvanhorn:fix/2041-fact-conditions
Open

mvanhorn wants to merge 1 commit into
pyinfra-dev:3.xfrom
mvanhorn:fix/2041-fact-conditions

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Background

An operation gated on a bare fact class always runs, even when the fact would be falsey. The condition is silently accepted without collecting the fact.

Fact classes pass callable validation, but invoking them constructs a truthy instance instead of retrieving a fact value. _if therefore evaluates the instance rather than the fact.

Summary of the fix

Adds any_fact and all_fact to combine zero-argument facts with explicit OR and AND semantics. Their conditions retrieve facts lazily from the current executing host and short-circuit. Bare FactBase and ShortFactBase subclasses are rejected during preparation before operation registration, including conditions inherited from deploy or host arguments. Documentation explains the helpers, empty-condition behavior, and lambdas for facts requiring arguments.

Verification

The targeted tests (tests/test_api/test_api_operations.py, tests/test_operations_utils.py) pass, 111 tests, and the full pytest suite passes (2252 passed). ruff check, ruff format --check, mypy and scripts/lint_arguments_sync.py all pass.

  • 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

Fixes #2041

AI disclosure:

AI was used for assistance.

  • Tools: Codex.

Adds `any_fact` and `all_fact` to combine zero-argument facts with
explicit OR and AND semantics. Their conditions retrieve facts lazily
from the current executing host and short-circuit. Bare `FactBase` and
`ShortFactBase` subclasses are rejected during preparation before
operation registration, including conditions inherited from deploy or
host arguments. Documentation explains the helpers, empty-condition
behavior, and lambdas for facts requiring arguments.

Fixes pyinfra-dev#2041
@wowi42 wowi42 added bug Label for all kind of bugs. API API mode specific issues. operations Issues with operations. labels Nov 4, 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. bug Label for all kind of bugs. operations Issues with operations.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ergonomic use of facts with _if

2 participants