Skip to content

Conversation

lmmx
Copy link

@lmmx lmmx commented Aug 13, 2025

Adds support for specifying functions directly using colon syntax in the typer CLI, as used in pyproject console scripts entrypoint syntax, and projects like uvicorn/gunicorn.

Described in discussion #1274

Before:

$ typer 'autocli.one:step_1' run 123
Not a valid file or Python module: autocli.one:step_1

$ typer --func=step_1 'autocli.one' run 123  # Required explicit --func flag
Step 1: Processing with a=123, result=processed_123.txt

After:

$ typer 'autocli.one:step_1' run 123
Step 1: Processing with a=123, result=processed_123.txt

$ typer 'path/to/file.py:step_1' run 123  # Also works with file paths
Step 1: Processing with a=123, result=processed_123.txt

The change is pretty minimal - 4 lines added to maybe_update_state() to parse the colon syntax and set the function parameter on the click Context params dict which is then picked up in the existing part of the function afterwards.

Changes:

  • Feature: Parse "module:function" and "/path/to/file.py:function" syntax in typer.cli:maybe_update_state
  • Tests: Add coverage of both module and file path variants
  • Docs: Updated tutorial with examples

This comment was marked as outdated.

@lmmx
Copy link
Author

lmmx commented Aug 14, 2025

Not sure why CI failed, maybe it needs a label added (triage)? Let me know if I can assist 👍

@svlandeg svlandeg changed the title [FEAT] Add module:function syntax support for typer CLI ✨ Add module:function syntax support for typer CLI Aug 18, 2025
@svlandeg svlandeg added the feature New feature, enhancement or request label Aug 18, 2025
@lmmx lmmx force-pushed the run-colon-func-syntax branch from 2137408 to 88b4ffb Compare August 18, 2025 21:17
@lmmx
Copy link
Author

lmmx commented Aug 18, 2025

Rebased to update with trunk, all checks passed 😄

Copy link
Contributor

@lmmx
Copy link
Author

lmmx commented Aug 18, 2025

Great, this looks ready @svlandeg 😄

@svlandeg
Copy link
Member

Thanks @lmmx! I'll try and review this soonish.

@svlandeg svlandeg self-assigned this Aug 22, 2025
Copy link
Member

@svlandeg svlandeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this break the use-case where Windows users specify a full path with C:\somepath?

@svlandeg svlandeg removed their assignment Aug 27, 2025
@lmmx
Copy link
Author

lmmx commented Aug 27, 2025

Oh great catch ! Yes we can check that, very good

import os

def maybe_update_state(ctx: click.Context) -> None:
    path_or_module = ctx.params.get("path_or_module")
    if path_or_module and ":" in path_or_module:
        drive, _ = os.path.splitdrive(path_or_module)
        if not drive:  # avoid misinterpreting "C:\..." on Windows
            module_part, func_part = path_or_module.rsplit(":", 1)
            path_or_module = module_part
            ctx.params.update({"func": func_part})
    ctx.params["path_or_module"] = path_or_module

Hmm and I’d add an OS check to that condition gate too

@github-actions github-actions bot removed the waiting label Aug 27, 2025
@svlandeg svlandeg self-assigned this Sep 3, 2025
Copy link
Member

@svlandeg svlandeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work on this @lmmx!

I've thought about this for a bit, and to be completely honest I'm a little on the fence about having this feature. Mostly because there is already a valid way to achieve what you want. While I can see the appeal of using the : syntax, that also makes the code more verbose and error-prone, as exemplified by the fact that we need to think specifically about Windows paths etc.

I'll solicit feedback from Tiangolo to get his opinion. If he does want to support this, we'll still need to make sure the edits for the Window paths get added & tested.

@svlandeg svlandeg removed their assignment Sep 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature, enhancement or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants