Skip to content

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Oct 25, 2025

This PR contains the following updates:

Package Change Age Confidence
cyclopts ~=3.24.0 -> ~=4.2.2 age confidence

Release Notes

BrianPugh/cyclopts (cyclopts)

v4.2.2

Compare Source

Bug Fixes

Docs

Full Changelog: BrianPugh/cyclopts@v4.2.1...v4.2.2

v4.2.1

Compare Source

Bug Fixes

  • Resolve TypeAliasType (python >=3.12). by @​BrianPugh in #​670
    • Fixes annotated parameter resolution for syntax like:
      type Foo = Annotated[int, cyclopts.Parameter(alias=-f”)]

Full Changelog: BrianPugh/cyclopts@v4.2.0...v4.2.1

v4.2.0

Compare Source

Features

Bug Fixes

Internal

Full Changelog: BrianPugh/cyclopts@v4.1.0...v4.2.0

v4.1.0

Compare Source

Features

  • Support pydantic Secret-types (SecretStr, SecretBytes, etc) by @​BrianPugh in #​620

  • Parameter.count for int counting-flags (e.g., verbosity -vvv). by @​BrianPugh in #​622

    from cyclopts import Parameter
    
    def main(verbose: Annotated[int, Parameter(alias="-v", count=True)] = 0):
        print(f"Verbosity level: {verbose}")  # -vvv → 3
  • Add App.help_epilogue, which prints a message at the bottom of the app's help-page. by @​BrianPugh in #​628

    app = App(help_epilogue="For more info, visit: https://cyclopts.readthedocs.io")
    
    @​app.default
    def main(name: str):
        """Greet someone."""
        print(f"Hello {name}")
    
    # ╭─ Parameters ───────────────────────────────╮
    # │ *  NAME  [required]                        │
    # ╰────────────────────────────────────────────╯
    #
    # For more info, visit: https://cyclopts.readthedocs.io
  • Add help from dataclass/attrs metadata to the resolution hierarchy. by @​BrianPugh in #​642

    from dataclasses import dataclass, field
    
    @​dataclass
    class Config:
        port: int = field(default=8080, metadata={"help": "Server port"})
  • Add GNU-style combined short options support by @​BrianPugh in #​639

    from typing import Annotated
    from cyclopts import Parameter
    
    def main(
        verbose: Annotated[bool, Parameter(alias="-v")],
        user: Annotated[str, Parameter(alias="-u")],
    ):
        pass
    
    # -v -uroot         → verbose=True, user="root"
    # -vuroot           → verbose=True, user="root"  (GNU-style combined)
    # -vu root          → verbose=True, user="root"
  • More powerful ArgumentCollection.__getitem__ to support looking up by parameter name by @​isoschiz in #​635

    arg = argument_collection["param_name"]  # Lookup by parameter name

Bug Fixes

  • Resolve the default version to the nearest explicitly set App.version value instead of root-app version value. by @​BrianPugh in #​632
  • Have MutuallyExclusive group validator accurately report the user-specified option name instead of the first positive name. by @​BrianPugh in #​634
  • Have MissingArgumentError accurately report the user-specified option name instead of the first positive name. by @​BrianPugh in #​638
  • Fix the negative-flag showing up twice for Optional[bool] in the help-page. by @​BrianPugh in #​633
  • Fix incorrect deleting of help/version flag commands when overwriting their respective flag attributes. by @​BrianPugh in #​644
  • Fix unexpected exception when both --help and --version are passed to a subcommand. --help takes precedence. by @​BrianPugh in #​650
  • Allow positional elements of kw-only dataclass. by @​BrianPugh in #​651
  • Fix cyclopts.__version__ not being updated (due to uv migration). by @​BrianPugh in #​657
  • Add parse=False to App.version_print handlers. by @​BrianPugh in #​656
  • Fix kw-only dataclass object instantiation by @​BrianPugh in #​658
  • Misc (mostly internal) type hinting improvements by @​BrianPugh in #​659
  • Fix config command filtering logic. by @​BrianPugh in #​660

Special thanks to @​isoschiz for thorough testing and bug reporting!

Documentation

New Contributors

Full Changelog: BrianPugh/cyclopts@v4.0.0...v4.1.0

v4.0.0

Compare Source

Cyclopts v4 represents a big feature update that makes it a no-compromise CLI python framework.

While Cyclopts v4 has a few breaking changes that generally make applications cleaner/terser/more intuitive, most shouldn't severely impact applications in the wild. This section lists the changes from most impactful to least.

Breaking Features / Breaking Changes / Migration

  • The default help/version formatting has been changed from RestructuredText to Markdown.

    • To keep old behavior, set App(help_format="restructuredtext").
  • Default behavior of App.__call__ and App.run_async return value has changed. By default, these methods do not return and now perform a sys.exit. This ensures that scripts and installed applications have consistent exit code behavior. Previously, a script might have had a different exit code compared to an equivalent installed package. This behavior can be controlled via the new attribute App.result_action.

    • To replicate the old behavior, set result_action="return_value" in your root app.

      app = App(result_action="return_value")
  • New App-inheritance mechanism/priorities. For most users this will have no impact, but pay attention if you use Meta Apps.

    • Previously, meta-apps were treated as mostly independent. They now inherit configurations from their parent App.
    • The execution path through the App tree may now be different from the inheritance path. Meta App parents are higher up the inheritance tree than meta-apps. I.e., app.meta inherits from app.
    • See #​497 for discussion.
  • Dropped Python 3.9 support. Python 3.9 EOL is October 31, 2025.

  • On the help page, the root application name falls back to the script name (instead of the registered @app.default command name).

  • If a dataclass-like parameter is annotated with Parameter(name="*"), and all of its attributes are optional, but the parameter itself is not optional, a ValueError will now be raised. The value in the function signature must have a default value like None. See discussion in #​519.

  • InvalidCommandError has been renamed UnknownCommandError for consistency.

  • Errors are now printed to stderr instead of stdout. Uses the new App.error_console.

    • If you want the old behavior (printing errors to stdout), set error_console to a console writing to stdout:

      from rich.console import Console
      app = App(error_console=Console())
  • All Parameter arguments except name (the only positional parameter) are now keyword-only.

  • If only nameless Groups are assigned to a Parameter, the default Argument/Parameter group is still also applied. This is most convenient when applying a validator without impacting the help page.

Features

Pure "value added" features.

  • Lazy loading - Commands can now be registered using import paths (e.g., "myapp.commands.users:create"), which defers module imports until the command is executed. This dramatically improves CLI startup time for applications with many commands or heavy dependencies.

    from cyclopts import App
    
    app = App(name="myapp")
    user_app = App(name="user")
    
    # Module only imported when command is executed
    user_app.command("myapp.commands.users:create")
    app.command(user_app)
  • Shell Completion (supports bash, zsh, fish). Enable with app.register_install_completion_command(), then users can install via myapp --install-completion.

    • Standalone python scripts can have dynamic shell completion via the new cyclopts run CLI command.
  • Help page customization via help_formatter parameter on App and Group.

    • Create fully custom formatters by implementing the HelpFormatter protocol.
    • Built-in formatters: DefaultFormatter (Rich-based with colors/borders) and PlainFormatter (accessibility-focused plain text).
  • New cyclopts CLI tool.

    • cyclopts run - Execute a python script with dynamic shell-completion.
    • cyclopts generate-docs - Generates documentation in a variety of formats (markdown, restructuredtext, html).
      • Example: cyclopts generate-docs myscript.py -o docs.md
  • Sphinx Extension for automatically generating CLI documentation from your Cyclopts App.

    • Use the .. cyclopts:: mypackage.cli:app directive in your RST files.
  • New App attributes; many of these were available as App.__call__ parameters, but now they can also be directly set on App and are inherited as expected:

    • print_error - Whether Cyclopts should print the rich-formatted error when a CycloptsError is encountered. True by default.
    • exit_on_error - If there is an error parsing/coercing the CLI tokens, invoke sys.exit(1). True by default.
    • help_on_error - If there is an error parsing/coercing the CLI tokens, print out the help-page for the parsed application. False by default.
    • verbose - Populate CycloptsError exception strings with more information intended for developers. False by default.
  • flatten subapp's subcommands if named "*". by @​BrianPugh in #​611

  • Add support for enum.Flag and enum.IntFlag.

  • Add support for datetime.date type by @​PerchunPak in #​601

  • Add cyclopts.config.Dict config class for in-memory configuration sources. Add new keyword argument source to config objects. by @​BrianPugh in #​599

  • App.console now always resolves to a console and respects the app-hierarchy. If a console is explicitly assigned, that console will always be used. This makes it easier to access a console object within commands.

  • Improved parsing of JSON strings from the CLI. Can now handle list[CustomClass] if each element is supplied as a JSON string.

  • Optimized "happy execution path" performance.

  • If App.sort_key or Group.sort_key are generators, Cyclopts automatically invokes next on them immediately.

    • This allows for streamlined lexical ordering of commands using itertools.count:

      from itertools import count
      from cyclopts import App, Group
      
      counter = count()
      
      @​app.command(group=Group("Commands", sort_key=counter))
      def first():
          pass
      
      @​app.command(group=Group("Commands", sort_key=counter))
      def second():
          pass

Bug Fixes

  • Fixed empty iterables handling within Pydantic models.
  • Allow for 0 arguments for iterables (e.g., list[int]) when consume_multiple=True.
  • Fixed incorrect parsing of very large integers.
  • Do not parse help_flags after end_of_options_delimiter by @​BrianPugh in #​609

Internal / Developer

  • Migrated internal project manager from Poetry to uv.

Configuration

📅 Schedule: Branch creation - "every weekend" in timezone US/Eastern, Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot force-pushed the renovate/cyclopts-4.x branch 16 times, most recently from 34d2dc7 to 0254f58 Compare November 1, 2025 10:52
@renovate renovate bot force-pushed the renovate/cyclopts-4.x branch 13 times, most recently from def00c4 to da84754 Compare November 8, 2025 11:16
@renovate renovate bot force-pushed the renovate/cyclopts-4.x branch from da84754 to adfa39b Compare November 8, 2025 19:10
@renovate renovate bot force-pushed the renovate/cyclopts-4.x branch 3 times, most recently from ded8416 to cd26534 Compare November 10, 2025 11:51
@renovate renovate bot force-pushed the renovate/cyclopts-4.x branch from cd26534 to 4df7ad9 Compare November 10, 2025 20:22
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