Skip to content

Raise NameError for unresolvable forward-ref annotations#2

Open
yashwant86 wants to merge 4 commits intomasterfrom
pr-15307
Open

Raise NameError for unresolvable forward-ref annotations#2
yashwant86 wants to merge 4 commits intomasterfrom
pr-15307

Conversation

@yashwant86
Copy link
Copy Markdown

@yashwant86 yashwant86 commented Apr 7, 2026

Mirror of fastapi#15307


Summary by MergeMonkey

  • Just Shipped:
    • Raise a clear NameError when forward-reference type annotations cannot be resolved at route registration time
  • Fixes & Patches:
    • Prevent silent failures when types are only imported inside TYPE_CHECKING blocks or defined after the route that uses them

@mergemonkeyhq
Copy link
Copy Markdown

mergemonkeyhq Bot commented Apr 14, 2026

Walkthrough

When a FastAPI route or dependency uses a type annotation that cannot be resolved at runtime — such as a type imported only under if TYPE_CHECKING: or a class defined after the route — the framework now raises a clear NameError at route registration time with an actionable error message, instead of silently producing incorrect behavior or cryptic errors later.

Changes

Files Summary
Forward-ref resolution error handling
fastapi/dependencies/utils.py
After evaluating a ForwardRef, checks whether the result is still a ForwardRef (indicating resolution failure) and raises a descriptive NameError with guidance about common causes like TYPE_CHECKING imports and late class definitions.
Unit tests for get_typed_annotation
tests/test_dependencies_utils.py
Adds unit tests covering unresolvable string and ForwardRef annotations (expecting NameError), resolvable annotations, and non-annotation passthrough behavior.
Integration test apps for unresolvable annotations
tests/test_unresolvable_annotations/apps/annotated_depends_late_type.py, type_checking_dep_return_type_safe.py, type_checking_in_dep_param.py, type_checking_in_endpoint_param.py, type_checking_in_return_type.py, type_declared_after_endpoint.py, valid_type_before_endpoint.py
Provides minimal FastAPI app fixtures exercising various annotation failure scenarios (TYPE_CHECKING imports, late-defined types, Annotated+Depends) and one valid baseline app.
Integration tests for unresolvable annotations
tests/test_unresolvable_annotations/test_unresolvable_annotations.py
Integration tests that import each app module and assert NameError is raised at route registration for unresolvable annotations, while verifying safe patterns and valid apps still work.

Sequence Diagram

sequenceDiagram
    participant App as FastAPI App
    participant Router as Route Registration
    participant DepUtils as get_typed_annotation
    participant EvalRef as evaluate_forwardref

    App->>Router: @app.get("/") with annotated param
    Router->>DepUtils: get_typed_annotation(annotation, globalns)
    alt annotation is string
        DepUtils->>DepUtils: Convert to ForwardRef
    end
    alt annotation is ForwardRef
        DepUtils->>EvalRef: evaluate_forwardref(ref, globalns, globalns)
        EvalRef-->>DepUtils: resolved type or unchanged ForwardRef
        alt result is still ForwardRef
            DepUtils-->>Router: raise NameError("Could not resolve...")
            Router-->>App: NameError propagates
        else result is resolved type
            DepUtils-->>Router: return resolved type
        end
    else annotation is concrete type
        DepUtils-->>Router: return annotation unchanged
    end
Loading

Dig Deeper With Commands

  • /review <file-path> <function-optional>
  • /chat <file-path> "<question>"
  • /roast <file-path>

Runs only when explicitly triggered.

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.

2 participants