Skip to content
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

Add warning when set "alias" in low level annontated field #9170

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions pydantic/_internal/_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ def collect_model_fields( # noqa: C901
# Nothing stops us from just creating a new FieldInfo for this type hint, so we do this.
field_info = FieldInfo.from_annotation(ann_type)
else:
_warning_if_annotate_have_low_level_alias(ann_type, ann_name)
sydney-runkle marked this conversation as resolved.
Show resolved Hide resolved
field_info = FieldInfo.from_annotated_attribute(ann_type, default)
# attributes which are fields are removed from the class namespace:
# 1. To match the behaviour of annotation-only fields
Expand All @@ -251,6 +252,21 @@ def collect_model_fields( # noqa: C901
return fields, class_vars


def _warning_if_annotate_have_low_level_alias(ann_type: type[Any], ann_name: str):
sydney-runkle marked this conversation as resolved.
Show resolved Hide resolved
from ..fields import FieldInfo

if hasattr(ann_type, '__args__'):
for anno_arg in ann_type.__args__:
if _typing_extra.is_annotated(anno_arg):
for anno_type_arg in _typing_extra.get_args(anno_arg):
if isinstance(anno_type_arg, FieldInfo) and anno_type_arg.alias is not None:
warnings.warn(
f'Field "{ann_name}" has `alias` should be set at higher level to have affect',
sydney-runkle marked this conversation as resolved.
Show resolved Hide resolved
UserWarning,
)
break


def _is_finalvar_with_default_val(type_: type[Any], val: Any) -> bool:
from ..fields import FieldInfo

Expand Down
13 changes: 12 additions & 1 deletion tests/test_annotated.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from typing import Any, Generic, Iterator, List, Set, TypeVar
from typing import Any, Generic, Iterator, List, Optional, Set, TypeVar

import pytest
from annotated_types import BaseMetadata, GroupedMetadata, Gt, Lt, Predicate
Expand Down Expand Up @@ -232,6 +232,17 @@ class _(BaseModel):
calls.clear()


def test_annotated_alias_at_low_level() -> None:
with pytest.warns(
UserWarning, match=r'Field "low_level_alias_field" has `alias` should be set at higher level to have affect'
sydney-runkle marked this conversation as resolved.
Show resolved Hide resolved
):

class Model(BaseModel):
low_level_alias_field: Optional[Annotated[int, Field(alias='field_alias')]] = None

assert Model(field_alias=1).low_level_alias_field is None


def test_get_pydantic_core_schema_source_type() -> None:
types: Set[Any] = set()

Expand Down