From a9d99f05e4eb2fdd14da11d23e26abb0d6bc4346 Mon Sep 17 00:00:00 2001 From: Andrei Polushin Date: Mon, 25 May 2026 13:32:57 +0700 Subject: [PATCH 1/3] Use 'from typer import' for conciseness When describing a CLI command with `typer`, it might be more common to use unqualified names, especially when you are defining many command parameters and want to avoid repetitive typing. --- source/guides/creating-command-line-tools.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/guides/creating-command-line-tools.rst b/source/guides/creating-command-line-tools.rst index cbe8b3bb0..dc06da618 100644 --- a/source/guides/creating-command-line-tools.rst +++ b/source/guides/creating-command-line-tools.rst @@ -35,15 +35,15 @@ named after the main module: .. code-block:: python - import typer + from typer import Argument, Option from typing_extensions import Annotated def greet( - name: Annotated[str, typer.Argument(help="The (last, if --title is given) name of the person to greet")] = "", - title: Annotated[str, typer.Option(help="The preferred title of the person to greet")] = "", - doctor: Annotated[bool, typer.Option(help="Whether the person is a doctor (MD or PhD)")] = False, - count: Annotated[int, typer.Option(help="Number of times to greet the person")] = 1 + name: Annotated[str, Argument(help="The (last, if --title is given) name of the person to greet")] = "", + title: Annotated[str, Option(help="The preferred title of the person to greet")] = "", + doctor: Annotated[bool, Option(help="Whether the person is a doctor (MD or PhD)")] = False, + count: Annotated[int, Option(help="Number of times to greet the person")] = 1 ): greeting = "Greetings, " if doctor and not title: From 01a70072a0ed55035558fb22212aa14aab69a16c Mon Sep 17 00:00:00 2001 From: Andrei Polushin Date: Mon, 25 May 2026 13:50:03 +0700 Subject: [PATCH 2/3] Separate reusable CLI configuration from executable entry points The intent of `greetings.cli` is likely to preconfigure the `app` object, exportable for reuse by others. Allowing `greetings.cli` to be runnable as a module didn't make much sense, because the `greetings` module itself is already runnable. Exporting the `main()` function and referencing it from the `pyproject.toml` is likely more common and concise than relying on the fact that the `app` object itself is callable. --- source/guides/creating-command-line-tools.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/guides/creating-command-line-tools.rst b/source/guides/creating-command-line-tools.rst index dc06da618..f9747eb42 100644 --- a/source/guides/creating-command-line-tools.rst +++ b/source/guides/creating-command-line-tools.rst @@ -69,13 +69,12 @@ in :file:`cli.py`: from .greet import greet - app = typer.Typer() app.command()(greet) - if __name__ == "__main__": - app() + def main(): + return app() The command-line interface is built with typer_, an easy-to-use CLI parser based on Python type hints. It provides auto-completion and nicely styled command-line help out of the box. Another option would be :py:mod:`argparse`, @@ -113,7 +112,7 @@ For the project to be recognised as a command-line tool, additionally a ``consol .. code-block:: toml [project.scripts] - greet = "greetings.cli:app" + greet = "greetings.cli:main" Now, the project's source tree is ready to be transformed into a :term:`distribution package `, which makes it installable. @@ -162,7 +161,7 @@ The same can be defined as follows in :file:`pyproject.toml`: .. code-block:: toml [project.entry-points."pipx.run"] - greetings = "greetings.cli:app" + greetings = "greetings.cli:main" Thanks to this entry point (which *must* match the package name), ``pipx`` will pick up the executable script as the From 00978cc826cc3f7389f3a65f6a5f24c3cdfcc4d5 Mon Sep 17 00:00:00 2001 From: Andrei Polushin Date: Mon, 25 May 2026 14:12:41 +0700 Subject: [PATCH 3/3] Simplify the launcher Importing the `main()` function is likely more common and concise than relying on the heavy-weight `app` object to be callable. --- source/guides/creating-command-line-tools.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/guides/creating-command-line-tools.rst b/source/guides/creating-command-line-tools.rst index f9747eb42..155be7658 100644 --- a/source/guides/creating-command-line-tools.rst +++ b/source/guides/creating-command-line-tools.rst @@ -90,9 +90,12 @@ so initialize the command-line interface here: .. code-block:: python - if __name__ == "__main__": - from greetings.cli import app - app() + import sys + + if __name__ == "__main__": + from greetings.cli import main + + sys.exit(main()) .. note::