Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7bd4597
Add StrEnum example for python 3.11+
Matthieu-LAURENT39 Mar 1, 2024
294a6e3
Merge branch 'master' into upstream_ml_docs
svlandeg Mar 29, 2024
a18db2c
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
pre-commit-ci[bot] Mar 29, 2024
d904897
update to Python 3.7 as support for 3.6 was recently dropped
svlandeg Mar 29, 2024
b556bca
Merge branch 'docs' of https://github.com/Matthieu-LAURENT39/typer in…
svlandeg Mar 29, 2024
ec692a6
Merge branch 'master' into upstream_ml_docs
svlandeg Apr 2, 2024
96e12d6
Rename to clarify what the difference exactly is
svlandeg Apr 2, 2024
918563e
add unit tests
svlandeg Apr 2, 2024
d8bd4cc
Merge branch 'master' into ml_docs
svlandeg Sep 12, 2025
00120f4
Merge branch 'master' into ml_docs
svlandeg Sep 12, 2025
2ebaa5e
use pytest.param to simplify test suite
svlandeg Sep 12, 2025
e5c0968
try specifying a py311 file as standard
svlandeg Sep 12, 2025
cec8e49
Merge branch 'master' into docs
svlandeg Sep 17, 2025
71caac2
Merge branch 'master' into docs
svlandeg Sep 29, 2025
bef9a67
Merge branch 'master' into docs
svlandeg Nov 26, 2025
d32b8d9
updates
svlandeg Nov 26, 2025
5b1effa
Merge branch 'docs' of https://github.com/Matthieu-LAURENT39/typer in…
svlandeg Nov 26, 2025
6908dbd
use mod as fixture instead of app
svlandeg Nov 26, 2025
2147114
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
pre-commit-ci[bot] Nov 26, 2025
8a3d5af
fix
svlandeg Nov 26, 2025
cb94ac0
Merge branch 'docs' of https://github.com/Matthieu-LAURENT39/typer in…
svlandeg Nov 26, 2025
01e0f26
cleanup
svlandeg Nov 26, 2025
6a3d9ba
use mod as fixture
svlandeg Nov 26, 2025
0897489
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
pre-commit-ci[bot] Nov 26, 2025
b20f925
fix highlighting
svlandeg Nov 26, 2025
9f14522
Merge branch 'master' into docs
svlandeg Jan 12, 2026
d0ce3db
🎨 Auto format
pre-commit-ci-lite[bot] Jan 12, 2026
06bba67
small fixes
svlandeg Jan 12, 2026
095f456
Merge branch 'master' into laurent_docs
svlandeg Feb 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/tutorial/parameter-types/enum.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

To define a *CLI parameter* that can take a value from a predefined set of values you can use a standard Python <a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">`enum.Enum`</a>:

{* docs_src/parameter_types/enum/tutorial001_py310.py hl[1,6:9,16:17] *}
{* docs_src/parameter_types/enum/tutorial001_py311.py hl[1,6:9,16:17] *}

/// tip

Expand Down Expand Up @@ -54,7 +54,7 @@ Error: Invalid value for '--network': 'CONV' is not one of 'simple', 'conv', 'ls

You can make an `Enum` (choice) *CLI parameter* be case-insensitive with the `case_sensitive` parameter:

{* docs_src/parameter_types/enum/tutorial002_an_py310.py hl[19] *}
{* docs_src/parameter_types/enum/tutorial002_an_py311.py hl[19] *}

And then the values of the `Enum` will be checked no matter if lower case, upper case, or a mix:

Expand Down
21 changes: 21 additions & 0 deletions docs_src/parameter_types/enum/tutorial001_py311.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from enum import StrEnum

import typer


class NeuralNetwork(StrEnum):
simple = "simple"
conv = "conv"
lstm = "lstm"


app = typer.Typer()


@app.command()
def main(network: NeuralNetwork = NeuralNetwork.simple):
print(f"Training neural network of type: {network.value}")


if __name__ == "__main__":
app()
26 changes: 26 additions & 0 deletions docs_src/parameter_types/enum/tutorial002_an_py311.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from enum import StrEnum
from typing import Annotated

import typer


class NeuralNetwork(StrEnum):
simple = "simple"
conv = "conv"
lstm = "lstm"


app = typer.Typer()


@app.command()
def main(
network: Annotated[
NeuralNetwork, typer.Option(case_sensitive=False)
] = NeuralNetwork.simple,
):
print(f"Training neural network of type: {network.value}")


if __name__ == "__main__":
app()
Original file line number Diff line number Diff line change
@@ -1,36 +1,49 @@
import importlib
import subprocess
import sys

import pytest
from typer.testing import CliRunner

from docs_src.parameter_types.enum import tutorial001_py310 as mod
from tests.utils import needs_py311

runner = CliRunner()
app = mod.app


def test_help():
result = runner.invoke(app, ["--help"])
@pytest.fixture(
name="mod",
params=[
"tutorial001_py310",
pytest.param("tutorial001_py311", marks=needs_py311),
],
)
def get_mod(request: pytest.FixtureRequest):
mod = importlib.import_module(f"docs_src.parameter_types.enum.{request.param}")
return mod


def test_help(mod):
result = runner.invoke(mod.app, ["--help"])
assert result.exit_code == 0
assert "--network" in result.output
assert "[simple|conv|lstm]" in result.output
assert "default: simple" in result.output


def test_main():
result = runner.invoke(app, ["--network", "conv"])
def test_main(mod):
result = runner.invoke(mod.app, ["--network", "conv"])
assert result.exit_code == 0
assert "Training neural network of type: conv" in result.output


def test_main_default():
result = runner.invoke(app)
def test_main_default(mod):
result = runner.invoke(mod.app)
assert result.exit_code == 0
assert "Training neural network of type: simple" in result.output


def test_invalid_case():
result = runner.invoke(app, ["--network", "CONV"])
def test_invalid_case(mod):
result = runner.invoke(mod.app, ["--network", "CONV"])
assert result.exit_code != 0
assert "Invalid value for '--network'" in result.output
assert "'CONV' is not one of" in result.output
Expand All @@ -39,8 +52,8 @@ def test_invalid_case():
assert "lstm" in result.output


def test_invalid_other():
result = runner.invoke(app, ["--network", "capsule"])
def test_invalid_other(mod):
result = runner.invoke(mod.app, ["--network", "capsule"])
assert result.exit_code != 0
assert "Invalid value for '--network'" in result.output
assert "'capsule' is not one of" in result.output
Expand All @@ -49,7 +62,7 @@ def test_invalid_other():
assert "lstm" in result.output


def test_script():
def test_script(mod):
result = subprocess.run(
[sys.executable, "-m", "coverage", "run", mod.__file__, "--help"],
capture_output=True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import pytest
from typer.testing import CliRunner

from tests.utils import needs_py311

runner = CliRunner()


Expand All @@ -14,6 +16,7 @@
params=[
pytest.param("tutorial002_py310"),
pytest.param("tutorial002_an_py310"),
pytest.param("tutorial002_an_py311", marks=needs_py311),
],
)
def get_mod(request: pytest.FixtureRequest) -> ModuleType:
Expand Down
4 changes: 4 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
from typer._completion_shared import _get_shell_name
from typer.core import HAS_RICH

needs_py311 = pytest.mark.skipif(
sys.version_info < (3, 11), reason="requires python3.11+"
)

needs_linux = pytest.mark.skipif(
not sys.platform.startswith("linux"), reason="Test requires Linux"
)
Expand Down