Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Add support for PEP-593 Annotated for specifying options and arguments #584

Merged
merged 12 commits into from
May 2, 2023
Merged
3 changes: 3 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ source =
tests
docs_src

omit =
typer/_typing.py

parallel = True
context = '${CONTEXT}'

Expand Down
39 changes: 32 additions & 7 deletions docs/tutorial/arguments/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,20 @@ That way the *CLI argument* will be optional *and also* have a default value.

We can also use `typer.Argument()` to make a *CLI argument* have a default value other than `None`:

```Python hl_lines="4"
{!../docs_src/arguments/default/tutorial001.py!}
```
=== "Python 3.6+"

```Python hl_lines="5"
{!> ../docs_src/arguments/default/tutorial001_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4"
{!> ../docs_src/arguments/default/tutorial001.py!}
```

!!! tip
Because now the value will be a `str` passed by the user or the default value of `"Wade Wilson"` which is also a `str`, we know the value will never be `None`, so we don't have to (and shouldn't) use `Optional[str]`.
Expand Down Expand Up @@ -49,16 +60,30 @@ Hello Camila

## Dynamic default value

And we can even make the default value be dynamically generated by passing a function as the first function argument:
And we can even make the default value be dynamically generated by passing a function as the `default_factory` argument:

```Python hl_lines="6 7 10"
{!../docs_src/arguments/default/tutorial002.py!}
```
=== "Python 3.6+"

```Python hl_lines="7-8 11"
{!> ../docs_src/arguments/default/tutorial002_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="6-7 10"
{!> ../docs_src/arguments/default/tutorial002.py!}
```

In this case, we created the function `get_name` that will just return a random `str` each time.

And we pass it as the first function argument to `typer.Argument()`.

!!! tip
The word "factory" in `default_factory` is just a fancy way of saying "function that will create the default value".

Check it:

<div class="termy">
Expand Down
51 changes: 42 additions & 9 deletions docs/tutorial/arguments/envvar.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ You can also configure a *CLI argument* to read a value from an environment vari

To do that, use the `envvar` parameter for `typer.Argument()`:

```Python hl_lines="4"
{!../docs_src/arguments/envvar/tutorial001.py!}
```
=== "Python 3.6+"

```Python hl_lines="5"
{!> ../docs_src/arguments/envvar/tutorial001_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4"
{!> ../docs_src/arguments/envvar/tutorial001.py!}
```

In this case, the *CLI argument* `name` will have a default value of `"World"`, but will also read any value passed to the environment variable `AWESOME_NAME` if no value is provided in the command line:

Expand Down Expand Up @@ -51,9 +62,20 @@ Hello Mr. Czernobog

You are not restricted to a single environment variable, you can declare a list of environment variables that could be used to get a value if it was not passed in the command line:

```Python hl_lines="4"
{!../docs_src/arguments/envvar/tutorial002.py!}
```
=== "Python 3.6+"

```Python hl_lines="6"
{!> ../docs_src/arguments/envvar/tutorial002_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4"
{!> ../docs_src/arguments/envvar/tutorial002.py!}
```

Check it:

Expand Down Expand Up @@ -90,9 +112,20 @@ Hello Mr. Anubis

By default, environment variables used will be shown in the help text, but you can disable them with `show_envvar=False`:

```Python hl_lines="4"
{!../docs_src/arguments/envvar/tutorial003.py!}
```
=== "Python 3.6+"

```Python hl_lines="7"
{!> ../docs_src/arguments/envvar/tutorial003_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4"
{!> ../docs_src/arguments/envvar/tutorial003.py!}
```

Check it:

Expand Down
136 changes: 112 additions & 24 deletions docs/tutorial/arguments/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,20 @@ Now that you also know how to use `typer.Argument()`, let's use it to add docume

You can use the `help` parameter to add a help text for a *CLI argument*:

```Python hl_lines="4"
{!../docs_src/arguments/help/tutorial001.py!}
```
=== "Python 3.6+"

```Python hl_lines="5"
{!> ../docs_src/arguments/help/tutorial001_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4"
{!> ../docs_src/arguments/help/tutorial001.py!}
```

And it will be used in the automatic `--help` option:

Expand All @@ -41,9 +52,20 @@ Options:

And of course, you can also combine that `help` with the <abbr title="a multi-line string as the first expression inside a function (not assigned to any variable) used for documentation">docstring</abbr>:

```Python hl_lines="4 5 6 7"
{!../docs_src/arguments/help/tutorial002.py!}
```
=== "Python 3.6+"

```Python hl_lines="5-8"
{!> ../docs_src/arguments/help/tutorial002_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4-7"
{!> ../docs_src/arguments/help/tutorial002.py!}
```

And the `--help` option will combine all the information:

Expand Down Expand Up @@ -72,9 +94,20 @@ Options:

If you have a *CLI argument* with a default value, like `"World"`:

```Python hl_lines="4"
{!../docs_src/arguments/help/tutorial003.py!}
```
=== "Python 3.6+"

```Python hl_lines="5"
{!> ../docs_src/arguments/help/tutorial003_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4"
{!> ../docs_src/arguments/help/tutorial003.py!}
```

It will show that default value in the help text:

Expand All @@ -101,9 +134,20 @@ Options:

But you can disable that if you want to, with `show_default=False`:

```Python hl_lines="4"
{!../docs_src/arguments/help/tutorial004.py!}
```
=== "Python 3.6+"

```Python hl_lines="7"
{!> ../docs_src/arguments/help/tutorial004_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4"
{!> ../docs_src/arguments/help/tutorial004.py!}
```

And then it won't show the default value:

Expand Down Expand Up @@ -138,9 +182,20 @@ Options:

You can use the same `show_default` to pass a custom string (instead of a `bool`) to customize the default value to be shown in the help text:

```Python hl_lines="6"
{!../docs_src/arguments/help/tutorial005.py!}
```
=== "Python 3.6+"

```Python hl_lines="9"
{!> ../docs_src/arguments/help/tutorial005_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="6"
{!> ../docs_src/arguments/help/tutorial005.py!}
```

And it will be used in the help text:

Expand Down Expand Up @@ -187,9 +242,20 @@ But you can customize it with the `metavar` parameter for `typer.Argument()`.

For example, let's say you don't want to have the default of `NAME`, you want to have `username`, in lowercase, and you really want ✨ emojis ✨ everywhere:

```Python hl_lines="4"
{!../docs_src/arguments/help/tutorial006.py!}
```
=== "Python 3.6+"

```Python hl_lines="5"
{!> ../docs_src/arguments/help/tutorial006_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4"
{!> ../docs_src/arguments/help/tutorial006.py!}
```

Now the generated help text will have `✨username✨` instead of `NAME`:

Expand Down Expand Up @@ -217,9 +283,20 @@ You might want to show the help information for *CLI arguments* in different pan

If you have installed Rich as described in the docs for [Printing and Colors](../printing.md){.internal-link target=_blank}, you can set the `rich_help_panel` parameter to the name of the panel where you want this *CLI argument* to be shown:

```Python hl_lines="7 10"
{!../docs_src/arguments/help/tutorial007.py!}
```
=== "Python 3.6+"

```Python hl_lines="8 12"
{!> ../docs_src/arguments/help/tutorial007_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="7 10"
{!> ../docs_src/arguments/help/tutorial007.py!}
```

Then, if you check the `--help` option, you will see a default panel named "`Arguments`" for the *CLI arguments* that don't have a custom `rich_help_panel`.

Expand Down Expand Up @@ -267,9 +344,20 @@ If you want, you can make a *CLI argument* **not** show up in the `Arguments` se

You will probably not want to do this normally, but it's possible:

```Python hl_lines="4"
{!../docs_src/arguments/help/tutorial008.py!}
```
=== "Python 3.6+"

```Python hl_lines="5"
{!> ../docs_src/arguments/help/tutorial008_an.py!}
```

=== "Python 3.6+ non-Annotated"

!!! tip
Prefer to use the `Annotated` version if possible.

```Python hl_lines="4"
{!> ../docs_src/arguments/help/tutorial008.py!}
```

Check it:

Expand Down
Loading