Skip to content

🐛 Fix evaluating stringified annotations in Python 3.8 & 3.9 (also from __future__ import annotations) #1264

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

sisp
Copy link

@sisp sisp commented Jul 30, 2025

I've fixed evaluating stringified annotations in Python 3.9 and less when using the Annotated[<type>, typer.{Argument,Option}(...)] syntax. When removing the @needs_py310 decorator from the test_annotated_argument_in_string_type_with_default test, it fails with the following error:

――――――――――――― test_annotated_argument_in_string_type_with_default ――――――――――――――
[gw0] linux -- Python 3.9.20 .../typer/.venv/bin/python3

    def test_annotated_argument_in_string_type_with_default():
        app = typer.Typer()
    
        @app.command()
        def cmd(val: "Annotated[int, typer.Argument()]" = 0):
            print(f"hello {val}")
    
        result = runner.invoke(app)
        assert result.exit_code == 0, result.output
        assert "hello 0" in result.output
    
        result = runner.invoke(app, ["42"])
>       assert result.exit_code == 0, result.output
E       AssertionError: Usage: cmd [OPTIONS]
E         Try 'cmd --help' for help.
E         
E         Error: Got unexpected extra argument (42)
E         
E       assert 2 == 0
E        +  where 2 = <Result SystemExit(2)>.exit_code

tests/test_annotated.py:38: AssertionError

This problem typically occurs when from __future__ import annotations is used with Python prior to 3.10.

This PR fixes the problem for Python 3.8 & 3.9 by evaluating string annotations with typing_extensions.get_annotations(...) (added in v4.13.0) instead of inspect.signature(..., eval_str=True), which is only available for Python 3.10+. I can't get this to work for Python 3.7, which is still declared as supported despite having reached EOL more than 2 years ago, as typing-extensions v4.13.0 requires Python 3.8+. Nevertheless, this PR fixes the above problem for all non-EOL Python versions and even Python 3.8.

Copy link

📝 Docs preview for commit cc4449a at: https://920dfd39.typertiangolo.pages.dev

@sisp sisp force-pushed the fix/eval-stringified-annotations-python-lt-3-10 branch from cc4449a to 07195af Compare July 30, 2025 14:24
@sisp sisp changed the title 🐛 Fix evaluating stringified annotations in Python 3.9 and less (also from __future__ import annotations) 🐛 Fix evaluating stringified annotations in Python 3.8 & 3.9 (also from __future__ import annotations) Jul 30, 2025
Copy link

📝 Docs preview for commit 07195af at: https://cf767148.typertiangolo.pages.dev

@sisp sisp force-pushed the fix/eval-stringified-annotations-python-lt-3-10 branch 2 times, most recently from 3121aa8 to 7e483b8 Compare July 30, 2025 14:43
Copy link

📝 Docs preview for commit 7e483b8 at: https://725f49dc.typertiangolo.pages.dev

@sisp sisp force-pushed the fix/eval-stringified-annotations-python-lt-3-10 branch from 7e483b8 to 33a2075 Compare July 30, 2025 15:14
Copy link

📝 Docs preview for commit 33a2075 at: https://f14cfab7.typertiangolo.pages.dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant