Skip to content

Conversation

@tselepakis
Copy link
Contributor

@tselepakis tselepakis commented Oct 20, 2025

Provide field metadata utility function to properly handle Annotated types.

The issue was mentioned here.

Fixes #715.

@hramezani hramezani requested a review from Viicos October 23, 2025 11:01
@tselepakis tselepakis force-pushed the issue-536-fix branch 2 times, most recently from bf696b4 to bd44f2c Compare October 23, 2025 16:32
@tselepakis
Copy link
Contributor Author

tselepakis commented Oct 23, 2025

@Viicos let's continue the discussion about this here if you like. I had a quick look on the tests and I wasn't able to find any relevant test that we have nested annotations with NoDecode. Although I understand your concern regarding nesting, I am not sure I can replicate the issue. Do we actually care about the underling structure? I think we only need to identify that this field should not be decoded.

I tried something like this and it seems to work.

IntOrStr = TypeAliasType('IntOrStr', int | str)
A = TypeAliasType('A', Annotated[list[IntOrStr], NoDecode])

this also works

ListOrTuple = TypeAliasType('ListOrTuple', list[str] | tuple[str])
A = TypeAliasType('A', Annotated[ListOrTuple, NoDecode])

)


def _get_field_metadata(field: Any) -> list[Any]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def _get_field_metadata(field: Any) -> list[Any]:
def _get_field_metadata(field: FieldInfo) -> list[Any]:

@Viicos
Copy link
Member

Viicos commented Nov 25, 2025

I tried something like this and it seems to work.

IntOrStr = TypeAliasType('IntOrStr', int | str)
A = TypeAliasType('A', Annotated[list[IntOrStr], NoDecode])

What I was referring to by "nested" type aliases, is with something like:

B = TypeAliasType('B', Annotated[list[str], NoDecode])
A = TypeAliasType('A', Annotated[B, ...])

class Settings(BaseSettings):
    a: A

To be tested but I think right now this isn't taken into account? If not, let's go with what we have currently now, as it looks like this was a regression initially.

@Viicos Viicos changed the title Issue 536 fix Unpack type alisases when looking for NoDecode Nov 25, 2025
@tselepakis
Copy link
Contributor Author

@Viicos you are correct, we don't take into account this case. I worked a solution but I am not sure if this is the correct approach. Does it makes sense to gather all metadata together or we care only about NoDecode?

def _get_annotation_metadata(annotation: Any) -> list[Any]:
    if typing_objects.is_typealiastype(annotation) or typing_objects.is_typealiastype(get_origin(annotation)):
        annotation = annotation.__value__

    origin = get_origin(annotation)
    if not typing_objects.is_annotated(origin):
        return []

    inner_annotation, *metadata = get_args(annotation)
    if typing_objects.is_typealiastype(inner_annotation) or typing_objects.is_typealiastype(
        get_origin(inner_annotation)
    ):
        metadata += _get_annotation_metadata(inner_annotation)

    return metadata


def _get_field_metadata(field: FieldInfo) -> list[Any]:
    annotation = field.annotation
    metadata = field.metadata

    metadata += _get_annotation_metadata(annotation)

    return metadata

@Viicos
Copy link
Member

Viicos commented Nov 27, 2025

@tselepakis more generally (as I mentioned in #644 (comment)) the approach pydantic-settings is taking isn't really ideal and I fear we are going to face more limitations as time goes by. Let's merge as is and we can iterate later as ideally I'd like to make use of pydantic/typing-inspection#35 for this.

Happy to merge once the remaining feedback is applied.

@tselepakis
Copy link
Contributor Author

Sounds good to me. PR updated. I think we are good to go.

Copy link
Member

@Viicos Viicos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @tselepakis!

@Viicos Viicos merged commit c313e06 into pydantic:main Nov 27, 2025
19 checks passed
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.

NoDecode not working when the field's annotation is defined by using the type statement instead of through simple assignment

2 participants