Skip to content

Nested dataclass settings class gives AttributeError: __pydantic_fields__ #356

Closed
@bschoenmaeckers

Description

@bschoenmaeckers

I have a dataclass that I don't control as a nested object (wrapped by a BaseSettings class). This used to work great but after v2.3.0 (#214) it throws a AttributeError. See the following testcase that passes on <=v2.2.1 but fails on >=v2.3.0.

def test_nested_dataclass_setting(env):
    @dataclasses.dataclass
    class DataClass:
        value: str

    class SubSettings(BaseSettings, DataClass):
        model_config = SettingsConfigDict(alias_generator=str.lower)

    class Cfg(BaseSettings):
        model_config = SettingsConfigDict(env_nested_delimiter='__')

        sub: SubSettings

    env.set('SUB__VALUE', 'something')
    cfg = Cfg()
The exception
pydantic_settings\main.py:141: in __init__
  **__pydantic_self__._settings_build_values(
pydantic_settings\main.py:260: in _settings_build_values
  CliSettingsSource(
pydantic_settings\sources.py:902: in __init__
  self._connect_root_parser(
pydantic_settings\sources.py:1236: in _connect_root_parser
  self._add_parser_args(
pydantic_settings\sources.py:1328: in _add_parser_args
  self._add_parser_args(
pydantic_settings\sources.py:1255: in _add_parser_args
  for field_name, resolved_name, field_info in self._sort_arg_fields(model):
pydantic_settings\sources.py:1151: in _sort_arg_fields
  fields = model.__pydantic_fields__ if is_pydantic_dataclass(model) else model.model_fields
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <class 'test.test_nested_dataclass_setting.<locals>.SubSettings'>, item = '__pydantic_fields__'

  def __getattr__(self, item: str) -> Any:
      """This is necessary to keep attribute access working for class attribute access."""
      private_attributes = self.__dict__.get('__private_attributes__')
      if private_attributes and item in private_attributes:
          return private_attributes[item]
      if item == '__pydantic_core_schema__':
          # This means the class didn't get a schema generated for it, likely because there was an undefined reference
          maybe_mock_validator = getattr(self, '__pydantic_validator__', None)
          if isinstance(maybe_mock_validator, MockValSer):
              rebuilt_validator = maybe_mock_validator.rebuild()
              if rebuilt_validator is not None:
                  # In this case, a validator was built, and so `__pydantic_core_schema__` should now be set
                  return getattr(self, '__pydantic_core_schema__')
>       raise AttributeError(item)
E       AttributeError: __pydantic_fields__. Did you mean: '__pydantic_fields_set__'?
maybe related to #303

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions