refactor(cli): migrate argument parsing from Click to Cyclopts - #1901
Merged
Conversation
This was referenced Jul 26, 2026
noirbizarre
force-pushed
the
refactor/cyclopts
branch
from
July 26, 2026 14:16
e31708d to
429f717
Compare
Fizzadar
requested changes
Jul 27, 2026
Fizzadar
left a comment
Member
There was a problem hiding this comment.
Couple of tweaks then we're good to go I think!
Replace Click with Cyclopts for command-line argument parsing while keeping the existing command syntax, flags and behaviour. Output styling continues to go through the pluggable `pyinfra.api.output` layer wired to Click (`set_formatter(click.style)` / `set_echo(click.echo)`), so this change is scoped to parsing only — Rich output is introduced in a follow-up. - `cli.py` becomes a Cyclopts `App` with `@app.default` and typed `Annotated` parameters; `PYINFRA_YES` keeps its lenient boolean parsing (empty/on/off). - `--help` groups the options into Execution / Inventory & Data / Privilege Escalation / SSH Connection / Debugging & Output sections, and the noisy auto-generated `--no-*` negation flags are suppressed. - `--support` is a Cyclopts command; the previously duplicated `support` parameter and its unreachable handler are removed. - `main.py` invokes the Cyclopts app and surfaces `click.ClickException` (CliError etc.) via their `.show()` / exit code. - The confirmation prompt and all human output remain Click-based. - pyproject: add `cyclopts`, keep `click` (now used for output only). - Tests invoke the Cyclopts app through the updated `run_cli` helper.
noirbizarre
force-pushed
the
refactor/cyclopts
branch
from
July 27, 2026 15:03
429f717 to
3a2146e
Compare
Contributor
Author
|
All comments addressed. 👍🏼 The version is now iso to the current format: (Good to know for #1753, I love pathlib!) |
wowi42
approved these changes
Aug 25, 2026
wowi42
left a comment
Collaborator
There was a problem hiding this comment.
Re-reviewed after the requested changes. Approving.
Verified locally on this branch (Python 3.13):
pyinfra --versionprintspyinfra: v...again (matches the old Click output).pyinfra --supportworks and exits 0.-vvvbundling still works for verbosity.- Missing operations exits 1 with a clear usage message (Click exited 2 with a usage error; the new message is more helpful, fine by me).
- Unknown option exits 1 (was 2 under Click; acceptable).
PYINFRA_YES=offlenient parsing works.- Full unit suite passes (1951 passed), ruff and mypy clean.
Two cosmetic Cyclopts differences in --help, not blockers:
- Flags now show
[default: False]and repeatable options show[default: ()], which adds noise Click did not have. If Cyclopts has a flag to hide defaults for these, worth using in Part 2 or 3. - The usage line reads
pyinfra COMMAND [OPTIONS] INVENTORY [ARGS...]; theCOMMANDtoken is a bit misleading for the default command.
The scripts/pyinfra-complete.{sh,zsh} removal is a breaking change for anyone sourcing those files, but it was requested in the earlier review and --install-completion (which also adds fish support) is a good replacement.
yagarea
pushed a commit
to yagarea/pyinfra
that referenced
this pull request
Aug 26, 2026
…ra-dev#1901) Co-authored-by: Loïc Tosser <loic@kalvad.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 1 of 3 of the CLI modernisation, split out of #1894 as requested for easier review.
This migrates command-line argument parsing from Click to Cyclopts, while keeping the existing command syntax, flags and behaviour. Output styling still goes through the pluggable
pyinfra.api.outputlayer wired to Click (set_formatter(click.style)/set_echo(click.echo)), so this change is scoped to parsing only — Rich output arrives in the next PR.cli.pybecomes a CycloptsAppwith@app.defaultand typedAnnotatedparameters;PYINFRA_YESkeeps its lenient boolean parsing (empty / on / off).--supportis now a Cyclopts command; the previously duplicatedsupportparameter and its unreachable handler are removed.main.pyinvokes the Cyclopts app and surfacesclick.ClickException(CliError etc.) via their.show()/ exit code.cyclopts, keepclick(now used for output only).run_clihelper.📚 Stacked PR series
This is one of three PRs that split the combined CLI refactor (originally #1894) into reviewable layers. They are stacked and land in order; Parts 2 & 3 stay in draft until the preceding part is merged.
Original combined PR (kept for reference/discussion): #1894
Related issue: #785 (use Rich) — referenced, not closed.
🎥 Showcase
Those are here to show what visually changed and what did not (yet).
In this PR,
clickis still in charge of rendering/styling,richis not yet introduced.Help
Inventory
Success
Error and diff
Multiline output