diff --git a/docs/tutorial/parameter-types/custom-types.md b/docs/tutorial/parameter-types/custom-types.md
index 0412ef0..56acbe4 100644
--- a/docs/tutorial/parameter-types/custom-types.md
+++ b/docs/tutorial/parameter-types/custom-types.md
@@ -11,10 +11,20 @@ There are two ways to achieve this:
`typer.Argument` and `typer.Option` can create custom parameter types with a `parser` callable.
+=== "Python 3.6+"
-```Python hl_lines="12-13 17 18"
-{!../docs_src/parameter_types/custom_types/tutorial001.py!}
-```
+ ```Python hl_lines="13-14 18-19"
+ {!> ../docs_src/parameter_types/custom_types/tutorial001_an.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ Prefer to use the `Annotated` version if possible.
+
+ ```Python hl_lines="12-13 17-18"
+ {!> ../docs_src/parameter_types/custom_types/tutorial001.py!}
+ ```
The function (or callable) that you pass to the parameter `parser` will receive the input value as a string and should return the parsed value with your own custom type.
@@ -22,6 +32,17 @@ The function (or callable) that you pass to the parameter `parser` will receive
If you already have a Click Custom Type, you can use it in `typer.Argument()` and `typer.Option()` with the `click_type` parameter.
-```Python hl_lines="13-17 21 22"
-{!../docs_src/parameter_types/custom_types/tutorial002.py!}
-```
+=== "Python 3.6+"
+
+ ```Python hl_lines="14-18 22-25"
+ {!> ../docs_src/parameter_types/custom_types/tutorial002_an.py!}
+ ```
+
+=== "Python 3.6+ non-Annotated"
+
+ !!! tip
+ Prefer to use the `Annotated` version if possible.
+
+ ```Python hl_lines="13-17 21-22"
+ {!> ../docs_src/parameter_types/custom_types/tutorial002.py!}
+ ```
diff --git a/docs_src/parameter_types/custom_types/tutorial001.py b/docs_src/parameter_types/custom_types/tutorial001.py
index 902fef1..456c46b 100644
--- a/docs_src/parameter_types/custom_types/tutorial001.py
+++ b/docs_src/parameter_types/custom_types/tutorial001.py
@@ -14,7 +14,7 @@ def parse_custom_class(value: str):
def main(
- custom_arg: CustomClass = typer.Argument("X", parser=parse_custom_class),
+ custom_arg: CustomClass = typer.Argument(parser=parse_custom_class),
custom_opt: CustomClass = typer.Option("Y", parser=parse_custom_class),
):
print(f"custom_arg is {custom_arg}")
diff --git a/docs_src/parameter_types/custom_types/tutorial001_an.py b/docs_src/parameter_types/custom_types/tutorial001_an.py
new file mode 100644
index 0000000..f43ae63
--- /dev/null
+++ b/docs_src/parameter_types/custom_types/tutorial001_an.py
@@ -0,0 +1,26 @@
+import typer
+from typing_extensions import Annotated
+
+
+class CustomClass:
+ def __init__(self, value: str):
+ self.value = value
+
+ def __str__(self):
+ return f""
+
+
+def parse_custom_class(value: str):
+ return CustomClass(value * 2)
+
+
+def main(
+ custom_arg: Annotated[CustomClass, typer.Argument(parser=parse_custom_class)],
+ custom_opt: Annotated[CustomClass, typer.Option(parser=parse_custom_class)] = "Foo",
+):
+ print(f"custom_arg is {custom_arg}")
+ print(f"--custom-opt is {custom_opt}")
+
+
+if __name__ == "__main__":
+ typer.run(main)
diff --git a/docs_src/parameter_types/custom_types/tutorial002.py b/docs_src/parameter_types/custom_types/tutorial002.py
index 9726230..bb8a108 100644
--- a/docs_src/parameter_types/custom_types/tutorial002.py
+++ b/docs_src/parameter_types/custom_types/tutorial002.py
@@ -18,8 +18,8 @@ class CustomClassParser(click.ParamType):
def main(
- custom_arg: CustomClass = typer.Argument("X", click_type=CustomClassParser()),
- custom_opt: CustomClass = typer.Option("Y", click_type=CustomClassParser()),
+ custom_arg: CustomClass = typer.Argument(click_type=CustomClassParser()),
+ custom_opt: CustomClass = typer.Option("Foo", click_type=CustomClassParser()),
):
print(f"custom_arg is {custom_arg}")
print(f"--custom-opt is {custom_opt}")
diff --git a/docs_src/parameter_types/custom_types/tutorial002_an.py b/docs_src/parameter_types/custom_types/tutorial002_an.py
new file mode 100644
index 0000000..f762c17
--- /dev/null
+++ b/docs_src/parameter_types/custom_types/tutorial002_an.py
@@ -0,0 +1,32 @@
+import click
+import typer
+from typing_extensions import Annotated
+
+
+class CustomClass:
+ def __init__(self, value: str):
+ self.value = value
+
+ def __repr__(self):
+ return f""
+
+
+class CustomClassParser(click.ParamType):
+ name = "CustomClass"
+
+ def convert(self, value, param, ctx):
+ return CustomClass(value * 3)
+
+
+def main(
+ custom_arg: Annotated[CustomClass, typer.Argument(click_type=CustomClassParser())],
+ custom_opt: Annotated[
+ CustomClass, typer.Option(click_type=CustomClassParser())
+ ] = "Foo",
+):
+ print(f"custom_arg is {custom_arg}")
+ print(f"--custom-opt is {custom_opt}")
+
+
+if __name__ == "__main__":
+ typer.run(main)
diff --git a/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial001_an.py b/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial001_an.py
new file mode 100644
index 0000000..779d86f
--- /dev/null
+++ b/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial001_an.py
@@ -0,0 +1,39 @@
+import subprocess
+import sys
+
+import typer
+from typer.testing import CliRunner
+
+from docs_src.parameter_types.custom_types import tutorial001_an as mod
+
+runner = CliRunner()
+
+app = typer.Typer()
+app.command()(mod.main)
+
+
+def test_help():
+ result = runner.invoke(app, ["--help"])
+ assert result.exit_code == 0
+
+
+def test_parse_custom_type():
+ result = runner.invoke(app, ["0", "--custom-opt", "1"])
+ assert "custom_arg is " in result.output
+ assert "custom-opt is " in result.output
+
+
+def test_parse_custom_type_with_default():
+ result = runner.invoke(app, ["0"])
+ assert "custom_arg is " in result.output
+ assert "custom-opt is " in result.output
+
+
+def test_script():
+ result = subprocess.run(
+ [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ encoding="utf-8",
+ )
+ assert "Usage" in result.stdout
diff --git a/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial002.py b/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial002.py
index 47ff20d..f9e7da0 100644
--- a/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial002.py
+++ b/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial002.py
@@ -26,7 +26,7 @@ def test_parse_custom_type():
def test_parse_custom_type_with_default():
result = runner.invoke(app, ["0"])
assert "custom_arg is " in result.output
- assert "custom-opt is " in result.output
+ assert "custom-opt is " in result.output
def test_script():
diff --git a/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial002_an.py b/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial002_an.py
new file mode 100644
index 0000000..fe3ce78
--- /dev/null
+++ b/tests/test_tutorial/test_parameter_types/test_custom_types/test_tutorial002_an.py
@@ -0,0 +1,39 @@
+import subprocess
+import sys
+
+import typer
+from typer.testing import CliRunner
+
+from docs_src.parameter_types.custom_types import tutorial002_an as mod
+
+runner = CliRunner()
+
+app = typer.Typer()
+app.command()(mod.main)
+
+
+def test_help():
+ result = runner.invoke(app, ["--help"])
+ assert result.exit_code == 0
+
+
+def test_parse_custom_type():
+ result = runner.invoke(app, ["0", "--custom-opt", "1"])
+ assert "custom_arg is " in result.output
+ assert "custom-opt is " in result.output
+
+
+def test_parse_custom_type_with_default():
+ result = runner.invoke(app, ["0"])
+ assert "custom_arg is " in result.output
+ assert "custom-opt is " in result.output
+
+
+def test_script():
+ result = subprocess.run(
+ [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ encoding="utf-8",
+ )
+ assert "Usage" in result.stdout
diff --git a/typer/params.py b/typer/params.py
index d0ef231..a143f3f 100644
--- a/typer/params.py
+++ b/typer/params.py
@@ -254,7 +254,7 @@ def Option(
@overload
def Argument(
# Parameter
- default: Optional[Any],
+ default: Optional[Any] = ...,
*,
callback: Optional[Callable[..., Any]] = None,
metavar: Optional[str] = None,
@@ -308,7 +308,7 @@ def Argument(
@overload
def Argument(
# Parameter
- default: Optional[Any],
+ default: Optional[Any] = ...,
*,
callback: Optional[Callable[..., Any]] = None,
metavar: Optional[str] = None,