File: version.md

package info (click to toggle)
typer 0.19.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,688 kB
  • sloc: python: 16,702; javascript: 280; sh: 28; makefile: 27
file content (112 lines) | stat: -rw-r--r-- 3,248 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# Version CLI Option, `is_eager`

You could use a callback to implement a `--version` *CLI option*.

It would show the version of your CLI program and then it would terminate it. Even before any other *CLI parameter* is processed.

## First version of `--version`

Let's see a first version of how it could look like:

{* docs_src/options/version/tutorial001_an.py hl[9:12,17:19] *}

/// tip

Notice that we don't have to get the `typer.Context` and check for `ctx.resilient_parsing` for completion to work, because we only print and modify the program when `--version` is passed, otherwise, nothing is printed or changed from the callback.

///

If the `--version` *CLI option* is passed, we get a value `True` in the callback.

Then we can print the version and raise `typer.Exit()` to make sure the program is terminated before anything else is executed.

We also declare the explicit *CLI option* name `--version`, because we don't want an automatic `--no-version`, it would look awkward.

Check it:

<div class="termy">

```console
$ python main.py --help

// We get a --version, and don't get an awkward --no-version 🎉
Usage: main.py [OPTIONS]

Options:
  --version
  --name TEXT
  --help                Show this message and exit.


// We can call it normally
$ python main.py --name Camila

Hello Camila

// And we can get the version
$ python main.py --version

Awesome CLI Version: 0.1.0

// Because we exit in the callback, we don't get a "Hello World" message after the version 🚀
```

</div>

## Previous parameters and `is_eager`

But now let's say that the `--name` *CLI option* that we declared before `--version` is required, and it has a callback that could exit the program:

{* docs_src/options/version/tutorial002_an.py hl[15:17,22:24] *}

Then our CLI program could not work as expected in some cases as it is *right now*, because if we use `--version` after `--name` then the callback for `--name` will be processed before and we can get its error:

<div class="termy">

```console
$ python main.py --name Rick --version

Only Camila is allowed
Aborted!
```

</div>

/// tip

We don't have to check for `ctx.resilient_parsing` in the `name_callback()` for completion to work, because we are not using `typer.echo()`, instead we are raising a `typer.BadParameter`.

///

/// note | Technical Details

`typer.BadParameter` prints the error to "standard error", not to "standard output", and because the completion system only reads from "standard output", it won't break completion.

///

/// info

If you need a refresher about what is "standard output" and "standard error" check the section in [Printing and Colors: "Standard Output" and "Standard Error"](../printing.md#standard-output-and-standard-error){.internal-link target=_blank}.

///

### Fix with `is_eager`

For those cases, we can mark a *CLI parameter* (a *CLI option* or *CLI argument*) with `is_eager=True`.

That will tell **Typer** (actually Click) that it should process this *CLI parameter* before the others:

{* docs_src/options/version/tutorial003_an.py hl[23:26] *}

Check it:

<div class="termy">

```console
$ python main.py --name Rick --version

// Now we only get the version, and the name is not used
Awesome CLI Version: 0.1.0
```

</div>