NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #366 most downloaded on PyPI
Intuitive, easy CLIs based on type hints.
Last release today
01 Oct 2026
Ships on a steady schedule
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
3 years old
167 releases · first in 2023
Add App.update method. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/281
App.update method. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/281Annotated is inside another type; namely list[Annotated[...]]. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/289Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v3.1.3...v3.1.4
Do not interpret choices/default as rich markup by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/278
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v3.1.2...v3.1.3
One column per month.
Fix NewType token count for python >=3.10. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/265
NewType token count for python >=3.10. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/265Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v3.1.1...v3.1.2
Correctly handle NewType type annotations by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/263
NewType type annotations by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/263Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v3.1.0...v3.1.1
New attribute App.sort_key that controls command-order in the help page. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/258
App.sort_key that controls command-order in the help page. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/258Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v3.0.1...v3.1.0
Allow for list[bool] and similar (list of flags). by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/251
list[bool] and similar (list of flags). by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/251Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v3.0.0...v3.0.1
Advanced parsing of user-defined classes (including pydantic/attrs/dataclasses/namedtuple).
UInt8, Int8, UInt16, Int16, Uint32, Int32, Json.Number and Path validators now work with sequences (e.g. list[Path]).POSITIONAL_ONLY parameters may follow an iterable POSITIONAL_ONLY parameter. This allows for programs like:@app.default
def foo(inputs: list[Path], output: Path, /):
pass
$ python my-program.py input_files/*.txt output.txt
-- special token for forcing all subsequent CLI tokens to be parsed as positional argument. This mimics getopt behavior.cyclopts.validators.MutuallyExclusive. Performs same action as the default LimitedChoice(), but may be more intuitive/obvious for developers reading application code.Drop python3.8 support; add python3.13 support.
Remove Group.converter and App.converter. Their use-cases are a bit contrived, don't provide much value, and increase the maintenance burden of the Cyclopts codebase.
Change in custom Parameter.converter. Previously, the converter had signature:
def converter(type_, *values: str): ...
The new signature is:
def converter(type_, tokens: Sequence[Token]): ...
See the new Token class. This allows for raising a CoercionError for the particular offending token, which will result in a more helpful error message for the user.
App.parse_args and App.parse_known_args now return an additional value, ignored, which is a dictionary mapping python-variable-names to their type annotation of parameters with parse=False.
Different CLI parsing scheme that is more directly similar to python's function rules. If a python variable is POSITIONAL_OR_KEYWORD, and a value is specified by keyword, subsequent POSITIONAL_OR_KEYWORD parameters in the function signature must be specified by keyword.
When an iterable-like datatype is specified by keyword, only a single element's worth of tokens will be consumed. To restore the old behavior where tokens are consumed until an option-like argument is reached, set Parameter.consume_multiple = True.
Parameter.negative_bool values must no longer start with --. E.g. if it was previously --no-, it should now be no-. A ValueError is raised if it starts with a hyphen.
Parameter.negative_iterable values must no longer start with --. E.g. if it was previously --empty-, it should now be empty-. A ValueError is raised if it starts with a hyphen.
Parameter.required field actually impacts whether or not the Parameter is mandatory. Previously it was only reflected in the help page.
Improve program load-time and --help performance. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/223
--help performance. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/223Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.9.8...v2.9.9
Use last command's help/version flags. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/220
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.9.7...v2.9.8
Optimize --help performance by passing down the App version to the help/version commands by @daudef in https://github.com/BrianPugh/cyclopts/pull/217
--help performance by passing down the App version to the help/version commands by @daudef in https://github.com/BrianPugh/cyclopts/pull/217Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.9.6...v2.9.7
Fix --help crash when a mutable default is assigned to a parameter by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/216
--help crash when a mutable default is assigned to a parameter by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/216Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.9.5...v2.9.6
Fix type hints for @app.default decorator. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/211
@app.default decorator. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/211Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.9.4...v2.9.5
loosen python version from ^3.8 to >=3.8 by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/201
^3.8 to >=3.8 by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/201Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.9.3...v2.9.4
Improved type hints by @andersjel in https://github.com/BrianPugh/cyclopts/pull/194
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.9.2...v2.9.3
More robustly resolve Unions when generating --help choices from Literal/Enum. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/193
--help choices from Literal/Enum. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/193Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.9.1...v2.9.2
resolve help-choices for python3.12 type-statements. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/192
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.9.0...v2.9.1
Python 3.12 type statement support (TypeAliasType). by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/191
TypeAliasType). by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/191Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.8.0...v2.9.0
Introduced new attribute, App.version_format. The verstion string was previously printed as-is, but is now formatted with the specified format, fallin
App.version_format. The verstion string was previously printed as-is, but is now formatted with the specified format, falling back to help_format if not specified. By @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/188Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.7.1...v2.8.0
Have meta apps inherit their parenting config. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/184
import docstring_parser by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/182Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.7.0...v2.7.1
New App.config field, that allows the loading of defaults from files.
App.config field, that allows the loading of defaults from files.
cyclopts.config.Json - Load defaults from a json file.cyclopts.config.Yaml - Load defaults from a yaml file.cyclopts.config.Toml - Load defaults from a toml file.cyclopts.config.Env - Load defaults from environment variables.Parameter.env_var_split attribute. Defaults to cyclopts.env_var_split, which behaviors similarly to Click's multiple values from environment values.Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.6.2...v2.7.0
New App.help_format="rich" option.
App.help_format="rich" option.help_format) across the different sections of the generated help-page. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/166help_format is now keyword only. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/164Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.6.1...v2.6.2
Significantly improve cyclopts import speed by lazy loading dependencies.
Significantly improve cyclopts import speed by lazy loading dependencies.
asyncio and importlib import by @OrHayat in https://github.com/BrianPugh/cyclopts/pull/154pydantic import, speeding up initial import by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/155rich import. Also defer difflib by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/156Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.6.0...v2.6.1
Add App.name_transform by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/147
App.name_transform by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/147Parameter.name_transform by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/149This release adds two new fields: App.name_transform and Parameter.name_transform. The function's responsibility is to convert python identifiers to their CLI counterparts and has signature:
def name_transform(s: str) -> str:
...
These name transforms can be set at a global level for your app:
app = App(
name_transform=lambda name: name, # don't modify the name at all. This applies to command names.
default_parameter=Parameter(name_transform=lambda name: name), # This applies to parameter names.
)
They can also be set in individual subapps (subapps inherit name_transform from their parent), or in individual Annotated[...., Parameter(name_transform=my_custom_transform)] definitions.
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.5.1...v2.6.0
Added support for Postponed Evaluation of types annotations (PEP-563) by @OrHayat in https://github.com/BrianPugh/cyclopts/pull/138
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.4.2...v2.5.0
Unfreeze help_flags and version_flags; create/delete commands on set/get by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/127. Addresses #1
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.4.1...v2.4.2
fixed showing choices of list,tuples and set type annotations by @OrHayat in https://github.com/BrianPugh/cyclopts/pull/123
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.4.0...v2.4.1
Introduces a new exception: UnknownOptionError (see "Breaking Changes" below).
async function support by @nesb1 in https://github.com/BrianPugh/cyclopts/pull/112UnknownOptionError (see "Breaking Changes" below).The following outlines incredibly-minor breaking changes:
UnknownOptionError.ValidationError to generic CycloptsError (ValidationError inherits from CycloptsError).
--no-flag=True now raises CycloptsError instead of ValidationError.ValidationError for this in a meta-app. This is an esoteric scenario that I imagine it doesn't exist in the wild.ValidationError to UnknownOptionError.
CycloptsError instead of a ValidationError.Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.3.2...v2.4.0
More fixes for parsing list of tuples with insufficient arguments by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/109
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.3.1...v2.3.2
Fix convert of Tuple[str]. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/106
convert of Tuple[str]. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/106token_count values. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/108Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.3.0...v2.3.1
Allow specifying a Rich console in App.__init__ by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/99
del app['foo']. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/91Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.2.0...v2.3.0
Added App.help_format which allows for rst and markdown docstring formatting. Defaults to rst. by @BrianPugh in https://github.com/BrianPugh/cyclopts/
App.help_format which allows for rst and markdown docstring formatting. Defaults to rst. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/85Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.1.2...v2.2.0
Fix recursive-parent default_parameter resolution by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/83
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.1.1...v2.1.2
Support python3.10 pipe unions. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/80
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.1.0...v2.1.1
Expose App.parse_commands to public API (previously internally named _parse_command_chain).
App.parse_commands to public API (previously internally named _parse_command_chain).show=False.pyproject.toml in a CLI project.Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v2.0.0...v2.1.0
Cyclopts v2 is *mostly* backwards compatible with v1. Most breaking changes fall under the "advanced users" category and can be fixed with minimal cha…
Cyclopts v2 introduces many new features, and more robust handling of complicated applications. Cyclopts v2 is mostly backwards compatible with v1. Most breaking changes fall under the "advanced users" category and can be fixed with minimal changes.
converter and validator:
cyclopts.validator.LimitedChoice:
App.group_arguments group. This group defaults to Group("Arguments").App.group_parameters group. This group defaults to Group("Parameters").@validate_call support.App.show=False. I.e. decorate a function with @app.command(show=False).App.usage.Parameter.allow_leading_hyphen=False field.List) now consume all remaining valid tokens, regardless if specified as positional or keyword.None or no default is provided, falls back to str.int coercion logic now accepts decimal numbers from the CLI. It will first round, then cast to an int.cyclopts.convert (previously cyclopts.coerce) now takes an optional callable converter, allowing custom-converters to leverage convert's list/tuple/etc parsing abilities, while leaving final element-conversion to a custom function.Path annotated types:ExistingPath, ResolvedPath, ResolvedExistingPath, Directory, ExistingDirectory, ResolvedDirectory, ResolvedExistingDirectory, File, ExistingFile, ResolvedFile, ResolvedExistingFile
Number annotated types:PositiveFloat, NonNegativeFloat, NegativeFloat, NonPositiveFloat, PositiveInt, NonNegativeInt, NegativeInt, NonPositiveInt
Cyclopts v2 is mostly backwards compatible with v1. Most breaking changes fall under the "advanced users" category.
Parameter.allow_leading_hyphen=False feature's default is opposite of the default behavior in Cyclopts v1. For most use-cases, the new behavior is better. This primarily impacts those using a meta-app.
If using a meta-app, the signature should probably be updated to be like:@app.meta.default
def main(*tokens: Annotated[str, Parameter(show=False, allow_leading_hyphen=True)]):
...
Parameter.allow_leading_hyphen==False, Iterable types (e.g. List) now consume all remaining tokens until an option is reached.Parameter.allow_leading_hyphen==True, Iterable types (e.g. List) now consume all remaining tokens.Parameter.token_count has been removed. The feature was kind of broken to begin with, and significantly increased code complexity. We can revisit this feature in the future if someone needs it.App.help_title_commands has been removed. Use the new App.group_commands feature to modify the default parameters help-page panel title. E.g. app.group_commands = "My Different Commands Title"App.help_title_parameters has been removed. Use the new App.group_arguments and App.group_parameters feature to modify the default parameters help-page panel title.cyclopts.coerce to cyclopts.convert for naming consistency.None or no default is provided, falls back to str. E.g.# old behavior
def foo(value = 5):
# `value` would be interpreted as a string.
# new behavior
def foo(value = 5):
# `value` would be interpreted as a `int` because thats `type(5)`.
Validator and Converter protocols (type-hinting) have been removed and replaced with just Callable. The more-specific type-hinting made typical use-case a bit more tedious than it really needed to be.create_bound_arguments is no longer part of the public API.=. I.e. --my-flag=True or --my-flag=false.cyclopts.validators.Path error messages.Path validator now only checks if the path is a file/directory if it exists. Previously it would always try to check.Special thanks to @ravencentric for user-testing and providing quick and useful feedback!
Configurable boolean and iterable negative prefixes. Defaults are --no- and --empty-, respectively. by @BrianPugh in https://github.com/BrianPugh/cycl
--no- and --empty-, respectively. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/38Parameter. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/43App.version to be a callable. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/44Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v1.2.0...v1.3.0
This release technically contains some breaking changes, but realistically no-one should be impacts.
App now takes an optional parameter default_parameter: Parameter that allows the configuration of what values a default Parameter uses. Parameters now have a resolution order for determining configuration values. Basically it goes (highest-to-lowest priority)annotated parameter -> parenting app default -> parenting-parenting app default -> .... by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/33Parameter.combine which can construct a new, single, Parameter from multiple Parameters.Parameter.default which is similar to Parameter(), but it will override all parenting Parameters.App and Parameter's repr strings have been greatly simplified to only include non-default supplied parameters.typing_extensions by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/34importlib.metadata to check distribution version. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/36This release technically contains some breaking changes, but realistically no-one should be impacts.
MultipleParameterAnnotationError; we now handle multiple Parameter resolution. Specifically, for mutliple Parameter in an Annotated, they are evaluated left->right (right-most has highest precedence/priority).Parameter's defaults are now None. No change in default functionality.Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v1.1.1...v1.2.0
Fix error-handling of POSITIONAL_ONLY, VAR_KEYWORD, and VAR_POSITIONAL arguments. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/27
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v1.1.0...v1.1.1
Add environment variable parsing via Parameter.env_var. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/20
Parameter.env_var. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/20Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v1.0.2...v1.1.0
attempt to import readline so that arrows work in interactive_shell.
readline so that arrows work in interactive_shell.Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v1.0.1...v1.0.2
Add unsupported Tuple[type_, ...] check. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/15
Tuple[type_, ...] check. by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/15Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v1.0.0...v1.0.1
Major release; I'm happy with the API and overall performance.
Major release; I'm happy with the API and overall performance.
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v0.2.0...v1.0.0
add dispatcher argument to interactive_shell by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/8
Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v0.1.2...v0.2.0
Don't consider show=False or parse=False parameters when determining column layout in help text by @BrianPugh in https://github.com/BrianPugh/cyclopts
show=False or parse=False parameters when determining column layout in help text by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/5sys.argv[0] by @BrianPugh in https://github.com/BrianPugh/cyclopts/pull/6App doesn't have explicit help text, it should fallback to app.default_command.__doc__, then app.meta.default_command, app.meta.meta.default_command, and so on.Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v0.1.1...v0.1.2
Removed app.__len__, causes more confusion than convenience it provided.
app.__len__, causes more confusion than convenience it provided.Full Changelog: https://github.com/BrianPugh/cyclopts/compare/v0.1.0...v0.1.1
Full Changelog: https://github.com/BrianPugh/cyclopts/commits/v0.1.0
Full Changelog: https://github.com/BrianPugh/cyclopts/commits/v0.1.0
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →