Showing preview only (1,374K chars total). Download the full file or copy to clipboard to get everything.
Repository: fastapi/typer
Branch: master
Commit: f47d887d4c3e
Files: 725
Total size: 1.2 MB
Directory structure:
gitextract_06wjnt0r/
├── .github/
│ ├── DISCUSSION_TEMPLATE/
│ │ └── questions.yml
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ └── privileged.yml
│ ├── dependabot.yml
│ ├── labeler.yml
│ └── workflows/
│ ├── add-to-project.yml
│ ├── build-docs.yml
│ ├── conflict.yml
│ ├── deploy-docs.yml
│ ├── issue-manager.yml
│ ├── labeler.yml
│ ├── latest-changes.yml
│ ├── pre-commit.yml
│ ├── publish.yml
│ ├── smokeshow.yml
│ ├── test-cpython-nightly.yml
│ ├── test-redistribute.yml
│ └── test.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── CITATION.cff
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── data/
│ └── members.yml
├── docs/
│ ├── about/
│ │ └── index.md
│ ├── alternatives.md
│ ├── contributing.md
│ ├── css/
│ │ ├── custom.css
│ │ └── termynal.css
│ ├── environment-variables.md
│ ├── features.md
│ ├── help-typer.md
│ ├── index.md
│ ├── js/
│ │ ├── custom.js
│ │ └── termynal.js
│ ├── management-tasks.md
│ ├── management.md
│ ├── overrides/
│ │ └── main.html
│ ├── reference/
│ │ ├── context.md
│ │ ├── file_objects.md
│ │ ├── index.md
│ │ ├── parameters.md
│ │ ├── run_launch.md
│ │ └── typer.md
│ ├── release-notes.md
│ ├── resources/
│ │ └── index.md
│ ├── tutorial/
│ │ ├── app-dir.md
│ │ ├── arguments/
│ │ │ ├── default.md
│ │ │ ├── envvar.md
│ │ │ ├── help.md
│ │ │ ├── index.md
│ │ │ ├── optional.md
│ │ │ └── other-uses.md
│ │ ├── commands/
│ │ │ ├── arguments.md
│ │ │ ├── callback.md
│ │ │ ├── context.md
│ │ │ ├── help.md
│ │ │ ├── index.md
│ │ │ ├── name.md
│ │ │ ├── one-or-multiple.md
│ │ │ └── options.md
│ │ ├── exceptions.md
│ │ ├── first-steps.md
│ │ ├── index.md
│ │ ├── install.md
│ │ ├── launch.md
│ │ ├── multiple-values/
│ │ │ ├── arguments-with-multiple-values.md
│ │ │ ├── index.md
│ │ │ ├── multiple-options.md
│ │ │ └── options-with-multiple-values.md
│ │ ├── one-file-per-command.md
│ │ ├── options/
│ │ │ ├── callback-and-context.md
│ │ │ ├── help.md
│ │ │ ├── index.md
│ │ │ ├── name.md
│ │ │ ├── password.md
│ │ │ ├── prompt.md
│ │ │ ├── required.md
│ │ │ └── version.md
│ │ ├── options-autocompletion.md
│ │ ├── package.md
│ │ ├── parameter-types/
│ │ │ ├── bool.md
│ │ │ ├── custom-types.md
│ │ │ ├── datetime.md
│ │ │ ├── enum.md
│ │ │ ├── file.md
│ │ │ ├── index.md
│ │ │ ├── number.md
│ │ │ ├── path.md
│ │ │ └── uuid.md
│ │ ├── printing.md
│ │ ├── progressbar.md
│ │ ├── prompt.md
│ │ ├── subcommands/
│ │ │ ├── add-typer.md
│ │ │ ├── callback-override.md
│ │ │ ├── index.md
│ │ │ ├── name-and-help.md
│ │ │ ├── nested-subcommands.md
│ │ │ └── single-file.md
│ │ ├── terminating.md
│ │ ├── testing.md
│ │ ├── typer-app.md
│ │ └── typer-command.md
│ └── virtual-environments.md
├── docs_src/
│ ├── app_dir/
│ │ ├── __init__.py
│ │ └── tutorial001_py310.py
│ ├── arguments/
│ │ ├── __init__.py
│ │ ├── default/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ ├── envvar/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ └── tutorial003_py310.py
│ │ ├── help/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_an_py310.py
│ │ │ ├── tutorial005_py310.py
│ │ │ ├── tutorial006_an_py310.py
│ │ │ ├── tutorial006_py310.py
│ │ │ ├── tutorial007_an_py310.py
│ │ │ ├── tutorial007_py310.py
│ │ │ ├── tutorial008_an_py310.py
│ │ │ └── tutorial008_py310.py
│ │ └── optional/
│ │ ├── __init__.py
│ │ ├── tutorial000_an_py310.py
│ │ ├── tutorial000_py310.py
│ │ ├── tutorial001_an_py310.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_an_py310.py
│ │ ├── tutorial002_py310.py
│ │ └── tutorial003_py310.py
│ ├── commands/
│ │ ├── __init__.py
│ │ ├── arguments/
│ │ │ ├── __init__.py
│ │ │ └── tutorial001_py310.py
│ │ ├── callback/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── context/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── help/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_an_py310.py
│ │ │ ├── tutorial005_py310.py
│ │ │ ├── tutorial006_py310.py
│ │ │ ├── tutorial007_an_py310.py
│ │ │ ├── tutorial007_py310.py
│ │ │ └── tutorial008_py310.py
│ │ ├── index/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ └── tutorial005_py310.py
│ │ ├── name/
│ │ │ ├── __init__.py
│ │ │ └── tutorial001_py310.py
│ │ ├── one_or_multiple/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ └── tutorial002_py310.py
│ │ └── options/
│ │ ├── __init__.py
│ │ ├── tutorial001_an_py310.py
│ │ └── tutorial001_py310.py
│ ├── exceptions/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ └── tutorial004_py310.py
│ ├── first_steps/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ ├── tutorial004_py310.py
│ │ ├── tutorial005_py310.py
│ │ └── tutorial006_py310.py
│ ├── launch/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ └── tutorial002_py310.py
│ ├── multiple_values/
│ │ ├── __init__.py
│ │ ├── arguments_with_multiple_values/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ ├── multiple_options/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ └── options_with_multiple_values/
│ │ ├── __init__.py
│ │ ├── tutorial001_an_py310.py
│ │ └── tutorial001_py310.py
│ ├── one_file_per_command/
│ │ ├── __init__.py
│ │ └── app_py310/
│ │ ├── __init__.py
│ │ ├── main.py
│ │ ├── users/
│ │ │ ├── __init__.py
│ │ │ ├── add.py
│ │ │ └── delete.py
│ │ └── version.py
│ ├── options/
│ │ ├── __init__.py
│ │ ├── callback/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── help/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── name/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_an_py310.py
│ │ │ └── tutorial005_py310.py
│ │ ├── password/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ ├── prompt/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ └── tutorial003_py310.py
│ │ ├── required/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ └── tutorial002_py310.py
│ │ └── version/
│ │ ├── __init__.py
│ │ ├── tutorial001_an_py310.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_an_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_an_py310.py
│ │ └── tutorial003_py310.py
│ ├── options_autocompletion/
│ │ ├── __init__.py
│ │ ├── tutorial001_an_py310.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_an_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_an_py310.py
│ │ ├── tutorial003_py310.py
│ │ ├── tutorial004_an_py310.py
│ │ ├── tutorial004_py310.py
│ │ ├── tutorial005_an_py310.py
│ │ ├── tutorial005_py310.py
│ │ ├── tutorial006_an_py310.py
│ │ ├── tutorial006_py310.py
│ │ ├── tutorial007_an_py310.py
│ │ ├── tutorial007_py310.py
│ │ ├── tutorial008_an_py310.py
│ │ ├── tutorial008_py310.py
│ │ ├── tutorial009_an_py310.py
│ │ └── tutorial009_py310.py
│ ├── parameter_types/
│ │ ├── __init__.py
│ │ ├── bool/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── custom_types/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ └── tutorial001_py310.py
│ │ ├── datetime/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ ├── enum/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── file/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_an_py310.py
│ │ │ └── tutorial005_py310.py
│ │ ├── index/
│ │ │ ├── __init__.py
│ │ │ └── tutorial001_py310.py
│ │ ├── number/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ └── tutorial003_py310.py
│ │ ├── path/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ └── uuid/
│ │ ├── __init__.py
│ │ └── tutorial001_py310.py
│ ├── printing/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ ├── tutorial004_py310.py
│ │ ├── tutorial005_py310.py
│ │ └── tutorial006_py310.py
│ ├── progressbar/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ ├── tutorial004_py310.py
│ │ ├── tutorial005_py310.py
│ │ └── tutorial006_py310.py
│ ├── prompt/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ └── tutorial004_py310.py
│ ├── subcommands/
│ │ ├── __init__.py
│ │ ├── callback_override/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── name_help/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_py310.py
│ │ │ ├── tutorial006_py310.py
│ │ │ ├── tutorial007_py310.py
│ │ │ └── tutorial008_py310.py
│ │ ├── tutorial001_py310/
│ │ │ ├── __init__.py
│ │ │ ├── items.py
│ │ │ ├── main.py
│ │ │ └── users.py
│ │ ├── tutorial002_py310/
│ │ │ ├── __init__.py
│ │ │ └── main.py
│ │ └── tutorial003_py310/
│ │ ├── __init__.py
│ │ ├── items.py
│ │ ├── lands.py
│ │ ├── main.py
│ │ ├── reigns.py
│ │ ├── towns.py
│ │ └── users.py
│ ├── terminating/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ └── tutorial003_py310.py
│ ├── testing/
│ │ ├── __init__.py
│ │ ├── app01_py310/
│ │ │ ├── __init__.py
│ │ │ ├── main.py
│ │ │ └── test_main.py
│ │ ├── app02_an_py310/
│ │ │ ├── __init__.py
│ │ │ ├── main.py
│ │ │ └── test_main.py
│ │ ├── app02_py310/
│ │ │ ├── __init__.py
│ │ │ ├── main.py
│ │ │ └── test_main.py
│ │ └── app03_py310/
│ │ ├── __init__.py
│ │ ├── main.py
│ │ └── test_main.py
│ └── typer_app/
│ ├── __init__.py
│ └── tutorial001_py310.py
├── mkdocs.env.yml
├── mkdocs.yml
├── pyproject.toml
├── scripts/
│ ├── deploy_docs_status.py
│ ├── docker/
│ │ ├── Dockerfile
│ │ └── compose.yaml
│ ├── docs.py
│ ├── format.sh
│ ├── get-pwsh-activate.sh
│ ├── lint.sh
│ ├── mkdocs_hooks.py
│ ├── test-cov-html.sh
│ ├── test-files.sh
│ └── test.sh
├── tests/
│ ├── __init__.py
│ ├── assets/
│ │ ├── __init__.py
│ │ ├── cli/
│ │ │ ├── __init__.py
│ │ │ ├── app_other_name.py
│ │ │ ├── empty_script.py
│ │ │ ├── extended_app_cli.py
│ │ │ ├── extended_empty_app_cli.py
│ │ │ ├── func_other_name.py
│ │ │ ├── multi_app.py
│ │ │ ├── multi_app_cli.py
│ │ │ ├── multi_app_norich.py
│ │ │ ├── multi_func.py
│ │ │ ├── multiapp-docs-title.md
│ │ │ ├── multiapp-docs.md
│ │ │ ├── not_python.txt
│ │ │ ├── rich_formatted_app.py
│ │ │ ├── richformattedapp-docs.md
│ │ │ └── sample.py
│ │ ├── completion_argument.py
│ │ ├── completion_no_types.py
│ │ ├── completion_no_types_order.py
│ │ ├── corner_cases.py
│ │ ├── print_modules.py
│ │ ├── prog_name.py
│ │ ├── type_error_no_rich.py
│ │ ├── type_error_no_rich_short_disable.py
│ │ └── type_error_normal_traceback.py
│ ├── test_ambiguous_params.py
│ ├── test_annotated.py
│ ├── test_callback_warning.py
│ ├── test_cli/
│ │ ├── __init__.py
│ │ ├── test_app_other_name.py
│ │ ├── test_completion_run.py
│ │ ├── test_doc.py
│ │ ├── test_empty_script.py
│ │ ├── test_extending_app.py
│ │ ├── test_extending_empty_app.py
│ │ ├── test_func_other_name.py
│ │ ├── test_help.py
│ │ ├── test_multi_app.py
│ │ ├── test_multi_app_cli.py
│ │ ├── test_multi_app_sub.py
│ │ ├── test_multi_func.py
│ │ ├── test_not_python.py
│ │ ├── test_sub.py
│ │ ├── test_sub_completion.py
│ │ ├── test_sub_help.py
│ │ └── test_version.py
│ ├── test_completion/
│ │ ├── __init__.py
│ │ ├── colon_example.py
│ │ ├── example_rich_tags.py
│ │ ├── path_example.py
│ │ ├── test_completion.py
│ │ ├── test_completion_complete.py
│ │ ├── test_completion_complete_no_help.py
│ │ ├── test_completion_complete_rich.py
│ │ ├── test_completion_install.py
│ │ ├── test_completion_option_colon.py
│ │ ├── test_completion_path.py
│ │ ├── test_completion_show.py
│ │ └── test_sanitization.py
│ ├── test_corner_cases.py
│ ├── test_deprecation.py
│ ├── test_exit_errors.py
│ ├── test_future_annotations.py
│ ├── test_launch.py
│ ├── test_others.py
│ ├── test_param_meta_empty.py
│ ├── test_prog_name.py
│ ├── test_rich_import.py
│ ├── test_rich_markup_mode.py
│ ├── test_rich_utils.py
│ ├── test_suggest_commands.py
│ ├── test_tracebacks.py
│ ├── test_tutorial/
│ │ ├── __init__.py
│ │ ├── test_app_dir/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial001.py
│ │ ├── test_arguments/
│ │ │ ├── __init__.py
│ │ │ ├── test_default/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ ├── test_envvar/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ └── test_tutorial003.py
│ │ │ ├── test_help/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ ├── test_tutorial005.py
│ │ │ │ ├── test_tutorial006.py
│ │ │ │ ├── test_tutorial007.py
│ │ │ │ └── test_tutorial008.py
│ │ │ └── test_optional/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial000.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ └── test_tutorial003.py
│ │ ├── test_commands/
│ │ │ ├── __init__.py
│ │ │ ├── test_arguments/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001.py
│ │ │ ├── test_callback/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_context/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_help/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ ├── test_tutorial005.py
│ │ │ │ ├── test_tutorial006.py
│ │ │ │ ├── test_tutorial007.py
│ │ │ │ └── test_tutorial008.py
│ │ │ ├── test_index/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ └── test_tutorial005.py
│ │ │ ├── test_name/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001.py
│ │ │ ├── test_one_or_multiple/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ └── test_options/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial001.py
│ │ ├── test_exceptions/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ └── test_tutorial004.py
│ │ ├── test_first_steps/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ ├── test_tutorial004.py
│ │ │ ├── test_tutorial005.py
│ │ │ └── test_tutorial006.py
│ │ ├── test_launch/
│ │ │ ├── test_tutorial001.py
│ │ │ └── test_tutorial002.py
│ │ ├── test_multiple_values/
│ │ │ ├── __init__.py
│ │ │ ├── test_arguments_with_multiple_values/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ ├── test_multiple_options/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ └── test_options_with_multiple_values/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial001.py
│ │ ├── test_one_file_per_command/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial.py
│ │ ├── test_options/
│ │ │ ├── __init__.py
│ │ │ ├── test_callback/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_help/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_name/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ └── test_tutorial005.py
│ │ │ ├── test_password/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ ├── test_prompt/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ └── test_tutorial003.py
│ │ │ ├── test_required/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001_tutorial002.py
│ │ │ └── test_version/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ └── test_tutorial003.py
│ │ ├── test_options_autocompletion/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ ├── test_tutorial004_tutorial005.py
│ │ │ ├── test_tutorial006.py
│ │ │ ├── test_tutorial007.py
│ │ │ ├── test_tutorial008.py
│ │ │ └── test_tutorial009.py
│ │ ├── test_parameter_types/
│ │ │ ├── __init__.py
│ │ │ ├── test_bool/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_custom_types/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001.py
│ │ │ ├── test_datetime/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ ├── test_enum/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_file/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ └── test_tutorial005.py
│ │ │ ├── test_index/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001.py
│ │ │ ├── test_number/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ └── test_tutorial003.py
│ │ │ ├── test_path/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ └── test_uuid/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial001.py
│ │ ├── test_printing/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ ├── test_tutorial004.py
│ │ │ ├── test_tutorial005.py
│ │ │ └── test_tutorial006.py
│ │ ├── test_progressbar/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ ├── test_tutorial004.py
│ │ │ ├── test_tutorial005.py
│ │ │ └── test_tutorial006.py
│ │ ├── test_prompt/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ └── test_tutorial004.py
│ │ ├── test_subcommands/
│ │ │ ├── __init__.py
│ │ │ ├── test_callback_override/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_name_help/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ ├── test_tutorial005.py
│ │ │ │ ├── test_tutorial006.py
│ │ │ │ ├── test_tutorial007.py
│ │ │ │ └── test_tutorial008.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ └── test_tutorial003.py
│ │ ├── test_terminating/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ └── test_tutorial003.py
│ │ ├── test_testing/
│ │ │ ├── __init__.py
│ │ │ ├── test_app01.py
│ │ │ ├── test_app02.py
│ │ │ └── test_app03.py
│ │ └── test_typer_app/
│ │ ├── __init__.py
│ │ └── test_tutorial001.py
│ ├── test_type_conversion.py
│ ├── test_types.py
│ └── utils.py
├── typer/
│ ├── __init__.py
│ ├── __main__.py
│ ├── _completion_classes.py
│ ├── _completion_shared.py
│ ├── _types.py
│ ├── _typing.py
│ ├── cli.py
│ ├── colors.py
│ ├── completion.py
│ ├── core.py
│ ├── main.py
│ ├── models.py
│ ├── params.py
│ ├── py.typed
│ ├── rich_utils.py
│ ├── testing.py
│ └── utils.py
├── typer-cli/
│ └── README.md
└── typer-slim/
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/DISCUSSION_TEMPLATE/questions.yml
================================================
labels: [question]
body:
- type: markdown
attributes:
value: |
Thanks for your interest in Typer! 🚀
Please follow these instructions, fill every question, and do every step. 🙏
I'm asking this because answering questions and solving problems in GitHub is what consumes most of the time.
I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling questions.
All that, on top of all the incredible help provided by a bunch of community members that give a lot of their time to come here and help others.
If more Typer users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
By asking questions in a structured way (following this) it will be much easier to help you.
And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
As there are too many questions, I'll have to discard and close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
- type: checkboxes
id: checks
attributes:
label: First Check
description: Please confirm and check all the following options.
options:
- label: I added a very descriptive title here.
required: true
- label: I used the GitHub search to find a similar question and didn't find it.
required: true
- label: I searched the Typer documentation, with the integrated search.
required: true
- label: I already searched in Google "How to X in Typer" and didn't find any information.
required: true
- label: I already read and followed all the tutorials in the docs and didn't find an answer.
required: true
- label: I already checked if it is not related to Typer but to [Click](https://github.com/pallets/click).
required: true
- type: checkboxes
id: help
attributes:
label: Commit to Help
description: |
After submitting this, I commit to one of:
* Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
* I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
* Review one Pull Request by downloading the code and following all the [review process](https://typer.tiangolo.com/help-typer/#review-pull-requests).
options:
- label: I commit to help with one of those options 👆
required: true
- type: textarea
id: example
attributes:
label: Example Code
description: |
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
If I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you.
placeholder: |
import typer
app = typer.Typer()
@app.command()
def main(name: str):
typer.echo(f"Hello {name}")
if __name__ == "__main__":
app()
render: python
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: |
What is the problem, question, or error?
Write a short description telling me what you are doing, what you expect to happen, and what is currently happening.
placeholder: |
* Create a small Typer script.
* Open a Terminal with Ninja-Turtle-Shell.
* Trigger autocompletion hitting TAB.
* I don't see any completion in the terminal using Ninja-Turtle-Shell.
* I expected to see autocompletion there.
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating System
description: What operating system are you on?
multiple: true
options:
- Linux
- Windows
- macOS
- Other
validations:
required: true
- type: textarea
id: os-details
attributes:
label: Operating System Details
description: You can add more details about your operating system here, in particular if you chose "Other".
- type: input
id: typer-version
attributes:
label: Typer Version
description: |
What Typer version are you using?
You can find the Typer version with:
```bash
python -c "import typer; print(typer.__version__)"
```
validations:
required: true
- type: input
id: python-version
attributes:
label: Python Version
description: |
What Python version are you using?
You can find the Python version with:
```bash
python --version
```
validations:
required: true
- type: textarea
id: context
attributes:
label: Additional Context
description: Add any additional context information or screenshots you think are useful.
================================================
FILE: .github/FUNDING.yml
================================================
github: [tiangolo]
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Security Contact
about: Please report security vulnerabilities to security@tiangolo.com
- name: Question or Problem
about: Ask a question or ask about a problem in GitHub Discussions.
url: https://github.com/fastapi/typer/discussions/categories/questions
- name: Feature Request
about: To suggest an idea or ask about a feature, please start with a question saying what you would like to achieve. There might be a way to do it already.
url: https://github.com/fastapi/typer/discussions/categories/questions
- name: Show and tell
about: Show what you built with Typer or to be used with Typer.
url: https://github.com/fastapi/typer/discussions/categories/show-and-tell
================================================
FILE: .github/ISSUE_TEMPLATE/privileged.yml
================================================
name: Privileged
description: You are @tiangolo or he asked you directly to create an issue here. If not, check the other options. 👇
body:
- type: markdown
attributes:
value: |
Thanks for your interest in Typer! 🚀
If you are not @tiangolo or he didn't ask you directly to create an issue here, please start the conversation in a [Question in GitHub Discussions](https://github.com/fastapi/typer/discussions/categories/questions) instead.
- type: checkboxes
id: privileged
attributes:
label: Privileged issue
description: Confirm that you are allowed to create an issue here.
options:
- label: I'm @tiangolo or he asked me directly to create an issue here.
required: true
- type: textarea
id: content
attributes:
label: Issue Content
description: Add the content of the issue here.
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
# GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
commit-message:
prefix: ⬆
# Python
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "daily"
commit-message:
prefix: ⬆
================================================
FILE: .github/labeler.yml
================================================
docs:
- all:
- changed-files:
- any-glob-to-any-file:
- docs/**
- docs_src/**
- all-globs-to-all-files:
- '!typer/**'
- '!pyproject.toml'
internal:
- all:
- changed-files:
- any-glob-to-any-file:
- .github/**
- scripts/**
- .gitignore
- .pre-commit-config.yaml
- uv.lock
- all-globs-to-all-files:
- '!docs/**'
- '!typer/**'
- '!pyproject.toml'
================================================
FILE: .github/workflows/add-to-project.yml
================================================
name: Add to Project
on:
pull_request_target:
issues:
types:
- opened
- reopened
jobs:
add-to-project:
name: Add to project
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v1.0.2
with:
project-url: https://github.com/orgs/fastapi/projects/2
github-token: ${{ secrets.PROJECTS_TOKEN }}
================================================
FILE: .github/workflows/build-docs.yml
================================================
name: Build Docs
on:
push:
branches:
- master
pull_request:
types:
- opened
- synchronize
jobs:
changes:
runs-on: ubuntu-latest
# Required permissions
permissions:
pull-requests: read
# Set job outputs to values from filter step
outputs:
docs: ${{ steps.filter.outputs.docs }}
steps:
- uses: actions/checkout@v6
# For pull requests it's not necessary to checkout the code but for the main branch it is
- uses: dorny/paths-filter@v4
id: filter
with:
filters: |
docs:
- README.md
- docs/**
- docs_src/**
- pyproject.toml
- uv.lock
- mkdocs.yml
- mkdocs.env.yml
- .github/workflows/build-docs.yml
- .github/workflows/deploy-docs.yml
- data/**
build-docs:
needs:
- changes
if: ${{ needs.changes.outputs.docs == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Install docs extras
run: uv sync --locked --no-dev --group docs
- uses: actions/cache@v5
with:
key: mkdocs-cards-${{ github.ref }}-v1
path: .cache
- name: Build Docs
run: uv run ./scripts/docs.py build
- uses: actions/upload-artifact@v7
with:
name: docs-site
path: ./site/**
include-hidden-files: true
# https://github.com/marketplace/actions/alls-green#why
docs-all-green: # This job does nothing and is only used for the branch protection
if: always()
needs:
- build-docs
runs-on: ubuntu-latest
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
allowed-skips: build-docs
================================================
FILE: .github/workflows/conflict.yml
================================================
name: "Conflict detector"
on:
push:
pull_request_target:
types: [synchronize]
jobs:
main:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Check if PRs have merge conflicts
uses: eps1lon/actions-label-merge-conflict@v3
with:
dirtyLabel: "conflicts"
repoToken: "${{ secrets.GITHUB_TOKEN }}"
commentOnDirty: "This pull request has a merge conflict that needs to be resolved."
================================================
FILE: .github/workflows/deploy-docs.yml
================================================
name: Deploy Docs
on:
workflow_run:
workflows:
- Build Docs
types:
- completed
permissions:
deployments: write
issues: write
pull-requests: write
statuses: write
jobs:
deploy-docs:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Install GitHub Actions dependencies
run: uv sync --locked --no-dev --group github-actions
- name: Deploy Docs Status Pending
run: uv run ./scripts/deploy_docs_status.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
RUN_ID: ${{ github.run_id }}
STATE: "pending"
- name: Clean site
run: |
rm -rf ./site
mkdir ./site
- uses: actions/download-artifact@v8
with:
path: ./site/
pattern: docs-site
merge-multiple: true
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
- name: Deploy to Cloudflare Pages
# hashFiles returns an empty string if there are no files
if: hashFiles('./site/*')
id: deploy
env:
PROJECT_NAME: typertiangolo
BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }}
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }}
- name: Deploy Docs Status Error
if: failure()
run: uv run ./scripts/deploy_docs_status.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
RUN_ID: ${{ github.run_id }}
STATE: "error"
- name: Comment Deploy
run: uv run ./scripts/deploy_docs_status.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }}
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
RUN_ID: ${{ github.run_id }}
STATE: "success"
================================================
FILE: .github/workflows/issue-manager.yml
================================================
name: Issue Manager
on:
schedule:
- cron: "13 21 * * *"
issue_comment:
types:
- created
issues:
types:
- labeled
pull_request_target:
types:
- labeled
workflow_dispatch:
permissions:
issues: write
pull-requests: write
jobs:
issue-manager:
if: github.repository_owner == 'fastapi'
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: tiangolo/issue-manager@0.6.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
{
"answered": {
"delay": 864000,
"message": "Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs."
},
"waiting": {
"delay": 2628000,
"message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.",
"reminder": {
"before": "P3D",
"message": "Heads-up: this will be closed in 3 days unless there's new activity."
}
},
"invalid": {
"delay": 0,
"message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
},
"maybe-ai": {
"delay": 0,
"message": "This was marked as potentially AI generated and will be closed now. If this is an error, please provide additional details, make sure to read the docs about contributing and AI."
}
}
================================================
FILE: .github/workflows/labeler.yml
================================================
name: Labels
on:
pull_request_target:
types:
- opened
- synchronize
- reopened
# For label-checker
- labeled
- unlabeled
jobs:
labeler:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v6
if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
- run: echo "Done adding labels"
# Run this after labeler applied labels
check-labels:
needs:
- labeler
permissions:
pull-requests: read
runs-on: ubuntu-latest
steps:
- uses: docker://agilepathway/pull-request-label-checker:latest
with:
one_of: breaking,security,feature,bug,refactor,upgrade,docs,lang-all,internal
repo_token: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/latest-changes.yml
================================================
name: Latest Changes
on:
pull_request_target:
branches:
- master
types:
- closed
workflow_dispatch:
inputs:
number:
description: PR number
required: true
debug_enabled:
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
required: false
default: 'false'
jobs:
latest-changes:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
with:
# To allow latest-changes to commit to the main branch
token: ${{ secrets.TYPER_LATEST_CHANGES }}
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
with:
limit-access-to-actor: true
- uses: tiangolo/latest-changes@0.4.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
latest_changes_file: docs/release-notes.md
latest_changes_header: '## Latest Changes'
end_regex: '^## '
debug_logs: true
label_header_prefix: '### '
================================================
FILE: .github/workflows/pre-commit.yml
================================================
name: pre-commit
on:
pull_request:
types:
- opened
- synchronize
env:
# Forks and Dependabot don't have access to secrets
HAS_SECRETS: ${{ secrets.PRE_COMMIT != '' }}
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
name: Checkout PR for own repo
if: env.HAS_SECRETS == 'true'
with:
# To be able to commit it needs to fetch the head of the branch, not the
# merge commit
ref: ${{ github.head_ref }}
# And it needs the full history to be able to compute diffs
fetch-depth: 0
# A token other than the default GITHUB_TOKEN is needed to be able to trigger CI
token: ${{ secrets.PRE_COMMIT }}
# pre-commit lite ci needs the default checkout configs to work
- uses: actions/checkout@v6
name: Checkout PR for fork
if: env.HAS_SECRETS == 'false'
with:
# To be able to commit it needs the head branch of the PR, the remote one
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv sync --locked
- name: Run prek - pre-commit
id: precommit
run: uvx prek run --from-ref origin/${GITHUB_BASE_REF} --to-ref HEAD --show-diff-on-failure
continue-on-error: true
- name: Commit and push changes
if: env.HAS_SECRETS == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "🎨 Auto format"
git push
fi
- uses: pre-commit-ci/lite-action@v1.1.0
if: env.HAS_SECRETS == 'false'
with:
msg: 🎨 Auto format
- name: Error out on pre-commit errors
if: steps.precommit.outcome == 'failure'
run: exit 1
# https://github.com/marketplace/actions/alls-green#why
pre-commit-alls-green: # This job does nothing and is only used for the branch protection
if: always()
needs:
- pre-commit
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish
on:
release:
types:
- created
jobs:
publish:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version-file: ".python-version"
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Build distribution
run: uv build
- name: Publish
run: uv publish
================================================
FILE: .github/workflows/smokeshow.yml
================================================
name: Smokeshow
on:
workflow_run:
workflows:
- Test
types:
- completed
permissions:
statuses: write
jobs:
smokeshow:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: |
pyproject.toml
uv.lock
- run: uv sync --locked --no-dev --group github-actions
- uses: actions/download-artifact@v8
with:
name: coverage-html
path: htmlcov
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
- run: uv run smokeshow upload htmlcov
env:
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 100
SMOKESHOW_GITHUB_CONTEXT: coverage
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }}
================================================
FILE: .github/workflows/test-cpython-nightly.yml
================================================
name: Test CPython Nightly
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
env:
UV_NO_SYNC: true
jobs:
test-latest-python:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v6
- name: Checkout CPython main
uses: actions/checkout@v6
with:
repository: python/cpython
ref: main
path: ./.cpython
- name: Install CPython build dependencies
run: sudo apt-get update && sudo apt-get install -y build-essential pkg-config libssl-dev zlib1g-dev
- name: Build CPython
run: |
cd ./.cpython
./configure && make -j $(nproc)
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv sync --locked --no-dev --group tests --python ./.cpython/python
- name: Lint
run: uv run bash scripts/lint.sh
- run: mkdir coverage
- run: uv run bash scripts/test-files.sh
- name: Test
run: uv run bash scripts/test.sh
env:
COVERAGE_FILE: coverage/.coverage.ubuntu-cpython-main
CONTEXT: ubuntu-cpython-main
- name: Store coverage files
uses: actions/upload-artifact@v7
with:
name: coverage-ubuntu-cpython-main
path: coverage
include-hidden-files: true
================================================
FILE: .github/workflows/test-redistribute.yml
================================================
name: Test Redistribute
on:
push:
branches:
- master
pull_request:
types:
- opened
- synchronize
jobs:
test-redistribute:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version-file: ".python-version"
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
# cache-dependency-path: pyproject.toml
- name: Install build dependencies
run: pip install build
- name: Build source distribution
run: python -m build --sdist
- name: Decompress source distribution
run: |
cd dist
tar xvf typer*.tar.gz
- name: Install test dependencies
run: |
cd dist/typer*/
pip install --group tests --editable .
- name: Run source distribution tests
run: |
cd dist/typer*/
bash scripts/test.sh
- name: Build wheel distribution
run: |
cd dist
pip wheel --no-deps typer*.tar.gz
# https://github.com/marketplace/actions/alls-green#why
test-redistribute-alls-green: # This job does nothing and is only used for the branch protection
if: always()
needs:
- test-redistribute
runs-on: ubuntu-latest
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
================================================
FILE: .github/workflows/test.yml
================================================
name: Test
on:
push:
branches:
- master
pull_request:
types:
- opened
- synchronize
schedule:
# cron every week on monday
- cron: "0 0 * * 1"
env:
UV_NO_SYNC: true
jobs:
test:
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
python-version: [ "3.14" ]
uv-resolution:
- highest
include:
- os: ubuntu-latest
python-version: "3.10"
uv-resolution: lowest-direct
- os: macos-latest
python-version: "3.11"
uv-resolution: highest
- os: windows-latest
python-version: "3.12"
uv-resolution: lowest-direct
- os: ubuntu-latest
python-version: "3.13"
uv-resolution: highest
fail-fast: false
runs-on: ${{ matrix.os }}
env:
UV_PYTHON: ${{ matrix.python-version }}
UV_RESOLUTION: ${{ matrix.uv-resolution }}
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv sync --no-dev --group tests
- run: mkdir coverage
- run: uv run bash scripts/test-files.sh
- name: Test
run: uv run bash scripts/test.sh
env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
- name: Store coverage files
uses: actions/upload-artifact@v7
with:
name: coverage-${{ runner.os }}-${{ matrix.python-version }}
path: coverage
include-hidden-files: true
coverage-combine:
needs: [test]
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Get coverage files
uses: actions/download-artifact@v8
with:
pattern: coverage-*
path: coverage
merge-multiple: true
- name: Install Dependencies
run: uv sync --locked --no-dev --group tests
- run: ls -la coverage
- run: uv run coverage combine coverage
- run: uv run coverage html --show-contexts --title "Coverage for ${{ github.sha }}"
- name: Store coverage HTML
uses: actions/upload-artifact@v7
with:
name: coverage-html
path: htmlcov
include-hidden-files: true
- run: uv run coverage report --fail-under=100
# https://github.com/marketplace/actions/alls-green#why
check: # This job does nothing and is only used for the branch protection
if: always()
needs:
- coverage-combine
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
================================================
FILE: .gitignore
================================================
.vscode
*.pyc
__pycache__
.venv*
env
dist
.mypy_cache
.idea
site
htmlcov
.pytest_cache
coverage.xml
.coverage*
.cache
================================================
FILE: .pre-commit-config.yaml
================================================
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-added-large-files
- id: check-toml
- id: check-yaml
args:
- --unsafe
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: local
hooks:
- id: local-ruff-check
name: ruff check
entry: uv run ruff check --force-exclude --fix --exit-non-zero-on-fix
require_serial: true
language: unsupported
types: [python]
- id: local-ruff-format
name: ruff format
entry: uv run ruff format --force-exclude --exit-non-zero-on-format
require_serial: true
language: unsupported
types: [python]
- id: local-mypy
name: mypy check
entry: uv run mypy typer
require_serial: true
language: unsupported
pass_filenames: false
- id: local-ty
name: ty check
entry: uv run ty check typer
require_serial: true
language: unsupported
pass_filenames: false
- id: generate-readme
language: unsupported
name: generate README.md from index.md
entry: uv run ./scripts/docs.py generate-readme
files: ^docs/index\.md|scripts/docs\.py$
pass_filenames: false
================================================
FILE: .python-version
================================================
3.10
================================================
FILE: CITATION.cff
================================================
# This CITATION.cff file was generated with cffinit.
# Visit https://bit.ly/cffinit to generate yours today!
cff-version: 1.2.0
title: Typer
message: >-
If you use this software, please cite it using the
metadata from this file.
type: software
authors:
- given-names: Sebastián
family-names: Ramírez
email: tiangolo@gmail.com
identifiers:
repository-code: 'https://github.com/fastapi/typer'
url: 'https://typer.tiangolo.com'
abstract: >-
Typer, build great CLIs. Easy to code. Based on Python type hints.
keywords:
- typer
- click
license: MIT
================================================
FILE: CONTRIBUTING.md
================================================
Please read the [Development - Contributing](https://typer.tiangolo.com/contributing/) guidelines in the documentation site.
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2019 Sebastián Ramírez
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
<p align="center">
<a href="https://typer.tiangolo.com"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg#only-light" alt="Typer"></a>
</p>
<p align="center">
<em>Typer, build great CLIs. Easy to code. Based on Python type hints.</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/typer/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/typer/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://github.com/fastapi/typer/actions?query=workflow%3APublish" target="_blank">
<img src="https://github.com/fastapi/typer/workflows/Publish/badge.svg" alt="Publish">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/typer" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/typer.svg" alt="Coverage">
<a href="https://pypi.org/project/typer" target="_blank">
<img src="https://img.shields.io/pypi/v/typer?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
</p>
---
**Documentation**: <a href="https://typer.tiangolo.com" target="_blank">https://typer.tiangolo.com</a>
**Source Code**: <a href="https://github.com/fastapi/typer" target="_blank">https://github.com/fastapi/typer</a>
---
Typer is a library for building <abbr title="command line interface, programs executed from a terminal">CLI</abbr> applications that users will **love using** and developers will **love creating**. Based on Python type hints.
It's also a command line tool to run scripts, automatically converting them to CLI applications.
The key features are:
* **Intuitive to write**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging. Designed to be easy to use and learn. Less time reading docs.
* **Easy to use**: It's easy to use for the final users. Automatic help, and automatic completion for all shells.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Start simple**: The simplest example adds only 2 lines of code to your app: **1 import, 1 function call**.
* **Grow large**: Grow in complexity as much as you want, create arbitrarily complex trees of commands and groups of subcommands, with options and arguments.
* **Run scripts**: Typer includes a `typer` command/program that you can use to run scripts, automatically converting them to CLIs, even if they don't use Typer internally.
## FastAPI of CLIs
**Typer** is <a href="https://fastapi.tiangolo.com" class="external-link" target="_blank">FastAPI</a>'s little sibling, it's the FastAPI of CLIs.
## Installation
Create and activate a <a href="https://typer.tiangolo.com/virtual-environments/" class="external-link" target="_blank">virtual environment</a> and then install **Typer**:
<div class="termy">
```console
$ pip install typer
---> 100%
Successfully installed typer rich shellingham
```
</div>
## Example
### The absolute minimum
* Create a file `main.py` with:
```Python
def main(name: str):
print(f"Hello {name}")
```
This script doesn't even use Typer internally. But you can use the `typer` command to run it as a CLI application.
### Run it
Run your application with the `typer` command:
<div class="termy">
```console
// Run your application
$ typer main.py run
// You get a nice error, you are missing NAME
Usage: typer [PATH_OR_MODULE] run [OPTIONS] NAME
Try 'typer [PATH_OR_MODULE] run --help' for help.
╭─ Error ───────────────────────────────────────────╮
│ Missing argument 'NAME'. │
╰───────────────────────────────────────────────────╯
// You get a --help for free
$ typer main.py run --help
Usage: typer [PATH_OR_MODULE] run [OPTIONS] NAME
Run the provided Typer app.
╭─ Arguments ───────────────────────────────────────╮
│ * name TEXT [default: None] [required] |
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────╯
// Now pass the NAME argument
$ typer main.py run Camila
Hello Camila
// It works! 🎉
```
</div>
This is the simplest use case, not even using Typer internally, but it can already be quite useful for simple scripts.
**Note**: auto-completion works when you create a Python package and run it with `--install-completion` or when you use the `typer` command.
## Use Typer in your code
Now let's start using Typer in your own code, update `main.py` with:
```Python
import typer
def main(name: str):
print(f"Hello {name}")
if __name__ == "__main__":
typer.run(main)
```
Now you could run it with Python directly:
<div class="termy">
```console
// Run your application
$ python main.py
// You get a nice error, you are missing NAME
Usage: main.py [OPTIONS] NAME
Try 'main.py --help' for help.
╭─ Error ───────────────────────────────────────────╮
│ Missing argument 'NAME'. │
╰───────────────────────────────────────────────────╯
// You get a --help for free
$ python main.py --help
Usage: main.py [OPTIONS] NAME
╭─ Arguments ───────────────────────────────────────╮
│ * name TEXT [default: None] [required] |
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────╯
// Now pass the NAME argument
$ python main.py Camila
Hello Camila
// It works! 🎉
```
</div>
**Note**: you can also call this same script with the `typer` command, but you don't need to.
## Example upgrade
This was the simplest example possible.
Now let's see one a bit more complex.
### An example with two subcommands
Modify the file `main.py`.
Create a `typer.Typer()` app, and create two subcommands with their parameters.
```Python hl_lines="3 6 11 20"
import typer
app = typer.Typer()
@app.command()
def hello(name: str):
print(f"Hello {name}")
@app.command()
def goodbye(name: str, formal: bool = False):
if formal:
print(f"Goodbye Ms. {name}. Have a good day.")
else:
print(f"Bye {name}!")
if __name__ == "__main__":
app()
```
And that will:
* Explicitly create a `typer.Typer` app.
* The previous `typer.run` actually creates one implicitly for you.
* Add two subcommands with `@app.command()`.
* Execute the `app()` itself, as if it was a function (instead of `typer.run`).
### Run the upgraded example
Check the new help:
<div class="termy">
```console
$ python main.py --help
Usage: main.py [OPTIONS] COMMAND [ARGS]...
╭─ Options ─────────────────────────────────────────╮
│ --install-completion Install completion │
│ for the current │
│ shell. │
│ --show-completion Show completion for │
│ the current shell, │
│ to copy it or │
│ customize the │
│ installation. │
│ --help Show this message │
│ and exit. │
╰───────────────────────────────────────────────────╯
╭─ Commands ────────────────────────────────────────╮
│ goodbye │
│ hello │
╰───────────────────────────────────────────────────╯
// When you create a package you get ✨ auto-completion ✨ for free, installed with --install-completion
// You have 2 subcommands (the 2 functions): goodbye and hello
```
</div>
Now check the help for the `hello` command:
<div class="termy">
```console
$ python main.py hello --help
Usage: main.py hello [OPTIONS] NAME
╭─ Arguments ───────────────────────────────────────╮
│ * name TEXT [default: None] [required] │
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────╯
```
</div>
And now check the help for the `goodbye` command:
<div class="termy">
```console
$ python main.py goodbye --help
Usage: main.py goodbye [OPTIONS] NAME
╭─ Arguments ───────────────────────────────────────╮
│ * name TEXT [default: None] [required] │
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --formal --no-formal [default: no-formal] │
│ --help Show this message │
│ and exit. │
╰───────────────────────────────────────────────────╯
// Automatic --formal and --no-formal for the bool option 🎉
```
</div>
Now you can try out the new command line application:
<div class="termy">
```console
// Use it with the hello command
$ python main.py hello Camila
Hello Camila
// And with the goodbye command
$ python main.py goodbye Camila
Bye Camila!
// And with --formal
$ python main.py goodbye --formal Camila
Goodbye Ms. Camila. Have a good day.
```
</div>
**Note**: If your app only has one command, by default the command name is **omitted** in usage: `python main.py Camila`. However, when there are multiple commands, you must **explicitly include the command name**: `python main.py hello Camila`. See [One or Multiple Commands](https://typer.tiangolo.com/tutorial/commands/one-or-multiple/) for more details.
### Recap
In summary, you declare **once** the types of parameters (*CLI arguments* and *CLI options*) as function parameters.
You do that with standard modern Python types.
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
Just standard **Python**.
For example, for an `int`:
```Python
total: int
```
or for a `bool` flag:
```Python
force: bool
```
And similarly for **files**, **paths**, **enums** (choices), etc. And there are tools to create **groups of subcommands**, add metadata, extra **validation**, etc.
**You get**: great editor support, including **completion** and **type checks** everywhere.
**Your users get**: automatic **`--help`**, **auto-completion** in their terminal (Bash, Zsh, Fish, PowerShell) when they install your package or when using the `typer` command.
For a more complete example including more features, see the <a href="https://typer.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
## Dependencies
**Typer** stands on the shoulders of giants. It has three required dependencies:
* <a href="https://click.palletsprojects.com/" class="external-link" target="_blank">Click</a>: a popular tool for building CLIs in Python. Typer is based on it.
* <a href="https://rich.readthedocs.io/en/stable/index.html" class="external-link" target="_blank"><code>rich</code></a>: to show nicely formatted errors automatically.
* <a href="https://github.com/sarugaku/shellingham" class="external-link" target="_blank"><code>shellingham</code></a>: to automatically detect the current shell when installing completion.
### `typer-slim`
There used to be a slimmed-down version of Typer called `typer-slim`, which didn't include the dependencies `rich` and `shellingham`, nor the `typer` command.
However, since version 0.22.0, we have stopped supporting this, and `typer-slim` now simply installs (all of) Typer.
If you want to disable Rich globally, you can set an environmental variable `TYPER_USE_RICH` to `False` or `0`.
## License
This project is licensed under the terms of the MIT license.
================================================
FILE: SECURITY.md
================================================
# Security Policy
Security is very important for Typer and its community. 🔒
Learn more about it below. 👇
## Versions
The latest versions of Typer are supported.
You are encouraged to [write tests](https://typer.tiangolo.com/tutorial/testing/) for your application and update your Typer version frequently after ensuring that your tests are passing. This way you will benefit from the latest features, bug fixes, and **security fixes**.
## Reporting a Vulnerability
If you think you found a vulnerability, and even if you are not sure about it, please report it right away by sending an email to: security@tiangolo.com. Please try to be as explicit as possible, describing all the steps and example code to reproduce the security issue.
I (the author, [@tiangolo](https://twitter.com/tiangolo)) will review it thoroughly and get back to you.
## Public Discussions
Please restrain from publicly discussing a potential security vulnerability. 🙊
It's better to discuss privately and try to find a solution first, to limit the potential impact as much as possible.
---
Thanks for your help!
The Typer community and I thank you for that. 🙇
================================================
FILE: data/members.yml
================================================
members:
- login: tiangolo
- login: svlandeg
- login: patrick91
================================================
FILE: docs/about/index.md
================================================
# About
About **Typer**, its design, inspiration, and more. 🤓
================================================
FILE: docs/alternatives.md
================================================
# Alternatives, Inspiration and Comparisons
What inspired **Typer**, how it compares to other alternatives and what it learned from them.
## Intro
**Typer** wouldn't exist if not for the previous work of others.
There have been many tools created before that have helped inspire its creation.
## Previous tools
### <a href="https://docs.python.org/3/library/argparse.html" class="external-link" target="_blank">`argparse`</a>
`argparse` is the Python standard library's module to write CLIs.
It provides a better alternative than reading the *CLI Parameters* as a `list` of `str` and parsing everything by hand.
/// check | Inspired **Typer** to
Provide a better development experience than just reading *CLI Parameters* by hand.
///
### <a href="https://hugapi.github.io/hug/" class="external-link" target="_blank">Hug</a>
Hug is a library to create APIs and CLIs, it uses parameters in functions to declare the required data.
It inspired a lot of the ideas in **FastAPI** and **Typer**.
/// check | Inspired **Typer** to
Use function parameters to declare *CLI arguments* and *CLI options* as it simplifies a lot the development experience.
///
### <a href="https://plac.readthedocs.io/en/latest/" class="external-link" target="_blank">Plac</a>
Plac is another library to create CLIs using parameters in functions, similar to Hug.
/// check | Inspired **Typer** to
Provide a simple way to use a function as a command line app, without having to create a complete app, with `typer.run(some_function)`.
///
### <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a>
Pydantic is a library to handle data validation using standard modern Python type annotations.
It powers **FastAPI** underneath.
It is not used by **Typer**, but it inspired a lot of the design (through **FastAPI**).
/// check | Inspired **Typer** to
Use standard Python type annotations to declare types instead of library-specific types or classes and use them for data validation and documentation.
///
### <a href="https://click.palletsprojects.com" class="external-link" target="_blank">Click</a>
Click is one of the most widely used libraries to create CLIs in Python.
It's a very powerful tool and there are many CLIs built with it. It is what powers **Typer** underneath.
It also uses functions with parameters for *CLI arguments* and *CLI options*, but the declaration of the specific *CLI arguments*, *CLI options*, types, etc, is done in decorators on top of the function. This requires some code repetition (e.g. a *CLI Option* name `--verbose` and a variable name `verbose`) and synchronization between two places related to the same information (the decorator and the parameter function).
It uses decorators on top of functions to modify the actual value of those functions, converting them to instances of a specific class. This is a clever trick, but code editors can't provide great support for autocompletion that way.
It was built with some great ideas and design using the features available in the language at the time (Python 2.x).
/// check | **Typer** uses it for
Everything. 🚀
**Typer** mainly adds a layer on top of Click, making the code simpler and easier to use, with autocompletion everywhere, etc, but providing all the powerful features of Click underneath.
As someone pointed out: <em><a href="https://twitter.com/fishnets88/status/1210126833745838080" class="external-link" target="_blank">"Nice to see it is built on Click but adds the type stuff. Me gusta!"</a></em>
///
### <a href="https://github.com/click-contrib/click-completion" class="external-link" target="_blank">`click-completion`</a>
`click-completion` is a plug-in for Click. It was created to extend completion support for shells when Click only had support for Bash completion.
Previous versions of **Typer** had deep integrations with `click-completion` and used it as an optional dependency. But now all the completion logic is implemented internally in **Typer** itself, the internal logic was heavily inspired and using some parts of `click-completion`.
And now **Typer** improved it to have new features, tests, some bug fixes (for issues in plain `click-completion` and Click), and better support for shells, including modern versions of PowerShell (e.g. the default versions that come with Windows 10).
/// check | Inspired **Typer** to
Provide auto completion for all the shells.
///
### <a href="https://fastapi.tiangolo.com/" class="external-link" target="_blank">FastAPI</a>
I created **FastAPI** to provide an easy way to build APIs with autocompletion for everything in the code (and some other <a href="https://fastapi.tiangolo.com/features/" class="external-link" target="_blank">features</a>).
**Typer** is the "FastAPI of CLIs".
It uses the same design and usage of FastAPI as much as possible. So, if you have used FastAPI, you know how to use Typer.
================================================
FILE: docs/contributing.md
================================================
# Development - Contributing
First, you might want to see the basic ways to [help Typer and get help](help-typer.md){.internal-link target=_blank}.
## Developing
If you already cloned the <a href="https://github.com/fastapi/typer" class="external-link" target="_blank">typer repository</a> and you want to deep dive in the code, here are some guidelines to set up your environment.
### Install Requirements Using `uv`
Create a virtual environment and install the required packages in one command:
<div class="termy">
```console
$ uv sync
---> 100%
```
</div>
It will install all the dependencies and your local Typer in your local environment.
### Using your Local Typer
If you create a Python file that imports and uses Typer, and run it with the Python from your local environment, it will use your cloned local Typer source code.
And if you update that local Typer source code when you run that Python file again, it will use the fresh version of Typer you just edited.
That way, you don't have to "install" your local version to be able to test every change.
/// note | "Technical Details"
This only happens when you install using this included `requirements.txt` instead of running `pip install typer` directly.
That is because inside the `requirements.txt` file, the local version of Typer is marked to be installed in "editable" mode, with the `-e` option.
///
### Format
There is a script that you can run that will format and clean all your code:
<div class="termy">
```console
$ bash scripts/format.sh
```
</div>
It will also auto-sort all your imports.
## Tests
There is a script that you can run locally to test all the code and generate coverage reports in HTML:
<div class="termy">
```console
$ bash scripts/test-cov-html.sh
```
</div>
This command generates a directory `./htmlcov/`, if you open the file `./htmlcov/index.html` in your browser, you can explore interactively the regions of code that are covered by the tests, and notice if there is any region missing.
## Completion
To try and test the completion for different shells and check that they are working you can use a Docker container.
There's a `Dockerfile` and a Docker Compose file `compose.yaml` at `./scripts/docker/`.
It has installed `bash`, `zsh`, `fish`, and `pwsh` (PowerShell for Linux).
It also has installed `nano` and `vim`, so that you can check the modified configuration files for the shells (for example `.bashrc`, `.zshrc`, etc).
It also has `uv` installed, so you can install the dependencies and the project quickly.
The Docker Compose file mounts the main directory as `/code` inside the container, so you can change things and try them out.
Go to the `./scripts/docker/` directory:
```console
$ cd scripts/docker/
```
Then run an interactive session with `bash` inside the container:
```console
$ docker compose run typer bash
root@79c4b9b70cbe:/code#
```
Then inside the container, you can install `typer` with:
```console
$ uv pip install -r requirements.txt
```
Then, you can start the shell you want to use, the one where you want to try out completion:
* `bash`
* `fish`
* `pwsh`
* `zsh`
For example:
```console
$ zsh
```
Then install `typer` completion:
```console
$ typer --install-completion
```
/// info
In `pwsh` you will probably get a warning of:
```plaintext
Set-ExecutionPolicy: Operation is not supported on this platform.
```
this is because that configuration is only available in Windows (and needed there), not in PowerShell for Linux.
///
For completion to take effect, you need to restart the shell. So, exit the current shell:
```console
$ exit
```
and start a new shell (for the same shell you installed completion in) again. For example:
```console
$ zsh
```
Now you could create a demo file on the same Typer directory in your editor, for example `demo.py`:
```python
import typer
app = typer.Typer()
@app.command()
def hello():
print("Hello")
@app.command()
def goodbye():
print("Goodbye")
if __name__ == "__main__":
app()
```
Because the directory is mounted as a volume, you will be able to access the file from inside the container.
So, you can try running it with the `typer` command, that will use the installed shell completion:
```console
$ typer demo.py <TAB>
```
And you should see the completion working:
```console
run -- Run the provided Typer app.
utils -- Extra utility commands for Typer apps.
```
And the same for the commands in your `demo.py` file:
```console
$ typer demo.py run <TAB>
hello goodbye
```
You can also check the configuration file using `nano` or `vim`, for example:
```bash
nano ~/.zshrc
```
It will show some content like:
```bash
fpath+=~/.zfunc; autoload -Uz compinit; compinit
zstyle ':completion:*' menu select
```
If you exit from the container, you can start a new one, you will probably have to install the packages again and install completion again.
Using this process, you can test all the shells, with their completions, being able to start from scratch quickly in a fresh container, and verifying that everything works as expected.
## Docs
First, make sure you set up your environment as described above, that will install all the requirements.
### Docs live
During local development, there is a script that builds the site and checks for any changes, live-reloading:
<div class="termy">
```console
$ python ./scripts/docs.py live
<span style="color: green;">[INFO]</span> Serving on http://127.0.0.1:8008
<span style="color: green;">[INFO]</span> Start watching changes
<span style="color: green;">[INFO]</span> Start detecting changes
```
</div>
It will serve the documentation on `http://127.0.0.1:8008`.
That way, you can edit the documentation/source files and see the changes live.
/// tip
Alternatively, you can perform the same steps that script does manually.
Go into the docs directory at `docs/`:
```console
$ cd docs/
```
Then run `mkdocs` in that directory:
```console
$ mkdocs serve --dev-addr 8008
```
///
#### Typer CLI (optional)
The instructions here show you how to use the script at `./scripts/docs.py` with the `python` program directly.
But you can also use <a href="https://typer.tiangolo.com/typer-cli/" class="external-link" target="_blank">Typer CLI</a>, and you will get autocompletion in your terminal for the commands after installing completion.
If you install Typer CLI, you can install completion with:
<div class="termy">
```console
$ typer --install-completion
zsh completion installed in /home/user/.bashrc.
Completion will take effect once you restart the terminal.
```
</div>
### Docs Structure
The documentation uses <a href="https://www.mkdocs.org/" class="external-link" target="_blank">MkDocs</a>.
And there are extra tools/scripts in place in `./scripts/docs.py`.
/// tip
You don't need to see the code in `./scripts/docs.py`, you just use it in the command line.
///
All the documentation is in Markdown format in the directory `./docs`.
Many of the tutorials have blocks of code.
In most of the cases, these blocks of code are actual complete applications that can be run as is.
In fact, those blocks of code are not written inside the Markdown, they are Python files in the `./docs_src/` directory.
And those Python files are included/injected in the documentation when generating the site.
### Docs for Tests
Most of the tests actually run against the example source files in the documentation.
This helps to make sure that:
* The documentation is up-to-date.
* The documentation examples can be run as is.
* Most of the features are covered by the documentation, ensured by test coverage.
## Automated Code and AI
You are encouraged to use all the tools you want to do your work and contribute as efficiently as possible, this includes AI (LLM) tools, etc. Nevertheless, contributions should have meaningful human intervention, judgement, context, etc.
If the **human effort** put in a PR, e.g. writing LLM prompts, is **less** than the **effort we would need to put** to **review it**, please **don't** submit the PR.
Think of it this way: we can already write LLM prompts or run automated tools ourselves, and that would be faster than reviewing external PRs.
### Closing Automated and AI PRs
If we see PRs that seem AI generated or automated in similar ways, we'll flag them and close them.
The same applies to comments and descriptions, please don't copy paste the content generated by an LLM.
### Human Effort Denial of Service
Using automated tools and AI to submit PRs or comments that we have to carefully review and handle would be the equivalent of a <a href="https://en.wikipedia.org/wiki/Denial-of-service_attack" class="external-link" target="_blank">Denial-of-service attack</a> on our human effort.
It would be very little effort from the person submitting the PR (an LLM prompt) that generates a large amount of effort on our side (carefully reviewing code).
Please don't do that.
We'll need to block accounts that spam us with repeated automated PRs or comments.
### Use Tools Wisely
As Uncle Ben said:
<blockquote>
With great <strike>power</strike> <strong>tools</strong> comes great responsibility.
</blockquote>
Avoid inadvertently doing harm.
You have amazing tools at hand, use them wisely to help effectively.
================================================
FILE: docs/css/custom.css
================================================
/* Fira Code, including characters used by Rich output, like the "heavy right-pointing angle bracket ornament", not included in Google Fonts */
@import url(https://cdn.jsdelivr.net/npm/firacode@6.2.0/distr/fira_code.css);
/* Noto Color Emoji for emoji support with the same font everywhere */
@import url(https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&display=swap);
/* Override default code font in Material for MkDocs to Fira Code */
:root {
--md-code-font: "Fira Code", monospace, "Noto Color Emoji";
}
/* Override default regular font in Material for MkDocs to include Noto Color Emoji */
:root {
--md-text-font: "Roboto", "Noto Color Emoji";
}
.termynal-comment {
color: #4a968f;
font-style: italic;
display: block;
}
.termy [data-termynal] {
white-space: pre-wrap;
}
.termy .linenos {
display: none;
}
/* External links: detected by JS comparing origin to site origin
JS sets data-external-link on links pointing outside the site
Skip image links, .no-link-icon, and .announce-link */
a[data-external-link]:not(:has(img)):not(.no-link-icon):not(.announce-link) {
/* For right to left languages */
direction: ltr;
display: inline-block;
}
a[data-external-link]:not(:has(img)):not(.no-link-icon):not(.announce-link)::after {
content: "";
display: inline-block;
width: 0.75em;
height: 0.75em;
margin-left: 0.25em;
vertical-align: middle;
opacity: 0.55;
background: currentColor;
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cline x1='10' y1='14' x2='21' y2='3'/%3E%3C/svg%3E");
-webkit-mask-size: contain;
-webkit-mask-repeat: no-repeat;
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cline x1='10' y1='14' x2='21' y2='3'/%3E%3C/svg%3E");
mask-size: contain;
mask-repeat: no-repeat;
}
a[data-external-link]:not(:has(img)):not(.no-link-icon):not(.announce-link):hover::after {
opacity: 0.85;
}
/* Internal links opening in new tab: same-origin links with target=_blank
JS sets data-internal-link on links pointing to the same site origin
Skip image links, .no-link-icon, and .announce-link */
a[data-internal-link][target="_blank"]:not(:has(img)):not(.no-link-icon):not(.announce-link) {
/* For right to left languages */
direction: ltr;
display: inline-block;
}
a[data-internal-link][target="_blank"]:not(:has(img)):not(.no-link-icon):not(.announce-link)::after {
content: "";
display: inline-block;
width: 0.75em;
height: 0.75em;
margin-left: 0.25em;
vertical-align: middle;
opacity: 0.55;
background: currentColor;
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='7' width='14' height='14' rx='2'/%3E%3Cpath d='M7 3h14v14'/%3E%3C/svg%3E");
-webkit-mask-size: contain;
-webkit-mask-repeat: no-repeat;
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='7' width='14' height='14' rx='2'/%3E%3Cpath d='M7 3h14v14'/%3E%3C/svg%3E");
mask-size: contain;
mask-repeat: no-repeat;
}
a[data-internal-link][target="_blank"]:not(:has(img)):not(.no-link-icon):not(.announce-link):hover::after {
opacity: 0.85;
}
/* Disable link icons in footer and header nav */
.md-footer a::after,
.md-header a::after {
content: none !important;
}
.shadow {
box-shadow: 5px 5px 10px #999;
}
.user-list {
display: flex;
flex-wrap: wrap;
margin-bottom: 2rem;
}
.user-list-center {
justify-content: space-evenly;
}
.user {
margin: 1em;
min-width: 7em;
}
.user .avatar-wrapper {
width: 80px;
height: 80px;
margin: 10px auto;
overflow: hidden;
border-radius: 50%;
position: relative;
}
.user .avatar-wrapper img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.user .title {
text-align: center;
}
.user .count {
font-size: 80%;
text-align: center;
}
================================================
FILE: docs/css/termynal.css
================================================
/**
* termynal.js
*
* @author Ines Montani <ines@ines.io>
* @version 0.0.1
* @license MIT
*/
:root {
--color-bg: #252a33;
--color-text: #eee;
--color-text-subtle: #a2a2a2;
}
[data-termynal] {
width: 750px;
max-width: 100%;
background: var(--color-bg);
color: var(--color-text);
/* font-size: 18px; */
font-size: 15px;
/* font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace; */
font-family: var(--md-code-font-family), 'Roboto Mono', 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace;
border-radius: 4px;
padding: 75px 45px 35px;
position: relative;
-webkit-box-sizing: border-box;
box-sizing: border-box;
/* Custom line-height */
line-height: 1.2;
}
[data-termynal]:before {
content: '';
position: absolute;
top: 15px;
left: 15px;
display: inline-block;
width: 15px;
height: 15px;
border-radius: 50%;
/* A little hack to display the window buttons in one pseudo element. */
background: #d9515d;
-webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
}
[data-termynal]:after {
content: 'bash';
position: absolute;
color: var(--color-text-subtle);
top: 5px;
left: 0;
width: 100%;
text-align: center;
}
a[data-terminal-control] {
text-align: right;
display: block;
color: #aebbff;
}
[data-ty] {
display: block;
line-height: 2;
}
[data-ty]:before {
/* Set up defaults and ensure empty lines are displayed. */
content: '';
display: inline-block;
vertical-align: middle;
}
[data-ty="input"]:before,
[data-ty-prompt]:before {
margin-right: 0.75em;
color: var(--color-text-subtle);
}
[data-ty="input"]:before {
content: '$';
}
[data-ty][data-ty-prompt]:before {
content: attr(data-ty-prompt);
}
[data-ty-cursor]:after {
content: attr(data-ty-cursor);
font-family: monospace;
margin-left: 0.5em;
-webkit-animation: blink 1s infinite;
animation: blink 1s infinite;
}
/* Cursor animation */
@-webkit-keyframes blink {
50% {
opacity: 0;
}
}
@keyframes blink {
50% {
opacity: 0;
}
}
================================================
FILE: docs/environment-variables.md
================================================
# Environment Variables
Before we jump into **Typer** code, let's cover a bit some of the **basics** that we'll need to understand how to work with Python (and programming) in general. Let's check a bit about **environment variables**.
/// tip
If you already know what "environment variables" are and how to use them, feel free to skip this.
///
An environment variable (also known as "**env var**") is a variable that lives **outside** of the Python code, in the **operating system**, and could be read by your Python code (or by other programs as well).
Environment variables could be useful for handling application **settings**, as part of the **installation** of Python, etc.
## Create and Use Env Vars
You can **create** and use environment variables in the **shell (terminal)**, without needing Python:
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
// You could create an env var MY_NAME with
$ export MY_NAME="Wade Wilson"
// Then you could use it with other programs, like
$ echo "Hello $MY_NAME"
Hello Wade Wilson
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
// Create an env var MY_NAME
$ $Env:MY_NAME = "Wade Wilson"
// Use it with other programs, like
$ echo "Hello $Env:MY_NAME"
Hello Wade Wilson
```
</div>
////
## Read env vars in Python
You could also create environment variables **outside** of Python, in the terminal (or with any other method), and then **read them in Python**.
For example you could have a file `main.py` with:
```Python hl_lines="3"
import os
name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
```
/// tip
The second argument to <a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> is the default value to return.
If not provided, it's `None` by default, here we provide `"World"` as the default value to use.
///
Then you could call that Python program:
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
// Here we don't set the env var yet
$ python main.py
// As we didn't set the env var, we get the default value
Hello World from Python
// But if we create an environment variable first
$ export MY_NAME="Wade Wilson"
// And then call the program again
$ python main.py
// Now it can read the environment variable
Hello Wade Wilson from Python
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
// Here we don't set the env var yet
$ python main.py
// As we didn't set the env var, we get the default value
Hello World from Python
// But if we create an environment variable first
$ $Env:MY_NAME = "Wade Wilson"
// And then call the program again
$ python main.py
// Now it can read the environment variable
Hello Wade Wilson from Python
```
</div>
////
As environment variables can be set outside of the code, but can be read by the code, and don't have to be stored (committed to `git`) with the rest of the files, it's common to use them for configurations or **settings**.
You can also create an environment variable only for a **specific program invocation**, that is only available to that program, and only for its duration.
To do that, create it right before the program itself, on the same line:
<div class="termy">
```console
// Create an env var MY_NAME in line for this program call
$ MY_NAME="Wade Wilson" python main.py
// Now it can read the environment variable
Hello Wade Wilson from Python
// The env var no longer exists afterwards
$ python main.py
Hello World from Python
```
</div>
/// tip
You can read more about it at <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>.
///
## Types and Validation
These environment variables can only handle **text strings**, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, as Linux, Windows, macOS).
That means that **any value** read in Python from an environment variable **will be a `str`**, and any conversion to a different type or any validation has to be done in code.
You will learn more about using environment variables for your <abbr title="command line interface">CLI</abbr> applications later in the section about [CLI Arguments with Environment Variables](./tutorial/arguments/envvar.md){.internal-link target=_blank}.
## `PATH` Environment Variable
There is a **special** environment variable called **`PATH`** that is used by the operating systems (Linux, macOS, Windows) to find programs to run.
The value of the variable `PATH` is a long string that is made of directories separated by a colon `:` on Linux and macOS, and by a semicolon `;` on Windows.
For example, the `PATH` environment variable could look like this:
//// tab | Linux, macOS
```plaintext
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```
This means that the system should look for programs in the directories:
* `/usr/local/bin`
* `/usr/bin`
* `/bin`
* `/usr/sbin`
* `/sbin`
////
//// tab | Windows
```plaintext
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
```
This means that the system should look for programs in the directories:
* `C:\Program Files\Python312\Scripts`
* `C:\Program Files\Python312`
* `C:\Windows\System32`
////
When you type a **command** in the terminal, the operating system **looks for** the program in **each of those directories** listed in the `PATH` environment variable.
For example, when you type `python` in the terminal, the operating system looks for a program called `python` in the **first directory** in that list.
If it finds it, then it will **use it**. Otherwise it keeps looking in the **other directories**.
### Installing Python and Updating the `PATH`
When you install Python, you might be asked if you want to update the `PATH` environment variable.
//// tab | Linux, macOS
Let's say you install Python and it ends up in a directory `/opt/custompython/bin`.
If you say yes to update the `PATH` environment variable, then the installer will add `/opt/custompython/bin` to the `PATH` environment variable.
It could look like this:
```plaintext
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
```
////
//// tab | Windows
Let's say you install Python and it ends up in a directory `C:\opt\custompython\bin`.
If you say yes to update the `PATH` environment variable, then the installer will add `C:\opt\custompython\bin` to the `PATH` environment variable.
```plaintext
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
```
////
So, if you type:
<div class="termy">
```console
$ python
```
</div>
//// tab | Linux, macOS
The system will **find** the `python` program in `/opt/custompython/bin` (the last directory) and run it.
It would be roughly equivalent to typing:
<div class="termy">
```console
$ /opt/custompython/bin/python
```
</div>
////
//// tab | Windows
The system will **find** the `python` program in `C:\opt\custompython\bin\python` (the last directory) and run it.
It would be roughly equivalent to typing:
<div class="termy">
```console
$ C:\opt\custompython\bin\python
```
</div>
////
This information will be useful when learning about [Virtual Environments](virtual-environments.md){.internal-link target=_blank}.
It will also be useful when you **create your own CLI programs** as, for them to be available for your users, they will need to be somewhere in the `PATH` environment variable.
## Conclusion
With this you should have a basic understanding of what **environment variables** are and how to use them in Python.
You can also read more about them in the <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia for Environment Variable</a>.
In many cases it's not very obvious how environment variables would be useful and applicable right away. But they keep showing up in many different scenarios when you are developing, so it's good to know about them.
For example, you will need this information in the next section, about [Virtual Environments](virtual-environments.md).
================================================
FILE: docs/features.md
================================================
# Features
## Design based on **FastAPI**
<a href="https://fastapi.tiangolo.com" target="_blank"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
**Typer** is <a href="https://fastapi.tiangolo.com" class="external-link" target="_blank">FastAPI</a>'s little sibling.
It follows the same design and ideas. If you know **FastAPI**, you already know **Typer**... more or less.
## Just Modern Python
It's all based on standard **Python type** declarations. No new syntax to learn. Just standard modern Python.
If you need a 2 minute refresher of how to use Python types (even if you don't use FastAPI or Typer), check the FastAPI tutorial section: <a href="https://fastapi.tiangolo.com/python-types/" class="external-link" target="_blank">Python types intro</a>.
You will also see a 20 seconds refresher on the section [Tutorial - User Guide: First Steps](tutorial/first-steps.md){.internal-link target=_blank}.
## Editor support
**Typer** was designed to be easy and intuitive to use, to ensure the best development experience. With autocompletion everywhere.
You will rarely need to come back to the docs.
Here's how your editor might help you:
* in <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:

* in <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:

You will get completion for everything. That's something no other CLI library provides right now.
No more guessing what type was that variable, if it could be `None`, etc.
### Short
It has sensible **defaults** for everything, with optional configurations everywhere. All the parameters can be fine-tuned to do what you need, customize the help, callbacks per parameter, make them required or not, etc.
But by default, it all **"just works"**.
## User friendly CLI apps
The resulting CLI apps created with **Typer** have the nice features of many "pro" command line programs you probably already love.
* Automatic help options for the main CLI program and all its subcommands.
* Automatic command and subcommand structure handling (you will see more about subcommands in the Tutorial - User Guide).
* Automatic completion for the CLI app in all operating systems, in all the shells (Bash, Zsh, Fish, PowerShell), so that the final user of your app can just hit <kbd>TAB</kbd> and get the available options or subcommands. *
/// note | * Auto completion
Auto completion works when you create a package (installable with `pip`). Or when using the `typer` command.
**Typer** uses `shellingham` to auto-detect the current shell when installing completion.
**Typer** will automatically create 2 *CLI options*:
* `--install-completion`: Install completion for the current shell.
* `--show-completion`: Show completion for the current shell, to copy it or customize the installation.
///
/// tip
**Typer**'s completion is implemented internally, it uses ideas and components from Click and ideas from `click-completion`, but it doesn't use `click-completion` and re-implements some of the relevant parts of Click.
Then it extends those ideas with features and bug fixes. For example, **Typer** programs also support modern versions of PowerShell (e.g. in Windows 10) among all the other shells.
///
## Tested
* 100% <abbr title="The amount of code that is automatically tested">test coverage</abbr>.
* 100% <abbr title="Python type annotations, with this your editor and external tools can give you better support">type annotated</abbr> code base.
* Used in production applications.
================================================
FILE: docs/help-typer.md
================================================
# Help Typer - Get Help
Are you liking **Typer**?
Would you like to help Typer, other users, and the author?
Or would you like to get help with **Typer**?
There are very simple ways to help (several involve just one or two clicks).
And there are several ways to get help too.
## Subscribe to the newsletter
You can subscribe to the (infrequent) [**FastAPI and friends** newsletter](https://fastapi.tiangolo.com/newsletter/){.internal-link target=_blank} to stay updated about:
* News about FastAPI and friends, including Typer 🚀
* Guides 📝
* Features ✨
* Breaking changes 🚨
* Tips and tricks ✅
## Star **Typer** in GitHub
You can "star" Typer in GitHub (clicking the star button at the top right): <a href="https://github.com/fastapi/typer" class="external-link" target="_blank">https://github.com/fastapi/typer</a>.
By adding a star, other users will be able to find it more easily and see that it has been already useful for others.
## Watch the GitHub repository for releases
You can "watch" Typer in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/fastapi/typer" class="external-link" target="_blank">https://github.com/fastapi/typer</a>.
There you can select "Releases only".
By doing it, you will receive notifications (in your email) whenever there's a new release (a new version) of **Typer** with bug fixes and new features.
## Connect with the author
You can connect with <a href="https://tiangolo.com" class="external-link" target="_blank">me (Sebastián Ramírez / `tiangolo`)</a>, the author.
You can:
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">Follow me on **GitHub**</a>.
* See other Open Source projects I have created that could help you.
* Follow me to see when I create a new Open Source project.
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Follow me on **Twitter**</a>.
* Tell me how you use Typer (I love to hear that).
* Hear when I make announcements or release new tools.
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Connect with me on **Linkedin**</a>.
* Hear when I make announcements or release new tools (although I use Twitter more often 🤷♂).
* Read what I write (or follow me) on <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> or <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>.
* Read other ideas, articles, and read about tools I have created.
* Follow me to read when I publish something new.
## Tweet about **Typer**
<a href="https://twitter.com/compose/tweet?text=I'm loving Typer because... https://github.com/fastapi/typer cc @tiangolo" class="external-link" target="_blank">Tweet about **Typer**</a> and let me and others know why you like it.
I love to hear about how **Typer** is being used, what have you liked in it, in which project/company you are using it, etc.
## Help others with questions in GitHub
You can try and help others with their questions in:
* <a href="https://github.com/fastapi/typer/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub Discussions</a>
* <a href="https://github.com/fastapi/typer/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub Issues</a>
In many cases you might already know the answer for those questions. 🤓
Just remember, the most important point is: try to be kind. People come with their frustrations and in many cases don't ask in the best way, but try as best as you can to be kind. 🤗
The idea is for the **Typer** community to be kind and welcoming. At the same time, don't accept bullying or disrespectful behavior towards others. We have to take care of each other.
---
Here's how to help others with questions (in discussions or issues):
### Understand the question
* Check if you can understand what is the **purpose** and use case of the person asking.
* Then check if the question (the vast majority are questions) is **clear**.
* In many cases the question asked is about an imaginary solution from the user, but there might be a **better** one. If you can understand the problem and use case better, you might be able to suggest a better **alternative solution**.
* If you can't understand the question, ask for more **details**.
### Reproduce the problem
For most of the cases and most of the questions there's something related to the person's **original code**.
In many cases they will only copy a fragment of the code, but that's not enough to **reproduce the problem**.
* You can ask them to provide a <a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">minimal, reproducible, example</a>, that you can **copy-paste** and run locally to see the same error or behavior they are seeing, or to understand their use case better.
* If you are feeling too generous, you can try to **create an example** like that yourself, just based on the description of the problem. Just have in mind that this might take a lot of time and it might be better to ask them to clarify the problem first.
### Suggest solutions
* After being able to understand the question, you can give them a possible **answer**.
* In many cases, it's better to understand their **underlying problem or use case**, because there might be a better way to solve it than what they are trying to do.
### Ask to close
If they reply, there's a high chance you would have solved their problem, congrats, **you're a hero**! 🦸
* Now, if that solved their problem, you can ask them to:
* In GitHub Discussions: mark the comment as the **answer**.
* In GitHub Issues: **close** the issue**.
## Watch the GitHub repository
You can "watch" Typer in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/fastapi/typer" class="external-link" target="_blank">https://github.com/fastapi/typer</a>.
If you select "Watching" instead of "Releases only" you will receive notifications when someone creates a new issue or question. You can also specify that you only want to be notified about new issues, or discussions, or PRs, etc.
Then you can try and help them solve those questions.
## Ask Questions
You can <a href="https://github.com/fastapi/typer/discussions/new?category=questions" class="external-link" target="_blank">create a new question</a> in the GitHub repository, for example to:
* Ask a **question** or ask about a **problem**.
* Suggest a new **feature**.
**Note**: if you do it, then I'm going to ask you to also help others. 😉
## Review Pull Requests
You can help me review pull requests from others.
Again, please try your best to be kind. 🤗
---
Here's what to have in mind and how to review a pull request:
### Understand the problem
* First, make sure you **understand the problem** that the pull request is trying to solve. It might have a longer discussion in a GitHub Discussion or issue.
* There's also a good chance that the pull request is not actually needed because the problem can be solved in a **different way**. Then you can suggest or ask about that.
### Don't worry about style
* Don't worry too much about things like commit message styles, I will squash and merge customizing the commit manually.
* Also don't worry about style rules, there are already automated tools checking that.
And if there's any other style or consistency need, I'll ask directly for that, or I'll add commits on top with the needed changes.
### Check the code
* Check and read the code, see if it makes sense, **run it locally** and see if it actually solves the problem.
* Then **comment** saying that you did that, that's how I will know you really checked it.
/// info
Unfortunately, I can't simply trust PRs that just have several approvals.
Several times it has happened that there are PRs with 3, 5 or more approvals, probably because the description is appealing, but when I check the PRs, they are actually broken, have a bug, or don't solve the problem they claim to solve. 😅
So, it's really important that you actually read and run the code, and let me know in the comments that you did. 🤓
///
* If the PR can be simplified in a way, you can ask for that, but there's no need to be too picky, there might be a lot of subjective points of view (and I will have my own as well 🙈), so it's better if you can focus on the fundamental things.
### Tests
* Help me check that the PR has **tests**.
* Check that the tests **fail** before the PR. 🚨
* Then check that the tests **pass** after the PR. ✅
* Many PRs don't have tests, you can **remind** them to add tests, or you can even **suggest** some tests yourself. That's one of the things that consume most time and you can help a lot with that.
* Then also comment what you tried, that way I'll know that you checked it. 🤓
## Create a Pull Request
You can [contribute](contributing.md){.internal-link target=_blank} to the source code with Pull Requests, for example:
* To fix a typo you found on the documentation.
* To propose new documentation sections.
* To fix an existing issue/bug.
* Make sure to add tests.
* To add a new feature.
* Make sure to add tests.
* Make sure to add documentation if it's relevant.
## Help Maintain Typer
Help me maintain **Typer**! 🤓
There's a lot of work to do, and for most of it, **YOU** can do it.
The main tasks that you can do right now are:
* [Help others with questions in GitHub](#help-others-with-questions-in-github){.internal-link target=_blank} (see the section above).
* [Review Pull Requests](#review-pull-requests){.internal-link target=_blank} (see the section above).
Those two tasks are what **consume time the most**. That's the main work of maintaining Typer.
If you can help me with that, **you are helping me maintain Typer** and making sure it keeps **advancing faster and better**. 🚀
## Join the chat
Join the 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">FastAPI and Friends Discord chat server</a> 👥 and hang out with others in the community. There's a `#typer` channel.
/// tip
For questions, ask them in <a href="https://github.com/fastapi/typer/discussions/new?category=questions" class="external-link" target="_blank">GitHub Discussions</a>, there's a much better chance you will receive help there.
Use the chat only for other general conversations.
///
### Don't use the chat for questions
Have in mind that as chats allow more "free conversation", it's easy to ask questions that are too general and more difficult to answer, so, you might not receive answers.
In GitHub, the template will guide you to write the right question so that you can more easily get a good answer, or even solve the problem yourself even before asking. And in GitHub I can make sure I always answer everything, even if it takes some time. I can't personally do that with the chat. 😅
Conversations in the chat are also not as easily searchable as in GitHub, so questions and answers might get lost in the conversation.
On the other side, there are thousands of users in the chat, so there's a high chance you'll find someone to talk to there, almost all the time. 😄
## Sponsor the author
You can also financially support the author (me) through <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>.
There you could buy me a coffee ☕️ to say thanks. 😄
## Sponsor the tools that power Typer
As you have seen in the documentation, Typer is built on top of Click.
You can also sponsor:
* Pallets Project (Click maintainers) <a href="https://palletsprojects.com/donate" class="external-link" target="_blank">via the PSF</a> or <a href="https://tidelift.com/subscription/pkg/pypi-click" class="external-link" target="_blank">via Tidelift</a>
---
Thanks! 🚀
================================================
FILE: docs/index.md
================================================
<style>
.md-content .md-typeset h1 { display: none; }
</style>
<p align="center">
<a href="https://typer.tiangolo.com"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg#only-light" alt="Typer"></a>
<!-- only-mkdocs -->
<a href="https://typer.tiangolo.com"><img src="img/logo-margin/logo-margin-white-vector.svg#only-dark" alt="Typer"></a>
<!-- /only-mkdocs -->
</p>
<p align="center">
<em>Typer, build great CLIs. Easy to code. Based on Python type hints.</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/typer/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/typer/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://github.com/fastapi/typer/actions?query=workflow%3APublish" target="_blank">
<img src="https://github.com/fastapi/typer/workflows/Publish/badge.svg" alt="Publish">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/typer" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/typer.svg" alt="Coverage">
<a href="https://pypi.org/project/typer" target="_blank">
<img src="https://img.shields.io/pypi/v/typer?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
</p>
---
**Documentation**: <a href="https://typer.tiangolo.com" target="_blank">https://typer.tiangolo.com</a>
**Source Code**: <a href="https://github.com/fastapi/typer" target="_blank">https://github.com/fastapi/typer</a>
---
Typer is a library for building <abbr title="command line interface, programs executed from a terminal">CLI</abbr> applications that users will **love using** and developers will **love creating**. Based on Python type hints.
It's also a command line tool to run scripts, automatically converting them to CLI applications.
The key features are:
* **Intuitive to write**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging. Designed to be easy to use and learn. Less time reading docs.
* **Easy to use**: It's easy to use for the final users. Automatic help, and automatic completion for all shells.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Start simple**: The simplest example adds only 2 lines of code to your app: **1 import, 1 function call**.
* **Grow large**: Grow in complexity as much as you want, create arbitrarily complex trees of commands and groups of subcommands, with options and arguments.
* **Run scripts**: Typer includes a `typer` command/program that you can use to run scripts, automatically converting them to CLIs, even if they don't use Typer internally.
## FastAPI of CLIs
**Typer** is <a href="https://fastapi.tiangolo.com" class="external-link" target="_blank">FastAPI</a>'s little sibling, it's the FastAPI of CLIs.
## Installation
Create and activate a <a href="https://typer.tiangolo.com/virtual-environments/" class="external-link" target="_blank">virtual environment</a> and then install **Typer**:
<div class="termy">
```console
$ pip install typer
---> 100%
Successfully installed typer rich shellingham
```
</div>
## Example
### The absolute minimum
* Create a file `main.py` with:
```Python
def main(name: str):
print(f"Hello {name}")
```
This script doesn't even use Typer internally. But you can use the `typer` command to run it as a CLI application.
### Run it
Run your application with the `typer` command:
<div class="termy">
```console
// Run your application
$ typer main.py run
// You get a nice error, you are missing NAME
Usage: typer [PATH_OR_MODULE] run [OPTIONS] NAME
Try 'typer [PATH_OR_MODULE] run --help' for help.
╭─ Error ───────────────────────────────────────────╮
│ Missing argument 'NAME'. │
╰───────────────────────────────────────────────────╯
// You get a --help for free
$ typer main.py run --help
Usage: typer [PATH_OR_MODULE] run [OPTIONS] NAME
Run the provided Typer app.
╭─ Arguments ───────────────────────────────────────╮
│ * name TEXT [default: None] [required] |
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────╯
// Now pass the NAME argument
$ typer main.py run Camila
Hello Camila
// It works! 🎉
```
</div>
This is the simplest use case, not even using Typer internally, but it can already be quite useful for simple scripts.
**Note**: auto-completion works when you create a Python package and run it with `--install-completion` or when you use the `typer` command.
## Use Typer in your code
Now let's start using Typer in your own code, update `main.py` with:
```Python
import typer
def main(name: str):
print(f"Hello {name}")
if __name__ == "__main__":
typer.run(main)
```
Now you could run it with Python directly:
<div class="termy">
```console
// Run your application
$ python main.py
// You get a nice error, you are missing NAME
Usage: main.py [OPTIONS] NAME
Try 'main.py --help' for help.
╭─ Error ───────────────────────────────────────────╮
│ Missing argument 'NAME'. │
╰───────────────────────────────────────────────────╯
// You get a --help for free
$ python main.py --help
Usage: main.py [OPTIONS] NAME
╭─ Arguments ───────────────────────────────────────╮
│ * name TEXT [default: None] [required] |
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────╯
// Now pass the NAME argument
$ python main.py Camila
Hello Camila
// It works! 🎉
```
</div>
**Note**: you can also call this same script with the `typer` command, but you don't need to.
## Example upgrade
This was the simplest example possible.
Now let's see one a bit more complex.
### An example with two subcommands
Modify the file `main.py`.
Create a `typer.Typer()` app, and create two subcommands with their parameters.
```Python hl_lines="3 6 11 20"
import typer
app = typer.Typer()
@app.command()
def hello(name: str):
print(f"Hello {name}")
@app.command()
def goodbye(name: str, formal: bool = False):
if formal:
print(f"Goodbye Ms. {name}. Have a good day.")
else:
print(f"Bye {name}!")
if __name__ == "__main__":
app()
```
And that will:
* Explicitly create a `typer.Typer` app.
* The previous `typer.run` actually creates one implicitly for you.
* Add two subcommands with `@app.command()`.
* Execute the `app()` itself, as if it was a function (instead of `typer.run`).
### Run the upgraded example
Check the new help:
<div class="termy">
```console
$ python main.py --help
Usage: main.py [OPTIONS] COMMAND [ARGS]...
╭─ Options ─────────────────────────────────────────╮
│ --install-completion Install completion │
│ for the current │
│ shell. │
│ --show-completion Show completion for │
│ the current shell, │
│ to copy it or │
│ customize the │
│ installation. │
│ --help Show this message │
│ and exit. │
╰───────────────────────────────────────────────────╯
╭─ Commands ────────────────────────────────────────╮
│ goodbye │
│ hello │
╰───────────────────────────────────────────────────╯
// When you create a package you get ✨ auto-completion ✨ for free, installed with --install-completion
// You have 2 subcommands (the 2 functions): goodbye and hello
```
</div>
Now check the help for the `hello` command:
<div class="termy">
```console
$ python main.py hello --help
Usage: main.py hello [OPTIONS] NAME
╭─ Arguments ───────────────────────────────────────╮
│ * name TEXT [default: None] [required] │
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────╯
```
</div>
And now check the help for the `goodbye` command:
<div class="termy">
```console
$ python main.py goodbye --help
Usage: main.py goodbye [OPTIONS] NAME
╭─ Arguments ───────────────────────────────────────╮
│ * name TEXT [default: None] [required] │
╰───────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────╮
│ --formal --no-formal [default: no-formal] │
│ --help Show this message │
│ and exit. │
╰───────────────────────────────────────────────────╯
// Automatic --formal and --no-formal for the bool option 🎉
```
</div>
Now you can try out the new command line application:
<div class="termy">
```console
// Use it with the hello command
$ python main.py hello Camila
Hello Camila
// And with the goodbye command
$ python main.py goodbye Camila
Bye Camila!
// And with --formal
$ python main.py goodbye --formal Camila
Goodbye Ms. Camila. Have a good day.
```
</div>
**Note**: If your app only has one command, by default the command name is **omitted** in usage: `python main.py Camila`. However, when there are multiple commands, you must **explicitly include the command name**: `python main.py hello Camila`. See [One or Multiple Commands](https://typer.tiangolo.com/tutorial/commands/one-or-multiple/) for more details.
### Recap
In summary, you declare **once** the types of parameters (*CLI arguments* and *CLI options*) as function parameters.
You do that with standard modern Python types.
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
Just standard **Python**.
For example, for an `int`:
```Python
total: int
```
or for a `bool` flag:
```Python
force: bool
```
And similarly for **files**, **paths**, **enums** (choices), etc. And there are tools to create **groups of subcommands**, add metadata, extra **validation**, etc.
**You get**: great editor support, including **completion** and **type checks** everywhere.
**Your users get**: automatic **`--help`**, **auto-completion** in their terminal (Bash, Zsh, Fish, PowerShell) when they install your package or when using the `typer` command.
For a more complete example including more features, see the <a href="https://typer.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
## Dependencies
**Typer** stands on the shoulders of giants. It has three required dependencies:
* <a href="https://click.palletsprojects.com/" class="external-link" target="_blank">Click</a>: a popular tool for building CLIs in Python. Typer is based on it.
* <a href="https://rich.readthedocs.io/en/stable/index.html" class="external-link" target="_blank"><code>rich</code></a>: to show nicely formatted errors automatically.
* <a href="https://github.com/sarugaku/shellingham" class="external-link" target="_blank"><code>shellingham</code></a>: to automatically detect the current shell when installing completion.
### `typer-slim`
There used to be a slimmed-down version of Typer called `typer-slim`, which didn't include the dependencies `rich` and `shellingham`, nor the `typer` command.
However, since version 0.22.0, we have stopped supporting this, and `typer-slim` now simply installs (all of) Typer.
If you want to disable Rich globally, you can set an environmental variable `TYPER_USE_RICH` to `False` or `0`.
## License
This project is licensed under the terms of the MIT license.
================================================
FILE: docs/js/custom.js
================================================
function setupTermynal() {
document.querySelectorAll(".use-termynal").forEach(node => {
node.style.display = "block";
new Termynal(node, {
lineDelay: 500
});
});
const progressLiteralStart = "---> 100%";
const promptLiteralStart = "$ ";
const customPromptLiteralStart = "# ";
const termynalActivateClass = "termy";
let termynals = [];
function createTermynals() {
document
.querySelectorAll(`.${termynalActivateClass} .highlight code`)
.forEach(node => {
const text = node.textContent;
const lines = text.split("\n");
const useLines = [];
let buffer = [];
function saveBuffer() {
if (buffer.length) {
let isBlankSpace = true;
buffer.forEach(line => {
if (line) {
isBlankSpace = false;
}
});
dataValue = {};
if (isBlankSpace) {
dataValue["delay"] = 0;
}
if (buffer[buffer.length - 1] === "") {
// A last single <br> won't have effect
// so put an additional one
buffer.push("");
}
const bufferValue = buffer.join("<br>");
dataValue["value"] = bufferValue;
useLines.push(dataValue);
buffer = [];
}
}
for (let line of lines) {
if (line === progressLiteralStart) {
saveBuffer();
useLines.push({
type: "progress"
});
} else if (line.startsWith(promptLiteralStart)) {
saveBuffer();
const value = line.replace(promptLiteralStart, "").trimEnd();
useLines.push({
type: "input",
value: value
});
} else if (line.startsWith("// ")) {
saveBuffer();
const value = "💬 " + line.replace("// ", "").trimEnd();
useLines.push({
value: value,
class: "termynal-comment",
delay: 0
});
} else if (line.startsWith(customPromptLiteralStart)) {
saveBuffer();
const promptStart = line.indexOf(promptLiteralStart);
if (promptStart === -1) {
console.error("Custom prompt found but no end delimiter", line)
}
const prompt = line.slice(0, promptStart).replace(customPromptLiteralStart, "")
let value = line.slice(promptStart + promptLiteralStart.length);
useLines.push({
type: "input",
value: value,
prompt: prompt
});
} else {
buffer.push(line);
}
}
saveBuffer();
const inputCommands = useLines.filter(line => line.type === "input").map(line => line.value).join("\n");
node.textContent = inputCommands;
const div = document.createElement("div");
node.style.display = "none";
node.after(div);
const termynal = new Termynal(div, {
lineData: useLines,
noInit: true,
lineDelay: 500
});
termynals.push(termynal);
});
}
function loadVisibleTermynals() {
termynals = termynals.filter(termynal => {
if (termynal.container.getBoundingClientRect().top - innerHeight <= 0) {
termynal.init();
return false;
}
return true;
});
}
window.addEventListener("scroll", loadVisibleTermynals);
createTermynals();
loadVisibleTermynals();
}
function openLinksInNewTab() {
const siteUrl = document.querySelector("link[rel='canonical']")?.href
|| window.location.origin;
const siteOrigin = new URL(siteUrl).origin;
document.querySelectorAll(".md-content a[href]").forEach(a => {
if (a.getAttribute("target") === "_self") return;
const href = a.getAttribute("href");
if (!href) return;
try {
const url = new URL(href, window.location.href);
// Skip same-page anchor links (only the hash differs)
if (url.origin === window.location.origin
&& url.pathname === window.location.pathname
&& url.search === window.location.search) return;
if (!a.hasAttribute("target")) {
a.setAttribute("target", "_blank");
a.setAttribute("rel", "noopener");
}
if (url.origin !== siteOrigin) {
a.dataset.externalLink = "";
} else {
a.dataset.internalLink = "";
}
} catch (_) {}
});
}
async function main() {
setupTermynal();
openLinksInNewTab();
}
document$.subscribe(() => {
main()
})
================================================
FILE: docs/js/termynal.js
================================================
/**
* termynal.js
* A lightweight, modern and extensible animated terminal window, using
* async/await.
*
* @author Ines Montani <ines@ines.io>
* @version 0.0.1
* @license MIT
*/
'use strict';
/** Generate a terminal widget. */
class Termynal {
/**
* Construct the widget's settings.
* @param {(string|Node)=} container - Query selector or container element.
* @param {Object=} options - Custom settings.
* @param {string} options.prefix - Prefix to use for data attributes.
* @param {number} options.startDelay - Delay before animation, in ms.
* @param {number} options.typeDelay - Delay between each typed character, in ms.
* @param {number} options.lineDelay - Delay between each line, in ms.
* @param {number} options.progressLength - Number of characters displayed as progress bar.
* @param {string} options.progressChar – Character to use for progress bar, defaults to █.
* @param {number} options.progressPercent - Max percent of progress.
* @param {string} options.cursor – Character to use for cursor, defaults to ▋.
* @param {Object[]} lineData - Dynamically loaded line data objects.
* @param {boolean} options.noInit - Don't initialise the animation.
*/
constructor(container = '#termynal', options = {}) {
this.container = (typeof container === 'string') ? document.querySelector(container) : container;
this.pfx = `data-${options.prefix || 'ty'}`;
this.originalStartDelay = this.startDelay = options.startDelay
|| parseFloat(this.container.getAttribute(`${this.pfx}-startDelay`)) || 600;
this.originalTypeDelay = this.typeDelay = options.typeDelay
|| parseFloat(this.container.getAttribute(`${this.pfx}-typeDelay`)) || 90;
this.originalLineDelay = this.lineDelay = options.lineDelay
|| parseFloat(this.container.getAttribute(`${this.pfx}-lineDelay`)) || 1500;
this.progressLength = options.progressLength
|| parseFloat(this.container.getAttribute(`${this.pfx}-progressLength`)) || 40;
this.progressChar = options.progressChar
|| this.container.getAttribute(`${this.pfx}-progressChar`) || '█';
this.progressPercent = options.progressPercent
|| parseFloat(this.container.getAttribute(`${this.pfx}-progressPercent`)) || 100;
this.cursor = options.cursor
|| this.container.getAttribute(`${this.pfx}-cursor`) || '▋';
this.lineData = this.lineDataToElements(options.lineData || []);
this.loadLines()
if (!options.noInit) this.init()
}
loadLines() {
// Load all the lines and create the container so that the size is fixed
// Otherwise it would be changing and the user viewport would be constantly
// moving as she/he scrolls
const finish = this.generateFinish()
finish.style.visibility = 'hidden'
this.container.appendChild(finish)
// Appends dynamically loaded lines to existing line elements.
this.lines = [...this.container.querySelectorAll(`[${this.pfx}]`)].concat(this.lineData);
for (let line of this.lines) {
line.style.visibility = 'hidden'
this.container.appendChild(line)
}
const restart = this.generateRestart()
restart.style.visibility = 'hidden'
this.container.appendChild(restart)
this.container.setAttribute('data-termynal', '');
}
/**
* Initialise the widget, get lines, clear container and start animation.
*/
init() {
/**
* Calculates width and height of Termynal container.
* If container is empty and lines are dynamically loaded, defaults to browser `auto` or CSS.
*/
const containerStyle = getComputedStyle(this.container);
this.container.style.width = containerStyle.width !== '0px' ?
containerStyle.width : undefined;
this.container.style.minHeight = containerStyle.height !== '0px' ?
containerStyle.height : undefined;
this.container.setAttribute('data-termynal', '');
this.container.innerHTML = '';
for (let line of this.lines) {
line.style.visibility = 'visible'
}
this.start();
}
/**
* Start the animation and rener the lines depending on their data attributes.
*/
async start() {
this.addFinish()
await this._wait(this.startDelay);
for (let line of this.lines) {
const type = line.getAttribute(this.pfx);
const delay = line.getAttribute(`${this.pfx}-delay`) || this.lineDelay;
if (type == 'input') {
line.setAttribute(`${this.pfx}-cursor`, this.cursor);
await this.type(line);
await this._wait(delay);
}
else if (type == 'progress') {
await this.progress(line);
await this._wait(delay);
}
else {
this.container.appendChild(line);
await this._wait(delay);
}
line.removeAttribute(`${this.pfx}-cursor`);
}
this.addRestart()
this.finishElement.style.visibility = 'hidden'
this.lineDelay = this.originalLineDelay
this.typeDelay = this.originalTypeDelay
this.startDelay = this.originalStartDelay
}
generateRestart() {
const restart = document.createElement('a')
restart.onclick = (e) => {
e.preventDefault()
this.container.innerHTML = ''
this.init()
}
restart.href = '#'
restart.setAttribute('data-terminal-control', '')
restart.innerHTML = "restart ↻"
return restart
}
generateFinish() {
const finish = document.createElement('a')
finish.onclick = (e) => {
e.preventDefault()
this.lineDelay = 0
this.typeDelay = 0
this.startDelay = 0
}
finish.href = '#'
finish.setAttribute('data-terminal-control', '')
finish.innerHTML = "fast →"
this.finishElement = finish
return finish
}
addRestart() {
const restart = this.generateRestart()
this.container.appendChild(restart)
}
addFinish() {
const finish = this.generateFinish()
this.container.appendChild(finish)
}
/**
* Animate a typed line.
* @param {Node} line - The line element to render.
*/
async type(line) {
const chars = [...line.textContent];
line.textContent = '';
this.container.appendChild(line);
for (let char of chars) {
const delay = line.getAttribute(`${this.pfx}-typeDelay`) || this.typeDelay;
await this._wait(delay);
line.textContent += char;
}
}
/**
* Animate a progress bar.
* @param {Node} line - The line element to render.
*/
async progress(line) {
const progressLength = line.getAttribute(`${this.pfx}-progressLength`)
|| this.progressLength;
const progressChar = line.getAttribute(`${this.pfx}-progressChar`)
|| this.progressChar;
const chars = progressChar.repeat(progressLength);
const progressPercent = line.getAttribute(`${this.pfx}-progressPercent`)
|| this.progressPercent;
line.textContent = '';
this.container.appendChild(line);
for (let i = 1; i < chars.length + 1; i++) {
await this._wait(this.typeDelay);
const percent = Math.round(i / chars.length * 100);
line.textContent = `${chars.slice(0, i)} ${percent}%`;
if (percent>progressPercent) {
break;
}
}
}
/**
* Helper function for animation delays, called with `await`.
* @param {number} time - Timeout, in ms.
*/
_wait(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
/**
* Converts line data objects into line elements.
*
* @param {Object[]} lineData - Dynamically loaded lines.
* @param {Object} line - Line data object.
* @returns {Element[]} - Array of line elements.
*/
lineDataToElements(lineData) {
return lineData.map(line => {
let div = document.createElement('div');
div.innerHTML = `<span ${this._attributes(line)}>${line.value || ''}</span>`;
return div.firstElementChild;
});
}
/**
* Helper function for generating attributes string.
*
* @param {Object} line - Line data object.
* @returns {string} - String of attributes.
*/
_attributes(line) {
let attrs = '';
for (let prop in line) {
// Custom add class
if (prop === 'class') {
attrs += ` class=${line[prop]} `
continue
}
if (prop === 'type') {
attrs += `${this.pfx}="${line[prop]}" `
} else if (prop !== 'value') {
attrs += `${this.pfx}-${prop}="${line[prop]}" `
}
}
return attrs;
}
}
/**
* HTML API: If current script has container(s) specified, initialise Termynal.
*/
if (document.currentScript.hasAttribute('data-termynal-container')) {
const containers = document.currentScript.getAttribute('data-termynal-container');
containers.split('|')
.forEach(container => new Termynal(container))
}
================================================
FILE: docs/management-tasks.md
================================================
# Repository Management Tasks
These are the tasks that can be performed to manage the Typer repository by [team members](./management.md#team){.internal-link target=_blank}.
/// tip
This section is useful only to a handful of people, team members with permissions to manage the repository. You can probably skip it. 😉
///
...so, you are a [team member of Typer](./management.md#team){.internal-link target=_blank}? Wow, you are so cool! 😎
You can help with everything on [Help Typer - Get Help](./help-typer.md){.internal-link target=_blank} the same ways as external contributors. But additionally, there are some tasks that only you (as part of the team) can perform.
Here are the general instructions for the tasks you can perform.
Thanks a lot for your help. 🙇
## Be Nice
First of all, be nice. 😊
You probably are super nice if you were added to the team, but it's worth mentioning it. 🤓
### When Things are Difficult
When things are great, everything is easier, so that doesn't need much instructions. But when things are difficult, here are some guidelines.
Try to find the good side. In general, if people are not being unfriendly, try to thank their effort and interest, even if you disagree with the main subject (discussion, PR), just thank them for being interested in the project, or for having dedicated some time to try to do something.
It's difficult to convey emotion in text, use emojis to help. 😅
In discussions and PRs, in many cases, people bring their frustration and show it without filter, in many cases exaggerating, complaining, being entitled, etc. That's really not nice, and when it happens, it lowers our priority to solve their problems. But still, try to breath, and be gentle with your answers.
Try to avoid using bitter sarcasm or potentially passive-aggressive comments. If something is wrong, it's better to be direct (try to be gentle) than sarcastic.
Try to be as specific and objective as possible, avoid generalizations.
For conversations that are more difficult, for example to reject a PR, you can ask me (@tiangolo) to handle it directly.
## Edit PR Titles
* Edit the PR title to start with an emoji from <a href="https://gitmoji.dev/" class="external-link" target="_blank">gitmoji</a>.
* Use the emoji character, not the GitHub code. So, use `🐛` instead of `:bug:`. This is so that it shows up correctly outside of GitHub, for example in the release notes.
* Start the title with a verb. For example `Add`, `Refactor`, `Fix`, etc. This way the title will say the action that the PR does. Like `Add support for teleporting`, instead of `Teleporting wasn't working, so this PR fixes it`.
* Edit the text of the PR title to start in "imperative", like giving an order. So, instead of `Adding support for teleporting` use `Add support for teleporting`.
* Try to make the title descriptive about what it achieves. If it's a feature, try to describe it, for example `Add support for teleporting` instead of `Create TeleportAdapter class`.
* Do not finish the title with a period (`.`).
Once the PR is merged, a GitHub Action (<a href="https://github.com/tiangolo/latest-changes" class="external-link" target="_blank">latest-changes</a>) will use the PR title to update the latest changes automatically.
So, having a nice PR title will not only look nice in GitHub, but also in the release notes. 📝
## Add Labels to PRs
The same GitHub Action <a href="https://github.com/tiangolo/latest-changes" class="external-link" target="_blank">latest-changes</a> uses one label in the PR to decide the section in the release notes to put this PR in.
Make sure you use a supported label from the <a href="https://github.com/tiangolo/latest-changes#using-labels" class="external-link" target="_blank">latest-changes list of labels</a>:
* `breaking`: Breaking Changes
* Existing code will break if they update the version without changing their code. This rarely happens, so this label is not frequently used.
* `security`: Security Fixes
* This is for security fixes, like vulnerabilities. It would almost never be used.
* `feature`: Features
* New features, adding support for things that didn't exist before.
* `bug`: Fixes
* Something that was supported didn't work, and this fixes it. There are many PRs that claim to be bug fixes because the user is doing something in an unexpected way that is not supported, but they considered it what should be supported by default. Many of these are actually features or refactors. But in some cases there's an actual bug.
* `refactor`: Refactors
* This is normally for changes to the internal code that don't change the behavior. Normally it improves maintainability, or enables future features, etc.
* `upgrade`: Upgrades
* This is for upgrades to direct dependencies from the project, or extra optional dependencies, normally in `pyproject.toml`. So, things that would affect final users, they would end up receiving the upgrade in their code base once they update. But this is not for upgrades to internal dependencies used for development, testing, docs, etc. Those internal dependencies or GitHub Action versions should be marked as `internal`, not `upgrade`.
* `docs`: Docs
* Changes in docs. This includes updating the docs, fixing typos. But it doesn't include changes to translations.
* You can normally quickly detect it by going to the "Files changed" tab in the PR and checking if the updated file(s) starts with `docs/en/docs`. The original version of the docs is always in English, so in `docs/en/docs`.
* `internal`: Internal
* Use this for changes that only affect how the repo is managed. For example upgrades to internal dependencies, changes in GitHub Actions or scripts, etc.
/// tip
Some tools like Dependabot, will add some labels, like `dependencies`, but have in mind that this label is not used by the `latest-changes` GitHub Action, so it won't be used in the release notes. Please make sure one of the labels above is added.
///
## Review PRs
* If a PR doesn't explain what it does or why, if it seems like it could be useful, ask for more information. Otherwise, feel free to close it.
* If a PR seems to be spam, meaningless, only to change statistics (to appear as "contributor") or similar, you can simply mark it as `invalid`, and it will be automatically closed.
* If a PR seems to be AI generated, and seems like reviewing it would take more time from you than the time it took to write the prompt, mark it as `maybe-ai`, and it will be automatically closed.
* A PR should have a specific use case that it is solving.
* If the PR is for a feature, it should have docs.
* Unless it's a feature we want to discourage, like support for a corner case that we don't want users to use.
* The docs should include a source example file, not write Python directly in Markdown.
* If the source example(s) file can have different syntax for different Python versions, there should be different versions of the file, and they should be shown in tabs in the docs.
* There should be tests testing the source example.
* Before the PR is applied, the new tests should fail.
* After applying the PR, the new tests should pass.
* Coverage should stay at 100%.
* If you see the PR makes sense, or we discussed it and considered it should be accepted, you can add commits on top of the PR to tweak it, to add docs, tests, format, refactor, remove extra files, etc.
* Feel free to comment in the PR to ask for more information, to suggest changes, etc.
* Once you think the PR is ready, move it in the internal GitHub project for me to review it.
## Dependabot PRs
Dependabot will create PRs to update dependencies for several things, and those PRs all look similar, but some are way more delicate than others.
* If the PR is for a direct dependency, so, Dependabot is modifying `pyproject.toml` in the main dependencies, **don't merge it**. 😱 Let me check it first. There's a good chance that some additional tweaks or updates are needed.
* If the PR updates one of the internal dependencies, for example the group `dev` in `pyproject.toml`, or GitHub Action versions, if the tests are passing, the release notes (shown in a summary in the PR) don't show any obvious potential breaking change, you can merge it. 😎
## Mark GitHub Discussions Answers
When a question in GitHub Discussions has been answered, mark the answer by clicking "Mark as answer".
You can filter discussions by <a href="https://github.com/fastapi/typer/discussions/categories/questions?discussions_q=category:Questions+is:open+is:unanswered" class="external-link" target="_blank">`Questions` that are `Unanswered`</a>.
================================================
FILE: docs/management.md
================================================
# Repository Management
Here's a short description of how the Typer repository is managed and maintained.
## Owner
I, <a href="https://github.com/tiangolo" target="_blank">@tiangolo</a>, am the creator and owner of the Typer repository. 🤓
I normally give the final review to each PR before merging them. I make the final decisions on the project, I'm the <a href="https://en.wikipedia.org/wiki/Benevolent_dictator_for_life" class="external-link" target="_blank"><abbr title="Benevolent Dictator For Life">BDFL</abbr></a>. 😅
## Team
There's a team of people that help manage and maintain the project. 😎
They have different levels of permissions and [specific instructions](./management-tasks.md){.internal-link target=_blank}.
Some of the tasks they can perform include:
* Adding labels to PRs.
* Editing PR titles.
* Adding commits on top of PRs to tweak them.
* Mark answers in GitHub Discussions questions, etc.
* Merge some specific types of PRs.
Joining the team is by invitation only, and I could update or remove permissions, instructions, or membership.
### Team Members
This is the current list of team members. 😎
<div class="user-list user-list-center">
{% for user in members["members"] %}
<div class="user"><a href="https://github.com/{{ user.login }}" target="_blank"><div class="avatar-wrapper"><img src="https://github.com/{{ user.login }}.png"/></div><div class="title">@{{ user.login }}</div></a></div>
{% endfor %}
</div>
Additional to them, there's a large community of people helping each other and getting involved in the projects in different ways.
## External Contributions
External contributions are very welcome and appreciated, including answering questions, submitting PRs, etc. 🙇♂️
There are many ways to [help maintain Typer](./help-typer.md){.internal-link target=_blank}.
================================================
FILE: docs/overrides/main.html
================================================
{% extends "base.html" %}
================================================
FILE: docs/reference/context.md
================================================
# Context
Every app has a special internal object that keeps track of state relevant to the script's execution.
For some advanced use-cases, you may want to access it directly.
This can be done by declaring a function parameter of type `typer.Context`.
Similarly, you can also declare a function parameter with type `typer.CallbackParam` in case a callback could be used
by several CLI parameters, and you need to figure out which one it was.
```python
from typing import Annotated
import typer
app = typer.Typer()
def name_callback(ctx: typer.Context, param: typer.CallbackParam, value: str):
if ctx.resilient_parsing:
return
print(f"Validating param: {param.name}")
if value != "Rick":
raise typer.BadParameter("Only Rick is allowed")
return value
@app.command()
def main(name: Annotated[str | None, typer.Option(callback=name_callback)] = None):
print(f"Hello {name}")
if __name__ == "__main__":
app()
```
::: typer.Context
::: typer.CallbackParam
================================================
FILE: docs/reference/file_objects.md
================================================
# File objects
When you want to declare some types of files, you can use `Path`.
However, in some cases you may need to have access to a file-like object, and then you can use these [special File types](https://typer.tiangolo.com/tutorial/parameter-types/file/).
These objects can be imported from `typer` directly:
```python
from typer import FileBinaryRead, FileBinaryWrite, FileText, FileTextWrite
```
::: typer.FileText
::: typer.FileTextWrite
::: typer.FileBinaryRead
::: typer.FileBinaryWrite
================================================
FILE: docs/reference/index.md
================================================
# Reference
Here's the reference or code API, the classes, functions, parameters, attributes, and
all the Typer parts you can use in your applications.
If you want to **learn Typer** you are much better off reading the
[Typer Tutorial](https://typer.tiangolo.com/tutorial/).
================================================
FILE: docs/reference/parameters.md
================================================
# Parameters
Parameters to our command line interface may be both [CLI Options](https://typer.tiangolo.com/tutorial/options/) and [CLI Arguments](https://typer.tiangolo.com/tutorial/arguments/):
```python
from typing import Annotated
import typer
app = typer.Typer()
@app.command()
def register(
user: Annotated[str, typer.Argument()],
age: Annotated[int, typer.Option(min=18)],
score: Annotated[float, typer.Option(max=100)] = 0,
):
print(f"User is {user}")
print(f"--age is {age}")
print(f"--score is {score}")
if __name__ == "__main__":
app()
```
::: typer.Argument
options:
show_overloads: false
::: typer.Option
options:
show_overloads: false
================================================
FILE: docs/reference/run_launch.md
================================================
# `run` and `launch`
These two functions can be imported from `typer` directly:
```python
from typer import launch, run
```
::: typer.run
::: typer.launch
================================================
FILE: docs/reference/typer.md
================================================
# `Typer` class
Here's the reference information for the `Typer` class, with all its parameters, attributes and methods.
You can import the `Typer` class directly from `typer`:
```python
from typer import Typer
```
::: typer.Typer
options:
members:
- callback
- command
- add_typer
================================================
FILE: docs/release-notes.md
================================================
# Release Notes
## Latest Changes
### Refactors
* 🎨 Ensure `ty` runs without errors. PR [#1628](https://github.com/fastapi/typer/pull/1628) by [@svlandeg](https://github.com/svlandeg).
### Docs
* 📝 Fix broken link to FastAPI and Friends newsletter. PR [#1540](https://github.com/fastapi/typer/pull/1540) by [@Karlemami](https://github.com/Karlemami).
* 🔨 Handle external links `target=_blank` and CSS automatically in JS and CSS. PR [#1622](https://github.com/fastapi/typer/pull/1622) by [@tiangolo](https://github.com/tiangolo).
* 📝 Remove link to Typer developer survey. PR [#1609](https://github.com/fastapi/typer/pull/1609) by [@svlandeg](https://github.com/svlandeg).
* ✏️ Clean up documentation in `install.md` file. PR [#1606](https://github.com/fastapi/typer/pull/1606) by [@Johandielangman](https://github.com/Johandielangman).
### Internal
* ⬆ Bump prek from 0.3.5 to 0.3.6. PR [#1638](https://github.com/fastapi/typer/pull/1638) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ty from 0.0.22 to 0.0.23. PR [#1639](https://github.com/fastapi/typer/pull/1639) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pyjwt from 2.10.1 to 2.12.0. PR [#1636](https://github.com/fastapi/typer/pull/1636) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump cairosvg from 2.8.2 to 2.9.0. PR [#1635](https://github.com/fastapi/typer/pull/1635) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.15.5 to 0.15.6. PR [#1633](https://github.com/fastapi/typer/pull/1633) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ty from 0.0.21 to 0.0.22. PR [#1634](https://github.com/fastapi/typer/pull/1634) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump dorny/paths-filter from 3 to 4. PR [#1632](https://github.com/fastapi/typer/pull/1632) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.7.4 to 9.7.5. PR [#1629](https://github.com/fastapi/typer/pull/1629) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump prek from 0.3.4 to 0.3.5. PR [#1627](https://github.com/fastapi/typer/pull/1627) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ty from 0.0.20 to 0.0.21. PR [#1624](https://github.com/fastapi/typer/pull/1624) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.15.4 to 0.15.5. PR [#1625](https://github.com/fastapi/typer/pull/1625) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.7.3 to 9.7.4. PR [#1621](https://github.com/fastapi/typer/pull/1621) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ty from 0.0.19 to 0.0.20. PR [#1618](https://github.com/fastapi/typer/pull/1618) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump prek from 0.3.3 to 0.3.4. PR [#1617](https://github.com/fastapi/typer/pull/1617) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.15.2 to 0.15.4. PR [#1616](https://github.com/fastapi/typer/pull/1616) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ty from 0.0.18 to 0.0.19. PR [#1615](https://github.com/fastapi/typer/pull/1615) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/download-artifact from 7 to 8. PR [#1614](https://github.com/fastapi/typer/pull/1614) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/upload-artifact from 6 to 7. PR [#1613](https://github.com/fastapi/typer/pull/1613) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.7.2 to 9.7.3. PR [#1611](https://github.com/fastapi/typer/pull/1611) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocstrings-python from 2.0.1 to 2.0.3. PR [#1605](https://github.com/fastapi/typer/pull/1605) by [@svlandeg](https://github.com/svlandeg).
* ⬆ Bump ty from 0.0.17 to 0.0.18. PR [#1602](https://github.com/fastapi/typer/pull/1602) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump griffe-warnings-deprecated from 1.1.0 to 1.1.1. PR [#1603](https://github.com/fastapi/typer/pull/1603) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump griffe-typingdoc from 0.3.0 to 0.3.1. PR [#1604](https://github.com/fastapi/typer/pull/1604) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Upgrade pytest version and config. PR [#1570](https://github.com/fastapi/typer/pull/1570) by [@tiangolo](https://github.com/tiangolo).
## 0.24.1
### Internal
* 👷 Fix CI, do not attempt to build `typer-slim`, nor `typer-cli`. PR [#1569](https://github.com/fastapi/typer/pull/1569) by [@tiangolo](https://github.com/tiangolo).
* ➖ Drop support for `typer-slim` and `typer-cli`, no more versions will be released, use only `typer`. PR [#1568](https://github.com/fastapi/typer/pull/1568) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump rich from 14.3.2 to 14.3.3. PR [#1565](https://github.com/fastapi/typer/pull/1565) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pydantic-settings from 2.13.0 to 2.13.1. PR [#1566](https://github.com/fastapi/typer/pull/1566) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.15.1 to 0.15.2. PR [#1567](https://github.com/fastapi/typer/pull/1567) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.7.1 to 9.7.2. PR [#1561](https://github.com/fastapi/typer/pull/1561) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pillow from 11.3.0 to 12.1.1. PR [#1550](https://github.com/fastapi/typer/pull/1550) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pytest from 8.4.2 to 9.0.2. PR [#1551](https://github.com/fastapi/typer/pull/1551) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pydantic-settings from 2.12.0 to 2.13.0. PR [#1552](https://github.com/fastapi/typer/pull/1552) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🎨 Upgrade types for Python 3.10. PR [#1549](https://github.com/fastapi/typer/pull/1549) by [@tiangolo](https://github.com/tiangolo).
* 🔨 Add internal scripts to migrate docs from Python 3.9 to 3.10. PR [#1547](https://github.com/fastapi/typer/pull/1547) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump ty from 0.0.16 to 0.0.17. PR [#1544](https://github.com/fastapi/typer/pull/1544) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.24.0
### Breaking Changes
* ➖ Drop support for Python 3.9. PR [#1546](https://github.com/fastapi/typer/pull/1546) by [@tiangolo](https://github.com/tiangolo).
## 0.23.2
### Features
* ✅ Monkeypatch console width to allow running `pytest` directly. PR [#1542](https://github.com/fastapi/typer/pull/1542) by [@SwaatiR](https://github.com/SwaatiR).
### Internal
* 👷 Run tests with lower bound uv sync, update minimum dependencies. PR [#1526](https://github.com/fastapi/typer/pull/1526) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump prek from 0.3.2 to 0.3.3. PR [#1545](https://github.com/fastapi/typer/pull/1545) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.15.0 to 0.15.1. PR [#1541](https://github.com/fastapi/typer/pull/1541) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.23.1
### Fixes
* 🐛 Fix `TYPER_USE_RICH` parsing to allow disabling Rich completely. PR [#1539](https://github.com/fastapi/typer/pull/1539) by [@bckohan](https://github.com/bckohan).
### Docs
* 📝 Remove documentation pages that reference using Click directly. PR [#1538](https://github.com/fastapi/typer/pull/1538) by [@svlandeg](https://github.com/svlandeg).
### Internal
* ⬆ Bump ty from 0.0.15 to 0.0.16. PR [#1533](https://github.com/fastapi/typer/pull/1533) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.23.0
### Breaking Changes
* ♻️ When printing error tracebacks with Rich, default to not showing locals, which are sometimes verbose. PR [#1072](https://github.com/fastapi/typer/pull/1072) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Add more explicit deprecation note in shell packages. PR [#1534](https://github.com/fastapi/typer/pull/1534) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ⬆ Bump cryptography from 46.0.4 to 46.0.5. PR [#1532](https://github.com/fastapi/typer/pull/1532) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔨 Tweak PDM hook script, remove unnecessary default. PR [#1536](https://github.com/fastapi/typer/pull/1536) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Simplify build setup scripts and configs for deprecated wrapper packages. PR [#1535](https://github.com/fastapi/typer/pull/1535) by [@tiangolo](https://github.com/tiangolo).
## 0.22.0
### Breaking Changes
* 💥 Make `typer-slim` a shallow wrapper around `typer`, always requiring `rich` and `shellingham`. PR [#1522](https://github.com/fastapi/typer/pull/1522) by [@svlandeg](https://github.com/svlandeg).
## 0.21.2
### Fixes
* 🐛 Fix highlighting of optional variadic argument metavars. PR [#1508](https://github.com/fastapi/typer/pull/1508) by [@BenjyWiener](https://github.com/BenjyWiener).
* 🐛 Fix `--help` text alignment when using `typer.style()` in option descriptions. PR [#1356](https://github.com/fastapi/typer/pull/1356) by [@mahimairaja](https://github.com/mahimairaja).
### Refactors
* 🎨 Update types and errors, comment ty for now. PR [#1531](https://github.com/fastapi/typer/pull/1531) by [@tiangolo](https://github.com/tiangolo).
### Upgrades
* ➖ Drop `typing-extensions` as external dependency. PR [#1467](https://github.com/fastapi/typer/pull/1467) by [@svlandeg](https://github.com/svlandeg).
### Docs
* 📝 Add reference (code API) docs. PR [#1504](https://github.com/fastapi/typer/pull/1504) by [@svlandeg](https://github.com/svlandeg).
* 📝 Update the "Building a Package" tutorial to use `uv` instead of `poetry`. PR [#1474](https://github.com/fastapi/typer/pull/1474) by [@svlandeg](https://github.com/svlandeg).
* 📝 Update `management-tasks.md` to be in line with `management-tasks.md` in FastAPI repo. PR [#1519](https://github.com/fastapi/typer/pull/1519) by [@YuriiMotov](https://github.com/YuriiMotov).
* 📝 Add link to Typer developer survey. PR [#1514](https://github.com/fastapi/typer/pull/1514) by [@tiangolo](https://github.com/tiangolo).
* 📝 Add contribution instructions about LLM generated code and comments and automated tools for PRs. PR [#1489](https://github.com/fastapi/typer/pull/1489) by [@alejsdev](https://github.com/alejsdev).
* 🐛 Fix copy button in `custom.js`. PR [#1488](https://github.com/fastapi/typer/pull/1488) by [@alejsdev](https://github.com/alejsdev).
### Internal
* 🔧 Update config for labeler. PR [#1530](https://github.com/fastapi/typer/pull/1530) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Remove no longer used requirements.txt file. PR [#1528](https://github.com/fastapi/typer/pull/1528) by [@tiangolo](https://github.com/tiangolo).
* 📌 Update internal dependency limits. PR [#1529](https://github.com/fastapi/typer/pull/1529) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add ty to pre-commit. PR [#1527](https://github.com/fastapi/typer/pull/1527) by [@tiangolo](https://github.com/tiangolo).
* 👷 Add `ty` to the CI `lint` check. PR [#1477](https://github.com/fastapi/typer/pull/1477) by [@svlandeg](https://github.com/svlandeg).
* ⬆ Bump prek from 0.3.1 to 0.3.2. PR [#1524](https://github.com/fastapi/typer/pull/1524) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.14.14 to 0.15.0. PR [#1516](https://github.com/fastapi/typer/pull/1516) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Add generate-readme to pre-commit. PR [#1515](https://github.com/fastapi/typer/pull/1515) by [@tiangolo](https://github.com/tiangolo).
* 👷 Run mypy in pre-commit instead of `Lint` step in `test.yml` workflow. PR [#1511](https://github.com/fastapi/typer/pull/1511) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump prek from 0.3.0 to 0.3.1. PR [#1510](https://github.com/fastapi/typer/pull/1510) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump rich from 14.3.1 to 14.3.2. PR [#1509](https://github.com/fastapi/typer/pull/1509) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ✅ Update test to use `mod` fixture. PR [#1506](https://github.com/fastapi/typer/pull/1506) by [@svlandeg](https://github.com/svlandeg).
* ⬆ Bump rich from 14.2.0 to 14.3.1. PR [#1502](https://github.com/fastapi/typer/pull/1502) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.14.13 to 0.14.14. PR [#1499](https://github.com/fastapi/typer/pull/1499) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Ensure that an edit to `uv.lock` gets the `internal` label. PR [#1497](https://github.com/fastapi/typer/pull/1497) by [@svlandeg](https://github.com/svlandeg).
* ⬆ Bump ruff from 0.14.10 to 0.14.13. PR [#1493](https://github.com/fastapi/typer/pull/1493) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump urllib3 from 2.6.2 to 2.6.3. PR [#1496](https://github.com/fastapi/typer/pull/1496) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump prek from 0.2.24 to 0.3.0. PR [#1495](https://github.com/fastapi/typer/pull/1495) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.21.1
### Fixes
* 🐛 Fix escaping in help text when `rich` is installed but not used. PR [#1089](https://github.com/fastapi/typer/pull/1089) by [@svlandeg](https://github.com/svlandeg).
### Internal
* ⬆️ Migrate to uv. PR [#1472](https://github.com/fastapi/typer/pull/1472) by [@DoctorJohn](https://github.com/DoctorJohn).
* ⬆ Bump mypy from 1.18.2 to 1.19.1. PR [#1469](https://github.com/fastapi/typer/pull/1469) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/checkout from 5 to 6. PR [#1456](https://github.com/fastapi/typer/pull/1456) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/download-artifact from 6 to 7. PR [#1444](https://github.com/fastapi/typer/pull/1444) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.14.8 to 0.14.10. PR [#1449](https://github.com/fastapi/typer/pull/1449) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.7.0 to 9.7.1. PR [#1446](https://github.com/fastapi/typer/pull/1446) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/upload-artifact from 5 to 6. PR [#1443](https://github.com/fastapi/typer/pull/1443) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/cache from 4 to 5. PR [#1441](https://github.com/fastapi/typer/pull/1441) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Update secrets check. PR [#1471](https://github.com/fastapi/typer/pull/1471) by [@YuriiMotov](https://github.com/YuriiMotov).
* ✅ Add missing tests for code examples. PR [#1465](https://github.com/fastapi/typer/pull/1465) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🔧 Update pre-commit to use local Ruff instead of hook, unpin `prek`. PR [#1466](https://github.com/fastapi/typer/pull/1466) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump mypy from 1.14.1 to 1.18.2. PR [#1382](https://github.com/fastapi/typer/pull/1382) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.21.0
### Breaking Changes
* ➖ Drop support for Python 3.8. PR [#1464](https://github.com/fastapi/typer/pull/1464) by [@tiangolo](https://github.com/tiangolo).
* ➖ Drop support for Python 3.8 in CI. PR [#1463](https://github.com/fastapi/typer/pull/1463) by [@YuriiMotov](https://github.com/YuriiMotov) and [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Update code examples to Python 3.9. PR [#1459](https://github.com/fastapi/typer/pull/1459) by [@YuriiMotov](https://github.com/YuriiMotov).
### Internal
* 💚 Move `ruff` dependency to shared `requirements-docs-tests.txt` to fix "Build docs" workflow in CI. PR [#1458](https://github.com/fastapi/typer/pull/1458) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump markdown-include-variants from 0.0.5 to 0.0.8. PR [#1442](https://github.com/fastapi/typer/pull/1442) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Add pre-commit workflow. PR [#1453](https://github.com/fastapi/typer/pull/1453) by [@tiangolo](https://github.com/tiangolo).
* 👷 Configure coverage, error on main tests, don't wait for Smokeshow. PR [#1448](https://github.com/fastapi/typer/pull/1448) by [@YuriiMotov](https://github.com/YuriiMotov).
* 👷 Run Smokeshow always, even on test failures. PR [#1447](https://github.com/fastapi/typer/pull/1447) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🔨 Add Typer script to generate example variants for Python files. PR [#1452](https://github.com/fastapi/typer/pull/1452) by [@tiangolo](https://github.com/tiangolo).
## 0.20.1
### Features
* ✨ Add support for standard tracebacks via the env `TYPER_STANDARD_TRACEBACK`. PR [#1299](https://github.com/fastapi/typer/pull/1299) by [@colin-nolan](https://github.com/colin-nolan).
### Fixes
* 🐛 Ensure that `options_metavar` is passed through correctly. PR [#816](https://github.com/fastapi/typer/pull/816) by [@gar1t](https://github.com/gar1t).
* 🐛 Ensure an optional argument is shown in brackets, even when `metavar` is set. PR [#1409](https://github.com/fastapi/typer/pull/1409) by [@svlandeg](https://github.com/svlandeg).
* 🐛 Ensure that the default `rich_markup_mode` is interpreted correctly. PR [#1304](https://github.com/fastapi/typer/pull/1304) by [@svlandeg](https://github.com/svlandeg).
### Refactors
* ♻️ Refactor the handling of `shellingham`. PR [#1347](https://github.com/fastapi/typer/pull/1347) by [@nathanjmcdougall](https://github.com/nathanjmcdougall).
### Docs
* 📝 Ensure that bold letters are rendered correctly in `printing.md`. PR [#1365](https://github.com/fastapi/typer/pull/1365) by [@svlandeg](https://github.com/svlandeg).
* 🩺 Update test badge to only reflect pushes to `master`. PR [#1414](https://github.com/fastapi/typer/pull/1414) by [@svlandeg](https://github.com/svlandeg).
* 📝 Update console output on the Rich help formatting page. PR [#1430](https://github.com/fastapi/typer/pull/1430) by [@svlandeg](https://github.com/svlandeg).
* 📝 Update emoji used in Rich help formatting tutorial. PR [#1429](https://github.com/fastapi/typer/pull/1429) by [@svlandeg](https://github.com/svlandeg).
* 📝 Remove duplicate explanation how the path is resolved. PR [#956](https://github.com/fastapi/typer/pull/956) by [@dennis-rall](https://github.com/dennis-rall).
* 📝 Update docs to use `Typer()` more prominently. PR [#1418](https://github.com/fastapi/typer/pull/1418) by [@svlandeg](https://github.com/svlandeg).
* 💄 Use font 'Fira Code' to fix display of Rich panels in docs in Windows. PR [#1419](https://github.com/fastapi/typer/pull/1419) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 🔨 Add `--showlocals` to `test.sh`. PR [#1169](https://github.com/fastapi/typer/pull/1169) by [@rickwporter](https://github.com/rickwporter).
* ⬆ Bump ruff from 0.14.6 to 0.14.8. PR [#1436](https://github.com/fastapi/typer/pull/1436) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1434](https://github.com/fastapi/typer/pull/1434) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ✅ Update tests to use `mod.app` . PR [#1427](https://github.com/fastapi/typer/pull/1427) by [@svlandeg](https://github.com/svlandeg).
* ⬆ Bump actions/checkout from 5 to 6. PR [#1426](https://github.com/fastapi/typer/pull/1426) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1425](https://github.com/fastapi/typer/pull/1425) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.14.5 to 0.14.6. PR [#1423](https://github.com/fastapi/typer/pull/1423) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/checkout from 5 to 6. PR [#1417](https://github.com/fastapi/typer/pull/1417) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Upgrade `latest-changes` GitHub Action and pin `actions/checkout@v5`. PR [#1424](https://github.com/fastapi/typer/pull/1424) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Upgrade Material for MkDocs and remove insiders. PR [#1416](https://github.com/fastapi/typer/pull/1416) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump mkdocs-material from 9.6.23 to 9.7.0. PR [#1404](https://github.com/fastapi/typer/pull/1404) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-macros-plugin from 1.4.1 to 1.5.0. PR [#1406](https://github.com/fastapi/typer/pull/1406) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.14.4 to 0.14.5. PR [#1407](https://github.com/fastapi/typer/pull/1407) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1413](https://github.com/fastapi/typer/pull/1413) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.14.3 to 0.14.4. PR [#1402](https://github.com/fastapi/typer/pull/1402) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1403](https://github.com/fastapi/typer/pull/1403) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.14.2 to 0.14.3. PR [#1396](https://github.com/fastapi/typer/pull/1396) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1399](https://github.com/fastapi/typer/pull/1399) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump mkdocs-material from 9.6.22 to 9.6.23. PR [#1398](https://github.com/fastapi/typer/pull/1398) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1394](https://github.com/fastapi/typer/pull/1394) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.14.1 to 0.14.2. PR [#1383](https://github.com/fastapi/typer/pull/1383) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/upload-artifact from 4 to 5. PR [#1388](https://github.com/fastapi/typer/pull/1388) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-macros-plugin from 1.4.0 to 1.4.1. PR [#1389](https://github.com/fastapi/typer/pull/1389) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/download-artifact from 5 to 6. PR [#1391](https://github.com/fastapi/typer/pull/1391) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Add PEP-639 license metadata. PR [#1387](https://github.com/fastapi/typer/pull/1387) by [@svlandeg](https://github.com/svlandeg).
* ⬆ Bump mypy from 1.11.2 to 1.14.1. PR [#1375](https://github.com/fastapi/typer/pull/1375) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1380](https://github.com/fastapi/typer/pull/1380) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.14.0 to 0.14.1. PR [#1379](https://github.com/fastapi/typer/pull/1379) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.20.0
### Features
* ✨ Enable command suggestions on typo by default. PR [#1371](https://github.com/fastapi/typer/pull/1371) by [@savannahostrowski](https://github.com/savannahostrowski).
### Upgrades
* ⬆️ Add support for Python 3.14. PR [#1372](https://github.com/fastapi/typer/pull/1372) by [@svlandeg](https://github.com/svlandeg).
### Internal
* 👷 Add nightly workflow to run tests against CPython main branch. PR [#1374](https://github.com/fastapi/typer/pull/1374) by [@savannahostrowski](https://github.com/savannahostrowski).
* ⬆ Bump mkdocs-material from 9.6.21 to 9.6.22. PR [#1377](https://github.com/fastapi/typer/pull/1377) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Configure reminder for `waiting` label in `issue-manager`. PR [#1378](https://github.com/fastapi/typer/pull/1378) by [@YuriiMotov](https://github.com/YuriiMotov).
* ⬆ Bump ruff from 0.13.3 to 0.14.0. PR [#1368](https://github.com/fastapi/typer/pull/1368) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1376](https://github.com/fastapi/typer/pull/1376) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump mkdocs-macros-plugin from 1.3.9 to 1.4.0. PR [#1354](https://github.com/fastapi/typer/pull/1354) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.6.20 to 9.6.21. PR [#1360](https://github.com/fastapi/typer/pull/1360) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mypy from 1.4.1 to 1.11.2. PR [#957](https://github.com/fastapi/typer/pull/957) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump astral-sh/setup-uv from 6 to 7. PR [#1369](https://github.com/fastapi/typer/pull/1369) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.13.2 to 0.13.3. PR [#1366](https://github.com/fastapi/typer/pull/1366) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1367](https://github.com/fastapi/typer/pull/1367) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump tiangolo/issue-manager from 0.5.1 to 0.6.0. PR [#1361](https://github.com/fastapi/typer/pull/1361) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.13.1 to 0.13.2. PR [#1357](https://github.com/fastapi/typer/pull/1357) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1358](https://github.com/fastapi/typer/pull/1358) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* 👷 Update docs previews comment, single comment, add failure status. PR [#1359](https://github.com/fastapi/typer/pull/1359) by [@tiangolo](https://github.com/tiangolo).
## 0.19.2
### Fixes
* 🐛 Fix list convertor with an empty list default factory . PR [#1350](https://github.com/fastapi/typer/pull/1350) by [@svlandeg](https://github.com/svlandeg).
### Refactors
* 🔥 Drop support for Python 3.7. PR [#830](https://github.com/fastapi/typer/pull/830) by [@kinuax](https://github.com/kinuax).
### Internal
* ⬆ Bump ruff from 0.13.0 to 0.13.1. PR [#1339](https://github.com/fastapi/typer/pull/1339) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1351](https://github.com/fastapi/typer/pull/1351) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump markdown-include-variants from 0.0.4 to 0.0.5. PR [#1348](https://github.com/fastapi/typer/pull/1348) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.19.1
**Note**: this is the last version to support Python 3.7, going forward Typer will require Python 3.8+. And soon Python 3.8 will also be dropped as [Python 3.8 reached it's end of life](https://devguide.python.org/versions/) almost a year ago.
### Fixes
* 🐛 Ensure that `Optional[list]` values work correctly with callbacks. PR [#1018](https://github.com/fastapi/typer/pull/1018) by [@solesensei](https://github.com/solesensei).
## 0.19.0
### Features
* ✨ Support `typing.Literal` to define a set of predefined choices. PR [#429](https://github.com/fastapi/typer/pull/429) by [@blackary](https://github.com/blackary).
* ✨ Allow setting an environment variable to `None` in `CliRunner.invoke`. PR [#1303](https://github.com/fastapi/typer/pull/1303) by [@arjenzorgdoc](https://github.com/arjenzorgdoc).
### Refactors
* ✅ Use Ruff rules to ensure safe lazy-loading of `rich`. PR [#1297](https://github.com/fastapi/typer/pull/1297) by [@nathanjmcdougall](https://github.com/nathanjmcdougall).
* ✅ Avoid rich formatting in number test. PR [#1305](https://github.com/fastapi/typer/pull/1305) by [@svlandeg](https://github.com/svlandeg).
### Docs
* 📝 Clarify single-command vs multi-command behaviour in README. PR [#1268](https://github.com/fastapi/typer/pull/1268) by [@MorgenPronk](https://github.com/MorgenPronk).
## 0.18.0
### Fixes
* 👽️ Ensure compatibility with Click 8.3.0 by restoring the original `value_is_missing` function. PR [#1333](https://github.com/fastapi/typer/pull/1333) by [@svlandeg](https://github.com/svlandeg).
### Upgrades
* 📌 Remove pin for Click < 8.3.0 now that there's a fix for the changes. PR [#1346](https://github.com/fastapi/typer/pull/1346) by [@tiangolo](https://github.com/tiangolo).
## 0.17.5
### Fixes
* ⬇️ Restrict Click to below 8.3.0 to handle changes in the new version. PR [#1336](https://github.com/fastapi/typer/pull/1336) by [@svlandeg](https://github.com/svlandeg).
### Internal
* ⬆ Bump mkdocs-material from 9.6.14 to 9.6.20. PR [#1308](https://github.com/fastapi/typer/pull/1308) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.5.50 to 9.6.14. PR [#1223](https://github.com/fastapi/typer/pull/1223) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/download-artifact from 4 to 5. PR [#1269](https://github.com/fastapi/typer/pull/1269) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.12.12 to 0.13.0. PR [#1302](https://github.com/fastapi/typer/pull/1302) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1307](https://github.com/fastapi/typer/pull/1307) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Update pytest-cov requirement from <7.0.0,>=2.10.0 to >=2.10.0,<8.0.0. PR [#1301](https://github.com/fastapi/typer/pull/1301) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/setup-python from 5 to 6. PR [#1291](https://github.com/fastapi/typer/pull/1291) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.12.11 to 0.12.12. PR [#1295](https://github.com/fastapi/typer/pull/1295) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1300](https://github.com/fastapi/typer/pull/1300) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump actions/labeler from 5 to 6. PR [#1296](https://github.com/fastapi/typer/pull/1296) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.17.4
### Fixes
* 🐛 Make sure `rich.markup` is imported when rendering help text. PR [#1290](https://github.com/fastapi/typer/pull/1290) by [@g-arjones](https://github.com/g-arjones).
### Internal
* ⬆ Bump pypa/gh-action-pypi-publish from 1.12.4 to 1.13.0. PR [#1292](https://github.com/fastapi/typer/pull/1292) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.12.10 to 0.12.11. PR [#1283](https://github.com/fastapi/typer/pull/1283) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1288](https://github.com/fastapi/typer/pull/1288) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* 👷 Set permissions for conflict detector workflow. PR [#1287](https://github.com/fastapi/typer/pull/1287) by [@svlandeg](https://github.com/svlandeg).
* 👷 Detect and label merge conflicts on PRs automatically. PR [#1286](https://github.com/fastapi/typer/pull/1286) by [@svlandeg](https://github.com/svlandeg).
## 0.17.3
### Features
* ✨ Allow annotated parsing with a subclass of `Path`. PR [#1183](https://github.com/fastapi/typer/pull/1183) by [@emfdavid](https://github.com/emfdavid).
## 0.17.2
### Fixes
* 🐛 Avoid printing `default: None` in the help section when using Rich. PR [#1120](https://github.com/fastapi/typer/pull/1120) by [@mattmess1221](https://github.com/mattmess1221).
## 0.17.1
### Fixes
* 🐛 Fix markdown formatting in `--help` output. PR [#815](https://github.com/fastapi/typer/pull/815) by [@gar1t](https://github.com/gar1t).
## 0.17.0
### Features
* ⚡️ Lazy-load `rich_utils` to reduce startup time. PR [#1128](https://github.com/fastapi/typer/pull/1128) by [@oefe](https://github.com/oefe).
### Internal
* ⬆ Bump ruff from 0.12.9 to 0.12.10. PR [#1280](https://github.com/fastapi/typer/pull/1280) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1281](https://github.com/fastapi/typer/pull/1281) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Update pytest-sugar requirement from <1.1.0,>=0.9.4 to >=0.9.4,<1.2.0. PR [#1279](https://github.com/fastapi/typer/pull/1279) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.16.1
### Fixes
* 🐛 Avoid printing additional output with `no_args_is_help=True` and Click 8.2. PR [#1278](https://github.com/fastapi/typer/pull/1278) by [@svlandeg](https://github.com/svlandeg).
### Docs
* 📝 Remove duplicated line in `environment-variables.md`. PR [#1277](https://github.com/fastapi/typer/pull/1277) by [@neirzhei](https://github.com/neirzhei).
* 📝 Fix reference to `count` parameter in the documentation. PR [#1201](https://github.com/fastapi/typer/pull/1201) by [@PokkaKiyo](https://github.com/PokkaKiyo).
### Internal
* ⬆ Bump ruff from 0.11.13 to 0.12.9. PR [#1276](https://github.com/fastapi/typer/pull/1276) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1247](https://github.com/fastapi/typer/pull/1247) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump actions/checkout from 4 to 5. PR [#1271](https://github.com/fastapi/typer/pull/1271) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-macros-plugin from 1.3.7 to 1.3.9. PR [#1272](https://github.com/fastapi/typer/pull/1272) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump tiangolo/latest-changes from 0.3.2 to 0.4.0. PR [#1265](https://github.com/fastapi/typer/pull/1265) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pillow from 11.2.1 to 11.3.0. PR [#1249](https://github.com/fastapi/typer/pull/1249) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1206](https://github.com/fastapi/typer/pull/1206) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump pillow from 11.1.0 to 11.2.1. PR [#1198](https://github.com/fastapi/typer/pull/1198) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump cairosvg from 2.7.1 to 2.8.2. PR [#1226](https://github.com/fastapi/typer/pull/1226) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.11.6 to 0.11.13. PR [#1241](https://github.com/fastapi/typer/pull/1241) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.16.0
### Upgrades
* ⬆️ Add compatibility with Click 8.2. PR [#1222](https://github.com/fastapi/typer/pull/1222) by [@tiangolo](https://github.com/tiangolo).
When using the `CliRunner` with Click < 8.2, to be able to access the `stderr` output, you needed to set the `mix_stderr` parameter to `True`. Since Click 8.2 (and Typer 0.160 this release supporting it) this is no longer necessary, so this parameter has been removed.
### Refactors
* ✅ Refactor tests for compatibility with Click 8.2. PR [#1230](https://github.com/fastapi/typer/pull/1230) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 🔧 Remove Google Analytics. PR [#1229](https://github.com/fastapi/typer/pull/1229) by [@tiangolo](https://github.com/tiangolo).
## 0.15.4
### Upgrades
* 📌 Pin Click to < 8.2, compatibility for Click >= 8.2 will be added in a future version. PR [#1225](https://github.com/fastapi/typer/pull/1225) by [@tiangolo](https://github.com/tiangolo).
## 0.15.3
### Fixes
* 🐛 Ensure that autocompletion works for `Path` arguments/options. PR [#1138](https://github.com/fastapi/typer/pull/1138) by [@svlandeg](https://github.com/svlandeg).
* 🐛 Fix newline after header in help text, and add more tests for the behaviour of `rich_markup_mode` . PR [#964](https://github.com/fastapi/typer/pull/964) by [@svlandeg](https://github.com/svlandeg).
### Internal
* ⬆ Bump astral-sh/setup-uv from 5 to 6. PR [#1203](https://github.com/fastapi/typer/pull/1203) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.11.2 to 0.11.6. PR [#1200](https://github.com/fastapi/typer/pull/1200) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1196](https://github.com/fastapi/typer/pull/1196) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.11.1 to 0.11.2. PR [#1186](https://github.com/fastapi/typer/pull/1186) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1187](https://github.com/fastapi/typer/pull/1187) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.11.0 to 0.11.1. PR [#1185](https://github.com/fastapi/typer/pull/1185) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.9.10 to 0.11.0. PR [#1180](https://github.com/fastapi/typer/pull/1180) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1181](https://github.com/fastapi/typer/pull/1181) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1176](https://github.com/fastapi/typer/pull/1176) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.9.9 to 0.9.10. PR [#1175](https://github.com/fastapi/typer/pull/1175) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1171](https://github.com/fastapi/typer/pull/1171) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.9.7 to 0.9.9. PR [#1166](https://github.com/fastapi/typer/pull/1166) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ✏️ Fix typo in test name. PR [#1165](https://github.com/fastapi/typer/pull/1165) by [@svlandeg](https://github.com/svlandeg).
## 0.15.2
### Features
* ✨ Allow custom styles for commands in help output. PR [#1103](https://github.com/fastapi/typer/pull/1103) by [@TheTechromancer](https://github.com/TheTechromancer).
* ✨ Avoid the unnecessary import of `typing_extensions` in newer Python versions. PR [#1048](https://github.com/fastapi/typer/pull/1048) by [@horta](https://github.com/horta).
### Fixes
* 🐛 Fix shell completions for the fish shell. PR [#1069](https://github.com/fastapi/typer/pull/1069) by [@goraje](https://github.com/goraje).
### Refactors
* 🚚 Rename test to corner-cases to make it more explicit. PR [#1083](https://github.com/fastapi/typer/pull/1083) by [@tiangolo](https://github.com/tiangolo).
### Docs
* ✏️ Fix small typos in the tutorial documentation. PR [#1137](https://github.com/fastapi/typer/pull/1137) by [@svlandeg](https://github.com/svlandeg).
* 📝 Update optional CLI argument section in tutorial with `Annotated`. PR [#983](https://github.com/fastapi/typer/pull/983) by [@gkeuccsr](https://github.com/gkeuccsr).
* 📝 Clarify the need for `mix_stderr` when accessing the output of `stderr` in tests. PR [#1045](https://github.com/fastapi/typer/pull/1045) by [@mrchrisadams](https://github.com/mrchrisadams).
### Internal
* 🔧 Add support for Python 3.13, tests in CI and add PyPI trove classifier. PR [#1091](https://github.com/fastapi/typer/pull/1091) by [@edgarrmondragon](https://github.com/edgarrmondragon).
* ⬆ Bump ruff from 0.9.6 to 0.9.7. PR [#1161](https://github.com/fastapi/typer/pull/1161) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1162](https://github.com/fastapi/typer/pull/1162) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.9.5 to 0.9.6. PR [#1153](https://github.com/fastapi/typer/pull/1153) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1151](https://github.com/fastapi/typer/pull/1151) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.9.4 to 0.9.5. PR [#1146](https://github.com/fastapi/typer/pull/1146) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1142](https://github.com/fastapi/typer/pull/1142) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.9.3 to 0.9.4. PR [#1139](https://github.com/fastapi/typer/pull/1139) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1135](https://github.com/fastapi/typer/pull/1135) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.9.1 to 0.9.3. PR [#1136](https://github.com/fastapi/typer/pull/1136) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1130](https://github.com/fastapi/typer/pull/1130) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.8.6 to 0.9.1. PR [#1118](https://github.com/fastapi/typer/pull/1118) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pypa/gh-action-pypi-publish from 1.12.3 to 1.12.4. PR [#1132](https://github.com/fastapi/typer/pull/1132) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.5.49 to 9.5.50. PR [#1129](https://github.com/fastapi/typer/pull/1129) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 💚 Fix test matrix for Python 3.7. PR [#1116](https://github.com/fastapi/typer/pull/1116) by [@svlandeg](https://github.com/svlandeg).
* ⬆ Bump ruff from 0.8.4 to 0.8.6. PR [#1107](https://github.com/fastapi/typer/pull/1107) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1109](https://github.com/fastapi/typer/pull/1109) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump pillow from 11.0.0 to 11.1.0. PR [#1104](https://github.com/fastapi/typer/pull/1104) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1102](https://github.com/fastapi/typer/pull/1102) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.8.3 to 0.8.4. PR [#1097](https://github.com/fastapi/typer/pull/1097) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump astral-sh/setup-uv from 4 to 5. PR [#1098](https://github.com/fastapi/typer/pull/1098) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump markdown-include-variants from 0.0.3 to 0.0.4. PR [#1100](https://github.com/fastapi/typer/pull/1100) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.8.2 to 0.8.3. PR [#1090](https://github.com/fastapi/typer/pull/1090) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1093](https://github.com/fastapi/typer/pull/1093) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump mkdocs-material from 9.5.48 to 9.5.49. PR [#1092](https://github.com/fastapi/typer/pull/1092) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pypa/gh-action-pypi-publish from 1.12.2 to 1.12.3. PR [#1088](https://github.com/fastapi/typer/pull/1088) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1087](https://github.com/fastapi/typer/pull/1087) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.8.1 to 0.8.2. PR [#1084](https://github.com/fastapi/typer/pull/1084) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.5.47 to 9.5.48. PR [#1086](https://github.com/fastapi/typer/pull/1086) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.15.1
### Features
* 🗑️ Deprecate `shell_complete` and continue to use `autocompletion` for CLI parameters. PR [#974](https://github.com/fastapi/typer/pull/974) by [@svlandeg](https://github.com/svlandeg).
### Docs
* ✏️ Fix a few typos in the source and documentation. PR [#1028](https://github.com/fastapi/typer/pull/1028) by [@kkirsche](https://github.com/kkirsche).
* 📝 Fix minor inconsistencies and typos in tutorial. PR [#1067](https://github.com/fastapi/typer/pull/1067) by [@tvoirand](https://github.com/tvoirand).
* ✏️ Fix a few small typos in the documentation. PR [#1077](https://github.com/fastapi/typer/pull/1077) by [@svlandeg](https://github.com/svlandeg).
### Internal
* 🔧 Update build-docs filter patterns. PR [#1080](https://github.com/fastapi/typer/pull/1080) by [@tiangolo](https://github.com/tiangolo).
* 🔨 Update deploy docs preview script. PR [#1079](https://github.com/fastapi/typer/pull/1079) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update members. PR [#1078](https://github.com/fastapi/typer/pull/1078) by [@tiangolo](https://github.com/tiangolo).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1071](https://github.com/fastapi/typer/pull/1071) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Update httpx requirement from <0.28.0,>=0.27.0 to >=0.27.0,<0.29.0. PR [#1065](https://github.com/fastapi/typer/pull/1065) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.15.0
### Features
* ✨ Add support for extending typer apps without passing a name, add commands to the top level. PR [#1037](https://github.com/fastapi/typer/pull/1037) by [@patrick91](https://github.com/patrick91).
* New docs: [One File Per Command](https://typer.tiangolo.com/tutorial/one-file-per-command/).
### Internal
* ⬆ Bump mkdocs-material from 9.5.46 to 9.5.47. PR [#1070](https://github.com/fastapi/typer/pull/1070) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.8.0 to 0.8.1. PR [#1066](https://github.com/fastapi/typer/pull/1066) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.14.0
### Breaking Changes
* 🔥 Remove auto naming of groups added via `add_typer` based on the group's callback function name. PR [#1052](https://github.com/fastapi/typer/pull/1052) by [@patrick91](https://github.com/patrick91).
Before, it was supported to infer the name of a command group from the callback function name in the sub-app, so, in this code:
```python
import typer
app = typer.Typer()
users_app = typer.Typer()
app.add_typer(users_app)
@users_app.callback()
def users(): # <-- This was the inferred command group name
"""
Manage users in the app.
"""
@users_app.command()
def create(name: str):
print(f"Creating user: {name}")
```
...the command group would be named `users`, based on the name of the function `def users()`.
Now you need to set it explicitly:
```python
import typer
app = typer.Typer()
users_app = typer.Typer()
app.add_typer(users_app, name="users") # <-- Explicitly set the command group name
@users_app.callback()
def users():
"""
Manage users in the app.
"""
@users_app.command()
def create(name: str):
print(f"Creating user: {name}")
```
Updated docs [SubCommand Name and Help](https://typer.tiangolo.com/tutorial/subcommands/name-and-help/).
**Note**: this change will enable important features in the next release. 🤩
### Internal
* ⬆ Bump pypa/gh-action-pypi-publish from 1.10.3 to 1.12.2. PR [#1043](https://github.com/fastapi/typer/pull/1043) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.5.44 to 9.5.46. PR [#1062](https://github.com/fastapi/typer/pull/1062) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.7.4 to 0.8.0. PR [#1059](https://github.com/fastapi/typer/pull/1059) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump astral-sh/setup-uv from 3 to 4. PR [#1061](https://github.com/fastapi/typer/pull/1061) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1053](https://github.com/fastapi/typer/pull/1053) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
## 0.13.1
### Features
* ✨ Remove Rich tags when showing completion text. PR [#877](https://github.com/fastapi/typer/pull/877) by [@svlandeg](https://github.com/svlandeg).
* ✨ Render Rich markup as HTML in Markdown docs. PR [#847](https://github.com/fastapi/typer/pull/847) by [@svlandeg](https://github.com/svlandeg).
* ✨ Support cp850 encoding for auto-completion in PowerShell. PR [#808](https://github.com/fastapi/typer/pull/808) by [@svlandeg](https://github.com/svlandeg).
* ✨ Allow gettext translation of help message. PR [#886](https://github.com/fastapi/typer/pull/886) by [@svlandeg](https://github.com/svlandeg).
### Refactors
* 🐛 Fix printing HTML from Rich output. PR [#1055](https://github.com/fastapi/typer/pull/1055) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Update markdown includes to use the new simpler format. PR [#1054](https://github.com/fastapi/typer/pull/1054) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ⬆ Bump ruff from 0.7.3 to 0.7.4. PR [#1051](https://github.com/fastapi/typer/pull/1051) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1047](https://github.com/fastapi/typer/pull/1047) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.7.2 to 0.7.3. PR [#1046](https://github.com/fastapi/typer/pull/1046) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump tiangolo/latest-changes from 0.3.1 to 0.3.2. PR [#1044](https://github.com/fastapi/typer/pull/1044) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Update pytest-cov requirement from <6.0.0,>=2.10.0 to >=2.10.0,<7.0.0. PR [#1033](https://github.com/fastapi/typer/pull/1033) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.13.0
### Features
* ✨ Handle `KeyboardInterrupt` separately from other exceptions. PR [#1039](https://github.com/fastapi/typer/pull/1039) by [@patrick91](https://github.com/patrick91).
* ✨ Update `launch` to not print anything when opening urls. PR [#1035](https://github.com/fastapi/typer/pull/1035) by [@patrick91](https://github.com/patrick91).
* ✨ Show help items in order of definition. PR [#944](https://github.com/fastapi/typer/pull/944) by [@svlandeg](https://github.com/svlandeg).
### Fixes
* 🐛 Fix equality check for custom classes. PR [#979](https://github.com/fastapi/typer/pull/979) by [@AryazE](https://github.com/AryazE).
* 🐛 Allow colon in zsh autocomplete values and descriptions. PR [#988](https://github.com/fastapi/typer/pull/988) by [@snapbug](https://github.com/snapbug).
### Refactors
* 🗑️ Deprecate support for `is_flag` and `flag_value` parameters. PR [#987](https://github.com/fastapi/typer/pull/987) by [@svlandeg](https://github.com/svlandeg).
* 🔥 Remove unused functionality from `_typing.py` file. PR [#805](https://github.com/fastapi/typer/pull/805) by [@ivantodorovich](https://github.com/ivantodorovich).
* ✏️ Fix typo in function name `_make_rich_text`. PR [#959](https://github.com/fastapi/typer/pull/959) by [@svlandeg](https://github.com/svlandeg).
### Internal
* ✅ Only run completion installation tests when the env var `_TYPER_RUN_INSTALL_COMPLETION_TESTS` is set. PR [#995](https://github.com/fastapi/typer/pull/995) by [@svlandeg](https://github.com/svlandeg).
* 📝 Update the docstring of the `_make_rich_text` method. PR [#972](https://github.com/fastapi/typer/pull/972) by [@svlandeg](https://github.com/svlandeg).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1040](https://github.com/fastapi/typer/pull/1040) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump mkdocs-material from 9.5.42 to 9.5.44. PR [#1042](https://github.com/fastapi/typer/pull/1042) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.7.1 to 0.7.2. PR [#1038](https://github.com/fastapi/typer/pull/1038) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-macros-plugin from 1.3.6 to 1.3.7. PR [#1031](https://github.com/fastapi/typer/pull/1031) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1032](https://github.com/fastapi/typer/pull/1032) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.7.0 to 0.7.1. PR [#1029](https://github.com/fastapi/typer/pull/1029) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pillow from 10.4.0 to 11.0.0. PR [#1023](https://github.com/fastapi/typer/pull/1023) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.5.35 to 9.5.42. PR [#1027](https://github.com/fastapi/typer/pull/1027) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.6.5 to 0.7.0. PR [#1026](https://github.com/fastapi/typer/pull/1026) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-macros-plugin from 1.2.0 to 1.3.6. PR [#1025](https://github.com/fastapi/typer/pull/1025) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Update pre-commit requirement from <4.0.0,>=2.17.0 to >=2.17.0,<5.0.0. PR [#1012](https://github.com/fastapi/typer/pull/1012) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pypa/gh-action-pypi-publish from 1.10.1 to 1.10.3. PR [#1009](https://github.com/fastapi/typer/pull/1009) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#1001](https://github.com/fastapi/typer/pull/1001) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* 👷 Update Deploy docs CI to use uv. PR [#1021](https://github.com/fastapi/typer/pull/1021) by [@tiangolo](https://github.com/tiangolo).
* 👷 Fix smokeshow, checkout files on CI. PR [#1020](https://github.com/fastapi/typer/pull/1020) by [@tiangolo](https://github.com/tiangolo).
* 👷 Use uv in CI. PR [#1019](https://github.com/fastapi/typer/pull/1019) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update `labeler.yml`. PR [#1014](https://github.com/fastapi/typer/pull/1014) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update worfkow deploy-docs-notify URL. PR [#1011](https://github.com/fastapi/typer/pull/1011) by [@tiangolo](https://github.com/tiangolo).
* 👷 Upgrade Cloudflare GitHub Action. PR [#1010](https://github.com/fastapi/typer/pull/1010) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump mkdocs-macros-plugin from 1.0.5 to 1.2.0. PR [#992](https://github.com/fastapi/typer/pull/992) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff from 0.6.4 to 0.6.5. PR [#991](https://github.com/fastapi/typer/pull/991) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.5.34 to 9.5.35. PR [#996](https://github.com/fastapi/typer/pull/996) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#993](https://github.com/fastapi/typer/pull/993) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#982](https://github.com/fastapi/typer/pull/982) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump tiangolo/issue-manager from 0.5.0 to 0.5.1. PR [#980](https://github.com/fastapi/typer/pull/980) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Update `issue-manager.yml`. PR [#978](https://github.com/fastapi/typer/pull/978) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump ruff from 0.6.3 to 0.6.4. PR [#975](https://github.com/fastapi/typer/pull/975) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.5.33 to 9.5.34. PR [#963](https://github.com/fastapi/typer/pull/963) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pypa/gh-action-pypi-publish from 1.9.0 to 1.10.1. PR [#973](https://github.com/fastapi/typer/pull/973) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#966](https://github.com/fastapi/typer/pull/966) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* 💚 Set `include-hidden-files` to `True` when using the `upload-artifact` GH action. PR [#967](https://github.com/fastapi/typer/pull/967) by [@svlandeg](https://github.com/svlandeg).
* ⬆ Bump ruff from 0.6.1 to 0.6.3. PR [#961](https://github.com/fastapi/typer/pull/961) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#689](https://github.com/fastapi/typer/pull/689) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆ Bump ruff from 0.2.0 to 0.6.1. PR [#938](https://github.com/fastapi/typer/pull/938) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Update `latest-changes` GitHub Action. PR [#955](https://github.com/fastapi/typer/pull/955) by [@tiangolo](https://github.com/tiangolo).
## 0.12.5
### Features
* 💄 Unify the width of the Rich console for help and errors. PR [#788](https://github.com/fastapi/typer/pull/788) by [@racinmat](https://github.com/racinmat).
* 🚸 Improve assertion error message if a group is not a valid subclass. PR [#425](https://github.com/fastapi/typer/pull/425) by [@chrisburr](https://github.com/chrisburr).
### Fixes
* 🐛 Ensure `rich_markup_mode=None` disables Rich formatting. PR [#859](https://github.com/fastapi/typer/pull/859) by [@svlandeg](https://github.com/svlandeg).
* 🐛 Fix sourcing of completion path for Git Bash. PR [#801](https://github.com/fastapi/typer/pull/801) by [@svlandeg](https://github.com/svlandeg).
* 🐛 Fix PowerShell completion with incomplete word. PR [#360](https://github.com/fastapi/typer/pull/360) by [@patricksurry](https://github.com/patricksurry).
### Refactors
* 🔥 Remove Python 3.6 specific code paths. PR [#850](https://github.com/fastapi/typer/pull/850) by [@svlandeg](https://github.com/svlandeg).
* 🔥 Clean up redundant code. PR [#858](https://github.com/fastapi/typer/pull/858) by [@svlandeg](https://github.com/svlandeg).
### Docs
* ♻️ Use F-strings in Click examples in docs. PR [#891](https://github.com/fastapi/typer/pull/891) by [@svlandeg](https://github.com/svlandeg).
* 📝Add missing `main.py` in tutorial on CLI option names. PR [#868](https://github.com/fastapi/typer/pull/868) by [@fsramalho](https://github.com/fsramalho).
* 📝 Fix broken link. PR [#835](https://github.com/fastapi/typer/pull/835) by [@OhioDschungel6](https://github.com/OhioDschungel6).
* 📝 Update package docs with the latest versions of Typer and Poetry. PR [#781](https://github.com/fastapi/typer/pull/781) by [@kinuax](https://github.com/kinuax).
* 📝 Update the Progress Bar tutorial with correct output. PR [#199](https://github.com/fastapi/typer/pull/199) by [@n1ckdm](https://github.com/n1ckdm).
* 📝 Add docs and scripts to test completion in different shells. PR [#953](https://github.com/fastapi/typer/pull/953) by [@tiangolo](https://github.com/tiangolo).
* ✏️ Fix a typo in `docs/virtual-environments.md`. PR [#952](https://github.com/fastapi/typer/pull/952) by [@tiangolo](https://github.com/tiangolo).
* ✏️ Fix typo in `docs/contributing.md`. PR [#947](https://github.com/fastapi/typer/pull/947) by [@tiangolo](https://github.com/tiangolo).
* 📝 Add docs for virtual environments, environment variables, and update contributing. PR [#946](https://github.com/fastapi/typer/pull/946) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 🔨 Pre-install dependencies in Docker so that testing in Docker is faster. PR [#954](https://github.com/fastapi/typer/pull/954) by [@tiangolo](https://github.com/tiangolo).
* ✅ Add `needs_bash` test fixture. PR [#888](https://github.com/fastapi/typer/pull/888) by [@svlandeg](https://github.com/svlandeg).
* ⬆ Bump mkdocs-material from 9.5.18 to 9.5.33. PR [#945](https://github.com/fastapi/typer/pull/945) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pillow from 10.3.0 to 10.4.0. PR [#939](https://github.com/fastapi/typer/pull/939) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Fix issue-manager. PR [#948](https://github.com/fastapi/typer/pull/948) by [@tiangolo](https://github.com/tiangolo).
* 🙈 Remove extra line in .gitignore. PR [#936](https://github.com/fastapi/typer/pull/936) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Update pytest-cov requirement from <5.0.0,>=2.10.0 to >=2.10.0,<6.0.0. PR [#844](https://github.com/fastapi/typer/pull/844) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pypa/gh-action-pypi-publish from 1.8.11 to 1.9.0. PR [#865](https://github.com/fastapi/typer/pull/865) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Update pytest requirement from <8.0.0,>=4.4.0 to >=4.4.0,<9.0.0. PR [#915](https://github.com/fastapi/typer/pull/915) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Update pytest-sugar requirement from <0.10.0,>=0.9.4 to >=0.9.4,<1.1.0. PR [#841](https://github.com/fastapi/typer/pull/841) by [@dependabot[bot]](https://github.com/apps/dependabot).
## 0.12.4
### Features
* ✨ Add support for Python 3.12, tests in CI and official marker. PR [#807](https://github.com/tiangolo/typer/pull/807) by [@ivantodorovich](https://github.com/ivantodorovich).
### Fixes
* 🐛 Fix support for `UnionType` (e.g. `str | None`) with Python 3.11. PR [#548
gitextract_06wjnt0r/
├── .github/
│ ├── DISCUSSION_TEMPLATE/
│ │ └── questions.yml
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ └── privileged.yml
│ ├── dependabot.yml
│ ├── labeler.yml
│ └── workflows/
│ ├── add-to-project.yml
│ ├── build-docs.yml
│ ├── conflict.yml
│ ├── deploy-docs.yml
│ ├── issue-manager.yml
│ ├── labeler.yml
│ ├── latest-changes.yml
│ ├── pre-commit.yml
│ ├── publish.yml
│ ├── smokeshow.yml
│ ├── test-cpython-nightly.yml
│ ├── test-redistribute.yml
│ └── test.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── CITATION.cff
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── data/
│ └── members.yml
├── docs/
│ ├── about/
│ │ └── index.md
│ ├── alternatives.md
│ ├── contributing.md
│ ├── css/
│ │ ├── custom.css
│ │ └── termynal.css
│ ├── environment-variables.md
│ ├── features.md
│ ├── help-typer.md
│ ├── index.md
│ ├── js/
│ │ ├── custom.js
│ │ └── termynal.js
│ ├── management-tasks.md
│ ├── management.md
│ ├── overrides/
│ │ └── main.html
│ ├── reference/
│ │ ├── context.md
│ │ ├── file_objects.md
│ │ ├── index.md
│ │ ├── parameters.md
│ │ ├── run_launch.md
│ │ └── typer.md
│ ├── release-notes.md
│ ├── resources/
│ │ └── index.md
│ ├── tutorial/
│ │ ├── app-dir.md
│ │ ├── arguments/
│ │ │ ├── default.md
│ │ │ ├── envvar.md
│ │ │ ├── help.md
│ │ │ ├── index.md
│ │ │ ├── optional.md
│ │ │ └── other-uses.md
│ │ ├── commands/
│ │ │ ├── arguments.md
│ │ │ ├── callback.md
│ │ │ ├── context.md
│ │ │ ├── help.md
│ │ │ ├── index.md
│ │ │ ├── name.md
│ │ │ ├── one-or-multiple.md
│ │ │ └── options.md
│ │ ├── exceptions.md
│ │ ├── first-steps.md
│ │ ├── index.md
│ │ ├── install.md
│ │ ├── launch.md
│ │ ├── multiple-values/
│ │ │ ├── arguments-with-multiple-values.md
│ │ │ ├── index.md
│ │ │ ├── multiple-options.md
│ │ │ └── options-with-multiple-values.md
│ │ ├── one-file-per-command.md
│ │ ├── options/
│ │ │ ├── callback-and-context.md
│ │ │ ├── help.md
│ │ │ ├── index.md
│ │ │ ├── name.md
│ │ │ ├── password.md
│ │ │ ├── prompt.md
│ │ │ ├── required.md
│ │ │ └── version.md
│ │ ├── options-autocompletion.md
│ │ ├── package.md
│ │ ├── parameter-types/
│ │ │ ├── bool.md
│ │ │ ├── custom-types.md
│ │ │ ├── datetime.md
│ │ │ ├── enum.md
│ │ │ ├── file.md
│ │ │ ├── index.md
│ │ │ ├── number.md
│ │ │ ├── path.md
│ │ │ └── uuid.md
│ │ ├── printing.md
│ │ ├── progressbar.md
│ │ ├── prompt.md
│ │ ├── subcommands/
│ │ │ ├── add-typer.md
│ │ │ ├── callback-override.md
│ │ │ ├── index.md
│ │ │ ├── name-and-help.md
│ │ │ ├── nested-subcommands.md
│ │ │ └── single-file.md
│ │ ├── terminating.md
│ │ ├── testing.md
│ │ ├── typer-app.md
│ │ └── typer-command.md
│ └── virtual-environments.md
├── docs_src/
│ ├── app_dir/
│ │ ├── __init__.py
│ │ └── tutorial001_py310.py
│ ├── arguments/
│ │ ├── __init__.py
│ │ ├── default/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ ├── envvar/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ └── tutorial003_py310.py
│ │ ├── help/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_an_py310.py
│ │ │ ├── tutorial005_py310.py
│ │ │ ├── tutorial006_an_py310.py
│ │ │ ├── tutorial006_py310.py
│ │ │ ├── tutorial007_an_py310.py
│ │ │ ├── tutorial007_py310.py
│ │ │ ├── tutorial008_an_py310.py
│ │ │ └── tutorial008_py310.py
│ │ └── optional/
│ │ ├── __init__.py
│ │ ├── tutorial000_an_py310.py
│ │ ├── tutorial000_py310.py
│ │ ├── tutorial001_an_py310.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_an_py310.py
│ │ ├── tutorial002_py310.py
│ │ └── tutorial003_py310.py
│ ├── commands/
│ │ ├── __init__.py
│ │ ├── arguments/
│ │ │ ├── __init__.py
│ │ │ └── tutorial001_py310.py
│ │ ├── callback/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── context/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── help/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_an_py310.py
│ │ │ ├── tutorial005_py310.py
│ │ │ ├── tutorial006_py310.py
│ │ │ ├── tutorial007_an_py310.py
│ │ │ ├── tutorial007_py310.py
│ │ │ └── tutorial008_py310.py
│ │ ├── index/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ └── tutorial005_py310.py
│ │ ├── name/
│ │ │ ├── __init__.py
│ │ │ └── tutorial001_py310.py
│ │ ├── one_or_multiple/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ └── tutorial002_py310.py
│ │ └── options/
│ │ ├── __init__.py
│ │ ├── tutorial001_an_py310.py
│ │ └── tutorial001_py310.py
│ ├── exceptions/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ └── tutorial004_py310.py
│ ├── first_steps/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ ├── tutorial004_py310.py
│ │ ├── tutorial005_py310.py
│ │ └── tutorial006_py310.py
│ ├── launch/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ └── tutorial002_py310.py
│ ├── multiple_values/
│ │ ├── __init__.py
│ │ ├── arguments_with_multiple_values/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ ├── multiple_options/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ └── options_with_multiple_values/
│ │ ├── __init__.py
│ │ ├── tutorial001_an_py310.py
│ │ └── tutorial001_py310.py
│ ├── one_file_per_command/
│ │ ├── __init__.py
│ │ └── app_py310/
│ │ ├── __init__.py
│ │ ├── main.py
│ │ ├── users/
│ │ │ ├── __init__.py
│ │ │ ├── add.py
│ │ │ └── delete.py
│ │ └── version.py
│ ├── options/
│ │ ├── __init__.py
│ │ ├── callback/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── help/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── name/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_an_py310.py
│ │ │ └── tutorial005_py310.py
│ │ ├── password/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ ├── prompt/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ └── tutorial003_py310.py
│ │ ├── required/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ └── tutorial002_py310.py
│ │ └── version/
│ │ ├── __init__.py
│ │ ├── tutorial001_an_py310.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_an_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_an_py310.py
│ │ └── tutorial003_py310.py
│ ├── options_autocompletion/
│ │ ├── __init__.py
│ │ ├── tutorial001_an_py310.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_an_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_an_py310.py
│ │ ├── tutorial003_py310.py
│ │ ├── tutorial004_an_py310.py
│ │ ├── tutorial004_py310.py
│ │ ├── tutorial005_an_py310.py
│ │ ├── tutorial005_py310.py
│ │ ├── tutorial006_an_py310.py
│ │ ├── tutorial006_py310.py
│ │ ├── tutorial007_an_py310.py
│ │ ├── tutorial007_py310.py
│ │ ├── tutorial008_an_py310.py
│ │ ├── tutorial008_py310.py
│ │ ├── tutorial009_an_py310.py
│ │ └── tutorial009_py310.py
│ ├── parameter_types/
│ │ ├── __init__.py
│ │ ├── bool/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── custom_types/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ └── tutorial001_py310.py
│ │ ├── datetime/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ ├── enum/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── file/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_an_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_an_py310.py
│ │ │ └── tutorial005_py310.py
│ │ ├── index/
│ │ │ ├── __init__.py
│ │ │ └── tutorial001_py310.py
│ │ ├── number/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_an_py310.py
│ │ │ └── tutorial003_py310.py
│ │ ├── path/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_an_py310.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_an_py310.py
│ │ │ └── tutorial002_py310.py
│ │ └── uuid/
│ │ ├── __init__.py
│ │ └── tutorial001_py310.py
│ ├── printing/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ ├── tutorial004_py310.py
│ │ ├── tutorial005_py310.py
│ │ └── tutorial006_py310.py
│ ├── progressbar/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ ├── tutorial004_py310.py
│ │ ├── tutorial005_py310.py
│ │ └── tutorial006_py310.py
│ ├── prompt/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ ├── tutorial003_py310.py
│ │ └── tutorial004_py310.py
│ ├── subcommands/
│ │ ├── __init__.py
│ │ ├── callback_override/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ └── tutorial004_py310.py
│ │ ├── name_help/
│ │ │ ├── __init__.py
│ │ │ ├── tutorial001_py310.py
│ │ │ ├── tutorial002_py310.py
│ │ │ ├── tutorial003_py310.py
│ │ │ ├── tutorial004_py310.py
│ │ │ ├── tutorial005_py310.py
│ │ │ ├── tutorial006_py310.py
│ │ │ ├── tutorial007_py310.py
│ │ │ └── tutorial008_py310.py
│ │ ├── tutorial001_py310/
│ │ │ ├── __init__.py
│ │ │ ├── items.py
│ │ │ ├── main.py
│ │ │ └── users.py
│ │ ├── tutorial002_py310/
│ │ │ ├── __init__.py
│ │ │ └── main.py
│ │ └── tutorial003_py310/
│ │ ├── __init__.py
│ │ ├── items.py
│ │ ├── lands.py
│ │ ├── main.py
│ │ ├── reigns.py
│ │ ├── towns.py
│ │ └── users.py
│ ├── terminating/
│ │ ├── __init__.py
│ │ ├── tutorial001_py310.py
│ │ ├── tutorial002_py310.py
│ │ └── tutorial003_py310.py
│ ├── testing/
│ │ ├── __init__.py
│ │ ├── app01_py310/
│ │ │ ├── __init__.py
│ │ │ ├── main.py
│ │ │ └── test_main.py
│ │ ├── app02_an_py310/
│ │ │ ├── __init__.py
│ │ │ ├── main.py
│ │ │ └── test_main.py
│ │ ├── app02_py310/
│ │ │ ├── __init__.py
│ │ │ ├── main.py
│ │ │ └── test_main.py
│ │ └── app03_py310/
│ │ ├── __init__.py
│ │ ├── main.py
│ │ └── test_main.py
│ └── typer_app/
│ ├── __init__.py
│ └── tutorial001_py310.py
├── mkdocs.env.yml
├── mkdocs.yml
├── pyproject.toml
├── scripts/
│ ├── deploy_docs_status.py
│ ├── docker/
│ │ ├── Dockerfile
│ │ └── compose.yaml
│ ├── docs.py
│ ├── format.sh
│ ├── get-pwsh-activate.sh
│ ├── lint.sh
│ ├── mkdocs_hooks.py
│ ├── test-cov-html.sh
│ ├── test-files.sh
│ └── test.sh
├── tests/
│ ├── __init__.py
│ ├── assets/
│ │ ├── __init__.py
│ │ ├── cli/
│ │ │ ├── __init__.py
│ │ │ ├── app_other_name.py
│ │ │ ├── empty_script.py
│ │ │ ├── extended_app_cli.py
│ │ │ ├── extended_empty_app_cli.py
│ │ │ ├── func_other_name.py
│ │ │ ├── multi_app.py
│ │ │ ├── multi_app_cli.py
│ │ │ ├── multi_app_norich.py
│ │ │ ├── multi_func.py
│ │ │ ├── multiapp-docs-title.md
│ │ │ ├── multiapp-docs.md
│ │ │ ├── not_python.txt
│ │ │ ├── rich_formatted_app.py
│ │ │ ├── richformattedapp-docs.md
│ │ │ └── sample.py
│ │ ├── completion_argument.py
│ │ ├── completion_no_types.py
│ │ ├── completion_no_types_order.py
│ │ ├── corner_cases.py
│ │ ├── print_modules.py
│ │ ├── prog_name.py
│ │ ├── type_error_no_rich.py
│ │ ├── type_error_no_rich_short_disable.py
│ │ └── type_error_normal_traceback.py
│ ├── test_ambiguous_params.py
│ ├── test_annotated.py
│ ├── test_callback_warning.py
│ ├── test_cli/
│ │ ├── __init__.py
│ │ ├── test_app_other_name.py
│ │ ├── test_completion_run.py
│ │ ├── test_doc.py
│ │ ├── test_empty_script.py
│ │ ├── test_extending_app.py
│ │ ├── test_extending_empty_app.py
│ │ ├── test_func_other_name.py
│ │ ├── test_help.py
│ │ ├── test_multi_app.py
│ │ ├── test_multi_app_cli.py
│ │ ├── test_multi_app_sub.py
│ │ ├── test_multi_func.py
│ │ ├── test_not_python.py
│ │ ├── test_sub.py
│ │ ├── test_sub_completion.py
│ │ ├── test_sub_help.py
│ │ └── test_version.py
│ ├── test_completion/
│ │ ├── __init__.py
│ │ ├── colon_example.py
│ │ ├── example_rich_tags.py
│ │ ├── path_example.py
│ │ ├── test_completion.py
│ │ ├── test_completion_complete.py
│ │ ├── test_completion_complete_no_help.py
│ │ ├── test_completion_complete_rich.py
│ │ ├── test_completion_install.py
│ │ ├── test_completion_option_colon.py
│ │ ├── test_completion_path.py
│ │ ├── test_completion_show.py
│ │ └── test_sanitization.py
│ ├── test_corner_cases.py
│ ├── test_deprecation.py
│ ├── test_exit_errors.py
│ ├── test_future_annotations.py
│ ├── test_launch.py
│ ├── test_others.py
│ ├── test_param_meta_empty.py
│ ├── test_prog_name.py
│ ├── test_rich_import.py
│ ├── test_rich_markup_mode.py
│ ├── test_rich_utils.py
│ ├── test_suggest_commands.py
│ ├── test_tracebacks.py
│ ├── test_tutorial/
│ │ ├── __init__.py
│ │ ├── test_app_dir/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial001.py
│ │ ├── test_arguments/
│ │ │ ├── __init__.py
│ │ │ ├── test_default/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ ├── test_envvar/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ └── test_tutorial003.py
│ │ │ ├── test_help/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ ├── test_tutorial005.py
│ │ │ │ ├── test_tutorial006.py
│ │ │ │ ├── test_tutorial007.py
│ │ │ │ └── test_tutorial008.py
│ │ │ └── test_optional/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial000.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ └── test_tutorial003.py
│ │ ├── test_commands/
│ │ │ ├── __init__.py
│ │ │ ├── test_arguments/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001.py
│ │ │ ├── test_callback/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_context/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_help/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ ├── test_tutorial005.py
│ │ │ │ ├── test_tutorial006.py
│ │ │ │ ├── test_tutorial007.py
│ │ │ │ └── test_tutorial008.py
│ │ │ ├── test_index/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ └── test_tutorial005.py
│ │ │ ├── test_name/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001.py
│ │ │ ├── test_one_or_multiple/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ └── test_options/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial001.py
│ │ ├── test_exceptions/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ └── test_tutorial004.py
│ │ ├── test_first_steps/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ ├── test_tutorial004.py
│ │ │ ├── test_tutorial005.py
│ │ │ └── test_tutorial006.py
│ │ ├── test_launch/
│ │ │ ├── test_tutorial001.py
│ │ │ └── test_tutorial002.py
│ │ ├── test_multiple_values/
│ │ │ ├── __init__.py
│ │ │ ├── test_arguments_with_multiple_values/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ ├── test_multiple_options/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ └── test_options_with_multiple_values/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial001.py
│ │ ├── test_one_file_per_command/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial.py
│ │ ├── test_options/
│ │ │ ├── __init__.py
│ │ │ ├── test_callback/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_help/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_name/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ └── test_tutorial005.py
│ │ │ ├── test_password/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ ├── test_prompt/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ └── test_tutorial003.py
│ │ │ ├── test_required/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001_tutorial002.py
│ │ │ └── test_version/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ └── test_tutorial003.py
│ │ ├── test_options_autocompletion/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ ├── test_tutorial004_tutorial005.py
│ │ │ ├── test_tutorial006.py
│ │ │ ├── test_tutorial007.py
│ │ │ ├── test_tutorial008.py
│ │ │ └── test_tutorial009.py
│ │ ├── test_parameter_types/
│ │ │ ├── __init__.py
│ │ │ ├── test_bool/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_custom_types/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001.py
│ │ │ ├── test_datetime/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ ├── test_enum/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_file/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ └── test_tutorial005.py
│ │ │ ├── test_index/
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_tutorial001.py
│ │ │ ├── test_number/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ └── test_tutorial003.py
│ │ │ ├── test_path/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ └── test_tutorial002.py
│ │ │ └── test_uuid/
│ │ │ ├── __init__.py
│ │ │ └── test_tutorial001.py
│ │ ├── test_printing/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ ├── test_tutorial004.py
│ │ │ ├── test_tutorial005.py
│ │ │ └── test_tutorial006.py
│ │ ├── test_progressbar/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ ├── test_tutorial004.py
│ │ │ ├── test_tutorial005.py
│ │ │ └── test_tutorial006.py
│ │ ├── test_prompt/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ ├── test_tutorial003.py
│ │ │ └── test_tutorial004.py
│ │ ├── test_subcommands/
│ │ │ ├── __init__.py
│ │ │ ├── test_callback_override/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ └── test_tutorial004.py
│ │ │ ├── test_name_help/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_tutorial001.py
│ │ │ │ ├── test_tutorial002.py
│ │ │ │ ├── test_tutorial003.py
│ │ │ │ ├── test_tutorial004.py
│ │ │ │ ├── test_tutorial005.py
│ │ │ │ ├── test_tutorial006.py
│ │ │ │ ├── test_tutorial007.py
│ │ │ │ └── test_tutorial008.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ └── test_tutorial003.py
│ │ ├── test_terminating/
│ │ │ ├── __init__.py
│ │ │ ├── test_tutorial001.py
│ │ │ ├── test_tutorial002.py
│ │ │ └── test_tutorial003.py
│ │ ├── test_testing/
│ │ │ ├── __init__.py
│ │ │ ├── test_app01.py
│ │ │ ├── test_app02.py
│ │ │ └── test_app03.py
│ │ └── test_typer_app/
│ │ ├── __init__.py
│ │ └── test_tutorial001.py
│ ├── test_type_conversion.py
│ ├── test_types.py
│ └── utils.py
├── typer/
│ ├── __init__.py
│ ├── __main__.py
│ ├── _completion_classes.py
│ ├── _completion_shared.py
│ ├── _types.py
│ ├── _typing.py
│ ├── cli.py
│ ├── colors.py
│ ├── completion.py
│ ├── core.py
│ ├── main.py
│ ├── models.py
│ ├── params.py
│ ├── py.typed
│ ├── rich_utils.py
│ ├── testing.py
│ └── utils.py
├── typer-cli/
│ └── README.md
└── typer-slim/
└── README.md
SYMBOL INDEX (1520 symbols across 477 files)
FILE: docs/js/custom.js
function setupTermynal (line 1) | function setupTermynal() {
function openLinksInNewTab (line 112) | function openLinksInNewTab() {
function main (line 139) | async function main() {
FILE: docs/js/termynal.js
class Termynal (line 14) | class Termynal {
method constructor (line 30) | constructor(container = '#termynal', options = {}) {
method loadLines (line 52) | loadLines() {
method init (line 74) | init() {
method start (line 96) | async start() {
method generateRestart (line 129) | generateRestart() {
method generateFinish (line 142) | generateFinish() {
method addRestart (line 157) | addRestart() {
method addFinish (line 162) | addFinish() {
method type (line 171) | async type(line) {
method progress (line 187) | async progress(line) {
method _wait (line 212) | _wait(time) {
method lineDataToElements (line 223) | lineDataToElements(lineData) {
method _attributes (line 238) | _attributes(line) {
FILE: docs_src/app_dir/tutorial001_py310.py
function main (line 11) | def main():
FILE: docs_src/arguments/default/tutorial001_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Argument()] = "Wade Wilson"):
FILE: docs_src/arguments/default/tutorial001_py310.py
function main (line 7) | def main(name: str = typer.Argument("Wade Wilson")):
FILE: docs_src/arguments/default/tutorial002_an_py310.py
function get_name (line 9) | def get_name():
function main (line 14) | def main(name: Annotated[str, typer.Argument(default_factory=get_name)]):
FILE: docs_src/arguments/default/tutorial002_py310.py
function get_name (line 8) | def get_name():
function main (line 13) | def main(name: str = typer.Argument(default_factory=get_name)):
FILE: docs_src/arguments/envvar/tutorial001_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Argument(envvar="AWESOME_NAME")] = "...
FILE: docs_src/arguments/envvar/tutorial001_py310.py
function main (line 7) | def main(name: str = typer.Argument("World", envvar="AWESOME_NAME")):
FILE: docs_src/arguments/envvar/tutorial002_an_py310.py
function main (line 9) | def main(
FILE: docs_src/arguments/envvar/tutorial002_py310.py
function main (line 7) | def main(name: str = typer.Argument("World", envvar=["AWESOME_NAME", "GO...
FILE: docs_src/arguments/envvar/tutorial003_an_py310.py
function main (line 9) | def main(
FILE: docs_src/arguments/envvar/tutorial003_py310.py
function main (line 7) | def main(name: str = typer.Argument("World", envvar="AWESOME_NAME", show...
FILE: docs_src/arguments/help/tutorial001_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Argument(help="The name of the user ...
FILE: docs_src/arguments/help/tutorial001_py310.py
function main (line 7) | def main(name: str = typer.Argument(..., help="The name of the user to g...
FILE: docs_src/arguments/help/tutorial002_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Argument(help="The name of the user ...
FILE: docs_src/arguments/help/tutorial002_py310.py
function main (line 7) | def main(name: str = typer.Argument(..., help="The name of the user to g...
FILE: docs_src/arguments/help/tutorial003_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Argument(help="Who to greet")] = "Wo...
FILE: docs_src/arguments/help/tutorial003_py310.py
function main (line 7) | def main(name: str = typer.Argument("World", help="Who to greet")):
FILE: docs_src/arguments/help/tutorial004_an_py310.py
function main (line 9) | def main(
FILE: docs_src/arguments/help/tutorial004_py310.py
function main (line 7) | def main(name: str = typer.Argument("World", help="Who to greet", show_d...
FILE: docs_src/arguments/help/tutorial005_an_py310.py
function main (line 9) | def main(
FILE: docs_src/arguments/help/tutorial005_py310.py
function main (line 7) | def main(
FILE: docs_src/arguments/help/tutorial006_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Argument(metavar="✨username✨")] = "W...
FILE: docs_src/arguments/help/tutorial006_py310.py
function main (line 7) | def main(name: str = typer.Argument("World", metavar="✨username✨")):
FILE: docs_src/arguments/help/tutorial007_an_py310.py
function main (line 9) | def main(
FILE: docs_src/arguments/help/tutorial007_py310.py
function main (line 7) | def main(
FILE: docs_src/arguments/help/tutorial008_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Argument(hidden=True)] = "World"):
FILE: docs_src/arguments/help/tutorial008_py310.py
function main (line 7) | def main(name: str = typer.Argument("World", hidden=True)):
FILE: docs_src/arguments/optional/tutorial000_an_py310.py
function main (line 6) | def main(name: Annotated[str, typer.Argument()]):
FILE: docs_src/arguments/optional/tutorial000_py310.py
function main (line 4) | def main(name: str = typer.Argument()):
FILE: docs_src/arguments/optional/tutorial001_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Argument()]):
FILE: docs_src/arguments/optional/tutorial001_py310.py
function main (line 7) | def main(name: str = typer.Argument()):
FILE: docs_src/arguments/optional/tutorial002_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Argument()] = "World"):
FILE: docs_src/arguments/optional/tutorial002_py310.py
function main (line 7) | def main(name: str = typer.Argument(default="World")):
FILE: docs_src/arguments/optional/tutorial003_py310.py
function main (line 7) | def main(name: str = typer.Argument(default=...)):
FILE: docs_src/commands/arguments/tutorial001_py310.py
function create (line 7) | def create(username: str):
function delete (line 12) | def delete(username: str):
FILE: docs_src/commands/callback/tutorial001_py310.py
function create (line 8) | def create(username: str):
function delete (line 17) | def delete(username: str):
function main (line 26) | def main(verbose: bool = False):
FILE: docs_src/commands/callback/tutorial002_py310.py
function callback (line 4) | def callback():
function create (line 12) | def create(name: str):
FILE: docs_src/commands/callback/tutorial003_py310.py
function callback (line 4) | def callback():
function new_callback (line 12) | def new_callback():
function create (line 17) | def create(name: str):
FILE: docs_src/commands/callback/tutorial004_py310.py
function callback (line 7) | def callback():
function create (line 18) | def create(name: str):
FILE: docs_src/commands/context/tutorial001_py310.py
function create (line 7) | def create(username: str):
function delete (line 12) | def delete(username: str):
function main (line 17) | def main(ctx: typer.Context):
FILE: docs_src/commands/context/tutorial002_py310.py
function create (line 7) | def create(username: str):
function delete (line 12) | def delete(username: str):
function main (line 17) | def main():
FILE: docs_src/commands/context/tutorial003_py310.py
function create (line 7) | def create(username: str):
function delete (line 12) | def delete(username: str):
function main (line 17) | def main(ctx: typer.Context):
FILE: docs_src/commands/context/tutorial004_py310.py
function main (line 9) | def main(ctx: typer.Context):
FILE: docs_src/commands/help/tutorial001_an_py310.py
function create (line 9) | def create(username: str):
function delete (line 17) | def delete(
function delete_all (line 39) | def delete_all(
function init (line 60) | def init():
FILE: docs_src/commands/help/tutorial001_py310.py
function create (line 7) | def create(username: str):
function delete (line 15) | def delete(
function delete_all (line 35) | def delete_all(
function init (line 54) | def init():
FILE: docs_src/commands/help/tutorial002_py310.py
function create (line 7) | def create(username: str):
function delete (line 15) | def delete(username: str):
FILE: docs_src/commands/help/tutorial003_py310.py
function create (line 7) | def create(username: str):
function delete (line 15) | def delete(username: str):
FILE: docs_src/commands/help/tutorial004_an_py310.py
function create (line 9) | def create(
function delete (line 23) | def delete(
FILE: docs_src/commands/help/tutorial004_py310.py
function create (line 7) | def create(
function delete (line 21) | def delete(
FILE: docs_src/commands/help/tutorial005_an_py310.py
function create (line 9) | def create(
function delete (line 27) | def delete(
FILE: docs_src/commands/help/tutorial005_py310.py
function create (line 7) | def create(username: str = typer.Argument(..., help="The username to be ...
function delete (line 23) | def delete(
FILE: docs_src/commands/help/tutorial006_py310.py
function create (line 7) | def create(username: str):
function delete (line 15) | def delete(username: str):
function config (line 23) | def config(configuration: str):
function sync (line 31) | def sync():
function help (line 39) | def help():
function report (line 47) | def report():
FILE: docs_src/commands/help/tutorial007_an_py310.py
function create (line 9) | def create(
function config (line 37) | def config(configuration: str):
FILE: docs_src/commands/help/tutorial007_py310.py
function create (line 7) | def create(
function config (line 29) | def config(configuration: str):
FILE: docs_src/commands/help/tutorial008_py310.py
function create (line 7) | def create(username: str):
FILE: docs_src/commands/index/tutorial002_py310.py
function create (line 7) | def create():
function delete (line 12) | def delete():
FILE: docs_src/commands/index/tutorial003_py310.py
function create (line 7) | def create():
function delete (line 12) | def delete():
FILE: docs_src/commands/index/tutorial004_py310.py
function delete (line 7) | def delete():
function create (line 12) | def create():
FILE: docs_src/commands/index/tutorial005_py310.py
function create (line 7) | def create():
function delete (line 12) | def delete():
FILE: docs_src/commands/name/tutorial001_py310.py
function cli_create_user (line 7) | def cli_create_user(username: str):
function cli_delete_user (line 12) | def cli_delete_user(username: str):
FILE: docs_src/commands/one_or_multiple/tutorial001_py310.py
function create (line 7) | def create():
function callback (line 12) | def callback():
FILE: docs_src/commands/one_or_multiple/tutorial002_py310.py
function create (line 7) | def create():
function callback (line 12) | def callback():
FILE: docs_src/commands/options/tutorial001_an_py310.py
function create (line 9) | def create(username: str):
function delete (line 14) | def delete(
function delete_all (line 27) | def delete_all(
function init (line 39) | def init():
FILE: docs_src/commands/options/tutorial001_py310.py
function create (line 7) | def create(username: str):
function delete (line 12) | def delete(
function delete_all (line 23) | def delete_all(
function init (line 35) | def init():
FILE: docs_src/exceptions/tutorial001_py310.py
function main (line 7) | def main(name: str = "morty"):
FILE: docs_src/exceptions/tutorial002_py310.py
function main (line 7) | def main(name: str = "morty"):
FILE: docs_src/exceptions/tutorial003_py310.py
function main (line 7) | def main(name: str = "morty"):
FILE: docs_src/exceptions/tutorial004_py310.py
function main (line 7) | def main(name: str = "morty"):
FILE: docs_src/first_steps/tutorial001_py310.py
function main (line 4) | def main():
FILE: docs_src/first_steps/tutorial002_py310.py
function main (line 4) | def main(name: str):
FILE: docs_src/first_steps/tutorial003_py310.py
function main (line 4) | def main(name: str, lastname: str):
FILE: docs_src/first_steps/tutorial004_py310.py
function main (line 4) | def main(name: str, lastname: str, formal: bool = False):
FILE: docs_src/first_steps/tutorial005_py310.py
function main (line 4) | def main(name: str, lastname: str = "", formal: bool = False):
FILE: docs_src/first_steps/tutorial006_py310.py
function main (line 4) | def main(name: str, lastname: str = "", formal: bool = False):
FILE: docs_src/launch/tutorial001_py310.py
function main (line 7) | def main():
FILE: docs_src/launch/tutorial002_py310.py
function main (line 11) | def main():
FILE: docs_src/multiple_values/arguments_with_multiple_values/tutorial001_py310.py
function main (line 9) | def main(files: list[Path], celebration: str):
FILE: docs_src/multiple_values/arguments_with_multiple_values/tutorial002_an_py310.py
function main (line 9) | def main(
FILE: docs_src/multiple_values/arguments_with_multiple_values/tutorial002_py310.py
function main (line 7) | def main(
FILE: docs_src/multiple_values/multiple_options/tutorial001_an_py310.py
function main (line 9) | def main(user: Annotated[list[str] | None, typer.Option()] = None):
FILE: docs_src/multiple_values/multiple_options/tutorial001_py310.py
function main (line 7) | def main(user: list[str] | None = typer.Option(None)):
FILE: docs_src/multiple_values/multiple_options/tutorial002_an_py310.py
function main (line 9) | def main(number: Annotated[list[float], typer.Option()] = []):
FILE: docs_src/multiple_values/multiple_options/tutorial002_py310.py
function main (line 7) | def main(number: list[float] = typer.Option([])):
FILE: docs_src/multiple_values/options_with_multiple_values/tutorial001_an_py310.py
function main (line 9) | def main(user: Annotated[tuple[str, int, bool], typer.Option()] = (None,...
FILE: docs_src/multiple_values/options_with_multiple_values/tutorial001_py310.py
function main (line 7) | def main(user: tuple[str, int, bool] = typer.Option((None, None, None))):
FILE: docs_src/one_file_per_command/app_py310/users/add.py
function add (line 7) | def add(name: str):
FILE: docs_src/one_file_per_command/app_py310/users/delete.py
function delete (line 7) | def delete(name: str):
FILE: docs_src/one_file_per_command/app_py310/version.py
function version (line 7) | def version():
FILE: docs_src/options/callback/tutorial001_an_py310.py
function name_callback (line 8) | def name_callback(value: str):
function main (line 15) | def main(name: Annotated[str | None, typer.Option(callback=name_callback...
FILE: docs_src/options/callback/tutorial001_py310.py
function name_callback (line 6) | def name_callback(value: str):
function main (line 13) | def main(name: str | None = typer.Option(default=None, callback=name_cal...
FILE: docs_src/options/callback/tutorial002_an_py310.py
function name_callback (line 8) | def name_callback(value: str):
function main (line 16) | def main(name: Annotated[str | None, typer.Option(callback=name_callback...
FILE: docs_src/options/callback/tutorial002_py310.py
function name_callback (line 6) | def name_callback(value: str):
function main (line 14) | def main(name: str | None = typer.Option(default=None, callback=name_cal...
FILE: docs_src/options/callback/tutorial003_an_py310.py
function name_callback (line 8) | def name_callback(ctx: typer.Context, value: str):
function main (line 18) | def main(name: Annotated[str | None, typer.Option(callback=name_callback...
FILE: docs_src/options/callback/tutorial003_py310.py
function name_callback (line 6) | def name_callback(ctx: typer.Context, value: str):
function main (line 16) | def main(name: str | None = typer.Option(default=None, callback=name_cal...
FILE: docs_src/options/callback/tutorial004_an_py310.py
function name_callback (line 8) | def name_callback(ctx: typer.Context, param: typer.CallbackParam, value:...
function main (line 18) | def main(name: Annotated[str | None, typer.Option(callback=name_callback...
FILE: docs_src/options/callback/tutorial004_py310.py
function name_callback (line 6) | def name_callback(ctx: typer.Context, param: typer.CallbackParam, value:...
function main (line 16) | def main(name: str | None = typer.Option(default=None, callback=name_cal...
FILE: docs_src/options/help/tutorial001_an_py310.py
function main (line 9) | def main(
FILE: docs_src/options/help/tutorial001_py310.py
function main (line 7) | def main(
FILE: docs_src/options/help/tutorial002_an_py310.py
function main (line 9) | def main(
FILE: docs_src/options/help/tutorial002_py310.py
function main (line 7) | def main(
FILE: docs_src/options/help/tutorial003_an_py310.py
function main (line 9) | def main(fullname: Annotated[str, typer.Option(show_default=False)] = "W...
FILE: docs_src/options/help/tutorial003_py310.py
function main (line 7) | def main(fullname: str = typer.Option("Wade Wilson", show_default=False)):
FILE: docs_src/options/help/tutorial004_an_py310.py
function main (line 9) | def main(
FILE: docs_src/options/help/tutorial004_py310.py
function main (line 7) | def main(
FILE: docs_src/options/name/tutorial001_an_py310.py
function main (line 9) | def main(user_name: Annotated[str, typer.Option("--name")]):
FILE: docs_src/options/name/tutorial001_py310.py
function main (line 7) | def main(user_name: str = typer.Option(..., "--name")):
FILE: docs_src/options/name/tutorial002_an_py310.py
function main (line 9) | def main(user_name: Annotated[str, typer.Option("--name", "-n")]):
FILE: docs_src/options/name/tutorial002_py310.py
function main (line 7) | def main(user_name: str = typer.Option(..., "--name", "-n")):
FILE: docs_src/options/name/tutorial003_an_py310.py
function main (line 9) | def main(user_name: Annotated[str, typer.Option("-n")]):
FILE: docs_src/options/name/tutorial003_py310.py
function main (line 7) | def main(user_name: str = typer.Option(..., "-n")):
FILE: docs_src/options/name/tutorial004_an_py310.py
function main (line 9) | def main(user_name: Annotated[str, typer.Option("--user-name", "-n")]):
FILE: docs_src/options/name/tutorial004_py310.py
function main (line 7) | def main(user_name: str = typer.Option(..., "--user-name", "-n")):
FILE: docs_src/options/name/tutorial005_an_py310.py
function main (line 9) | def main(
FILE: docs_src/options/name/tutorial005_py310.py
function main (line 7) | def main(
FILE: docs_src/options/password/tutorial001_an_py310.py
function main (line 9) | def main(
FILE: docs_src/options/password/tutorial001_py310.py
function main (line 7) | def main(
FILE: docs_src/options/password/tutorial002_an_py310.py
function main (line 9) | def main(
FILE: docs_src/options/password/tutorial002_py310.py
function main (line 7) | def main(
FILE: docs_src/options/prompt/tutorial001_an_py310.py
function main (line 9) | def main(name: str, lastname: Annotated[str, typer.Option(prompt=True)]):
FILE: docs_src/options/prompt/tutorial001_py310.py
function main (line 7) | def main(name: str, lastname: str = typer.Option(..., prompt=True)):
FILE: docs_src/options/prompt/tutorial002_an_py310.py
function main (line 9) | def main(
FILE: docs_src/options/prompt/tutorial002_py310.py
function main (line 7) | def main(
FILE: docs_src/options/prompt/tutorial003_an_py310.py
function main (line 9) | def main(
FILE: docs_src/options/prompt/tutorial003_py310.py
function main (line 7) | def main(project_name: str = typer.Option(..., prompt=True, confirmation...
FILE: docs_src/options/required/tutorial001_an_py310.py
function main (line 9) | def main(name: str, lastname: Annotated[str, typer.Option()]):
FILE: docs_src/options/required/tutorial001_py310.py
function main (line 7) | def main(name: str, lastname: str = typer.Option()):
FILE: docs_src/options/required/tutorial002_py310.py
function main (line 7) | def main(name: str, lastname: str = typer.Option(default=...)):
FILE: docs_src/options/version/tutorial001_an_py310.py
function version_callback (line 10) | def version_callback(value: bool):
function main (line 17) | def main(
FILE: docs_src/options/version/tutorial001_py310.py
function version_callback (line 8) | def version_callback(value: bool):
function main (line 15) | def main(
FILE: docs_src/options/version/tutorial002_an_py310.py
function version_callback (line 10) | def version_callback(value: bool):
function name_callback (line 16) | def name_callback(name: str):
function main (line 23) | def main(
FILE: docs_src/options/version/tutorial002_py310.py
function version_callback (line 8) | def version_callback(value: bool):
function name_callback (line 14) | def name_callback(name: str):
function main (line 21) | def main(
FILE: docs_src/options/version/tutorial003_an_py310.py
function version_callback (line 10) | def version_callback(value: bool):
function name_callback (line 16) | def name_callback(name: str):
function main (line 23) | def main(
FILE: docs_src/options/version/tutorial003_py310.py
function version_callback (line 8) | def version_callback(value: bool):
function name_callback (line 14) | def name_callback(name: str):
function main (line 21) | def main(
FILE: docs_src/options_autocompletion/tutorial001_an_py310.py
function main (line 9) | def main(name: Annotated[str, typer.Option(help="The name to say hi to."...
FILE: docs_src/options_autocompletion/tutorial001_py310.py
function main (line 7) | def main(name: str = typer.Option("World", help="The name to say hi to.")):
FILE: docs_src/options_autocompletion/tutorial002_an_py310.py
function complete_name (line 6) | def complete_name():
function main (line 14) | def main(
FILE: docs_src/options_autocompletion/tutorial002_py310.py
function complete_name (line 4) | def complete_name():
function main (line 12) | def main(
FILE: docs_src/options_autocompletion/tutorial003_an_py310.py
function complete_name (line 8) | def complete_name(incomplete: str):
function main (line 20) | def main(
FILE: docs_src/options_autocompletion/tutorial003_py310.py
function complete_name (line 6) | def complete_name(incomplete: str):
function main (line 18) | def main(
FILE: docs_src/options_autocompletion/tutorial004_an_py310.py
function complete_name (line 12) | def complete_name(incomplete: str):
function main (line 25) | def main(
FILE: docs_src/options_autocompletion/tutorial004_py310.py
function complete_name (line 10) | def complete_name(incomplete: str):
function main (line 23) | def main(
FILE: docs_src/options_autocompletion/tutorial005_an_py310.py
function complete_name (line 12) | def complete_name(incomplete: str):
function main (line 22) | def main(
FILE: docs_src/options_autocompletion/tutorial005_py310.py
function complete_name (line 10) | def complete_name(incomplete: str):
function main (line 20) | def main(
FILE: docs_src/options_autocompletion/tutorial006_an_py310.py
function main (line 9) | def main(
FILE: docs_src/options_autocompletion/tutorial006_py310.py
function main (line 7) | def main(name: list[str] = typer.Option(["World"], help="The name to say...
FILE: docs_src/options_autocompletion/tutorial007_an_py310.py
function complete_name (line 12) | def complete_name(ctx: typer.Context, incomplete: str):
function main (line 23) | def main(
FILE: docs_src/options_autocompletion/tutorial007_py310.py
function complete_name (line 10) | def complete_name(ctx: typer.Context, incomplete: str):
function main (line 21) | def main(
FILE: docs_src/options_autocompletion/tutorial008_an_py310.py
function complete_name (line 15) | def complete_name(args: list[str], incomplete: str):
function main (line 26) | def main(
FILE: docs_src/options_autocompletion/tutorial008_py310.py
function complete_name (line 13) | def complete_name(args: list[str], incomplete: str):
function main (line 24) | def main(
FILE: docs_src/options_autocompletion/tutorial009_an_py310.py
function complete_name (line 15) | def complete_name(ctx: typer.Context, args: list[str], incomplete: str):
function main (line 27) | def main(
FILE: docs_src/options_autocompletion/tutorial009_py310.py
function complete_name (line 13) | def complete_name(ctx: typer.Context, args: list[str], incomplete: str):
function main (line 25) | def main(
FILE: docs_src/parameter_types/bool/tutorial001_an_py310.py
function main (line 9) | def main(force: Annotated[bool, typer.Option("--force")] = False):
FILE: docs_src/parameter_types/bool/tutorial001_py310.py
function main (line 7) | def main(force: bool = typer.Option(False, "--force")):
FILE: docs_src/parameter_types/bool/tutorial002_an_py310.py
function main (line 9) | def main(accept: Annotated[bool | None, typer.Option("--accept/--reject"...
FILE: docs_src/parameter_types/bool/tutorial002_py310.py
function main (line 7) | def main(accept: bool | None = typer.Option(None, "--accept/--reject")):
FILE: docs_src/parameter_types/bool/tutorial003_an_py310.py
function main (line 9) | def main(force: Annotated[bool, typer.Option("--force/--no-force", "-f/-...
FILE: docs_src/parameter_types/bool/tutorial003_py310.py
function main (line 7) | def main(force: bool = typer.Option(False, "--force/--no-force", "-f/-F")):
FILE: docs_src/parameter_types/bool/tutorial004_an_py310.py
function main (line 9) | def main(in_prod: Annotated[bool, typer.Option(" /--demo", " /-d")] = Tr...
FILE: docs_src/parameter_types/bool/tutorial004_py310.py
function main (line 7) | def main(in_prod: bool = typer.Option(True, " /--demo", " /-d")):
FILE: docs_src/parameter_types/custom_types/tutorial001_an_py310.py
class CustomClass (line 6) | class CustomClass:
method __init__ (line 7) | def __init__(self, value: str):
method __str__ (line 10) | def __str__(self):
function parse_custom_class (line 14) | def parse_custom_class(value: str):
function main (line 22) | def main(
FILE: docs_src/parameter_types/custom_types/tutorial001_py310.py
class CustomClass (line 4) | class CustomClass:
method __init__ (line 5) | def __init__(self, value: str):
method __str__ (line 8) | def __str__(self):
function parse_custom_class (line 12) | def parse_custom_class(value: str):
function main (line 20) | def main(
FILE: docs_src/parameter_types/datetime/tutorial001_py310.py
function main (line 9) | def main(birth: datetime):
FILE: docs_src/parameter_types/datetime/tutorial002_an_py310.py
function main (line 10) | def main(
FILE: docs_src/parameter_types/datetime/tutorial002_py310.py
function main (line 9) | def main(
FILE: docs_src/parameter_types/enum/tutorial001_py310.py
class NeuralNetwork (line 6) | class NeuralNetwork(str, Enum):
function main (line 16) | def main(network: NeuralNetwork = NeuralNetwork.simple):
FILE: docs_src/parameter_types/enum/tutorial002_an_py310.py
class NeuralNetwork (line 7) | class NeuralNetwork(str, Enum):
function main (line 17) | def main(
FILE: docs_src/parameter_types/enum/tutorial002_py310.py
class NeuralNetwork (line 6) | class NeuralNetwork(str, Enum):
function main (line 16) | def main(
FILE: docs_src/parameter_types/enum/tutorial003_an_py310.py
class Food (line 7) | class Food(str, Enum):
function main (line 17) | def main(groceries: Annotated[list[Food], typer.Option()] = [Food.food_1...
FILE: docs_src/parameter_types/enum/tutorial003_py310.py
class Food (line 6) | class Food(str, Enum):
function main (line 16) | def main(groceries: list[Food] = typer.Option([Food.food_1, Food.food_3])):
FILE: docs_src/parameter_types/enum/tutorial004_an_py310.py
function main (line 9) | def main(
FILE: docs_src/parameter_types/enum/tutorial004_py310.py
function main (line 9) | def main(network: Literal["simple", "conv", "lstm"] = typer.Option("simp...
FILE: docs_src/parameter_types/file/tutorial001_an_py310.py
function main (line 9) | def main(config: Annotated[typer.FileText, typer.Option()]):
FILE: docs_src/parameter_types/file/tutorial001_py310.py
function main (line 7) | def main(config: typer.FileText = typer.Option(...)):
FILE: docs_src/parameter_types/file/tutorial002_an_py310.py
function main (line 9) | def main(config: Annotated[typer.FileTextWrite, typer.Option()]):
FILE: docs_src/parameter_types/file/tutorial002_py310.py
function main (line 7) | def main(config: typer.FileTextWrite = typer.Option(...)):
FILE: docs_src/parameter_types/file/tutorial003_an_py310.py
function main (line 9) | def main(file: Annotated[typer.FileBinaryRead, typer.Option()]):
FILE: docs_src/parameter_types/file/tutorial003_py310.py
function main (line 7) | def main(file: typer.FileBinaryRead = typer.Option(...)):
FILE: docs_src/parameter_types/file/tutorial004_an_py310.py
function main (line 9) | def main(file: Annotated[typer.FileBinaryWrite, typer.Option()]):
FILE: docs_src/parameter_types/file/tutorial004_py310.py
function main (line 7) | def main(file: typer.FileBinaryWrite = typer.Option(...)):
FILE: docs_src/parameter_types/file/tutorial005_an_py310.py
function main (line 9) | def main(config: Annotated[typer.FileText, typer.Option(mode="a")]):
FILE: docs_src/parameter_types/file/tutorial005_py310.py
function main (line 7) | def main(config: typer.FileText = typer.Option(..., mode="a")):
FILE: docs_src/parameter_types/index/tutorial001_py310.py
function main (line 7) | def main(name: str, age: int = 20, height_meters: float = 1.89, female: ...
FILE: docs_src/parameter_types/number/tutorial001_an_py310.py
function main (line 9) | def main(
FILE: docs_src/parameter_types/number/tutorial001_py310.py
function main (line 7) | def main(
FILE: docs_src/parameter_types/number/tutorial002_an_py310.py
function main (line 9) | def main(
FILE: docs_src/parameter_types/number/tutorial002_py310.py
function main (line 7) | def main(
FILE: docs_src/parameter_types/number/tutorial003_an_py310.py
function main (line 9) | def main(verbose: Annotated[int, typer.Option("--verbose", "-v", count=T...
FILE: docs_src/parameter_types/number/tutorial003_py310.py
function main (line 7) | def main(verbose: int = typer.Option(0, "--verbose", "-v", count=True)):
FILE: docs_src/parameter_types/path/tutorial001_an_py310.py
function main (line 10) | def main(config: Annotated[Path | None, typer.Option()] = None):
FILE: docs_src/parameter_types/path/tutorial001_py310.py
function main (line 9) | def main(config: Path | None = typer.Option(None)):
FILE: docs_src/parameter_types/path/tutorial002_an_py310.py
function main (line 10) | def main(
FILE: docs_src/parameter_types/path/tutorial002_py310.py
function main (line 9) | def main(
FILE: docs_src/parameter_types/uuid/tutorial001_py310.py
function main (line 9) | def main(user_id: UUID):
FILE: docs_src/printing/tutorial001_py310.py
function main (line 16) | def main():
FILE: docs_src/printing/tutorial002_py310.py
function main (line 8) | def main():
FILE: docs_src/printing/tutorial003_py310.py
function main (line 11) | def main():
FILE: docs_src/printing/tutorial004_py310.py
function main (line 10) | def main():
FILE: docs_src/printing/tutorial005_py310.py
function main (line 7) | def main(good: bool = True):
FILE: docs_src/printing/tutorial006_py310.py
function main (line 7) | def main(name: str):
FILE: docs_src/progressbar/tutorial001_py310.py
function main (line 10) | def main():
FILE: docs_src/progressbar/tutorial002_py310.py
function main (line 10) | def main():
FILE: docs_src/progressbar/tutorial003_py310.py
function main (line 9) | def main():
FILE: docs_src/progressbar/tutorial004_py310.py
function iterate_user_ids (line 6) | def iterate_user_ids():
function main (line 16) | def main():
FILE: docs_src/progressbar/tutorial005_py310.py
function main (line 9) | def main():
FILE: docs_src/progressbar/tutorial006_py310.py
function main (line 9) | def main():
FILE: docs_src/prompt/tutorial001_py310.py
function main (line 7) | def main():
FILE: docs_src/prompt/tutorial002_py310.py
function main (line 7) | def main():
FILE: docs_src/prompt/tutorial003_py310.py
function main (line 7) | def main():
FILE: docs_src/prompt/tutorial004_py310.py
function main (line 8) | def main():
FILE: docs_src/subcommands/callback_override/tutorial001_py310.py
function users_callback (line 10) | def users_callback():
function create (line 15) | def create(name: str):
FILE: docs_src/subcommands/callback_override/tutorial002_py310.py
function users_callback (line 6) | def users_callback():
function create (line 15) | def create(name: str):
FILE: docs_src/subcommands/callback_override/tutorial003_py310.py
function default_callback (line 6) | def default_callback():
function user_callback (line 15) | def user_callback():
function create (line 20) | def create(name: str):
FILE: docs_src/subcommands/callback_override/tutorial004_py310.py
function default_callback (line 6) | def default_callback():
function callback_for_add_typer (line 13) | def callback_for_add_typer():
function user_callback (line 21) | def user_callback():
function create (line 26) | def create(name: str):
FILE: docs_src/subcommands/name_help/tutorial001_py310.py
function create (line 10) | def create(name: str):
FILE: docs_src/subcommands/name_help/tutorial002_py310.py
function users (line 10) | def users():
function create (line 17) | def create(name: str):
FILE: docs_src/subcommands/name_help/tutorial003_py310.py
function users (line 6) | def users():
function create (line 17) | def create(name: str):
FILE: docs_src/subcommands/name_help/tutorial004_py310.py
function old_callback (line 6) | def old_callback():
function users (line 17) | def users():
function create (line 24) | def create(name: str):
FILE: docs_src/subcommands/name_help/tutorial005_py310.py
function old_callback (line 6) | def old_callback():
function new_users (line 15) | def new_users():
function users (line 25) | def users():
function create (line 32) | def create(name: str):
FILE: docs_src/subcommands/name_help/tutorial006_py310.py
function old_callback (line 6) | def old_callback():
function new_users (line 15) | def new_users():
function users (line 25) | def users():
function create (line 32) | def create(name: str):
FILE: docs_src/subcommands/name_help/tutorial007_py310.py
function old_callback (line 6) | def old_callback():
function new_users (line 15) | def new_users():
function users (line 25) | def users():
function create (line 32) | def create(name: str):
FILE: docs_src/subcommands/name_help/tutorial008_py310.py
function old_callback (line 6) | def old_callback():
function new_users (line 15) | def new_users():
function users (line 30) | def users():
function create (line 37) | def create(name: str):
FILE: docs_src/subcommands/tutorial001_py310/items.py
function create (line 7) | def create(item: str):
function delete (line 12) | def delete(item: str):
function sell (line 17) | def sell(item: str):
FILE: docs_src/subcommands/tutorial001_py310/users.py
function create (line 7) | def create(user_name: str):
function delete (line 12) | def delete(user_name: str):
FILE: docs_src/subcommands/tutorial002_py310/main.py
function items_create (line 11) | def items_create(item: str):
function items_delete (line 16) | def items_delete(item: str):
function items_sell (line 21) | def items_sell(item: str):
function users_create (line 26) | def users_create(user_name: str):
function users_delete (line 31) | def users_delete(user_name: str):
FILE: docs_src/subcommands/tutorial003_py310/items.py
function create (line 7) | def create(item: str):
function delete (line 12) | def delete(item: str):
function sell (line 17) | def sell(item: str):
FILE: docs_src/subcommands/tutorial003_py310/reigns.py
function conquer (line 7) | def conquer(name: str):
function destroy (line 12) | def destroy(name: str):
FILE: docs_src/subcommands/tutorial003_py310/towns.py
function found (line 7) | def found(name: str):
function burn (line 12) | def burn(name: str):
FILE: docs_src/subcommands/tutorial003_py310/users.py
function create (line 7) | def create(user_name: str):
function delete (line 12) | def delete(user_name: str):
FILE: docs_src/terminating/tutorial001_py310.py
function maybe_create_user (line 6) | def maybe_create_user(username: str):
function send_new_user_notification (line 14) | def send_new_user_notification(username: str):
function main (line 23) | def main(username: str):
FILE: docs_src/terminating/tutorial002_py310.py
function main (line 7) | def main(username: str):
FILE: docs_src/terminating/tutorial003_py310.py
function main (line 7) | def main(username: str):
FILE: docs_src/testing/app01_py310/main.py
function main (line 7) | def main(name: str, city: str | None = None):
FILE: docs_src/testing/app01_py310/test_main.py
function test_app (line 8) | def test_app():
FILE: docs_src/testing/app02_an_py310/main.py
function main (line 9) | def main(name: str, email: Annotated[str, typer.Option(prompt=True)]):
FILE: docs_src/testing/app02_an_py310/test_main.py
function test_app (line 8) | def test_app():
FILE: docs_src/testing/app02_py310/main.py
function main (line 7) | def main(name: str, email: str = typer.Option(..., prompt=True)):
FILE: docs_src/testing/app02_py310/test_main.py
function test_app (line 8) | def test_app():
FILE: docs_src/testing/app03_py310/main.py
function main (line 4) | def main(name: str = "World"):
FILE: docs_src/testing/app03_py310/test_main.py
function test_app (line 12) | def test_app():
FILE: docs_src/typer_app/tutorial001_py310.py
function main (line 7) | def main(name: str):
FILE: scripts/deploy_docs_status.py
class Settings (line 12) | class Settings(BaseSettings):
class LinkData (line 21) | class LinkData(BaseModel):
function main (line 26) | def main() -> None:
FILE: scripts/docs.py
function callback (line 22) | def callback() -> None:
function generate_readme_content (line 27) | def generate_readme_content() -> str:
function generate_readme (line 46) | def generate_readme() -> None:
function verify_readme (line 57) | def verify_readme() -> None:
function live (line 74) | def live(dirty: bool = False) -> None:
function build (line 92) | def build() -> None:
function serve (line 102) | def serve() -> None:
function generate_docs_src_versions_for_file (line 124) | def generate_docs_src_versions_for_file(file_path: Path) -> None:
function generate_docs_src_versions (line 185) | def generate_docs_src_versions() -> None:
function copy_py39_to_py310 (line 195) | def copy_py39_to_py310() -> None:
function update_docs_includes_py39_to_py310 (line 227) | def update_docs_includes_py39_to_py310() -> None:
function remove_unused_docs_src (line 251) | def remove_unused_docs_src() -> None:
FILE: scripts/mkdocs_hooks.py
function generate_renamed_section_items (line 9) | def generate_renamed_section_items(
function on_nav (line 34) | def on_nav(
FILE: tests/assets/cli/app_other_name.py
function callback (line 7) | def callback(name: str = "World"):
FILE: tests/assets/cli/extended_app_cli.py
function sub_sub_command (line 7) | def sub_sub_command():
function hello (line 16) | def hello():
function bye (line 21) | def bye():
function top (line 30) | def top():
FILE: tests/assets/cli/extended_empty_app_cli.py
function hello (line 9) | def hello():
function bye (line 14) | def bye():
FILE: tests/assets/cli/func_other_name.py
function some_function (line 1) | def some_function(name: str = "World"):
FILE: tests/assets/cli/multi_app.py
function hello (line 9) | def hello(name: str = "World", age: int = typer.Option(0, help="The age ...
function hi (line 17) | def hi(user: str = typer.Argument("World", help="The name of the user to...
function bye (line 24) | def bye():
function top (line 36) | def top():
FILE: tests/assets/cli/multi_app_cli.py
function hello (line 7) | def hello():
function bye (line 12) | def bye():
function top (line 21) | def top():
FILE: tests/assets/cli/multi_app_norich.py
function hello (line 9) | def hello(name: str = "World", age: int = typer.Option(0, help="The age ...
function hi (line 16) | def hi(user: str = typer.Argument("World", help="The name of the user to...
function bye (line 23) | def bye():
function top (line 34) | def top():
FILE: tests/assets/cli/multi_func.py
function say_stuff (line 4) | def say_stuff():
function main (line 8) | def main(name: str = "World"):
FILE: tests/assets/cli/rich_formatted_app.py
function hello (line 9) | def hello(
FILE: tests/assets/cli/sample.py
function hello (line 7) | def hello(name: str = "World", formal: bool = False):
function bye (line 18) | def bye(friend: bool = False):
FILE: tests/assets/completion_argument.py
function shell_complete (line 7) | def shell_complete(ctx: click.Context, param: click.Parameter, incomplet...
function main (line 15) | def main(name: str = typer.Argument(shell_complete=shell_complete)):
FILE: tests/assets/completion_no_types.py
function complete (line 6) | def complete(ctx, args, incomplete):
function main (line 18) | def main(name: str = typer.Option("World", autocompletion=complete)):
FILE: tests/assets/completion_no_types_order.py
function complete (line 6) | def complete(args, incomplete, ctx):
function main (line 18) | def main(name: str = typer.Option("World", autocompletion=complete)):
FILE: tests/assets/corner_cases.py
function main (line 7) | def main(
FILE: tests/assets/print_modules.py
function main (line 9) | def main():
FILE: tests/assets/prog_name.py
function main (line 7) | def main(i: int): # pragma: no cover
FILE: tests/assets/type_error_no_rich.py
function main (line 10) | def main(name: str = "morty"):
FILE: tests/assets/type_error_no_rich_short_disable.py
function main (line 11) | def main(name: str = "morty"):
FILE: tests/assets/type_error_normal_traceback.py
function main (line 7) | def main(name: str = "morty"):
function broken (line 15) | def broken(name: str = "morty"):
FILE: tests/test_ambiguous_params.py
function test_split_annotations_from_typer_annotations_simple (line 17) | def test_split_annotations_from_typer_annotations_simple():
function test_forbid_default_value_in_annotated_argument (line 27) | def test_forbid_default_value_in_annotated_argument():
function test_allow_options_to_have_names (line 44) | def test_allow_options_to_have_names():
function test_forbid_annotated_param_and_default_param (line 63) | def test_forbid_annotated_param_and_default_param(param, param_info_type):
function test_forbid_multiple_typer_params_in_annotated (line 79) | def test_forbid_multiple_typer_params_in_annotated():
function test_allow_multiple_non_typer_params_in_annotated (line 93) | def test_allow_multiple_non_typer_params_in_annotated():
function test_forbid_default_factory_and_default_value_in_annotated (line 113) | def test_forbid_default_factory_and_default_value_in_annotated(param, pa...
function test_allow_default_factory_with_default_param (line 140) | def test_allow_default_factory_with_default_param(param):
function test_forbid_default_and_default_factory_with_default_param (line 162) | def test_forbid_default_and_default_factory_with_default_param(param, pa...
function test_error_rendering (line 231) | def test_error_rendering(error, message):
FILE: tests/test_annotated.py
function test_annotated_argument_with_default (line 11) | def test_annotated_argument_with_default():
function test_annotated_argument_in_string_type_with_default (line 27) | def test_annotated_argument_in_string_type_with_default():
function test_annotated_argument_with_default_factory (line 43) | def test_annotated_argument_with_default_factory():
function test_annotated_option_with_argname_doesnt_mutate_multiple_calls (line 62) | def test_annotated_option_with_argname_doesnt_mutate_multiple_calls():
function test_annotated_custom_path (line 81) | def test_annotated_custom_path():
FILE: tests/test_callback_warning.py
function test_warns_when_callback_is_not_supported (line 8) | def test_warns_when_callback_is_not_supported():
function test_warns_when_callback_is_not_supported_added_after_add_typer (line 28) | def test_warns_when_callback_is_not_supported_added_after_add_typer():
FILE: tests/test_cli/test_app_other_name.py
function test_script_help (line 5) | def test_script_help():
function test_script (line 24) | def test_script():
FILE: tests/test_cli/test_completion_run.py
function test_script_completion_run (line 6) | def test_script_completion_run():
FILE: tests/test_cli/test_doc.py
function test_doc (line 7) | def test_doc():
function test_doc_output (line 31) | def test_doc_output(tmp_path: Path):
function test_doc_title_output (line 59) | def test_doc_title_output(tmp_path: Path):
function test_doc_no_rich (line 89) | def test_doc_no_rich():
function test_doc_not_existing (line 113) | def test_doc_not_existing():
function test_doc_no_typer (line 132) | def test_doc_no_typer():
function test_doc_file_not_existing (line 151) | def test_doc_file_not_existing():
function test_doc_html_output (line 170) | def test_doc_html_output(tmp_path: Path):
FILE: tests/test_cli/test_empty_script.py
function test_script_help (line 5) | def test_script_help():
FILE: tests/test_cli/test_extending_app.py
function test_script_help (line 5) | def test_script_help():
function test_script_top (line 26) | def test_script_top():
function test_script_hello (line 45) | def test_script_hello():
function test_script_bye (line 64) | def test_script_bye():
function test_script_sub_command_help (line 83) | def test_script_sub_command_help():
function test_script_sub_sub_command (line 103) | def test_script_sub_sub_command():
FILE: tests/test_cli/test_extending_empty_app.py
function test_script_help (line 5) | def test_script_help():
function test_script_hello (line 24) | def test_script_hello():
function test_script_bye (line 43) | def test_script_bye():
FILE: tests/test_cli/test_func_other_name.py
function test_script (line 5) | def test_script():
FILE: tests/test_cli/test_help.py
function test_script_help (line 5) | def test_script_help():
function test_not_python (line 23) | def test_not_python():
FILE: tests/test_cli/test_multi_app.py
function test_script_help (line 5) | def test_script_help():
function test_script_app_non_existent (line 25) | def test_script_app_non_existent():
function test_script_sub (line 46) | def test_script_sub():
function test_script_top (line 67) | def test_script_top():
function test_script_sub_hello (line 86) | def test_script_sub_hello():
function test_script_sub_bye (line 106) | def test_script_sub_bye():
FILE: tests/test_cli/test_multi_app_cli.py
function test_script_help (line 5) | def test_script_help():
function test_script_sub (line 25) | def test_script_sub():
function test_script_top (line 46) | def test_script_top():
function test_script_sub_hello (line 65) | def test_script_sub_hello():
function test_script_sub_bye (line 85) | def test_script_sub_bye():
FILE: tests/test_cli/test_multi_app_sub.py
function test_script_help (line 5) | def test_script_help():
function test_script (line 28) | def test_script():
FILE: tests/test_cli/test_multi_func.py
function test_help (line 5) | def test_help():
function test_script (line 24) | def test_script():
function test_script_func_non_existent (line 44) | def test_script_func_non_existent():
function test_script_func_not_function (line 66) | def test_script_func_not_function():
function test_script_func (line 88) | def test_script_func():
FILE: tests/test_cli/test_not_python.py
function test_not_python (line 5) | def test_not_python():
FILE: tests/test_cli/test_sub.py
function test_script_hello (line 5) | def test_script_hello():
function test_script_hello_name (line 24) | def test_script_hello_name():
function test_script_hello_name_formal (line 45) | def test_script_hello_name_formal():
function test_script_bye (line 67) | def test_script_bye():
function test_script_bye_friend (line 86) | def test_script_bye_friend():
function test_script_help (line 106) | def test_script_help():
function test_not_python (line 124) | def test_not_python():
FILE: tests/test_cli/test_sub_completion.py
function test_script_completion_run (line 6) | def test_script_completion_run():
FILE: tests/test_cli/test_sub_help.py
function test_script_help (line 5) | def test_script_help():
FILE: tests/test_cli/test_version.py
function test_script_help (line 5) | def test_script_help():
FILE: tests/test_completion/colon_example.py
function _complete (line 10) | def _complete(incomplete: str) -> str:
function image (line 20) | def image(name: str = typer.Option(autocompletion=_complete)):
FILE: tests/test_completion/example_rich_tags.py
function create (line 7) | def create(username: str):
function delete (line 15) | def delete(username: str):
function delete_all (line 23) | def delete_all():
FILE: tests/test_completion/path_example.py
function f (line 9) | def f(p: Path):
FILE: tests/test_completion/test_completion.py
function test_show_completion (line 13) | def test_show_completion():
function test_install_completion (line 30) | def test_install_completion():
function test_completion_invalid_instruction (line 53) | def test_completion_invalid_instruction():
function test_completion_source_bash (line 67) | def test_completion_source_bash():
function test_completion_source_invalid_shell (line 83) | def test_completion_source_invalid_shell():
function test_completion_source_invalid_instruction (line 96) | def test_completion_source_invalid_instruction():
function test_completion_source_zsh (line 109) | def test_completion_source_zsh():
function test_completion_source_fish (line 124) | def test_completion_source_fish():
function test_completion_source_powershell (line 137) | def test_completion_source_powershell():
function test_completion_source_pwsh (line 153) | def test_completion_source_pwsh():
FILE: tests/test_completion/test_completion_complete.py
function get_mod (line 18) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_completion_complete_subcommand_bash (line 24) | def test_completion_complete_subcommand_bash(mod: ModuleType):
function test_completion_complete_subcommand_bash_invalid (line 41) | def test_completion_complete_subcommand_bash_invalid(mod: ModuleType):
function test_completion_complete_subcommand_zsh (line 57) | def test_completion_complete_subcommand_zsh(mod: ModuleType):
function test_completion_complete_subcommand_zsh_files (line 75) | def test_completion_complete_subcommand_zsh_files(mod: ModuleType):
function test_completion_complete_subcommand_fish (line 90) | def test_completion_complete_subcommand_fish(mod: ModuleType):
function test_completion_complete_subcommand_fish_should_complete (line 109) | def test_completion_complete_subcommand_fish_should_complete(mod: Module...
function test_completion_complete_subcommand_fish_should_complete_no (line 125) | def test_completion_complete_subcommand_fish_should_complete_no(mod: Mod...
function test_completion_complete_subcommand_powershell (line 141) | def test_completion_complete_subcommand_powershell(mod: ModuleType):
function test_completion_complete_subcommand_pwsh (line 158) | def test_completion_complete_subcommand_pwsh(mod: ModuleType):
function test_completion_complete_subcommand_noshell (line 175) | def test_completion_complete_subcommand_noshell(mod: ModuleType):
FILE: tests/test_completion/test_completion_complete_no_help.py
function test_completion_complete_subcommand_zsh (line 8) | def test_completion_complete_subcommand_zsh():
function test_completion_complete_subcommand_fish (line 23) | def test_completion_complete_subcommand_fish():
function test_completion_complete_subcommand_powershell (line 38) | def test_completion_complete_subcommand_powershell():
function test_completion_complete_subcommand_pwsh (line 52) | def test_completion_complete_subcommand_pwsh():
FILE: tests/test_completion/test_completion_complete_rich.py
function test_script (line 8) | def test_script():
function test_completion_complete_subcommand_bash (line 34) | def test_completion_complete_subcommand_bash():
function test_completion_complete_subcommand_zsh (line 49) | def test_completion_complete_subcommand_zsh():
function test_completion_complete_subcommand_fish (line 66) | def test_completion_complete_subcommand_fish():
function test_completion_complete_subcommand_powershell (line 84) | def test_completion_complete_subcommand_powershell():
function test_completion_complete_subcommand_pwsh (line 100) | def test_completion_complete_subcommand_pwsh():
FILE: tests/test_completion/test_completion_install.py
function test_completion_install_no_shell (line 19) | def test_completion_install_no_shell():
function test_completion_install_bash (line 33) | def test_completion_install_bash():
function test_completion_install_zsh (line 73) | def test_completion_install_zsh():
function test_completion_install_fish (line 114) | def test_completion_install_fish():
function test_completion_install_powershell (line 144) | def test_completion_install_powershell():
FILE: tests/test_completion/test_completion_option_colon.py
function test_script (line 8) | def test_script():
function test_completion_colon_bash_all (line 18) | def test_completion_colon_bash_all():
function test_completion_colon_bash_partial (line 35) | def test_completion_colon_bash_partial():
function test_completion_colon_bash_single (line 52) | def test_completion_colon_bash_single():
function test_completion_colon_zsh_all (line 69) | def test_completion_colon_zsh_all():
function test_completion_colon_zsh_partial (line 85) | def test_completion_colon_zsh_partial():
function test_completion_colon_zsh_single (line 101) | def test_completion_colon_zsh_single():
function test_completion_colon_powershell_all (line 117) | def test_completion_colon_powershell_all():
function test_completion_colon_powershell_partial (line 134) | def test_completion_colon_powershell_partial():
function test_completion_colon_powershell_single (line 151) | def test_completion_colon_powershell_single():
function test_completion_colon_pwsh_all (line 168) | def test_completion_colon_pwsh_all():
function test_completion_colon_pwsh_partial (line 185) | def test_completion_colon_pwsh_partial():
function test_completion_colon_pwsh_single (line 202) | def test_completion_colon_pwsh_single():
FILE: tests/test_completion/test_completion_path.py
function test_script (line 8) | def test_script():
function test_completion_path_bash (line 18) | def test_completion_path_bash():
FILE: tests/test_completion/test_completion_show.py
function test_completion_show_no_shell (line 16) | def test_completion_show_no_shell():
function test_completion_show_bash (line 29) | def test_completion_show_bash():
function test_completion_source_zsh (line 53) | def test_completion_source_zsh():
function test_completion_source_fish (line 76) | def test_completion_source_fish():
function test_completion_source_powershell (line 97) | def test_completion_source_powershell():
function test_completion_source_pwsh (line 121) | def test_completion_source_pwsh():
function test_completion_show_invalid_shell (line 145) | def test_completion_show_invalid_shell():
FILE: tests/test_completion/test_sanitization.py
function test_sanitize_help_text (line 33) | def test_sanitize_help_text(
FILE: tests/test_corner_cases.py
function test_hidden_option (line 10) | def test_hidden_option():
function test_hidden_option_no_rich (line 20) | def test_hidden_option_no_rich(monkeypatch: pytest.MonkeyPatch):
function test_coverage_call (line 32) | def test_coverage_call():
FILE: tests/test_deprecation.py
function test_deprecation (line 8) | def test_deprecation():
FILE: tests/test_exit_errors.py
function test_eoferror (line 10) | def test_eoferror():
function test_keyboardinterrupt (line 22) | def test_keyboardinterrupt():
function test_oserror (line 35) | def test_oserror():
function test_oserror_no_epipe (line 49) | def test_oserror_no_epipe():
FILE: tests/test_future_annotations.py
function test_annotated (line 11) | def test_annotated():
FILE: tests/test_launch.py
function test_launch_url_unix (line 18) | def test_launch_url_unix(system: str, command: str):
function test_launch_url_windows (line 31) | def test_launch_url_windows():
function test_launch_url_no_xdg_open (line 41) | def test_launch_url_no_xdg_open():
function test_calls_original_launch_when_not_passing_urls (line 52) | def test_calls_original_launch_when_not_passing_urls():
FILE: tests/test_others.py
function test_help_from_info (line 24) | def test_help_from_info():
function test_defaults_from_info (line 30) | def test_defaults_from_info():
function test_too_many_parsers (line 36) | def test_too_many_parsers():
function test_valid_parser_permutations (line 60) | def test_valid_parser_permutations():
function test_install_invalid_shell (line 81) | def test_install_invalid_shell():
function test_callback_too_many_parameters (line 97) | def test_callback_too_many_parameters():
function test_callback_2_untyped_parameters (line 114) | def test_callback_2_untyped_parameters():
function test_callback_3_untyped_parameters (line 130) | def test_callback_3_untyped_parameters():
function test_callback_4_list_none (line 148) | def test_callback_4_list_none():
function test_empty_list_default_generator (line 172) | def test_empty_list_default_generator():
function test_completion_argument (line 188) | def test_completion_argument():
function test_completion_untyped_parameters (line 207) | def test_completion_untyped_parameters():
function test_completion_untyped_parameters_different_order_correct_names (line 233) | def test_completion_untyped_parameters_different_order_correct_names():
function test_autocompletion_too_many_parameters (line 259) | def test_autocompletion_too_many_parameters():
function test_forward_references (line 274) | def test_forward_references():
function test_context_settings_inheritance_single_command (line 295) | def test_context_settings_inheritance_single_command():
function test_split_opt (line 306) | def test_split_opt():
function test_options_metadata_typer_default (line 324) | def test_options_metadata_typer_default():
FILE: tests/test_param_meta_empty.py
function test_default_with_class_with_custom_eq (line 7) | def test_default_with_class_with_custom_eq():
FILE: tests/test_prog_name.py
function test_custom_prog_name (line 6) | def test_custom_prog_name():
FILE: tests/test_rich_import.py
function test_rich_not_imported_unnecessary (line 8) | def test_rich_not_imported_unnecessary():
FILE: tests/test_rich_markup_mode.py
function test_rich_markup_mode_none (line 14) | def test_rich_markup_mode_none():
function test_rich_markup_mode_rich (line 32) | def test_rich_markup_mode_rich():
function test_rich_markup_mode_envvar (line 63) | def test_rich_markup_mode_envvar(env_var_value: str, expected_result: bo...
function test_markup_mode_newline_pr815 (line 101) | def test_markup_mode_newline_pr815(mode: str, lines: list[str]):
function test_markup_mode_newline_issue447 (line 139) | def test_markup_mode_newline_issue447(mode: str, lines: list[str]):
function test_markup_mode_newline_mixed (line 212) | def test_markup_mode_newline_mixed(mode: str, lines: list[str]):
function test_markup_mode_bullets_single_newline (line 256) | def test_markup_mode_bullets_single_newline(mode: str, lines: list[str]):
function test_markup_mode_bullets_double_newline (line 299) | def test_markup_mode_bullets_double_newline(mode: str, lines: list[str]):
function test_markup_mode_default (line 329) | def test_markup_mode_default():
FILE: tests/test_rich_utils.py
function test_rich_utils_click_rewrapp (line 13) | def test_rich_utils_click_rewrapp():
function test_rich_help_no_commands (line 46) | def test_rich_help_no_commands():
function test_rich_doesnt_print_None_default (line 60) | def test_rich_doesnt_print_None_default():
function test_rich_markup_import_regression (line 89) | def test_rich_markup_import_regression():
function test_metavar_highlighter (line 109) | def test_metavar_highlighter(input_text: str):
function test_make_rich_text_with_ansi_escape_sequences (line 138) | def test_make_rich_text_with_ansi_escape_sequences():
function test_make_rich_text_with_typer_style_in_help (line 162) | def test_make_rich_text_with_typer_style_in_help():
function test_help_table_alignment_with_styled_text (line 181) | def test_help_table_alignment_with_styled_text():
FILE: tests/test_suggest_commands.py
function test_typo_suggestion_enabled (line 7) | def test_typo_suggestion_enabled():
function test_typo_suggestion_multiple_matches (line 25) | def test_typo_suggestion_multiple_matches():
function test_typo_suggestion_no_matches (line 44) | def test_typo_suggestion_no_matches():
function test_typo_suggestion_exact_match_works (line 62) | def test_typo_suggestion_exact_match_works():
function test_typo_suggestion_disabled (line 83) | def test_typo_suggestion_disabled():
FILE: tests/test_tracebacks.py
function test_traceback_no_rich (line 7) | def test_traceback_no_rich():
function test_traceback_no_rich_short_disable (line 26) | def test_traceback_no_rich_short_disable():
function test_unmodified_traceback (line 45) | def test_unmodified_traceback():
FILE: tests/test_tutorial/test_app_dir/test_tutorial001.py
function create_config_file (line 15) | def create_config_file():
function test_cli_config_doesnt_exist (line 27) | def test_cli_config_doesnt_exist():
function test_cli_config_exists (line 33) | def test_cli_config_exists(config_file: Path):
function test_script (line 39) | def test_script():
FILE: tests/test_tutorial/test_arguments/test_default/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_no_arg (line 33) | def test_call_no_arg(mod: ModuleType):
function test_call_arg (line 39) | def test_call_arg(mod: ModuleType):
function test_script (line 45) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_default/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_no_arg (line 33) | def test_call_no_arg(mod: ModuleType):
function test_call_arg (line 41) | def test_call_arg(mod: ModuleType):
function test_script (line 47) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_envvar/test_tutorial001.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 27) | def test_help(mod: ModuleType):
function test_help_no_rich (line 36) | def test_help_no_rich(monkeypatch: pytest.MonkeyPatch, mod: ModuleType):
function test_call_arg (line 46) | def test_call_arg(mod: ModuleType):
function test_call_env_var (line 52) | def test_call_env_var(mod: ModuleType):
function test_call_env_var_arg (line 58) | def test_call_env_var_arg(mod: ModuleType):
function test_script (line 64) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_envvar/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_arg (line 34) | def test_call_arg(mod: ModuleType):
function test_call_env_var1 (line 40) | def test_call_env_var1(mod: ModuleType):
function test_call_env_var2 (line 46) | def test_call_env_var2(mod: ModuleType):
function test_script (line 52) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_envvar/test_tutorial003.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_arg (line 34) | def test_call_arg(mod: ModuleType):
function test_call_env_var (line 40) | def test_call_env_var(mod: ModuleType):
function test_call_env_var_arg (line 46) | def test_call_env_var_arg(mod: ModuleType):
function test_script (line 52) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_help/test_tutorial001.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 26) | def test_help(mod: ModuleType):
function test_help_no_rich (line 36) | def test_help_no_rich(monkeypatch: pytest.MonkeyPatch, mod: ModuleType):
function test_call_arg (line 47) | def test_call_arg(mod: ModuleType):
function test_script (line 53) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_help/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_arg (line 36) | def test_call_arg(mod: ModuleType):
function test_script (line 42) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_help/test_tutorial003.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_arg (line 36) | def test_call_arg(mod: ModuleType):
function test_script (line 42) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_help/test_tutorial004.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_arg (line 36) | def test_call_arg(mod: ModuleType):
function test_script (line 42) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_help/test_tutorial005.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_arg (line 34) | def test_call_arg(mod: ModuleType):
function test_script (line 40) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_help/test_tutorial006.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_arg (line 33) | def test_call_arg(mod: ModuleType):
function test_script (line 39) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_help/test_tutorial007.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_arg (line 33) | def test_call_arg(mod: ModuleType):
function test_script (line 39) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_help/test_tutorial008.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 26) | def test_help(mod: ModuleType):
function test_help_no_rich (line 35) | def test_help_no_rich(monkeypatch: pytest.MonkeyPatch, mod: ModuleType):
function test_call_arg (line 45) | def test_call_arg(mod: ModuleType):
function test_script (line 51) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_optional/test_tutorial000.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function get_app (line 27) | def get_app(mod: ModuleType) -> typer.Typer:
function test_cli (line 33) | def test_cli(app: typer.Typer):
function test_cli_missing_argument (line 39) | def test_cli_missing_argument(app: typer.Typer):
function test_script (line 45) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_optional/test_tutorial001.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_call_no_arg (line 26) | def test_call_no_arg(mod: ModuleType):
function test_call_no_arg_standalone (line 32) | def test_call_no_arg_standalone(mod: ModuleType):
function test_call_no_arg_no_rich (line 38) | def test_call_no_arg_no_rich(monkeypatch: pytest.MonkeyPatch, mod: Modul...
function test_call_arg (line 46) | def test_call_arg(mod: ModuleType):
function test_script (line 52) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_optional/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_no_arg (line 31) | def test_call_no_arg(mod: ModuleType):
function test_call_arg (line 37) | def test_call_arg(mod: ModuleType):
function test_script (line 43) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_arguments/test_optional/test_tutorial003.py
function test_call_no_arg (line 15) | def test_call_no_arg():
function test_call_no_arg_standalone (line 21) | def test_call_no_arg_standalone():
function test_call_no_arg_no_rich (line 27) | def test_call_no_arg_no_rich(monkeypatch: pytest.MonkeyPatch):
function test_call_arg (line 35) | def test_call_arg():
function test_script (line 41) | def test_script():
FILE: tests/test_tutorial/test_commands/test_arguments/test_tutorial001.py
function test_help_create (line 13) | def test_help_create():
function test_help_delete (line 19) | def test_help_delete():
function test_create (line 25) | def test_create():
function test_delete (line 31) | def test_delete():
function test_script (line 37) | def test_script():
FILE: tests/test_tutorial/test_commands/test_callback/test_tutorial001.py
function test_help (line 15) | def test_help():
function test_help_no_rich (line 23) | def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
function test_create (line 32) | def test_create():
function test_create_verbose (line 38) | def test_create_verbose():
function test_delete (line 47) | def test_delete():
function test_delete_verbose (line 53) | def test_delete_verbose():
function test_wrong_verbose (line 62) | def test_wrong_verbose():
function test_script (line 68) | def test_script():
FILE: tests/test_tutorial/test_commands/test_callback/test_tutorial002.py
function test_app (line 13) | def test_app():
function test_script (line 20) | def test_script():
FILE: tests/test_tutorial/test_commands/test_callback/test_tutorial003.py
function test_app (line 13) | def test_app():
function test_for_coverage (line 21) | def test_for_coverage():
function test_script (line 25) | def test_script():
FILE: tests/test_tutorial/test_commands/test_callback/test_tutorial004.py
function test_help (line 13) | def test_help():
function test_app (line 21) | def test_app():
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_commands/test_context/test_tutorial001.py
function test_create (line 13) | def test_create():
function test_delete (line 20) | def test_delete():
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_commands/test_context/test_tutorial002.py
function test_create (line 13) | def test_create():
function test_delete (line 20) | def test_delete():
function test_callback (line 27) | def test_callback():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_commands/test_context/test_tutorial003.py
function test_create (line 13) | def test_create():
function test_delete (line 20) | def test_delete():
function test_callback (line 27) | def test_callback():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_commands/test_context/test_tutorial004.py
function test_1 (line 13) | def test_1():
function test_script (line 22) | def test_script():
FILE: tests/test_tutorial/test_commands/test_help/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_help_create (line 39) | def test_help_create(mod: ModuleType):
function test_help_delete (line 46) | def test_help_delete(mod: ModuleType):
function test_help_delete_all (line 56) | def test_help_delete_all(mod: ModuleType):
function test_help_init (line 68) | def test_help_init(mod: ModuleType):
function test_create (line 75) | def test_create(mod: ModuleType):
function test_delete (line 81) | def test_delete(mod: ModuleType):
function test_no_delete (line 88) | def test_no_delete(mod: ModuleType):
function test_delete_all (line 95) | def test_delete_all(mod: ModuleType):
function test_no_delete_all (line 102) | def test_no_delete_all(mod: ModuleType):
function test_init (line 109) | def test_init(mod: ModuleType):
function test_script (line 115) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_commands/test_help/test_tutorial002.py
function test_help (line 13) | def test_help():
function test_help_create (line 24) | def test_help_create():
function test_help_delete (line 31) | def test_help_delete():
function test_create (line 38) | def test_create():
function test_delete (line 44) | def test_delete():
function test_script (line 50) | def test_script():
FILE: tests/test_tutorial/test_commands/test_help/test_tutorial003.py
function test_help (line 13) | def test_help():
function test_help_delete (line 23) | def test_help_delete():
function test_call (line 30) | def test_call():
function test_script (line 38) | def test_script():
FILE: tests/test_tutorial/test_commands/test_help/test_tutorial004.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 26) | def test_help(mod: ModuleType):
function test_help_create (line 37) | def test_help_create(mod: ModuleType):
function test_help_delete (line 45) | def test_help_delete(mod: ModuleType):
function test_create (line 54) | def test_create(mod: ModuleType):
function test_delete (line 60) | def test_delete(mod: ModuleType):
function test_script (line 66) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_commands/test_help/test_tutorial005.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 26) | def test_help(mod: ModuleType):
function test_help_create (line 37) | def test_help_create(mod: ModuleType):
function test_help_delete (line 46) | def test_help_delete(mod: ModuleType):
function test_create (line 55) | def test_create(mod: ModuleType):
function test_delete (line 61) | def test_delete(mod: ModuleType):
function test_script (line 67) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_commands/test_help/test_tutorial006.py
function test_main_help (line 14) | def test_main_help():
function test_call (line 30) | def test_call():
function test_script (line 46) | def test_script():
FILE: tests/test_tutorial/test_commands/test_help/test_tutorial007.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main_help (line 26) | def test_main_help(mod: ModuleType):
function test_create_help (line 36) | def test_create_help(mod: ModuleType):
function test_call (line 54) | def test_call(mod: ModuleType):
function test_script (line 62) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_commands/test_help/test_tutorial008.py
function test_main_help (line 13) | def test_main_help():
function test_call (line 20) | def test_call():
function test_script (line 26) | def test_script():
FILE: tests/test_tutorial/test_commands/test_index/test_tutorial002.py
function test_help (line 13) | def test_help():
function test_create (line 22) | def test_create():
function test_delete (line 28) | def test_delete():
function test_script (line 34) | def test_script():
FILE: tests/test_tutorial/test_commands/test_index/test_tutorial003.py
function test_no_arg (line 13) | def test_no_arg():
function test_no_additional_output (line 21) | def test_no_additional_output():
function test_create (line 28) | def test_create():
function test_delete (line 34) | def test_delete():
function test_script (line 40) | def test_script():
FILE: tests/test_tutorial/test_commands/test_index/test_tutorial004.py
function test_help (line 13) | def test_help():
function test_create (line 27) | def test_create():
function test_delete (line 33) | def test_delete():
function test_script (line 39) | def test_script():
FILE: tests/test_tutorial/test_commands/test_index/test_tutorial005.py
function test_creates_successfully (line 9) | def test_creates_successfully():
function test_shows_suggestion (line 20) | def test_shows_suggestion():
FILE: tests/test_tutorial/test_commands/test_name/test_tutorial001.py
function test_help (line 13) | def test_help():
function test_create (line 21) | def test_create():
function test_delete (line 27) | def test_delete():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_commands/test_one_or_multiple/test_tutorial001.py
function test_help (line 13) | def test_help():
function test_command (line 20) | def test_command():
function test_script (line 26) | def test_script():
FILE: tests/test_tutorial/test_commands/test_one_or_multiple/test_tutorial002.py
function test_help (line 13) | def test_help():
function test_command (line 22) | def test_command():
function test_script (line 28) | def test_script():
FILE: tests/test_tutorial/test_commands/test_options/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_create (line 35) | def test_create(mod: ModuleType):
function test_delete (line 41) | def test_delete(mod: ModuleType):
function test_no_delete (line 48) | def test_no_delete(mod: ModuleType):
function test_delete_all (line 55) | def test_delete_all(mod: ModuleType):
function test_no_delete_all (line 62) | def test_no_delete_all(mod: ModuleType):
function test_delete_all_force (line 69) | def test_delete_all_force(mod: ModuleType):
function test_init (line 76) | def test_init(mod: ModuleType):
function test_script (line 82) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_exceptions/test_tutorial001.py
function test_traceback_rich (line 14) | def test_traceback_rich():
function test_standard_traceback_env_var (line 37) | def test_standard_traceback_env_var(env_var: str):
function test_script (line 53) | def test_script():
FILE: tests/test_tutorial/test_exceptions/test_tutorial002.py
function test_traceback_rich (line 14) | def test_traceback_rich():
function test_standard_traceback_env_var (line 37) | def test_standard_traceback_env_var(env_var: str):
function test_script (line 53) | def test_script():
FILE: tests/test_tutorial/test_exceptions/test_tutorial003.py
function test_traceback_rich_pretty_short_disable (line 13) | def test_traceback_rich_pretty_short_disable():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_exceptions/test_tutorial004.py
function test_rich_pretty_exceptions_disable (line 13) | def test_rich_pretty_exceptions_disable():
function test_script (line 32) | def test_script():
FILE: tests/test_tutorial/test_first_steps/test_tutorial001.py
function test_cli (line 12) | def test_cli():
function test_script (line 19) | def test_script():
FILE: tests/test_tutorial/test_first_steps/test_tutorial002.py
function test_1 (line 15) | def test_1():
function test_2 (line 21) | def test_2():
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_first_steps/test_tutorial003.py
function test_1 (line 15) | def test_1():
function test_2 (line 21) | def test_2():
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_first_steps/test_tutorial004.py
function test_help (line 15) | def test_help():
function test_1 (line 27) | def test_1():
function test_formal_1 (line 33) | def test_formal_1():
function test_formal_2 (line 39) | def test_formal_2():
function test_formal_3 (line 45) | def test_formal_3():
function test_script (line 51) | def test_script():
FILE: tests/test_tutorial/test_first_steps/test_tutorial005.py
function test_help (line 15) | def test_help():
function test_1 (line 27) | def test_1():
function test_option_lastname (line 33) | def test_option_lastname():
function test_option_lastname_2 (line 39) | def test_option_lastname_2():
function test_formal_1 (line 45) | def test_formal_1():
function test_script (line 51) | def test_script():
FILE: tests/test_tutorial/test_first_steps/test_tutorial006.py
function test_help (line 15) | def test_help():
function test_1 (line 22) | def test_1():
function test_option_lastname (line 28) | def test_option_lastname():
function test_option_lastname_2 (line 34) | def test_option_lastname_2():
function test_formal_1 (line 40) | def test_formal_1():
function test_script (line 46) | def test_script():
FILE: tests/test_tutorial/test_launch/test_tutorial001.py
function test_cli (line 12) | def test_cli():
function test_script (line 21) | def test_script():
FILE: tests/test_tutorial/test_launch/test_tutorial002.py
function app_dir (line 16) | def app_dir():
function test_cli (line 32) | def test_cli(app_dir: Path):
function test_script (line 41) | def test_script():
FILE: tests/test_tutorial/test_multiple_values/test_arguments_with_multiple_values/test_tutorial001.py
function test_main (line 14) | def test_main():
function test_script (line 21) | def test_script():
FILE: tests/test_tutorial/test_multiple_values/test_arguments_with_multiple_values/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 27) | def test_help(mod: ModuleType):
function test_defaults (line 35) | def test_defaults(mod: ModuleType):
function test_invalid_args (line 43) | def test_invalid_args(mod: ModuleType):
function test_valid_args (line 49) | def test_valid_args(mod: ModuleType):
function test_script (line 57) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 25) | def test_main(mod: ModuleType):
function test_1_user (line 33) | def test_1_user(mod: ModuleType):
function test_3_user (line 39) | def test_3_user(mod: ModuleType):
function test_script (line 49) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_multiple_values/test_multiple_options/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 25) | def test_main(mod: ModuleType):
function test_1_number (line 31) | def test_1_number(mod: ModuleType):
function test_2_number (line 37) | def test_2_number(mod: ModuleType):
function test_script (line 45) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_multiple_values/test_options_with_multiple_values/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 27) | def test_main(mod: ModuleType):
function test_user_1 (line 34) | def test_user_1(mod: ModuleType):
function test_user_2 (line 41) | def test_user_2(mod: ModuleType):
function test_invalid_user (line 48) | def test_invalid_user(mod: ModuleType):
function test_script (line 54) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_one_file_per_command/test_tutorial.py
function test_help (line 8) | def test_help():
function test_version (line 17) | def test_version():
function test_users_help (line 24) | def test_users_help():
function test_add_user (line 33) | def test_add_user():
function test_delete_user (line 40) | def test_delete_user():
FILE: tests/test_tutorial/test_options/test_callback/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_1 (line 25) | def test_1(mod: ModuleType):
function test_2 (line 31) | def test_2(mod: ModuleType):
function test_script (line 38) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_callback/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_1 (line 25) | def test_1(mod: ModuleType):
function test_2 (line 32) | def test_2(mod: ModuleType):
function test_script (line 40) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_callback/test_tutorial003.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_1 (line 27) | def test_1(mod: ModuleType):
function test_2 (line 34) | def test_2(mod: ModuleType):
function test_script (line 41) | def test_script(mod: ModuleType):
function test_completion (line 50) | def test_completion(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_callback/test_tutorial004.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_1 (line 27) | def test_1(mod: ModuleType):
function test_2 (line 34) | def test_2(mod: ModuleType):
function test_script (line 41) | def test_script(mod: ModuleType):
function test_completion (line 50) | def test_completion(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_help/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_1 (line 34) | def test_1(mod: ModuleType):
function test_option_lastname (line 40) | def test_option_lastname(mod: ModuleType):
function test_formal (line 46) | def test_formal(mod: ModuleType):
function test_script (line 52) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_help/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_call (line 25) | def test_call(mod: ModuleType):
function test_formal (line 31) | def test_formal(mod: ModuleType):
function test_help (line 37) | def test_help(mod: ModuleType):
function test_script (line 48) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_help/test_tutorial003.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_call (line 25) | def test_call(mod: ModuleType):
function test_help (line 31) | def test_help(mod: ModuleType):
function test_script (line 39) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_help/test_tutorial004.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_call (line 25) | def test_call(mod: ModuleType):
function test_help (line 31) | def test_help(monkeypatch, mod: ModuleType):
function test_script (line 41) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_name/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_option_help (line 25) | def test_option_help(mod: ModuleType):
function test_call (line 33) | def test_call(mod: ModuleType):
function test_call_no_args (line 39) | def test_call_no_args(mod: ModuleType):
function test_script (line 45) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_name/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_option_help (line 25) | def test_option_help(mod: ModuleType):
function test_call (line 34) | def test_call(mod: ModuleType):
function test_call_long (line 40) | def test_call_long(mod: ModuleType):
function test_script (line 46) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_name/test_tutorial003.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_option_help (line 25) | def test_option_help(mod: ModuleType):
function test_call (line 34) | def test_call(mod: ModuleType):
function test_script (line 40) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_name/test_tutorial004.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_option_help (line 25) | def test_option_help(mod: ModuleType):
function test_call (line 34) | def test_call(mod: ModuleType):
function test_call_long (line 40) | def test_call_long(mod: ModuleType):
function test_script (line 46) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_name/test_tutorial005.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_option_help (line 25) | def test_option_help(mod: ModuleType):
function test_call (line 35) | def test_call(mod: ModuleType):
function test_call_formal (line 41) | def test_call_formal(mod: ModuleType):
function test_call_formal_condensed (line 47) | def test_call_formal_condensed(mod: ModuleType):
function test_call_condensed_wrong_order (line 53) | def test_call_condensed_wrong_order(mod: ModuleType):
function test_script (line 58) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_password/test_tutorial001.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_option_email (line 27) | def test_option_email(mod: ModuleType):
function test_option_email_prompt (line 33) | def test_option_email_prompt(mod: ModuleType):
function test_help (line 43) | def test_help(mod: ModuleType):
function test_script (line 50) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_password/test_tutorial002.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_option_password (line 27) | def test_option_password(mod: ModuleType):
function test_option_password_prompt (line 34) | def test_option_password_prompt(mod: ModuleType):
function test_help (line 47) | def test_help(mod: ModuleType):
function test_script (line 54) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_prompt/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_option_lastname (line 25) | def test_option_lastname(mod: ModuleType):
function test_option_lastname_prompt (line 31) | def test_option_lastname_prompt(mod: ModuleType):
function test_help (line 38) | def test_help(mod: ModuleType):
function test_script (line 46) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_prompt/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_option_lastname (line 25) | def test_option_lastname(mod: ModuleType):
function test_option_lastname_prompt (line 31) | def test_option_lastname_prompt(mod: ModuleType):
function test_help (line 38) | def test_help(mod: ModuleType):
function test_script (line 46) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_prompt/test_tutorial003.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_prompt (line 25) | def test_prompt(mod: ModuleType):
function test_prompt_not_equal (line 31) | def test_prompt_not_equal(mod: ModuleType):
function test_option (line 40) | def test_option(mod: ModuleType):
function test_help (line 47) | def test_help(mod: ModuleType):
function test_script (line 55) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_required/test_tutorial001_tutorial002.py
function get_mod (line 22) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_1 (line 28) | def test_1(mod: ModuleType):
function test_option_lastname (line 34) | def test_option_lastname(mod: ModuleType):
function test_help (line 40) | def test_help(mod: ModuleType):
function test_help_no_rich (line 48) | def test_help_no_rich(monkeypatch: pytest.MonkeyPatch, mod: ModuleType):
function test_script (line 57) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_version/test_tutorial001.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_version (line 27) | def test_version(mod: ModuleType):
function test_version_with_name (line 33) | def test_version_with_name(mod: ModuleType):
function test_no_version (line 40) | def test_no_version(mod: ModuleType):
function test_script (line 46) | def test_script(mod: ModuleType):
function test_completion (line 55) | def test_completion(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_version/test_tutorial002.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_version_camila (line 27) | def test_version_camila(mod: ModuleType):
function test_version_not_camila (line 33) | def test_version_not_camila(mod: ModuleType):
function test_version_camila_no_version (line 40) | def test_version_camila_no_version(mod: ModuleType):
function test_script (line 46) | def test_script(mod: ModuleType):
function test_completion (line 55) | def test_completion(mod: ModuleType):
FILE: tests/test_tutorial/test_options/test_version/test_tutorial003.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_1 (line 27) | def test_1(mod: ModuleType):
function test_2 (line 33) | def test_2(mod: ModuleType):
function test_3 (line 40) | def test_3(mod: ModuleType):
function test_script (line 46) | def test_script(mod: ModuleType):
function test_completion (line 55) | def test_completion(mod: ModuleType):
FILE: tests/test_tutorial/test_options_autocompletion/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_1 (line 25) | def test_1(mod: ModuleType):
function test_script (line 31) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options_autocompletion/test_tutorial002.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_completion (line 27) | def test_completion(mod: ModuleType):
function test_1 (line 44) | def test_1(mod: ModuleType):
function test_script (line 50) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options_autocompletion/test_tutorial003.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_completion_zsh (line 27) | def test_completion_zsh(mod: ModuleType):
function test_completion_powershell (line 44) | def test_completion_powershell(mod: ModuleType):
function test_1 (line 62) | def test_1(mod: ModuleType):
function test_script (line 68) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options_autocompletion/test_tutorial004_tutorial005.py
function get_mod (line 23) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_completion (line 29) | def test_completion(mod: ModuleType):
function test_1 (line 46) | def test_1(mod: ModuleType):
function test_script (line 52) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options_autocompletion/test_tutorial006.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_1 (line 25) | def test_1(mod: ModuleType):
function test_2 (line 31) | def test_2(mod: ModuleType):
function test_script (line 38) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options_autocompletion/test_tutorial007.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_completion (line 27) | def test_completion(mod: ModuleType):
function test_1 (line 44) | def test_1(mod: ModuleType):
function test_script (line 51) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options_autocompletion/test_tutorial008.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_completion (line 27) | def test_completion(mod: ModuleType):
function test_1 (line 45) | def test_1(mod: ModuleType):
function test_script (line 52) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_options_autocompletion/test_tutorial009.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_completion (line 27) | def test_completion(mod: ModuleType):
function test_1 (line 45) | def test_1(mod: ModuleType):
function test_script (line 52) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_bool/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_no_force (line 32) | def test_no_force(mod: ModuleType):
function test_force (line 38) | def test_force(mod: ModuleType):
function test_invalid_no_force (line 44) | def test_invalid_no_force(mod: ModuleType):
function test_script (line 50) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_bool/test_tutorial002.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 26) | def test_help(mod: ModuleType):
function test_help_no_rich (line 34) | def test_help_no_rich(monkeypatch: pytest.MonkeyPatch, mod: ModuleType):
function test_main (line 43) | def test_main(mod: ModuleType):
function test_accept (line 49) | def test_accept(mod: ModuleType):
function test_reject (line 55) | def test_reject(mod: ModuleType):
function test_invalid_no_accept (line 61) | def test_invalid_no_accept(mod: ModuleType):
function test_script (line 67) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_bool/test_tutorial003.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_force (line 34) | def test_force(mod: ModuleType):
function test_no_force (line 40) | def test_no_force(mod: ModuleType):
function test_script (line 46) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_bool/test_tutorial004.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_main (line 32) | def test_main(mod: ModuleType):
function test_demo (line 38) | def test_demo(mod: ModuleType):
function test_short_demo (line 44) | def test_short_demo(mod: ModuleType):
function test_script (line 50) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial001.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_parse_custom_type (line 30) | def test_parse_custom_type(mod: ModuleType):
function test_parse_custom_type_with_default (line 36) | def test_parse_custom_type_with_default(mod: ModuleType):
function test_script (line 42) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_datetime/test_tutorial001.py
function test_help (line 12) | def test_help():
function test_main (line 18) | def test_main():
function test_invalid (line 25) | def test_invalid():
function test_script (line 38) | def test_script():
FILE: tests/test_tutorial/test_parameter_types/test_datetime/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 25) | def test_main(mod: ModuleType):
function test_usa_weird_date_format (line 31) | def test_usa_weird_date_format(mod: ModuleType):
function test_script (line 37) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_enum/test_tutorial001.py
function test_help (line 12) | def test_help():
function test_main (line 20) | def test_main():
function test_main_default (line 26) | def test_main_default():
function test_invalid_case (line 32) | def test_invalid_case():
function test_invalid_other (line 42) | def test_invalid_other():
function test_script (line 52) | def test_script():
FILE: tests/test_tutorial/test_parameter_types/test_enum/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_upper (line 25) | def test_upper(mod: ModuleType):
function test_mix (line 31) | def test_mix(mod: ModuleType):
function test_script (line 37) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_enum/test_tutorial003.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_call_no_arg (line 33) | def test_call_no_arg(mod: ModuleType):
function test_call_single_arg (line 39) | def test_call_single_arg(mod: ModuleType):
function test_call_multiple_arg (line 45) | def test_call_multiple_arg(mod: ModuleType):
function test_script (line 51) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_enum/test_tutorial004.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 25) | def test_help(mod: ModuleType):
function test_main (line 31) | def test_main(mod):
function test_invalid (line 37) | def test_invalid(mod: ModuleType):
function test_script (line 50) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_file/test_tutorial001.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 26) | def test_main(tmpdir, mod: ModuleType):
function test_script (line 36) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_file/test_tutorial002.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 26) | def test_main(tmpdir, mod: ModuleType):
function test_script (line 38) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_file/test_tutorial003.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 26) | def test_main(tmpdir, mod: ModuleType):
function test_script (line 35) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_file/test_tutorial004.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 26) | def test_main(tmpdir, mod: ModuleType):
function test_script (line 39) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_file/test_tutorial005.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 26) | def test_main(tmpdir, mod: ModuleType):
function test_script (line 41) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_index/test_tutorial001.py
function test_help (line 12) | def test_help():
function test_params (line 21) | def test_params():
function test_invalid (line 32) | def test_invalid():
function test_script (line 39) | def test_script():
FILE: tests/test_tutorial/test_parameter_types/test_number/test_tutorial001.py
function get_mod (line 21) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_help (line 27) | def test_help(mod: ModuleType):
function test_help_no_rich (line 36) | def test_help_no_rich(monkeypatch: pytest.MonkeyPatch, mod: ModuleType):
function test_params (line 46) | def test_params(mod: ModuleType):
function test_invalid_id (line 54) | def test_invalid_id(mod: ModuleType):
function test_invalid_age (line 62) | def test_invalid_age(mod: ModuleType):
function test_invalid_score (line 69) | def test_invalid_score(monkeypatch: pytest.MonkeyPatch, mod: ModuleType):
function test_negative_score (line 77) | def test_negative_score(mod: ModuleType):
function test_script (line 85) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_number/test_tutorial002.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_invalid_id (line 25) | def test_invalid_id(mod: ModuleType):
function test_clamped (line 33) | def test_clamped(mod: ModuleType):
function test_script (line 41) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_number/test_tutorial003.py
function get_mod (line 19) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_main (line 25) | def test_main(mod: ModuleType):
function test_verbose_1 (line 31) | def test_verbose_1(mod: ModuleType):
function test_verbose_3 (line 37) | def test_verbose_3(mod: ModuleType):
function test_verbose_short_1 (line 43) | def test_verbose_short_1(mod: ModuleType):
function test_verbose_short_3 (line 49) | def test_verbose_short_3(mod: ModuleType):
function test_verbose_short_3_condensed (line 55) | def test_verbose_short_3_condensed(mod: ModuleType):
function test_script (line 61) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_path/test_tutorial001.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_no_path (line 26) | def test_no_path(tmpdir, mod: ModuleType):
function test_not_exists (line 34) | def test_not_exists(tmpdir, mod: ModuleType):
function test_exists (line 43) | def test_exists(tmpdir, mod: ModuleType):
function test_dir (line 52) | def test_dir(mod: ModuleType):
function test_script (line 58) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_path/test_tutorial002.py
function get_mod (line 20) | def get_mod(request: pytest.FixtureRequest) -> ModuleType:
function test_not_exists (line 26) | def test_not_exists(tmpdir, mod: ModuleType):
function test_exists (line 37) | def test_exists(tmpdir, mod: ModuleType):
function test_dir (line 46) | def test_dir(mod: ModuleType):
function test_script (line 53) | def test_script(mod: ModuleType):
FILE: tests/test_tutorial/test_parameter_types/test_uuid/test_tutorial001.py
function test_main (line 12) | def test_main():
function test_invalid_uuid (line 19) | def test_invalid_uuid():
function test_script (line 28) | def test_script():
FILE: tests/test_tutorial/test_printing/test_tutorial001.py
function test_cli (line 16) | def test_cli():
function test_script (line 38) | def test_script():
FILE: tests/test_tutorial/test_printing/test_tutorial002.py
function test_cli (line 16) | def test_cli():
function test_cli_without_formatting (line 28) | def test_cli_without_formatting():
function test_script (line 35) | def test_script():
FILE: tests/test_tutorial/test_printing/test_tutorial003.py
function test_cli (line 14) | def test_cli():
function test_script (line 26) | def test_script():
FILE: tests/test_tutorial/test_printing/test_tutorial004.py
function test_cli (line 13) | def test_cli():
function test_script (line 20) | def test_script():
FILE: tests/test_tutorial/test_printing/test_tutorial005.py
function test_good_true (line 14) | def test_good_true():
function test_good_false (line 25) | def test_good_false():
function test_script (line 36) | def test_script():
FILE: tests/test_tutorial/test_printing/test_tutorial006.py
function test_cli (line 14) | def test_cli():
function test_script (line 25) | def test_script():
FILE: tests/test_tutorial/test_progressbar/test_tutorial001.py
function test_cli_one_step (line 16) | def test_cli_one_step():
function test_cli (line 28) | def test_cli():
function test_script (line 42) | def test_script():
FILE: tests/test_tutorial/test_progressbar/test_tutorial002.py
function test_cli (line 15) | def test_cli(): # Checking only final state of spinner progress bar
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_progressbar/test_tutorial003.py
function test_cli (line 15) | def test_cli(): # Checking only final state of progress bar
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_progressbar/test_tutorial004.py
function test_cli (line 15) | def test_cli(): # Checking only final state of progress bar
function test_cli_no_mock_generator (line 41) | def test_cli_no_mock_generator():
function test_script (line 55) | def test_script():
FILE: tests/test_tutorial/test_progressbar/test_tutorial005.py
function test_cli (line 15) | def test_cli(): # Checking only final state of progress bar
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_progressbar/test_tutorial006.py
function test_cli (line 15) | def test_cli(): # Checking only final state of progress bar
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_prompt/test_tutorial001.py
function test_cli (line 12) | def test_cli():
function test_script (line 19) | def test_script():
FILE: tests/test_tutorial/test_prompt/test_tutorial002.py
function test_cli (line 12) | def test_cli():
function test_no_confirm (line 19) | def test_no_confirm():
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_prompt/test_tutorial003.py
function test_cli (line 12) | def test_cli():
function test_no_confirm (line 19) | def test_no_confirm():
function test_script (line 26) | def test_script():
FILE: tests/test_tutorial/test_prompt/test_tutorial004.py
function test_cli (line 12) | def test_cli():
function test_script (line 19) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_callback_override/test_tutorial001.py
function test_cli (line 13) | def test_cli():
function test_script (line 20) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_callback_override/test_tutorial002.py
function test_cli (line 13) | def test_cli():
function test_script (line 20) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_callback_override/test_tutorial003.py
function test_cli (line 13) | def test_cli():
function test_for_coverage (line 21) | def test_for_coverage():
function test_script (line 25) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_callback_override/test_tutorial004.py
function test_cli (line 13) | def test_cli():
function test_for_coverage (line 22) | def test_for_coverage():
function test_script (line 27) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_name_help/test_tutorial001.py
function test_help (line 13) | def test_help():
function test_command_help (line 21) | def test_command_help():
function test_command (line 27) | def test_command():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_name_help/test_tutorial002.py
function test_help (line 13) | def test_help():
function test_command_help (line 21) | def test_command_help():
function test_command (line 27) | def test_command():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_name_help/test_tutorial003.py
function test_help (line 13) | def test_help():
function test_command_help (line 21) | def test_command_help():
function test_command (line 27) | def test_command():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_name_help/test_tutorial004.py
function test_help (line 13) | def test_help():
function test_command_help (line 21) | def test_command_help():
function test_command (line 27) | def test_command():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_name_help/test_tutorial005.py
function test_help (line 13) | def test_help():
function test_command_help (line 21) | def test_command_help():
function test_command (line 27) | def test_command():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_name_help/test_tutorial006.py
function test_help (line 13) | def test_help():
function test_command_help (line 21) | def test_command_help():
function test_command (line 27) | def test_command():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_name_help/test_tutorial007.py
function test_help (line 13) | def test_help():
function test_command_help (line 21) | def test_command_help():
function test_command (line 27) | def test_command():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_name_help/test_tutorial008.py
function test_help (line 13) | def test_help():
function test_command_help (line 21) | def test_command_help():
function test_command (line 27) | def test_command():
function test_script (line 33) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_tutorial001.py
function mod (line 14) | def mod(monkeypatch):
function app (line 23) | def app(mod):
function test_help (line 27) | def test_help(app):
function test_help_items (line 36) | def test_help_items(app):
function test_items_create (line 46) | def test_items_create(app):
function test_items_sell (line 52) | def test_items_sell(app):
function test_items_delete (line 58) | def test_items_delete(app):
function test_help_users (line 64) | def test_help_users(app):
function test_users_create (line 74) | def test_users_create(app):
function test_users_delete (line 80) | def test_users_delete(app):
function test_scripts (line 86) | def test_scripts(mod):
FILE: tests/test_tutorial/test_subcommands/test_tutorial002.py
function test_help (line 12) | def test_help():
function test_help_items (line 21) | def test_help_items():
function test_items_create (line 31) | def test_items_create():
function test_items_sell (line 37) | def test_items_sell():
function test_items_delete (line 43) | def test_items_delete():
function test_help_users (line 49) | def test_help_users():
function test_users_create (line 59) | def test_users_create():
function test_users_delete (line 65) | def test_users_delete():
function test_script (line 71) | def test_script():
FILE: tests/test_tutorial/test_subcommands/test_tutorial003.py
function mod (line 15) | def mod(monkeypatch):
function app (line 24) | def app(mod):
function test_help (line 28) | def test_help(app):
function test_help_items (line 38) | def test_help_items(app):
function test_items_create (line 48) | def test_items_create(app):
function test_items_sell (line 58) | def test_items_sell(app):
function test_items_delete (line 68) | def test_items_delete(app):
function test_help_users (line 78) | def test_help_users(app):
function test_users_create (line 88) | def test_users_create(app):
function test_users_delete (line 98) | def test_users_delete(app):
function test_help_lands (line 108) | def test_help_lands(app):
function test_help_lands_reigns (line 117) | def test_help_lands_reigns(app):
function test_lands_reigns_conquer (line 126) | def test_lands_reigns_conquer(app):
function test_lands_reigns_destroy (line 132) | def test_lands_reigns_destroy(app):
function test_help_lands_towns (line 138) | def test_help_lands_towns(app):
function test_lands_towns_found (line 147) | def test_lands_towns_found(app):
function test_lands_towns_burn (line 153) | def test_lands_towns_burn(app):
function test_scripts (line 159) | def test_scripts(mod):
FILE: tests/test_tutorial/test_terminating/test_tutorial001.py
function test_cli (line 12) | def test_cli():
function test_existing (line 19) | def test_existing():
function test_existing_no_standalone (line 26) | def test_existing_no_standalone():
function test_script (line 34) | def test_script():
FILE: tests/test_tutorial/test_terminating/test_tutorial002.py
function test_cli (line 12) | def test_cli():
function test_root (line 18) | def test_root():
function test_script (line 24) | def test_script():
FILE: tests/test_tutorial/test_terminating/test_tutorial003.py
function test_cli (line 15) | def test_cli():
function test_root (line 21) | def test_root():
function test_root_no_standalone (line 28) | def test_root_no_standalone():
function test_root_no_rich (line 34) | def test_root_no_rich(monkeypatch: pytest.MonkeyPatch):
function test_script (line 43) | def test_script():
FILE: tests/test_tutorial/test_testing/test_app01.py
function test_app01 (line 8) | def test_app01():
function test_script (line 12) | def test_script():
FILE: tests/test_tutorial/test_testing/test_app02.py
function get_modules_path (line 16) | def get_modules_path(request: pytest.FixtureRequest) -> str:
function get_main_mod (line 21) | def get_main_mod(module_paths: str) -> ModuleType:
function get_test_mod (line 27) | def get_test_mod(module_paths: str) -> ModuleType:
function test_app02 (line 32) | def test_app02(test_mod: ModuleType):
function test_script (line 36) | def test_script(main_mod: ModuleType):
FILE: tests/test_tutorial/test_testing/test_app03.py
function test_app03 (line 8) | def test_app03():
function test_script (line 12) | def test_script():
FILE: tests/test_tutorial/test_typer_app/test_tutorial001.py
function test_no_arg (line 13) | def test_no_arg():
function test_arg (line 19) | def test_arg():
function test_script (line 25) | def test_script():
FILE: tests/test_type_conversion.py
function test_optional (line 13) | def test_optional():
function test_union_type_optional (line 32) | def test_union_type_optional():
function test_optional_tuple (line 51) | def test_optional_tuple():
function test_no_type (line 70) | def test_no_type():
class SomeEnum (line 82) | class SomeEnum(Enum):
function test_list_parameters_convert_to_lists (line 92) | def test_list_parameters_convert_to_lists(type_annotation):
function test_tuple_parameter_elements_are_converted_recursively (line 118) | def test_tuple_parameter_elements_are_converted_recursively(type_annotat...
function test_custom_parse (line 136) | def test_custom_parse():
function test_custom_click_type (line 149) | def test_custom_click_type():
FILE: tests/test_types.py
class User (line 9) | class User(str, Enum):
function hello (line 15) | def hello(name: User = User.rick) -> None:
function test_enum_choice (line 22) | def test_enum_choice() -> None:
FILE: tests/utils.py
function strip_double_spaces (line 26) | def strip_double_spaces(text: str) -> str:
function normalize_rich_output (line 30) | def normalize_rich_output(
FILE: typer/_completion_classes.py
function _sanitize_help_text (line 21) | def _sanitize_help_text(text: str) -> str:
class BashComplete (line 30) | class BashComplete(click.shell_completion.BashComplete):
method source_vars (line 34) | def source_vars(self) -> dict[str, Any]:
method get_completion_args (line 41) | def get_completion_args(self) -> tuple[list[str], str]:
method format_completion (line 53) | def format_completion(self, item: click.shell_completion.CompletionIte...
method complete (line 59) | def complete(self) -> str:
class ZshComplete (line 66) | class ZshComplete(click.shell_completion.ZshComplete):
method source_vars (line 70) | def source_vars(self) -> dict[str, Any]:
method get_completion_args (line 77) | def get_completion_args(self) -> tuple[list[str], str]:
method format_completion (line 88) | def format_completion(self, item: click.shell_completion.CompletionIte...
method complete (line 106) | def complete(self) -> str:
class FishComplete (line 117) | class FishComplete(click.shell_completion.FishComplete):
method source_vars (line 121) | def source_vars(self) -> dict[str, Any]:
method get_completion_args (line 128) | def get_completion_args(self) -> tuple[list[str], str]:
method format_completion (line 139) | def format_completion(self, item: click.shell_completion.CompletionIte...
method complete (line 152) | def complete(self) -> str:
class PowerShellComplete (line 170) | class PowerShellComplete(click.shell_completion.ShellComplete):
method source_vars (line 174) | def source_vars(self) -> dict[str, Any]:
method get_completion_args (line 181) | def get_completion_args(self) -> tuple[list[str], str]:
method format_completion (line 188) | def format_completion(self, item: click.shell_completion.CompletionIte...
function completion_init (line 192) | def completion_init() -> None:
FILE: typer/_completion_shared.py
class Shells (line 11) | class Shells(str, Enum):
function get_completion_script (line 77) | def get_completion_script(*, prog_name: str, complete_var: str, shell: s...
function install_bash (line 93) | def install_bash(*, prog_name: str, complete_var: str, shell: str) -> Path:
function install_zsh (line 119) | def install_zsh(*, prog_name: str, complete_var: str, shell: str) -> Path:
function install_fish (line 147) | def install_fish(*, prog_name: str, complete_var: str, shell: str) -> Path:
function install_powershell (line 158) | def install_powershell(*, prog_name: str, complete_var: str, shell: str)...
function install (line 201) | def install(
function _get_shell_name (line 238) | def _get_shell_name() -> str | None:
FILE: typer/_types.py
class TyperChoice (line 9) | class TyperChoice(click.Choice[ParamTypeValue]):
method normalize_choice (line 10) | def normalize_choice(
FILE: typer/_typing.py
function is_union (line 19) | def is_union(tp: type[Any] | None) -> bool:
function is_none_type (line 44) | def is_none_type(type_: Any) -> bool:
function is_callable_type (line 51) | def is_callable_type(type_: type[Any]) -> bool:
function is_literal_type (line 55) | def is_literal_type(type_: type[Any]) -> bool:
function literal_values (line 59) | def literal_values(type_: type[Any]) -> tuple[Any, ...]:
function all_literal_values (line 63) | def all_literal_values(type_: type[Any]) -> tuple[Any, ...]:
FILE: typer/cli.py
class State (line 23) | class State:
method __init__ (line 24) | def __init__(self) -> None:
function maybe_update_state (line 34) | def maybe_update_state(ctx: click.Context) -> None:
class TyperCLIGroup (line 55) | class TyperCLIGroup(typer.core.TyperGroup):
method list_commands (line 56) | def list_commands(self, ctx: click.Context) -> list[str]:
method get_command (line 60) | def get_command(self, ctx: click.Context, name: str) -> Command | None...
method invoke (line 64) | def invoke(self, ctx: click.Context) -> Any:
method maybe_add_run (line 68) | def maybe_add_run(self, ctx: click.Context) -> None:
function get_typer_from_module (line 73) | def get_typer_from_module(module: Any) -> typer.Typer | None:
function get_typer_from_state (line 121) | def get_typer_from_state() -> typer.Typer | None:
function maybe_add_run_to_cli (line 141) | def maybe_add_run_to_cli(cli: click.Group) -> None:
function print_version (line 154) | def print_version(ctx: click.Context, param: Option, value: bool) -> None:
function callback (line 162) | def callback(
function get_docs_for_click (line 187) | def get_docs_for_click(
function _parse_html (line 271) | def _parse_html(to_parse: bool, input_text: str) -> str:
function docs (line 280) | def docs(
function main (line 317) | def main() -> Any:
FILE: typer/completion.py
function get_completion_inspect_parameters (line 17) | def get_completion_inspect_parameters() -> tuple[ParamMeta, ParamMeta]:
function install_callback (line 30) | def install_callback(ctx: click.Context, param: click.Parameter, value: ...
function show_callback (line 42) | def show_callback(ctx: click.Context, param: click.Parameter, value: Any...
function _install_completion_placeholder_function (line 64) | def _install_completion_placeholder_function(
function _install_completion_no_auto_placeholder_function (line 83) | def _install_completion_no_auto_placeholder_function(
function shell_complete (line 105) | def shell_complete(
FILE: typer/core.py
function _split_opt (line 38) | def _split_opt(opt: str) -> tuple[str, str]:
function _typer_param_setup_autocompletion_compat (line 47) | def _typer_param_setup_autocompletion_compat(
function _get_default_string (line 89) | def _get_default_string(
function _extract_default_help_str (line 138) | def _extract_default_help_str(
function _main (line 156) | def _main(
class TyperArgument (line 250) | class TyperArgument(click.core.Argument):
method __init__ (line 251) | def __init__(
method _get_default_string (line 304) | def _get_default_string(
method _extract_default_help_str (line 318) | def _extract_default_help_str(
method get_help_record (line 323) | def get_help_record(self, ctx: click.Context) -> tuple[str, str] | None:
method make_metavar (line 379) | def make_metavar(self, ctx: click.Context | None = None) -> str:
method value_is_missing (line 398) | def value_is_missing(self, value: Any) -> bool:
class TyperOption (line 402) | class TyperOption(click.core.Option):
method __init__ (line 403) | def __init__(
method _get_default_string (line 471) | def _get_default_string(
method _extract_default_help_str (line 485) | def _extract_default_help_str(
method make_metavar (line 490) | def make_metavar(self, ctx: click.Context | None = None) -> str:
method get_help_record (line 493) | def get_help_record(self, ctx: click.Context) -> tuple[str, str] | None:
method value_is_missing (line 588) | def value_is_missing(self, value: Any) -> bool:
function _value_is_missing (line 592) | def _value_is_missing(param: click.Parameter, value: Any) -> bool:
function _typer_format_options (line 606) | def _typer_format_options(
function _typer_main_shell_completion (line 627) | def _typer_main_shell_completion(
class TyperCommand (line 648) | class TyperCommand(click.core.Command):
method __init__ (line 649) | def __init__(
method format_options (line 685) | def format_options(
method _main_shell_completion (line 690) | def _main_shell_completion(
method main (line 700) | def main(
method format_help (line 720) | def format_help(self, ctx: click.Context, formatter: click.HelpFormatt...
class TyperGroup (line 736) | class TyperGroup(click.core.Group):
method __init__ (line 737) | def __init__(
method format_options (line 753) | def format_options(
method _main_shell_completion (line 759) | def _main_shell_completion(
method resolve_command (line 769) | def resolve_command(
method main (line 786) | def main(
method format_help (line 806) | def format_help(self, ctx: click.Context, formatter: click.HelpFormatt...
method list_commands (line 817) | def list_commands(self, ctx: click.Context) -> list[str]:
FILE: typer/main.py
function except_hook (line 59) | def except_hook(
function get_install_completion_arguments (line 110) | def get_install_completion_arguments() -> tuple[click.Parameter, click.P...
class Typer (line 117) | class Typer:
method __init__ (line 133) | def __init__(
method callback (line 547) | def callback(
method command (line 751) | def command(
method add_typer (line 913) | def add_typer(
method __call__ (line 1131) | def __call__(self, *args: Any, **kwargs: Any) -> Any:
method _info_val_str (line 1154) | def _info_val_str(self, name: str) -> str:
function get_group (line 1161) | def get_group(typer_instance: Typer) -> TyperGroup:
function get_command (line 1171) | def get_command(typer_instance: Typer) -> click.Command:
function solve_typer_info_help (line 1209) | def solve_typer_info_help(typer_info: TyperInfo) -> str:
function solve_typer_info_defaults (line 1246) | def solve_typer_info_defaults(typer_info: TyperInfo) -> TyperInfo:
function get_group_from_info (line 1281) | def get_group_from_info(
function get_command_name (line 1359) | def get_command_name(name: str) -> str:
function get_params_convertors_ctx_param_name_from_function (line 1363) | def get_params_convertors_ctx_param_name_from_function(
function get_command_from_info (line 1382) | def get_command_from_info(
function determine_type_convertor (line 1427) | def determine_type_convertor(type_: Any) -> Callable[[Any], Any] | None:
function param_path_convertor (line 1436) | def param_path_convertor(value: str | None = None) -> Path | None:
function generate_enum_convertor (line 1444) | def generate_enum_convertor(enum: type[Enum]) -> Callable[[Any], Any]:
function generate_list_convertor (line 1457) | def generate_list_convertor(
function generate_tuple_convertor (line 1468) | def generate_tuple_convertor(
function get_callback (line 1486) | def get_callback(
function get_click_type (line 1520) | def get_click_type(
function lenient_issubclass (line 1623) | def lenient_issubclass(cls: Any, class_or_tuple: AnyType | tuple[AnyType...
function get_click_param (line 1627) | def get_click_param(
function get_param_callback (line 1790) | def get_param_callback(
function get_param_completion (line 1842) | def get_param_completion(
function run (line 1895) | def run(
function _is_macos (line 1925) | def _is_macos() -> bool:
function _is_linux_or_bsd (line 1929) | def _is_linux_or_bsd() -> bool:
function launch (line 1936) | def launch(
FILE: typer/models.py
class Context (line 26) | class Context(click.Context):
class FileText (line 36) | class FileText(io.TextIOWrapper):
class FileTextWrite (line 63) | class FileTextWrite(FileText):
class FileBinaryRead (line 90) | class FileBinaryRead(io.BufferedReader):
class FileBinaryWrite (line 121) | class FileBinaryWrite(io.BufferedWriter):
class CallbackParam (line 156) | class CallbackParam(click.Parameter):
class DefaultPlaceholder (line 165) | class DefaultPlaceholder:
method __init__ (line 173) | def __init__(self, value: Any):
method __bool__ (line 176) | def __bool__(self) -> bool:
function Default (line 185) | def Default(value: DefaultType) -> DefaultType:
class CommandInfo (line 195) | class CommandInfo:
method __init__ (line 196) | def __init__(
class TyperInfo (line 230) | class TyperInfo:
method __init__ (line 231) | def __init__(
class ParameterInfo (line 275) | class ParameterInfo:
method __init__ (line 276) | def __init__(
class OptionInfo (line 383) | class OptionInfo(ParameterInfo):
method __init__ (line 384) | def __init__(
class ArgumentInfo (line 511) | class ArgumentInfo(ParameterInfo):
method __init__ (line 512) | def __init__(
class ParamMeta (line 615) | class ParamMeta:
method __init__ (line 618) | def __init__(
class DeveloperExceptionConfig (line 630) | class DeveloperExceptionConfig:
method __init__ (line 631) | def __init__(
class TyperPath (line 643) | class TyperPath(click.Path):
method shell_complete (line 645) | def shell_complete(
FILE: typer/params.py
function Option (line 15) | def Option(
function Option (line 80) | def Option(
function Option (line 143) | def Option(
function Argument (line 1005) | def Argument(
function Argument (line 1061) | def Argument(
function Argument (line 1115) | def Argument(
FILE: typer/rich_utils.py
class OptionHighlighter (line 106) | class OptionHighlighter(RegexHighlighter):
class NegativeOptionHighlighter (line 117) | class NegativeOptionHighlighter(RegexHighlighter):
class MetavarHighlighter (line 125) | class MetavarHighlighter(RegexHighlighter):
function _has_ansi_character (line 138) | def _has_ansi_character(text: str) -> bool:
function _get_rich_console (line 142) | def _get_rich_console(stderr: bool = False) -> Console:
function _make_rich_text (line 163) | def _make_rich_text(
function _get_help_text (line 185) | def _get_help_text(
function _get_parameter_help (line 232) | def _get_parameter_help(
function _make_command_help (line 321) | def _make_command_help(
function _print_options_panel (line 348) | def _print_options_panel(
function _print_commands_panel (line 459) | def _print_commands_panel(
function rich_format_help (line 535) | def rich_format_help(
function rich_format_error (line 677) | def rich_format_error(self: click.ClickException) -> None:
function rich_abort_error (line 710) | def rich_abort_error() -> None:
function escape_before_html_export (line 716) | def escape_before_html_export(input_text: str) -> str:
function rich_to_html (line 721) | def rich_to_html(input_text: str) -> str:
function rich_render_text (line 734) | def rich_render_text(text: str) -> str:
function get_traceback (line 740) | def get_traceback(
FILE: typer/testing.py
class CliRunner (line 10) | class CliRunner(ClickCliRunner):
method invoke (line 11) | def invoke( # type: ignore
FILE: typer/utils.py
function _param_type_to_user_string (line 10) | def _param_type_to_user_string(param_type: type[ParameterInfo]) -> str:
class AnnotatedParamWithDefaultValueError (line 22) | class AnnotatedParamWithDefaultValueError(Exception):
method __init__ (line 26) | def __init__(self, argument_name: str, param_type: type[ParameterInfo]):
method __str__ (line 30) | def __str__(self) -> str:
class MixedAnnotatedAndDefaultStyleError (line 38) | class MixedAnnotatedAndDefaultStyleError(Exception):
method __init__ (line 43) | def __init__(
method __str__ (line 53) | def __str__(self) -> str:
class MultipleTyperAnnotationsError (line 65) | class MultipleTyperAnnotationsError(Exception):
method __init__ (line 68) | def __init__(self, argument_name: str):
method __str__ (line 71) | def __str__(self) -> str:
class DefaultFactoryAndDefaultValueError (line 78) | class DefaultFactoryAndDefaultValueError(Exception):
method __init__ (line 82) | def __init__(self, argument_name: str, param_type: type[ParameterInfo]):
method __str__ (line 86) | def __str__(self) -> str:
function _split_annotation_from_typer_annotations (line 94) | def _split_annotation_from_typer_annotations(
function get_params_from_function (line 107) | def get_params_from_function(func: Callable[..., Any]) -> dict[str, Para...
function parse_boolean_env_var (line 189) | def parse_boolean_env_var(env_var_value: str | None, default: bool) -> b...
Condensed preview — 725 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,352K chars).
[
{
"path": ".github/DISCUSSION_TEMPLATE/questions.yml",
"chars": 5328,
"preview": "labels: [question]\nbody:\n - type: markdown\n attributes:\n value: |\n Thanks for your interest in Typer! 🚀\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 19,
"preview": "github: [tiangolo]\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 755,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: Security Contact\n about: Please report security vulnerabilities "
},
{
"path": ".github/ISSUE_TEMPLATE/privileged.yml",
"chars": 878,
"preview": "name: Privileged\ndescription: You are @tiangolo or he asked you directly to create an issue here. If not, check the othe"
},
{
"path": ".github/dependabot.yml",
"chars": 304,
"preview": "version: 2\nupdates:\n # GitHub Actions\n - package-ecosystem: \"github-actions\"\n directory: \"/\"\n schedule:\n in"
},
{
"path": ".github/labeler.yml",
"chars": 477,
"preview": "docs:\n - all:\n - changed-files:\n - any-glob-to-any-file:\n - docs/**\n - docs_src/**\n - all-gl"
},
{
"path": ".github/workflows/add-to-project.yml",
"chars": 368,
"preview": "name: Add to Project\n\non:\n pull_request_target:\n issues:\n types:\n - opened\n - reopened\n\njobs:\n add-to-pr"
},
{
"path": ".github/workflows/build-docs.yml",
"chars": 2325,
"preview": "name: Build Docs\non:\n push:\n branches:\n - master\n pull_request:\n types:\n - opened\n - synchronize\n"
},
{
"path": ".github/workflows/conflict.yml",
"chars": 499,
"preview": "name: \"Conflict detector\"\non:\n push:\n pull_request_target:\n types: [synchronize]\n\njobs:\n main:\n permissions:\n "
},
{
"path": ".github/workflows/deploy-docs.yml",
"chars": 2807,
"preview": "name: Deploy Docs\non:\n workflow_run:\n workflows:\n - Build Docs\n types:\n - completed\n\npermissions:\n dep"
},
{
"path": ".github/workflows/issue-manager.yml",
"chars": 1869,
"preview": "name: Issue Manager\n\non:\n schedule:\n - cron: \"13 21 * * *\"\n issue_comment:\n types:\n - created\n issues:\n "
},
{
"path": ".github/workflows/labeler.yml",
"chars": 828,
"preview": "name: Labels\non:\n pull_request_target:\n types:\n - opened\n - synchronize\n - reopened\n # For label"
},
{
"path": ".github/workflows/latest-changes.yml",
"chars": 1333,
"preview": "name: Latest Changes\n\non:\n pull_request_target:\n branches:\n - master\n types:\n - closed\n workflow_dispa"
},
{
"path": ".github/workflows/pre-commit.yml",
"chars": 2969,
"preview": "name: pre-commit\n\non:\n pull_request:\n types:\n - opened\n - synchronize\n\nenv:\n # Forks and Dependabot don't"
},
{
"path": ".github/workflows/publish.yml",
"chars": 629,
"preview": "name: Publish\n\non:\n release:\n types:\n - created\n\njobs:\n publish:\n runs-on: ubuntu-latest\n permissions:\n "
},
{
"path": ".github/workflows/smokeshow.yml",
"chars": 1324,
"preview": "name: Smokeshow\n\non:\n workflow_run:\n workflows:\n - Test\n types:\n - completed\n\npermissions:\n statuses: "
},
{
"path": ".github/workflows/test-cpython-nightly.yml",
"chars": 1485,
"preview": "name: Test CPython Nightly\n\non:\n schedule:\n - cron: \"0 0 * * *\"\n workflow_dispatch:\n\nenv:\n UV_NO_SYNC: true\n\njobs:"
},
{
"path": ".github/workflows/test-redistribute.yml",
"chars": 1671,
"preview": "name: Test Redistribute\n\non:\n push:\n branches:\n - master\n pull_request:\n types:\n - opened\n - sync"
},
{
"path": ".github/workflows/test.yml",
"chars": 3789,
"preview": "name: Test\n\non:\n push:\n branches:\n - master\n pull_request:\n types:\n - opened\n - synchronize\n sch"
},
{
"path": ".gitignore",
"chars": 118,
"preview": ".vscode\n*.pyc\n__pycache__\n.venv*\nenv\ndist\n.mypy_cache\n.idea\nsite\nhtmlcov\n.pytest_cache\ncoverage.xml\n.coverage*\n.cache\n"
},
{
"path": ".pre-commit-config.yaml",
"chars": 1417,
"preview": "# See https://pre-commit.com for more information\n# See https://pre-commit.com/hooks.html for more hooks\nrepos:\n- repo"
},
{
"path": ".python-version",
"chars": 5,
"preview": "3.10\n"
},
{
"path": "CITATION.cff",
"chars": 565,
"preview": "# This CITATION.cff file was generated with cffinit.\n# Visit https://bit.ly/cffinit to generate yours today!\n\ncff-versio"
},
{
"path": "CONTRIBUTING.md",
"chars": 125,
"preview": "Please read the [Development - Contributing](https://typer.tiangolo.com/contributing/) guidelines in the documentation s"
},
{
"path": "LICENSE",
"chars": 1084,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2019 Sebastián Ramírez\n\nPermission is hereby granted, free of charge, to any person"
},
{
"path": "README.md",
"chars": 11769,
"preview": "<p align=\"center\">\n <a href=\"https://typer.tiangolo.com\"><img src=\"https://typer.tiangolo.com/img/logo-margin/logo-marg"
},
{
"path": "SECURITY.md",
"chars": 1148,
"preview": "# Security Policy\n\nSecurity is very important for Typer and its community. 🔒\n\nLearn more about it below. 👇\n\n## Versions\n"
},
{
"path": "data/members.yml",
"chars": 64,
"preview": "members:\n- login: tiangolo\n- login: svlandeg\n- login: patrick91\n"
},
{
"path": "docs/about/index.md",
"chars": 63,
"preview": "# About\n\nAbout **Typer**, its design, inspiration, and more. 🤓\n"
},
{
"path": "docs/alternatives.md",
"chars": 4930,
"preview": "# Alternatives, Inspiration and Comparisons\n\nWhat inspired **Typer**, how it compares to other alternatives and what it "
},
{
"path": "docs/contributing.md",
"chars": 9314,
"preview": "# Development - Contributing\n\nFirst, you might want to see the basic ways to [help Typer and get help](help-typer.md){.i"
},
{
"path": "docs/css/custom.css",
"chars": 4661,
"preview": "/* Fira Code, including characters used by Rich output, like the \"heavy right-pointing angle bracket ornament\", not incl"
},
{
"path": "docs/css/termynal.css",
"chars": 2271,
"preview": "/**\n * termynal.js\n *\n * @author Ines Montani <ines@ines.io>\n * @version 0.0.1\n * @license MIT\n */\n\n:root {\n --color-"
},
{
"path": "docs/environment-variables.md",
"chars": 8269,
"preview": "# Environment Variables\n\nBefore we jump into **Typer** code, let's cover a bit some of the **basics** that we'll need to"
},
{
"path": "docs/features.md",
"chars": 3700,
"preview": "# Features\n\n## Design based on **FastAPI**\n\n<a href=\"https://fastapi.tiangolo.com\" target=\"_blank\"><img src=\"https://fas"
},
{
"path": "docs/help-typer.md",
"chars": 12026,
"preview": "# Help Typer - Get Help\n\nAre you liking **Typer**?\n\nWould you like to help Typer, other users, and the author?\n\nOr would"
},
{
"path": "docs/index.md",
"chars": 11997,
"preview": "<style>\n.md-content .md-typeset h1 { display: none; }\n</style>\n\n<p align=\"center\">\n <a href=\"https://typer.tiangolo.com"
},
{
"path": "docs/js/custom.js",
"chars": 5741,
"preview": "function setupTermynal() {\n document.querySelectorAll(\".use-termynal\").forEach(node => {\n node.style.display ="
},
{
"path": "docs/js/termynal.js",
"chars": 9523,
"preview": "/**\n * termynal.js\n * A lightweight, modern and extensible animated terminal window, using\n * async/await.\n *\n * @author"
},
{
"path": "docs/management-tasks.md",
"chars": 8658,
"preview": "# Repository Management Tasks\n\nThese are the tasks that can be performed to manage the Typer repository by [team members"
},
{
"path": "docs/management.md",
"chars": 1822,
"preview": "# Repository Management\n\nHere's a short description of how the Typer repository is managed and maintained.\n\n## Owner\n\nI,"
},
{
"path": "docs/overrides/main.html",
"chars": 26,
"preview": "{% extends \"base.html\" %}\n"
},
{
"path": "docs/reference/context.md",
"chars": 1005,
"preview": "# Context\n\nEvery app has a special internal object that keeps track of state relevant to the script's execution.\nFor som"
},
{
"path": "docs/reference/file_objects.md",
"chars": 506,
"preview": "# File objects\n\nWhen you want to declare some types of files, you can use `Path`.\nHowever, in some cases you may need to"
},
{
"path": "docs/reference/index.md",
"chars": 277,
"preview": "# Reference\n\nHere's the reference or code API, the classes, functions, parameters, attributes, and\nall the Typer parts y"
},
{
"path": "docs/reference/parameters.md",
"chars": 703,
"preview": "# Parameters\n\nParameters to our command line interface may be both [CLI Options](https://typer.tiangolo.com/tutorial/opt"
},
{
"path": "docs/reference/run_launch.md",
"chars": 159,
"preview": "# `run` and `launch`\n\nThese two functions can be imported from `typer` directly:\n\n```python\nfrom typer import launch, ru"
},
{
"path": "docs/reference/typer.md",
"chars": 334,
"preview": "# `Typer` class\n\nHere's the reference information for the `Typer` class, with all its parameters, attributes and methods"
},
{
"path": "docs/release-notes.md",
"chars": 111072,
"preview": "# Release Notes\n\n## Latest Changes\n\n### Refactors\n\n* 🎨 Ensure `ty` runs without errors. PR [#1628](https://github.com/fa"
},
{
"path": "docs/resources/index.md",
"chars": 101,
"preview": "# Resources\n\nAdditional resources, how to **help** and get help, how to **contribute**, and more. ✈️\n"
},
{
"path": "docs/tutorial/app-dir.md",
"chars": 1459,
"preview": "# CLI Application Directory\n\nYou can get the application directory where you can, for example, save configuration files "
},
{
"path": "docs/tutorial/arguments/default.md",
"chars": 2230,
"preview": "# CLI Arguments with Default\n\nWe can also use the same `typer.Argument()` to set a default value.\n\nThat way the *CLI arg"
},
{
"path": "docs/tutorial/arguments/envvar.md",
"chars": 2605,
"preview": "# CLI Arguments with Environment Variables\n\nYou can also configure a *CLI argument* to read a value from an environment "
},
{
"path": "docs/tutorial/arguments/help.md",
"chars": 7977,
"preview": "# CLI Arguments with Help\n\nIn the *First Steps* section you saw how to add help for a CLI app/command by adding it to a "
},
{
"path": "docs/tutorial/arguments/index.md",
"chars": 190,
"preview": "# CLI Arguments\n\nIn the next few sections we'll see some ways to modify how *CLI arguments* work.\n\nWe'll create optional"
},
{
"path": "docs/tutorial/arguments/optional.md",
"chars": 6616,
"preview": "# Optional CLI Arguments\n\nWe said before that *by default*:\n\n* *CLI options* are **optional**\n* *CLI arguments* are **re"
},
{
"path": "docs/tutorial/arguments/other-uses.md",
"chars": 177,
"preview": "# Other uses\n\n`typer.Argument()` has several other use cases. Such as for data validation, to enable other features, etc"
},
{
"path": "docs/tutorial/commands/arguments.md",
"chars": 1088,
"preview": "# Command CLI Arguments\n\nThe same way as with a CLI application with a single command, subcommands (or just \"commands\") "
},
{
"path": "docs/tutorial/commands/callback.md",
"chars": 3993,
"preview": "# Typer Callback\n\nWhen you create an `app = typer.Typer()` it works as a group of commands.\n\nAnd you can create multiple"
},
{
"path": "docs/tutorial/commands/context.md",
"chars": 3133,
"preview": "# Using the Context\n\nWhen you create a **Typer** application it always has a special, hidden object underneath called th"
},
{
"path": "docs/tutorial/commands/help.md",
"chars": 27338,
"preview": "# Command Help\n\nThe same as before, you can add help for the commands in the docstrings and the *CLI options*.\n\nAnd the "
},
{
"path": "docs/tutorial/commands/index.md",
"chars": 4789,
"preview": "# Commands\n\nWe have seen how to create a CLI program with possibly several *CLI options* and *CLI arguments*.\n\nBut **Typ"
},
{
"path": "docs/tutorial/commands/name.md",
"chars": 1386,
"preview": "# Custom Command Name\n\nBy default, the command names are generated from the function name.\n\nSo, if your function is some"
},
{
"path": "docs/tutorial/commands/one-or-multiple.md",
"chars": 3416,
"preview": "# One or Multiple Commands\n\nYou might have noticed that if you create a single command, as in the following example:\n\n{*"
},
{
"path": "docs/tutorial/commands/options.md",
"chars": 2056,
"preview": "# Command CLI Options\n\nCommands can also have their own *CLI options*.\n\nIn fact, each command can have different *CLI ar"
},
{
"path": "docs/tutorial/exceptions.md",
"chars": 23095,
"preview": "# Exceptions and Errors\n\nWhen your code has errors and you run it, it will show the error and an exception.\n\nTyper does "
},
{
"path": "docs/tutorial/first-steps.md",
"chars": 19233,
"preview": "# First Steps\n\n## The simplest example\n\nThe simplest **Typer** file could look like this:\n\n{* docs_src/first_steps/tutor"
},
{
"path": "docs/tutorial/index.md",
"chars": 2350,
"preview": "# Learn\n\nLearn how to use **Typer** in this step-by-step **Tutorial** - **User Guide**.\n\nIt covers everything you need t"
},
{
"path": "docs/tutorial/install.md",
"chars": 413,
"preview": "# Install **Typer**\n\nThe first step is to install **Typer**.\n\nFirst, make sure you create your [virtual environment](../"
},
{
"path": "docs/tutorial/launch.md",
"chars": 966,
"preview": "# Launching Applications\n\nYou can launch applications from your CLI program with `typer.launch()`.\n\nIt will launch the a"
},
{
"path": "docs/tutorial/multiple-values/arguments-with-multiple-values.md",
"chars": 1715,
"preview": "# CLI Arguments with Multiple Values\n\n*CLI arguments* can also receive multiple values.\n\nYou can define the type of a *C"
},
{
"path": "docs/tutorial/multiple-values/index.md",
"chars": 152,
"preview": "# Multiple Values\n\nThere are several ways to declare multiple values for *CLI options* and *CLI arguments*.\n\nWe'll see t"
},
{
"path": "docs/tutorial/multiple-values/multiple-options.md",
"chars": 1267,
"preview": "# Multiple CLI Options\n\nYou can declare a *CLI option* that can be used multiple times, and then get all the values.\n\nFo"
},
{
"path": "docs/tutorial/multiple-values/options-with-multiple-values.md",
"chars": 1880,
"preview": "# CLI Options with Multiple Values\n\nYou can also declare a *CLI option* that takes several values of different types.\n\nY"
},
{
"path": "docs/tutorial/one-file-per-command.md",
"chars": 5093,
"preview": "# One File Per Command\n\nWhen your CLI application grows, you can split it into multiple files and modules. This pattern "
},
{
"path": "docs/tutorial/options/callback-and-context.md",
"chars": 6481,
"preview": "# CLI Option Callback and Context\n\nIn some occasions you might want to have some custom logic for a specific *CLI parame"
},
{
"path": "docs/tutorial/options/help.md",
"chars": 5680,
"preview": "# CLI Options with Help\n\nYou already saw how to add a help text for *CLI arguments* with the `help` parameter.\n\nLet's no"
},
{
"path": "docs/tutorial/options/index.md",
"chars": 217,
"preview": "# CLI Options\n\nIn the next short sections we will see how to modify *CLI options* using `typer.Option()`.\n\n`typer.Option"
},
{
"path": "docs/tutorial/options/name.md",
"chars": 7799,
"preview": "# CLI Option Name\n\nBy default **Typer** will create a *CLI option* name from the function parameter.\n\nSo, if you have a "
},
{
"path": "docs/tutorial/options/password.md",
"chars": 1313,
"preview": "# Password CLI Option and Confirmation Prompt\n\nApart from having a prompt, you can make a *CLI option* have a `confirmat"
},
{
"path": "docs/tutorial/options/prompt.md",
"chars": 1869,
"preview": "# CLI Option Prompt\n\nIt's also possible to, instead of just showing an error, ask for the missing value with `prompt=Tru"
},
{
"path": "docs/tutorial/options/required.md",
"chars": 2038,
"preview": "# Required CLI Options\n\nWe said before that *by default*:\n\n* *CLI options* are **optional**\n* *CLI arguments* are **requ"
},
{
"path": "docs/tutorial/options/version.md",
"chars": 3244,
"preview": "# Version CLI Option, `is_eager`\n\nYou could use a callback to implement a `--version` *CLI option*.\n\nIt would show the v"
},
{
"path": "docs/tutorial/options-autocompletion.md",
"chars": 12183,
"preview": "# CLI Option autocompletion\n\nAs you have seen, apps built with **Typer** have completion in your shell that works when y"
},
{
"path": "docs/tutorial/package.md",
"chars": 17521,
"preview": "# Building a Package\n\nWhen you create a CLI program with **Typer** you probably want to create your own Python package.\n"
},
{
"path": "docs/tutorial/parameter-types/bool.md",
"chars": 3313,
"preview": "# Boolean CLI Options\n\nWe have seen some examples of *CLI options* with `bool`, and how **Typer** creates `--something` "
},
{
"path": "docs/tutorial/parameter-types/custom-types.md",
"chars": 705,
"preview": "# Custom Types\n\nYou can easily use your own custom types in your **Typer** applications.\n\nThe way to do it is by providi"
},
{
"path": "docs/tutorial/parameter-types/datetime.md",
"chars": 2239,
"preview": "# DateTime\n\nYou can specify a *CLI parameter* as a Python <a href=\"https://docs.python.org/3/library/datetime.html\" clas"
},
{
"path": "docs/tutorial/parameter-types/enum.md",
"chars": 3336,
"preview": "# Enum - Choices\n\nTo define a *CLI parameter* that can take a value from a predefined set of values you can use a standa"
},
{
"path": "docs/tutorial/parameter-types/file.md",
"chars": 6263,
"preview": "# File\n\nApart from `Path` *CLI parameters* you can also declare some types of \"files\".\n\n/// tip\n\nIn most of the cases yo"
},
{
"path": "docs/tutorial/parameter-types/index.md",
"chars": 1770,
"preview": "# CLI Parameter Types\n\nYou can use several data types for the *CLI options* and *CLI arguments*, and you can add data va"
},
{
"path": "docs/tutorial/parameter-types/number.md",
"chars": 2991,
"preview": "# Number\n\nYou can define numeric validations with `max` and `min` values for `int` and `float` *CLI parameters*:\n\n{* doc"
},
{
"path": "docs/tutorial/parameter-types/path.md",
"chars": 3169,
"preview": "# Path\n\nYou can declare a *CLI parameter* to be a standard Python <a href=\"https://docs.python.org/3/library/pathlib.htm"
},
{
"path": "docs/tutorial/parameter-types/uuid.md",
"chars": 1692,
"preview": "# UUID\n\n/// info\n\nA UUID is a <a href=\"https://en.wikipedia.org/wiki/Universally_unique_identifier\" class=\"external-link"
},
{
"path": "docs/tutorial/printing.md",
"chars": 9459,
"preview": "# Printing and Colors\n\nYou can use the normal `print()` to show information on the screen:\n\n{* docs_src/typer_app/tutori"
},
{
"path": "docs/tutorial/progressbar.md",
"chars": 5833,
"preview": "# Progress Bar\n\nIf you are executing an operation that can take some time, you can inform it to the user. 🤓\n\n## Progress"
},
{
"path": "docs/tutorial/prompt.md",
"chars": 1756,
"preview": "# Ask with Prompt\n\nWhen you need to ask the user for info interactively you should normally use [*CLI Option*s with Prom"
},
{
"path": "docs/tutorial/subcommands/add-typer.md",
"chars": 3746,
"preview": "# Add Typer\n\nWe'll start with the core idea.\n\nTo add a `typer.Typer()` app inside of another.\n\n## Manage items\n\nLet's im"
},
{
"path": "docs/tutorial/subcommands/callback-override.md",
"chars": 2947,
"preview": "# Sub-Typer Callback Override\n\nWhen creating a **Typer** app you can define a callback function, it always executes and "
},
{
"path": "docs/tutorial/subcommands/index.md",
"chars": 1230,
"preview": "# SubCommands - Command Groups\n\nYou read before how to create a program with [Commands](../commands/index.md){.internal-"
},
{
"path": "docs/tutorial/subcommands/name-and-help.md",
"chars": 11841,
"preview": "# SubCommand Name and Help\n\nWhen adding a Typer app to another we have seen how to set the `name` to use for the command"
},
{
"path": "docs/tutorial/subcommands/nested-subcommands.md",
"chars": 5997,
"preview": "# Nested SubCommands\n\nWe'll now see how these same ideas can be extended for deeply nested commands.\n\nLet's imagine that"
},
{
"path": "docs/tutorial/subcommands/single-file.md",
"chars": 2688,
"preview": "# SubCommands in a Single File\n\nIn some cases, it's possible that your application code needs to live on a single file.\n"
},
{
"path": "docs/tutorial/terminating.md",
"chars": 2961,
"preview": "# Terminating\n\nThere are some cases where you might want to terminate a command at some point, and stop all subsequent e"
},
{
"path": "docs/tutorial/testing.md",
"chars": 6048,
"preview": "# Testing\n\nTesting **Typer** applications is very easy with <a href=\"https://docs.pytest.org/en/latest/\" class=\"external"
},
{
"path": "docs/tutorial/typer-app.md",
"chars": 3159,
"preview": "# Typer App\n\n## Explicit application\n\nSo far, you have seen how to create a single function and then pass that function "
},
{
"path": "docs/tutorial/typer-command.md",
"chars": 8015,
"preview": "# `typer` command\n\nThe `typer` command provides ✨ completion ✨ in the Terminal for your own small scripts. Even if they "
},
{
"path": "docs/virtual-environments.md",
"chars": 22146,
"preview": "# Virtual Environments\n\nWhen you work in Python projects you probably should use a **virtual environment** (or a similar"
},
{
"path": "docs_src/app_dir/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/app_dir/tutorial001_py310.py",
"chars": 336,
"preview": "from pathlib import Path\n\nimport typer\n\nAPP_NAME = \"my-super-cli-app\"\n\napp = typer.Typer()\n\n\n@app.command()\ndef main():\n"
},
{
"path": "docs_src/arguments/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/arguments/default/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/arguments/default/tutorial001_an_py310.py",
"chars": 213,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: Annotated[str, typer.Arg"
},
{
"path": "docs_src/arguments/default/tutorial001_py310.py",
"chars": 170,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(\"Wade Wilson\")):\n print(f\"Hell"
},
{
"path": "docs_src/arguments/default/tutorial002_an_py310.py",
"chars": 317,
"preview": "import random\nfrom typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\ndef get_name():\n return random.choice"
},
{
"path": "docs_src/arguments/default/tutorial002_py310.py",
"chars": 278,
"preview": "import random\n\nimport typer\n\napp = typer.Typer()\n\n\ndef get_name():\n return random.choice([\"Deadpool\", \"Rick\", \"Morty\""
},
{
"path": "docs_src/arguments/envvar/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/arguments/envvar/tutorial001_an_py310.py",
"chars": 232,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: Annotated[str, typer.Arg"
},
{
"path": "docs_src/arguments/envvar/tutorial001_py310.py",
"chars": 191,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(\"World\", envvar=\"AWESOME_NAME\")):"
},
{
"path": "docs_src/arguments/envvar/tutorial002_an_py310.py",
"chars": 253,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(\n name: Annotated[str, type"
},
{
"path": "docs_src/arguments/envvar/tutorial002_py310.py",
"chars": 205,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(\"World\", envvar=[\"AWESOME_NAME\", "
},
{
"path": "docs_src/arguments/envvar/tutorial003_an_py310.py",
"chars": 272,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(\n name: Annotated[\n "
},
{
"path": "docs_src/arguments/envvar/tutorial003_py310.py",
"chars": 210,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(\"World\", envvar=\"AWESOME_NAME\", s"
},
{
"path": "docs_src/arguments/help/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/arguments/help/tutorial001_an_py310.py",
"chars": 233,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: Annotated[str, typer.Arg"
},
{
"path": "docs_src/arguments/help/tutorial001_py310.py",
"chars": 198,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(..., help=\"The name of the user t"
},
{
"path": "docs_src/arguments/help/tutorial002_an_py310.py",
"chars": 292,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: Annotated[str, typer.Arg"
},
{
"path": "docs_src/arguments/help/tutorial002_py310.py",
"chars": 257,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(..., help=\"The name of the user t"
},
{
"path": "docs_src/arguments/help/tutorial003_an_py310.py",
"chars": 285,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: Annotated[str, typer.Arg"
},
{
"path": "docs_src/arguments/help/tutorial003_py310.py",
"chars": 244,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(\"World\", help=\"Who to greet\")):\n "
},
{
"path": "docs_src/arguments/help/tutorial004_an_py310.py",
"chars": 326,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(\n name: Annotated[\n "
},
{
"path": "docs_src/arguments/help/tutorial004_py310.py",
"chars": 264,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(\"World\", help=\"Who to greet\", sho"
},
{
"path": "docs_src/arguments/help/tutorial005_an_py310.py",
"chars": 330,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(\n name: Annotated[\n "
},
{
"path": "docs_src/arguments/help/tutorial005_py310.py",
"chars": 258,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(\n name: str = typer.Argument(\n \"Wade Wilson\", help"
},
{
"path": "docs_src/arguments/help/tutorial006_an_py310.py",
"chars": 227,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: Annotated[str, typer.Arg"
},
{
"path": "docs_src/arguments/help/tutorial006_py310.py",
"chars": 186,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(\"World\", metavar=\"✨username✨\")):\n"
},
{
"path": "docs_src/arguments/help/tutorial007_an_py310.py",
"chars": 539,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(\n name: Annotated[str, type"
},
{
"path": "docs_src/arguments/help/tutorial007_py310.py",
"chars": 473,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(\n name: str = typer.Argument(..., help=\"Who to greet\"),\n "
},
{
"path": "docs_src/arguments/help/tutorial008_an_py310.py",
"chars": 277,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: Annotated[str, typer.Arg"
},
{
"path": "docs_src/arguments/help/tutorial008_py310.py",
"chars": 236,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(\"World\", hidden=True)):\n \"\"\"\n "
},
{
"path": "docs_src/arguments/optional/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/arguments/optional/tutorial000_an_py310.py",
"chars": 171,
"preview": "from typing import Annotated\n\nimport typer\n\n\ndef main(name: Annotated[str, typer.Argument()]):\n print(f\"Hello {name}\""
},
{
"path": "docs_src/arguments/optional/tutorial000_py310.py",
"chars": 131,
"preview": "import typer\n\n\ndef main(name: str = typer.Argument()):\n print(f\"Hello {name}\")\n\n\nif __name__ == \"__main__\":\n typer"
},
{
"path": "docs_src/arguments/optional/tutorial001_an_py310.py",
"chars": 197,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: Annotated[str, typer.Arg"
},
{
"path": "docs_src/arguments/optional/tutorial001_py310.py",
"chars": 157,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument()):\n print(f\"Hello {name}\")\n\n\n"
},
{
"path": "docs_src/arguments/optional/tutorial002_an_py310.py",
"chars": 208,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: Annotated[str, typer.Arg"
},
{
"path": "docs_src/arguments/optional/tutorial002_py310.py",
"chars": 173,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=\"World\")):\n print(f\"He"
},
{
"path": "docs_src/arguments/optional/tutorial003_py310.py",
"chars": 168,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = typer.Argument(default=...)):\n print(f\"Hello "
},
{
"path": "docs_src/commands/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/commands/arguments/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/commands/arguments/tutorial001_py310.py",
"chars": 241,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create(username: str):\n print(f\"Creating user: {username}\")\n\n\n"
},
{
"path": "docs_src/commands/callback/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/commands/callback/tutorial001_py310.py",
"chars": 721,
"preview": "import typer\n\napp = typer.Typer()\nstate = {\"verbose\": False}\n\n\n@app.command()\ndef create(username: str):\n if state[\"v"
},
{
"path": "docs_src/commands/callback/tutorial002_py310.py",
"chars": 216,
"preview": "import typer\n\n\ndef callback():\n print(\"Running a command\")\n\n\napp = typer.Typer(callback=callback)\n\n\n@app.command()\nde"
},
{
"path": "docs_src/commands/callback/tutorial003_py310.py",
"chars": 304,
"preview": "import typer\n\n\ndef callback():\n print(\"Running a command\")\n\n\napp = typer.Typer(callback=callback)\n\n\n@app.callback()\nd"
},
{
"path": "docs_src/commands/callback/tutorial004_py310.py",
"chars": 315,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.callback()\ndef callback():\n \"\"\"\n Manage users CLI app.\n\n Use it with t"
},
{
"path": "docs_src/commands/context/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/commands/context/tutorial001_py310.py",
"chars": 411,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create(username: str):\n print(f\"Creating user: {username}\")\n\n\n"
},
{
"path": "docs_src/commands/context/tutorial002_py310.py",
"chars": 390,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create(username: str):\n print(f\"Creating user: {username}\")\n\n\n"
},
{
"path": "docs_src/commands/context/tutorial003_py310.py",
"chars": 451,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create(username: str):\n print(f\"Creating user: {username}\")\n\n\n"
},
{
"path": "docs_src/commands/context/tutorial004_py310.py",
"chars": 277,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command(\n context_settings={\"allow_extra_args\": True, \"ignore_unknown_option"
},
{
"path": "docs_src/commands/help/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/commands/help/tutorial001_an_py310.py",
"chars": 1291,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer(help=\"Awesome CLI user manager.\")\n\n\n@app.command()\ndef cre"
},
{
"path": "docs_src/commands/help/tutorial001_py310.py",
"chars": 1197,
"preview": "import typer\n\napp = typer.Typer(help=\"Awesome CLI user manager.\")\n\n\n@app.command()\ndef create(username: str):\n \"\"\"\n "
},
{
"path": "docs_src/commands/help/tutorial002_py310.py",
"chars": 439,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command(help=\"Create a new user with USERNAME.\")\ndef create(username: str):\n "
},
{
"path": "docs_src/commands/help/tutorial003_py310.py",
"chars": 386,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create(username: str):\n \"\"\"\n Create a user.\n \"\"\"\n pri"
},
{
"path": "docs_src/commands/help/tutorial004_an_py310.py",
"chars": 892,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command()\ndef create(\n "
},
{
"path": "docs_src/commands/help/tutorial004_py310.py",
"chars": 827,
"preview": "import typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command()\ndef create(\n username: str = typer.Argument"
},
{
"path": "docs_src/commands/help/tutorial005_an_py310.py",
"chars": 844,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"markdown\")\n\n\n@app.command()\ndef create(\n"
},
{
"path": "docs_src/commands/help/tutorial005_py310.py",
"chars": 786,
"preview": "import typer\n\napp = typer.Typer(rich_markup_mode=\"markdown\")\n\n\n@app.command()\ndef create(username: str = typer.Argument("
},
{
"path": "docs_src/commands/help/tutorial006_py310.py",
"chars": 1146,
"preview": "import typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command()\ndef create(username: str):\n \"\"\"\n [green]"
},
{
"path": "docs_src/commands/help/tutorial007_an_py310.py",
"chars": 1150,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command()\ndef create(\n "
},
{
"path": "docs_src/commands/help/tutorial007_py310.py",
"chars": 1004,
"preview": "import typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command()\ndef create(\n username: str = typer.Argument"
},
{
"path": "docs_src/commands/help/tutorial008_py310.py",
"chars": 293,
"preview": "import typer\n\napp = typer.Typer(rich_markup_mode=\"rich\")\n\n\n@app.command(epilog=\"Made with :heart: in [blue]Venus[/blue]\""
},
{
"path": "docs_src/commands/index/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/commands/index/tutorial002_py310.py",
"chars": 215,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create():\n print(\"Creating user: Hiro Hamada\")\n\n\n@app.command("
},
{
"path": "docs_src/commands/index/tutorial003_py310.py",
"chars": 235,
"preview": "import typer\n\napp = typer.Typer(no_args_is_help=True)\n\n\n@app.command()\ndef create():\n print(\"Creating user: Hiro Hama"
},
{
"path": "docs_src/commands/index/tutorial004_py310.py",
"chars": 215,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef delete():\n print(\"Deleting user: Hiro Hamada\")\n\n\n@app.command("
},
{
"path": "docs_src/commands/index/tutorial005_py310.py",
"chars": 216,
"preview": "import typer\n\napp = typer.Typer(suggest_commands=True)\n\n\n@app.command()\ndef create():\n typer.echo(\"Creating...\")\n\n\n@a"
},
{
"path": "docs_src/commands/name/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/commands/name/tutorial001_py310.py",
"chars": 275,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command(\"create\")\ndef cli_create_user(username: str):\n print(f\"Creating user"
},
{
"path": "docs_src/commands/one_or_multiple/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/commands/one_or_multiple/tutorial001_py310.py",
"chars": 187,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create():\n print(\"Creating user: Hiro Hamada\")\n\n\n@app.callback"
},
{
"path": "docs_src/commands/one_or_multiple/tutorial002_py310.py",
"chars": 287,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create():\n print(\"Creating user: Hiro Hamada\")\n\n\n@app.callback"
},
{
"path": "docs_src/commands/options/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/commands/options/tutorial001_an_py310.py",
"chars": 762,
"preview": "from typing import Annotated\n\nimport typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create(username: str):\n print(f\""
},
{
"path": "docs_src/commands/options/tutorial001_py310.py",
"chars": 708,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef create(username: str):\n print(f\"Creating user: {username}\")\n\n\n"
},
{
"path": "docs_src/exceptions/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/exceptions/tutorial001_py310.py",
"chars": 141,
"preview": "import typer\n\napp = typer.Typer()\n\n\n@app.command()\ndef main(name: str = \"morty\"):\n print(name + 3)\n\n\nif __name__ == \""
},
{
"path": "docs_src/exceptions/tutorial002_py310.py",
"chars": 175,
"preview": "import typer\n\napp = typer.Typer(pretty_exceptions_show_locals=True)\n\n\n@app.command()\ndef main(name: str = \"morty\"):\n "
},
{
"path": "docs_src/exceptions/tutorial003_py310.py",
"chars": 170,
"preview": "import typer\n\napp = typer.Typer(pretty_exceptions_short=False)\n\n\n@app.command()\ndef main(name: str = \"morty\"):\n print"
},
{
"path": "docs_src/exceptions/tutorial004_py310.py",
"chars": 171,
"preview": "import typer\n\napp = typer.Typer(pretty_exceptions_enable=False)\n\n\n@app.command()\ndef main(name: str = \"morty\"):\n prin"
},
{
"path": "docs_src/first_steps/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs_src/first_steps/tutorial001_py310.py",
"chars": 101,
"preview": "import typer\n\n\ndef main():\n print(\"Hello World\")\n\n\nif __name__ == \"__main__\":\n typer.run(main)\n"
},
{
"path": "docs_src/first_steps/tutorial002_py310.py",
"chars": 112,
"preview": "import typer\n\n\ndef main(name: str):\n print(f\"Hello {name}\")\n\n\nif __name__ == \"__main__\":\n typer.run(main)\n"
},
{
"path": "docs_src/first_steps/tutorial003_py310.py",
"chars": 138,
"preview": "import typer\n\n\ndef main(name: str, lastname: str):\n print(f\"Hello {name} {lastname}\")\n\n\nif __name__ == \"__main__\":\n "
},
{
"path": "docs_src/first_steps/tutorial004_py310.py",
"chars": 239,
"preview": "import typer\n\n\ndef main(name: str, lastname: str, formal: bool = False):\n if formal:\n print(f\"Good day Ms. {na"
},
{
"path": "docs_src/first_steps/tutorial005_py310.py",
"chars": 244,
"preview": "import typer\n\n\ndef main(name: str, lastname: str = \"\", formal: bool = False):\n if formal:\n print(f\"Good day Ms"
},
{
"path": "docs_src/first_steps/tutorial006_py310.py",
"chars": 358,
"preview": "import typer\n\n\ndef main(name: str, lastname: str = \"\", formal: bool = False):\n \"\"\"\n Say hi to NAME, optionally wit"
},
{
"path": "docs_src/launch/__init__.py",
"chars": 0,
"preview": ""
}
]
// ... and 525 more files (download for full content)
About this extraction
This page contains the full source code of the fastapi/typer GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 725 files (1.2 MB), approximately 333.6k tokens, and a symbol index with 1520 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.