Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-typer-slim for 
openSUSE:Factory checked in at 2025-09-22 16:38:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-typer-slim (Old)
 and      /work/SRC/openSUSE:Factory/.python-typer-slim.new.27445 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-typer-slim"

Mon Sep 22 16:38:28 2025 rev:17 rq:1306167 version:0.19.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-typer-slim/python-typer-slim.changes      
2025-09-08 09:56:31.615906190 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-typer-slim.new.27445/python-typer-slim.changes
   2025-09-22 16:38:42.910976127 +0200
@@ -1,0 +2,15 @@
+Sat Sep 20 18:24:01 UTC 2025 - Matthias Bach <ma...@marix.org> - 0.19.1
+
+- Update to 0.19.1
+  * Ensure that Optional[list] values work correctly with callbacks.
+  * Support typing.Literal to define a set of predefined choices.
+  * Allow setting an environment variable to None in CliRunner.invoke.
+
+-------------------------------------------------------------------
+Fri Sep 19 22:51:43 UTC 2025 - Matthias Bach <ma...@marix.org> - 0.18.0
+
+- Update to 0.18.0
+  * Ensure compatibility with Click 8.3.0 by restoring the original
+    value_is_missing function.
+
+-------------------------------------------------------------------

Old:
----
  typer_slim-0.17.4.tar.gz

New:
----
  typer_slim-0.19.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-typer-slim.spec ++++++
--- /var/tmp/diff_new_pack.OFq0st/_old  2025-09-22 16:38:43.643006928 +0200
+++ /var/tmp/diff_new_pack.OFq0st/_new  2025-09-22 16:38:43.643006928 +0200
@@ -20,7 +20,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-typer-slim
-Version:        0.17.4
+Version:        0.19.1
 Release:        0
 Summary:        Typer, build great CLIs. Easy to code. Based on Python type 
hints
 License:        MIT

++++++ typer_slim-0.17.4.tar.gz -> typer_slim-0.19.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/PKG-INFO 
new/typer_slim-0.19.1/PKG-INFO
--- old/typer_slim-0.17.4/PKG-INFO      1970-01-01 01:00:00.000000000 +0100
+++ new/typer_slim-0.19.1/PKG-INFO      1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: typer-slim
-Version: 0.17.4
+Version: 0.19.1
 Summary: Typer, build great CLIs. Easy to code. Based on Python type hints.
 Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiang...@gmail.com>
 Classifier: Intended Audience :: Information Technology
@@ -357,6 +357,8 @@
 
 </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.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/README.md 
new/typer_slim-0.19.1/README.md
--- old/typer_slim-0.17.4/README.md     2025-09-05 20:14:23.142923600 +0200
+++ new/typer_slim-0.19.1/README.md     2025-09-20 10:59:07.667539600 +0200
@@ -318,6 +318,8 @@
 
 </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.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/docs_src/parameter_types/enum/tutorial004.py 
new/typer_slim-0.19.1/docs_src/parameter_types/enum/tutorial004.py
--- old/typer_slim-0.17.4/docs_src/parameter_types/enum/tutorial004.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/typer_slim-0.19.1/docs_src/parameter_types/enum/tutorial004.py  
2025-09-20 10:59:07.678539800 +0200
@@ -0,0 +1,10 @@
+import typer
+from typing_extensions import Literal
+
+
+def main(network: Literal["simple", "conv", "lstm"] = typer.Option("simple")):
+    print(f"Training neural network of type: {network}")
+
+
+if __name__ == "__main__":
+    typer.run(main)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/docs_src/parameter_types/enum/tutorial004_an.py 
new/typer_slim-0.19.1/docs_src/parameter_types/enum/tutorial004_an.py
--- old/typer_slim-0.17.4/docs_src/parameter_types/enum/tutorial004_an.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/typer_slim-0.19.1/docs_src/parameter_types/enum/tutorial004_an.py       
2025-09-20 10:59:07.678539800 +0200
@@ -0,0 +1,12 @@
+import typer
+from typing_extensions import Annotated, Literal
+
+
+def main(
+    network: Annotated[Literal["simple", "conv", "lstm"], typer.Option()] = 
"simple",
+):
+    print(f"Training neural network of type: {network}")
+
+
+if __name__ == "__main__":
+    typer.run(main)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/pyproject.toml 
new/typer_slim-0.19.1/pyproject.toml
--- old/typer_slim-0.17.4/pyproject.toml        2025-09-05 20:14:25.710039400 
+0200
+++ new/typer_slim-0.19.1/pyproject.toml        2025-09-20 10:59:14.761332300 
+0200
@@ -40,7 +40,7 @@
     "typing-extensions >= 3.7.4.3",
 ]
 readme = "README.md"
-version = "0.17.4"
+version = "0.19.1"
 
 [project.urls]
 Homepage = "https://github.com/fastapi/typer";
@@ -165,15 +165,20 @@
     "B",
     "C4",
     "UP",
+    "TID",
 ]
 ignore = [
     "E501",
     "B008",
     "C901",
     "W191",
+    "TID252",
 ]
 
 [tool.ruff.lint.per-file-ignores]
+"typer/rich_utils.py" = [
+    "TID251",
+]
 "docs_src/progressbar/tutorial004.py" = [
     "UP028",
     "B007",
@@ -214,6 +219,9 @@
 "docs_src/using_click/tutorial001.py" = [
     "B007",
 ]
+"docs_src/*" = [
+    "TID",
+]
 
 [tool.ruff.lint.isort]
 known-third-party = [
@@ -230,3 +238,11 @@
 
 [tool.ruff.lint.pyupgrade]
 keep-runtime-typing = true
+
+[tool.ruff.lint.flake8-tidy-imports]
+banned-module-level-imports = [
+    "typer.rich_utils",
+]
+
+[tool.ruff.lint.flake8-tidy-imports.banned-api.rich]
+msg = "Use 'typer.rich_utils' instead of importing from 'rich' directly."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/requirements-docs.txt 
new/typer_slim-0.19.1/requirements-docs.txt
--- old/typer_slim-0.17.4/requirements-docs.txt 2025-09-05 20:14:23.157924200 
+0200
+++ new/typer_slim-0.19.1/requirements-docs.txt 2025-09-20 10:59:07.681539800 
+0200
@@ -1,6 +1,6 @@
 -e .
 
-mkdocs-material==9.5.50
+mkdocs-material==9.6.20
 mdx-include >=1.4.1,<2.0.0
 mkdocs-redirects>=1.2.1,<1.3.0
 pyyaml >=5.3.1,<7.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/requirements-tests.txt 
new/typer_slim-0.19.1/requirements-tests.txt
--- old/typer_slim-0.17.4/requirements-tests.txt        2025-09-05 
20:14:23.157924200 +0200
+++ new/typer_slim-0.19.1/requirements-tests.txt        2025-09-20 
10:59:07.682539700 +0200
@@ -1,12 +1,12 @@
 -e .
 
 pytest >=4.4.0,<9.0.0
-pytest-cov >=2.10.0,<7.0.0
+pytest-cov >=2.10.0,<8.0.0
 coverage[toml] >=6.2,<8.0
 pytest-xdist >=1.32.0,<4.0.0
 pytest-sugar >=0.9.4,<1.2.0
 mypy ==1.4.1
-ruff ==0.12.11
+ruff ==0.13.0
 # Needed explicitly by typer-slim
 rich >=10.11.0
 shellingham >=1.3.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/tests/assets/type_error_no_rich.py 
new/typer_slim-0.19.1/tests/assets/type_error_no_rich.py
--- old/typer_slim-0.17.4/tests/assets/type_error_no_rich.py    2025-09-05 
20:14:23.158924300 +0200
+++ new/typer_slim-0.19.1/tests/assets/type_error_no_rich.py    2025-09-20 
10:59:07.683539600 +0200
@@ -1,7 +1,7 @@
 import typer
 import typer.main
 
-typer.main.rich = None
+typer.main.HAS_RICH = False
 
 
 def main(name: str = "morty"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/assets/type_error_no_rich_short_disable.py 
new/typer_slim-0.19.1/tests/assets/type_error_no_rich_short_disable.py
--- old/typer_slim-0.17.4/tests/assets/type_error_no_rich_short_disable.py      
2025-09-05 20:14:23.158924300 +0200
+++ new/typer_slim-0.19.1/tests/assets/type_error_no_rich_short_disable.py      
2025-09-20 10:59:07.683539600 +0200
@@ -1,7 +1,7 @@
 import typer
 import typer.main
 
-typer.main.rich = None
+typer.main.HAS_RICH = False
 
 
 app = typer.Typer(pretty_exceptions_short=False)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/tests/test_corner_cases.py 
new/typer_slim-0.19.1/tests/test_corner_cases.py
--- old/typer_slim-0.17.4/tests/test_corner_cases.py    2025-09-05 
20:14:23.159924300 +0200
+++ new/typer_slim-0.19.1/tests/test_corner_cases.py    2025-09-20 
10:59:07.684539800 +0200
@@ -1,3 +1,4 @@
+import pytest
 import typer.core
 from typer.testing import CliRunner
 
@@ -16,9 +17,9 @@
     assert "(dynamic)" in result.output
 
 
-def test_hidden_option_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_hidden_option_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
+
     result = runner.invoke(mod.app, ["--help"])
     assert result.exit_code == 0
     assert "Say hello" in result.output
@@ -26,7 +27,6 @@
     assert "/lastname" in result.output
     assert "TEST_LASTNAME" in result.output
     assert "(dynamic)" in result.output
-    typer.core.rich = rich
 
 
 def test_coverage_call():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/tests/test_others.py 
new/typer_slim-0.19.1/tests/test_others.py
--- old/typer_slim-0.17.4/tests/test_others.py  2025-09-05 20:14:23.159924300 
+0200
+++ new/typer_slim-0.19.1/tests/test_others.py  2025-09-20 10:59:07.684539800 
+0200
@@ -144,6 +144,32 @@
     assert "value is: Camila" in result.stdout
 
 
+def test_callback_4_list_none():
+    app = typer.Typer()
+
+    def names_callback(ctx, param, values: typing.Optional[typing.List[str]]):
+        if values is None:
+            return values
+        return [value.upper() for value in values]
+
+    @app.command()
+    def main(
+        names: typing.Optional[typing.List[str]] = typer.Option(
+            None, "--name", callback=names_callback
+        ),
+    ):
+        if names is None:
+            print("Hello World")
+        else:
+            print(f"Hello {', '.join(names)}")
+
+    result = runner.invoke(app, ["--name", "Sideshow", "--name", "Bob"])
+    assert "Hello SIDESHOW, BOB" in result.stdout
+
+    result = runner.invoke(app, [])
+    assert "Hello World" in result.stdout
+
+
 def test_completion_argument():
     file_path = Path(__file__).parent / "assets/completion_argument.py"
     result = subprocess.run(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_envvar/test_tutorial001.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_envvar/test_tutorial001.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_envvar/test_tutorial001.py
    2025-09-05 20:14:23.160924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_envvar/test_tutorial001.py
    2025-09-20 10:59:07.685539700 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -22,16 +23,14 @@
     assert "default: World" in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "[OPTIONS] [NAME]" in result.output
     assert "Arguments" in result.output
     assert "env var: AWESOME_NAME" in result.output
     assert "default: World" in result.output
-    typer.core.rich = rich
 
 
 def test_call_arg():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_envvar/test_tutorial001_an.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_envvar/test_tutorial001_an.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_envvar/test_tutorial001_an.py
 2025-09-05 20:14:23.160924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_envvar/test_tutorial001_an.py
 2025-09-20 10:59:07.685539700 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -22,16 +23,15 @@
     assert "default: World" in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
+
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "[OPTIONS] [NAME]" in result.output
     assert "Arguments" in result.output
     assert "env var: AWESOME_NAME" in result.output
     assert "default: World" in result.output
-    typer.core.rich = rich
 
 
 def test_call_arg():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_help/test_tutorial001.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_help/test_tutorial001.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_help/test_tutorial001.py
      2025-09-05 20:14:23.160924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_help/test_tutorial001.py
      2025-09-20 10:59:07.685539700 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -23,9 +24,8 @@
     assert "[required]" in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "[OPTIONS] NAME" in result.output
@@ -33,7 +33,6 @@
     assert "NAME" in result.output
     assert "The name of the user to greet" in result.output
     assert "[required]" in result.output
-    typer.core.rich = rich
 
 
 def test_call_arg():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_help/test_tutorial001_an.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_help/test_tutorial001_an.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_help/test_tutorial001_an.py
   2025-09-05 20:14:23.160924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_help/test_tutorial001_an.py
   2025-09-20 10:59:07.685539700 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -23,9 +24,8 @@
     assert "[required]" in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "[OPTIONS] NAME" in result.output
@@ -33,7 +33,6 @@
     assert "NAME" in result.output
     assert "The name of the user to greet" in result.output
     assert "[required]" in result.output
-    typer.core.rich = rich
 
 
 def test_call_arg():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_help/test_tutorial008.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_help/test_tutorial008.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_help/test_tutorial008.py
      2025-09-05 20:14:23.161924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_help/test_tutorial008.py
      2025-09-20 10:59:07.685539700 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -22,16 +23,14 @@
     assert "[default: World]" not in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "[OPTIONS] [NAME]" in result.output
     assert "Say hi to NAME very gently, like Dirk." in result.output
     assert "Arguments" not in result.output
     assert "[default: World]" not in result.output
-    typer.core.rich = rich
 
 
 def test_call_arg():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_help/test_tutorial008_an.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_help/test_tutorial008_an.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_help/test_tutorial008_an.py
   2025-09-05 20:14:23.161924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_help/test_tutorial008_an.py
   2025-09-20 10:59:07.685539700 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -22,16 +23,14 @@
     assert "[default: World]" not in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "[OPTIONS] [NAME]" in result.output
     assert "Say hi to NAME very gently, like Dirk." in result.output
     assert "Arguments" not in result.output
     assert "[default: World]" not in result.output
-    typer.core.rich = rich
 
 
 def test_call_arg():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_optional/test_tutorial001.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_optional/test_tutorial001.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_optional/test_tutorial001.py
  2025-09-05 20:14:23.161924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_optional/test_tutorial001.py
  2025-09-20 10:59:07.685539700 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -25,14 +26,12 @@
     assert result.exit_code != 0
 
 
-def test_call_no_arg_no_rich():
+def test_call_no_arg_no_rich(monkeypatch: pytest.MonkeyPatch):
     # Mainly for coverage
-    rich = typer.core.rich
-    typer.core.rich = None
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app)
     assert result.exit_code != 0
     assert "Error: Missing argument 'NAME'" in result.output
-    typer.core.rich = rich
 
 
 def test_call_arg():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_optional/test_tutorial001_an.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_optional/test_tutorial001_an.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_optional/test_tutorial001_an.py
       2025-09-05 20:14:23.161924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_optional/test_tutorial001_an.py
       2025-09-20 10:59:07.685539700 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -25,14 +26,12 @@
     assert result.exit_code != 0
 
 
-def test_call_no_arg_no_rich():
+def test_call_no_arg_no_rich(monkeypatch: pytest.MonkeyPatch):
     # Mainly for coverage
-    rich = typer.core.rich
-    typer.core.rich = None
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app)
     assert result.exit_code != 0
     assert "Error: Missing argument 'NAME'" in result.output
-    typer.core.rich = rich
 
 
 def test_call_arg():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_optional/test_tutorial003.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_optional/test_tutorial003.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_arguments/test_optional/test_tutorial003.py
  2025-09-05 20:14:23.161924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_arguments/test_optional/test_tutorial003.py
  2025-09-20 10:59:07.686539600 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -25,14 +26,12 @@
     assert result.exit_code != 0
 
 
-def test_call_no_arg_no_rich():
+def test_call_no_arg_no_rich(monkeypatch: pytest.MonkeyPatch):
     # Mainly for coverage
-    rich = typer.core.rich
-    typer.core.rich = None
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app)
     assert result.exit_code != 0
     assert "Error: Missing argument 'NAME'" in result.output
-    typer.core.rich = rich
 
 
 def test_call_arg():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_commands/test_callback/test_tutorial001.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_commands/test_callback/test_tutorial001.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_commands/test_callback/test_tutorial001.py
   2025-09-05 20:14:23.161924400 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_commands/test_callback/test_tutorial001.py
   2025-09-20 10:59:07.686539600 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer.core
 from typer.testing import CliRunner
 
@@ -19,15 +20,13 @@
     assert "--no-verbose" in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "Manage users in the awesome CLI app." in result.output
     assert "--verbose" in result.output
     assert "--no-verbose" in result.output
-    typer.core.rich = rich
 
 
 def test_create():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_options/test_required/test_tutorial001.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_options/test_required/test_tutorial001.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_options/test_required/test_tutorial001.py
    2025-09-05 20:14:23.164924600 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_options/test_required/test_tutorial001.py
    2025-09-20 10:59:07.689540000 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -33,15 +34,13 @@
     assert "[required]" in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "--lastname" in result.output
     assert "TEXT" in result.output
     assert "[required]" in result.output
-    typer.core.rich = rich
 
 
 def test_script():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_options/test_required/test_tutorial001_an.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_options/test_required/test_tutorial001_an.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_options/test_required/test_tutorial001_an.py
 2025-09-05 20:14:23.164924600 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_options/test_required/test_tutorial001_an.py
 2025-09-20 10:59:07.689540000 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -33,15 +34,13 @@
     assert "[required]" in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "--lastname" in result.output
     assert "TEXT" in result.output
     assert "[required]" in result.output
-    typer.core.rich = rich
 
 
 def test_script():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_bool/test_tutorial002.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_bool/test_tutorial002.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_bool/test_tutorial002.py
        2025-09-05 20:14:23.165924500 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_bool/test_tutorial002.py
        2025-09-20 10:59:07.690539800 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -21,15 +22,13 @@
     assert "--no-accept" not in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "--accept" in result.output
     assert "--reject" in result.output
     assert "--no-accept" not in result.output
-    typer.core.rich = rich
 
 
 def test_main():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_bool/test_tutorial002_an.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_bool/test_tutorial002_an.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_bool/test_tutorial002_an.py
     2025-09-05 20:14:23.165924500 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_bool/test_tutorial002_an.py
     2025-09-20 10:59:07.690539800 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -21,15 +22,13 @@
     assert "--no-accept" not in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "--accept" in result.output
     assert "--reject" in result.output
     assert "--no-accept" not in result.output
-    typer.core.rich = rich
 
 
 def test_main():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_enum/test_tutorial004.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_enum/test_tutorial004.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_enum/test_tutorial004.py
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_enum/test_tutorial004.py
        2025-09-20 10:59:07.691539800 +0200
@@ -0,0 +1,46 @@
+import subprocess
+import sys
+
+import typer
+from typer.testing import CliRunner
+
+from docs_src.parameter_types.enum import tutorial004 as mod
+
+runner = CliRunner()
+
+app = typer.Typer()
+app.command()(mod.main)
+
+
+def test_help():
+    result = runner.invoke(app, ["--help"])
+    assert result.exit_code == 0
+    assert "--network [simple|conv|lstm]" in result.output.replace("  ", "")
+
+
+def test_main():
+    result = runner.invoke(app, ["--network", "conv"])
+    assert result.exit_code == 0
+    assert "Training neural network of type: conv" in result.output
+
+
+def test_invalid():
+    result = runner.invoke(app, ["--network", "capsule"])
+    assert result.exit_code != 0
+    assert "Invalid value for '--network'" in result.output
+    assert (
+        "invalid choice: capsule. (choose from" in result.output
+        or "'capsule' is not one of" in result.output
+    )
+    assert "simple" in result.output
+    assert "conv" in result.output
+    assert "lstm" in result.output
+
+
+def test_script():
+    result = subprocess.run(
+        [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"],
+        capture_output=True,
+        encoding="utf-8",
+    )
+    assert "Usage" in result.stdout
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_enum/test_tutorial004_an.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_enum/test_tutorial004_an.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_enum/test_tutorial004_an.py
     1970-01-01 01:00:00.000000000 +0100
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_enum/test_tutorial004_an.py
     2025-09-20 10:59:07.691539800 +0200
@@ -0,0 +1,46 @@
+import subprocess
+import sys
+
+import typer
+from typer.testing import CliRunner
+
+from docs_src.parameter_types.enum import tutorial004_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
+    assert "--network [simple|conv|lstm]" in result.output.replace("  ", "")
+
+
+def test_main():
+    result = runner.invoke(app, ["--network", "conv"])
+    assert result.exit_code == 0
+    assert "Training neural network of type: conv" in result.output
+
+
+def test_invalid():
+    result = runner.invoke(app, ["--network", "capsule"])
+    assert result.exit_code != 0
+    assert "Invalid value for '--network'" in result.output
+    assert (
+        "invalid choice: capsule. (choose from" in result.output
+        or "'capsule' is not one of" in result.output
+    )
+    assert "simple" in result.output
+    assert "conv" in result.output
+    assert "lstm" in result.output
+
+
+def test_script():
+    result = subprocess.run(
+        [sys.executable, "-m", "coverage", "run", mod.__file__, "--help"],
+        capture_output=True,
+        encoding="utf-8",
+    )
+    assert "Usage" in result.stdout
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_number/test_tutorial001.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_number/test_tutorial001.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_number/test_tutorial001.py
      2025-09-05 20:14:23.166924700 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_number/test_tutorial001.py
      2025-09-20 10:59:07.691539800 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -9,7 +10,7 @@
 
 runner = CliRunner()
 
-app = typer.Typer()
+app = typer.Typer(rich_markup_mode=None)
 app.command()(mod.main)
 
 
@@ -22,16 +23,14 @@
     assert "FLOAT RANGE" in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "--age" in result.output
     assert "INTEGER RANGE" in result.output
     assert "--score" in result.output
     assert "FLOAT RANGE" in result.output
-    typer.core.rich = rich
 
 
 def test_params():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_number/test_tutorial001_an.py
 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_number/test_tutorial001_an.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_parameter_types/test_number/test_tutorial001_an.py
   2025-09-05 20:14:23.166924700 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_parameter_types/test_number/test_tutorial001_an.py
   2025-09-20 10:59:07.691539800 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -9,7 +10,7 @@
 
 runner = CliRunner()
 
-app = typer.Typer()
+app = typer.Typer(rich_markup_mode=None)
 app.command()(mod.main)
 
 
@@ -22,16 +23,14 @@
     assert "FLOAT RANGE" in result.output
 
 
-def test_help_no_rich():
-    rich = typer.core.rich
-    typer.core.rich = None
+def test_help_no_rich(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["--help"])
     assert result.exit_code == 0
     assert "--age" in result.output
     assert "INTEGER RANGE" in result.output
     assert "--score" in result.output
     assert "FLOAT RANGE" in result.output
-    typer.core.rich = rich
 
 
 def test_params():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/typer_slim-0.17.4/tests/test_tutorial/test_terminating/test_tutorial003.py 
new/typer_slim-0.19.1/tests/test_tutorial/test_terminating/test_tutorial003.py
--- 
old/typer_slim-0.17.4/tests/test_tutorial/test_terminating/test_tutorial003.py  
    2025-09-05 20:14:23.167924600 +0200
+++ 
new/typer_slim-0.19.1/tests/test_tutorial/test_terminating/test_tutorial003.py  
    2025-09-20 10:59:07.692540000 +0200
@@ -1,6 +1,7 @@
 import subprocess
 import sys
 
+import pytest
 import typer
 import typer.core
 from typer.testing import CliRunner
@@ -32,15 +33,13 @@
     assert result.exit_code == 1
 
 
-def test_root_no_rich():
+def test_root_no_rich(monkeypatch: pytest.MonkeyPatch):
     # Mainly for coverage
-    rich = typer.core.rich
-    typer.core.rich = None
+    monkeypatch.setattr(typer.core, "HAS_RICH", False)
     result = runner.invoke(app, ["root"])
     assert result.exit_code == 1
     assert "The root user is reserved" in result.output
     assert "Aborted!" in result.output
-    typer.core.rich = rich
 
 
 def test_script():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/typer/__init__.py 
new/typer_slim-0.19.1/typer/__init__.py
--- old/typer_slim-0.17.4/typer/__init__.py     2025-09-05 20:14:23.168924800 
+0200
+++ new/typer_slim-0.19.1/typer/__init__.py     2025-09-20 10:59:07.693539900 
+0200
@@ -1,6 +1,6 @@
 """Typer, build great CLIs. Easy to code. Based on Python type hints."""
 
-__version__ = "0.17.4"
+__version__ = "0.19.1"
 
 from shutil import get_terminal_size as get_terminal_size
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/typer/_typing.py 
new/typer_slim-0.19.1/typer/_typing.py
--- old/typer_slim-0.17.4/typer/_typing.py      2025-09-05 20:14:23.168924800 
+0200
+++ new/typer_slim-0.19.1/typer/_typing.py      2025-09-20 10:59:07.693539900 
+0200
@@ -93,7 +93,9 @@
 
 
 def is_literal_type(type_: Type[Any]) -> bool:
-    return Literal is not None and get_origin(type_) is Literal
+    import typing_extensions
+
+    return get_origin(type_) in (Literal, typing_extensions.Literal)
 
 
 def literal_values(type_: Type[Any]) -> Tuple[Any, ...]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/typer/cli.py 
new/typer_slim-0.19.1/typer/cli.py
--- old/typer_slim-0.17.4/typer/cli.py  2025-09-05 20:14:23.168924800 +0200
+++ new/typer_slim-0.19.1/typer/cli.py  2025-09-20 10:59:07.693539900 +0200
@@ -10,15 +10,7 @@
 from click import Command, Group, Option
 
 from . import __version__
-
-try:
-    import rich
-
-    has_rich = True
-
-except ImportError:  # pragma: no cover
-    has_rich = False
-    rich = None  # type: ignore
+from .core import HAS_RICH
 
 default_app_names = ("app", "cli", "main")
 default_func_names = ("main", "cli", "app")
@@ -272,7 +264,7 @@
 
 
 def _parse_html(input_text: str) -> str:
-    if not has_rich:  # pragma: no cover
+    if not HAS_RICH:  # pragma: no cover
         return input_text
     from . import rich_utils
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/typer/core.py 
new/typer_slim-0.19.1/typer/core.py
--- old/typer_slim-0.17.4/typer/core.py 2025-09-05 20:14:23.168924800 +0200
+++ new/typer_slim-0.19.1/typer/core.py 2025-09-20 10:59:07.693539900 +0200
@@ -1,4 +1,5 @@
 import errno
+import importlib.util
 import inspect
 import os
 import sys
@@ -30,13 +31,11 @@
 
 MarkupMode = Literal["markdown", "rich", None]
 
-try:
-    import rich
+HAS_RICH = importlib.util.find_spec("rich") is not None
 
+if HAS_RICH:
     DEFAULT_MARKUP_MODE: MarkupMode = "rich"
-
-except ImportError:  # pragma: no cover
-    rich = None  # type: ignore
+else:  # pragma: no cover
     DEFAULT_MARKUP_MODE = None
 
 
@@ -210,7 +209,7 @@
             if not standalone_mode:
                 raise
             # Typer override
-            if rich and rich_markup_mode is not None:
+            if HAS_RICH and rich_markup_mode is not None:
                 from . import rich_utils
 
                 rich_utils.rich_format_error(e)
@@ -242,7 +241,7 @@
         if not standalone_mode:
             raise
         # Typer override
-        if rich and rich_markup_mode is not None:
+        if HAS_RICH and rich_markup_mode is not None:
             from . import rich_utils
 
             rich_utils.rich_abort_error()
@@ -370,7 +369,7 @@
         if extra:
             extra_str = "; ".join(extra)
             extra_str = f"[{extra_str}]"
-            if rich is not None:
+            if HAS_RICH:
                 # This is needed for when we want to export to HTML
                 from . import rich_utils
 
@@ -403,6 +402,9 @@
             var += "..."
         return var
 
+    def value_is_missing(self, value: Any) -> bool:
+        return _value_is_missing(self, value)
+
 
 class TyperOption(click.core.Option):
     def __init__(
@@ -583,7 +585,7 @@
         if extra:
             extra_str = "; ".join(extra)
             extra_str = f"[{extra_str}]"
-            if rich is not None:
+            if HAS_RICH:
                 # This is needed for when we want to export to HTML
                 from . import rich_utils
 
@@ -593,6 +595,23 @@
 
         return ("; " if any_prefix_is_slash else " / ").join(rv), help
 
+    def value_is_missing(self, value: Any) -> bool:
+        return _value_is_missing(self, value)
+
+
+def _value_is_missing(param: click.Parameter, value: Any) -> bool:
+    if value is None:
+        return True
+
+    # Click 8.3 and beyond
+    # if value is UNSET:
+    #     return True
+
+    if (param.nargs != 1 or param.multiple) and value == ():
+        return True  # pragma: no cover
+
+    return False
+
 
 def _typer_format_options(
     self: click.core.Command, *, ctx: click.Context, formatter: 
click.HelpFormatter
@@ -709,7 +728,7 @@
         )
 
     def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) 
-> None:
-        if not rich or self.rich_markup_mode is None:
+        if not HAS_RICH or self.rich_markup_mode is None:
             return super().format_help(ctx, formatter)
         from . import rich_utils
 
@@ -774,7 +793,7 @@
         )
 
     def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) 
-> None:
-        if not rich or self.rich_markup_mode is None:
+        if not HAS_RICH or self.rich_markup_mode is None:
             return super().format_help(ctx, formatter)
         from . import rich_utils
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/typer/main.py 
new/typer_slim-0.19.1/typer/main.py
--- old/typer_slim-0.17.4/typer/main.py 2025-09-05 20:14:23.168924800 +0200
+++ new/typer_slim-0.19.1/typer/main.py 2025-09-20 10:59:07.694539800 +0200
@@ -17,10 +17,11 @@
 import click
 from typer._types import TyperChoice
 
-from ._typing import get_args, get_origin, is_union
+from ._typing import get_args, get_origin, is_literal_type, is_union, 
literal_values
 from .completion import get_completion_inspect_parameters
 from .core import (
     DEFAULT_MARKUP_MODE,
+    HAS_RICH,
     MarkupMode,
     TyperArgument,
     TyperCommand,
@@ -49,12 +50,6 @@
 )
 from .utils import get_params_from_function
 
-try:
-    import rich
-
-except ImportError:  # pragma: no cover
-    rich = None  # type: ignore
-
 _original_except_hook = sys.excepthook
 _typer_developer_exception_attr_name = "__typer_developer_exception__"
 
@@ -77,7 +72,7 @@
     click_path = os.path.dirname(click.__file__)
     internal_dir_names = [typer_path, click_path]
     exc = exc_value
-    if rich:
+    if HAS_RICH:
         from . import rich_utils
 
         rich_tb = rich_utils.get_traceback(exc, exception_config, 
internal_dir_names)
@@ -632,10 +627,10 @@
 
 def generate_list_convertor(
     convertor: Optional[Callable[[Any], Any]], default_value: Optional[Any]
-) -> Callable[[Sequence[Any]], Optional[List[Any]]]:
-    def internal_convertor(value: Sequence[Any]) -> Optional[List[Any]]:
-        if default_value is None and len(value) == 0:
-            return None
+) -> Callable[[Optional[Sequence[Any]]], Optional[List[Any]]]:
+    def internal_convertor(value: Optional[Sequence[Any]]) -> 
Optional[List[Any]]:
+        if value is None or len(value) == 0:
+            return default_value
         return [convertor(v) if convertor else v for v in value]
 
     return internal_convertor
@@ -788,6 +783,11 @@
             [item.value for item in annotation],
             case_sensitive=parameter_info.case_sensitive,
         )
+    elif is_literal_type(annotation):
+        return click.Choice(
+            literal_values(annotation),
+            case_sensitive=parameter_info.case_sensitive,
+        )
     raise RuntimeError(f"Type not yet supported: {annotation}")  # pragma: no 
cover
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/typer_slim-0.17.4/typer/testing.py 
new/typer_slim-0.19.1/typer/testing.py
--- old/typer_slim-0.17.4/typer/testing.py      2025-09-05 20:14:23.169924700 
+0200
+++ new/typer_slim-0.19.1/typer/testing.py      2025-09-20 10:59:07.694539800 
+0200
@@ -12,7 +12,7 @@
         app: Typer,
         args: Optional[Union[str, Sequence[str]]] = None,
         input: Optional[Union[bytes, str, IO[Any]]] = None,
-        env: Optional[Mapping[str, str]] = None,
+        env: Optional[Mapping[str, Optional[str]]] = None,
         catch_exceptions: bool = True,
         color: bool = False,
         **extra: Any,

Reply via email to