Skip to content

Unwrap Annotated[T, ...] inside find_graphene_type#115

Open
vishwa2710 wants to merge 1 commit intographql-python:mainfrom
vishwa2710:fix/unwrap-annotated-in-find-graphene-type
Open

Unwrap Annotated[T, ...] inside find_graphene_type#115
vishwa2710 wants to merge 1 commit intographql-python:mainfrom
vishwa2710:fix/unwrap-annotated-in-find-graphene-type

Conversation

@vishwa2710
Copy link
Copy Markdown

@vishwa2710 vishwa2710 commented May 1, 2026

Summary

Pydantic v2 strips top-level Annotated metadata from FieldInfo.annotation, so x: PositiveFloat reaches the converter as bare float. However, pydantic does not strip Annotated inside Union arms or generic containers, so x: Optional[PositiveFloat] reaches find_graphene_type as Union[Annotated[float, Gt(gt=0)], None]. The inner arm gets dispatched to convert_generic_python_type (because Annotated.__origin__ is the inner type) and raises ConversionError.

This affects every constrained pydantic scalar — PositiveFloat, PositiveInt, NonNegativeInt, conint(...), confloat(...) — whenever it appears inside Optional, a list, or any other container. It also breaks user-defined Annotated[T, ...] aliases in the same positions.

Recursive call sites (convert_union_type, convert_generic_python_type) re-enter find_graphene_type and benefit automatically.

(Created with help from Claude Code)

Pydantic v2 strips top-level Annotated metadata from FieldInfo.annotation,
but does not strip Annotated inside Union arms or generic containers, so
Optional[PositiveFloat] reaches find_graphene_type as
Union[Annotated[float, Gt(gt=0)], None]. The inner arm was dispatched to
convert_generic_python_type and raised ConversionError. This affected
every constrained pydantic scalar (PositiveFloat, PositiveInt,
NonNegativeInt, conint(...), confloat(...)) inside Optional or any
container, plus user-defined Annotated[T, ...] aliases in the same
positions.

Unwrap Annotated[T, ...] -> T at the entry point alongside the existing
PEP 604 UnionType normalization. Constraints (Gt, Le, etc.) are already
enforced by pydantic at validation time and have no GraphQL
representation, so dropping them at conversion is correct.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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