Skip to content

Commit c788a08

Browse files
committed
Fix handle type alias declared with type statement
1 parent 9380bc6 commit c788a08

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

pydantic_settings/sources/base.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from pydantic._internal._utils import is_model_class
1717
from pydantic.fields import FieldInfo
1818
from typing_extensions import get_args
19+
from typing_inspection import typing_objects
1920
from typing_inspection.introspection import is_union_origin
2021

2122
from ..exceptions import SettingsError
@@ -25,6 +26,7 @@
2526
_annotation_is_complex,
2627
_get_alias_names,
2728
_get_model_fields,
29+
_strip_annotated,
2830
_union_is_complex,
2931
)
3032

@@ -353,7 +355,10 @@ def _extract_field_info(self, field: FieldInfo, field_name: str) -> list[tuple[s
353355
field_info.append((v_alias, self._apply_case_sensitive(v_alias), False))
354356

355357
if not v_alias or self.config.get('populate_by_name', False):
356-
if is_union_origin(get_origin(field.annotation)) and _union_is_complex(field.annotation, field.metadata):
358+
annotation = field.annotation
359+
if typing_objects.is_typealiastype(annotation):
360+
annotation = _strip_annotated(annotation.__value__)
361+
if is_union_origin(get_origin(annotation)) and _union_is_complex(annotation, field.metadata):
357362
field_info.append((field_name, self._apply_case_sensitive(self.env_prefix + field_name), True))
358363
else:
359364
field_info.append((field_name, self._apply_case_sensitive(self.env_prefix + field_name), False))

pydantic_settings/sources/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ def parse_env_vars(
4343
def _annotation_is_complex(annotation: type[Any] | None, metadata: list[Any]) -> bool:
4444
# If the model is a root model, the root annotation should be used to
4545
# evaluate the complexity.
46+
if typing_objects.is_typealiastype(annotation):
47+
annotation = annotation.__value__
4648
if annotation is not None and _lenient_issubclass(annotation, RootModel) and annotation is not RootModel:
4749
annotation = cast('type[RootModel[Any]]', annotation)
4850
root_annotation = annotation.model_fields['root'].annotation

tests/test_settings.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
dataclasses as pydantic_dataclasses,
3535
)
3636
from pydantic.fields import FieldInfo
37-
from typing_extensions import override
37+
from typing_extensions import TypeAliasType, override
3838

3939
from pydantic_settings import (
4040
BaseSettings,
@@ -474,6 +474,21 @@ class AnnotatedComplexSettings(BaseSettings):
474474
]
475475

476476

477+
def test_annotated_with_type(env):
478+
"""https://github.com/pydantic/pydantic-settings/issues/536.
479+
480+
PEP 695 type aliases need to be analyzed when determining if an annotation is complex.
481+
"""
482+
MinLenList = TypeAliasType('MinLenList', Annotated[Union[list[str], list[int]], MinLen(2)])
483+
484+
class AnnotatedComplexSettings(BaseSettings):
485+
apples: MinLenList
486+
487+
env.set('apples', '["russet", "granny smith"]')
488+
s = AnnotatedComplexSettings()
489+
assert s.apples == ['russet', 'granny smith']
490+
491+
477492
def test_set_dict_model(env):
478493
env.set('bananas', '[1, 2, 3, 3]')
479494
env.set('CARROTS', '{"a": null, "b": 4}')

0 commit comments

Comments
 (0)