pydantic / pydantic-settings

Settings management using pydantic
https://docs.pydantic.dev/latest/usage/pydantic_settings/
MIT License
555 stars 55 forks source link

Determine RootModel complexity from root type #344

Closed user1584 closed 3 weeks ago

user1584 commented 1 month ago

As described in #342, on initialization of RootModels based on non-complex types such as str, the json.loads function is called to parse the environment variable contents. Thus, even though str-based variables can be passed as plain strings, a str-based RootModel requires the string to be wrapped in double quotes to make it json-compliant. The proposed code change works around this behaviour by determining the complexity of the field base on the root attribute's type. Thus, RootModels with non-complex root types should be handled as if the root type was used without being wrapped in a RootModel.

hramezani commented 1 month ago

Thanks @user1584 for this PR.

The Python 3.8 and 3.9 failing is because annotation.__annotations__.get('root', None) returns RootModelRootType for RootModel[List[Foo]] in python 3.8 and 3.9 but it returns None for the rest of python version.

So, we can probably ignore this like:

    if isinstance(annotation, type) and issubclass(annotation, RootModel):
        root_annotation = annotation.__annotations__.get('root', None)
        if root_annotation is not None and root_annotation != 'RootModelRootType':
            annotation = root_annotation

Also, I would suggest moving the whole logic to def _annotation_is_complex:

user1584 commented 3 weeks ago

@hramezani, thank you for your suggestion! I adapted the PR accordingly and the tests are working now.

hramezani commented 3 weeks ago

Thanks @user1584