4848except ImportError :
4949 yaml = None
5050
51+ has_pydantic_settings = True
52+ cdef bint pydantic_v1 = False
53+ cdef str pydantic_module = " pydantic_settings"
54+ cdef str pydantic_extra = " pydantic2"
55+
5156try :
52- import pydantic
57+ from pydantic_settings import BaseSettings as PydanticSettings
5358except ImportError :
54- pydantic = None
59+ try :
60+ # pydantic-settings requires pydantic v2,
61+ # so it is safe to assume that we're dealing with v1:
62+ from pydantic import BaseSettings as PydanticSettings
63+ pydantic_v1 = True
64+ pydantic_module = " pydantic"
65+ pydantic_extra = " pydantic"
66+ except ImportError :
67+ # if it is present, ofc
68+ has_pydantic_settings = False
69+
5570
5671from .errors import (
5772 Error,
@@ -149,6 +164,31 @@ cdef int ASYNC_MODE_DISABLED = 2
149164cdef set __iscoroutine_typecache = set ()
150165cdef tuple __COROUTINE_TYPES = asyncio.coroutines._COROUTINE_TYPES if asyncio else tuple ()
151166
167+ cdef dict pydantic_settings_to_dict(settings, dict kwargs):
168+ if not has_pydantic_settings:
169+ raise Error(
170+ f" Unable to load pydantic configuration - {pydantic_module} is not installed. "
171+ " Install pydantic or install Dependency Injector with pydantic extras: "
172+ f" \" pip install dependency-injector[{pydantic_extra}]\" "
173+ )
174+
175+ if isinstance (settings, CLASS_TYPES) and issubclass (settings, PydanticSettings):
176+ raise Error(
177+ " Got settings class, but expect instance: "
178+ " instead \" {0}\" use \" {0}()\" " .format(settings.__name__ )
179+ )
180+
181+ if not isinstance (settings, PydanticSettings):
182+ raise Error(
183+ f" Unable to recognize settings instance, expect \" {pydantic_module}.BaseSettings\" , "
184+ f" got {settings} instead"
185+ )
186+
187+ if pydantic_v1:
188+ return settings.dict(** kwargs)
189+
190+ return settings.model_dump(mode = " python" , ** kwargs)
191+
152192
153193cdef class Provider(object ):
154194 """ Base provider class.
@@ -1786,36 +1826,20 @@ cdef class ConfigurationOption(Provider):
17861826 Loaded configuration is merged recursively over existing configuration.
17871827
17881828 :param settings: Pydantic settings instances.
1789- :type settings: :py:class:`pydantic.BaseSettings`
1829+ :type settings: :py:class:`pydantic.BaseSettings` (pydantic v1) or
1830+ :py:class:`pydantic_settings.BaseSettings` (pydantic v2 and onwards)
17901831
17911832 :param required: When required is True, raise an exception if settings dict is empty.
17921833 :type required: bool
17931834
1794- :param kwargs: Keyword arguments forwarded to ``pydantic.BaseSettings.dict()`` call.
1835+ :param kwargs: Keyword arguments forwarded to ``pydantic.BaseSettings.dict()`` or
1836+ ``pydantic_settings.BaseSettings.model_dump()`` call (based on pydantic version).
17951837 :type kwargs: Dict[Any, Any]
17961838
17971839 :rtype: None
17981840 """
1799- if pydantic is None :
1800- raise Error(
1801- " Unable to load pydantic configuration - pydantic is not installed. "
1802- " Install pydantic or install Dependency Injector with pydantic extras: "
1803- " \" pip install dependency-injector[pydantic]\" "
1804- )
18051841
1806- if isinstance (settings, CLASS_TYPES) and issubclass (settings, pydantic.BaseSettings):
1807- raise Error(
1808- " Got settings class, but expect instance: "
1809- " instead \" {0}\" use \" {0}()\" " .format(settings.__name__ )
1810- )
1811-
1812- if not isinstance (settings, pydantic.BaseSettings):
1813- raise Error(
1814- " Unable to recognize settings instance, expect \" pydantic.BaseSettings\" , "
1815- " got {0} instead" .format(settings)
1816- )
1817-
1818- self .from_dict(settings.dict(** kwargs), required = required)
1842+ self .from_dict(pydantic_settings_to_dict(settings, kwargs), required = required)
18191843
18201844 def from_dict (self , options , required = UNDEFINED):
18211845 """ Load configuration from the dictionary.
@@ -2355,7 +2379,8 @@ cdef class Configuration(Object):
23552379 Loaded configuration is merged recursively over existing configuration.
23562380
23572381 :param settings: Pydantic settings instances.
2358- :type settings: :py:class:`pydantic.BaseSettings`
2382+ :type settings: :py:class:`pydantic.BaseSettings` (pydantic v1) or
2383+ :py:class:`pydantic_settings.BaseSettings` (pydantic v2 and onwards)
23592384
23602385 :param required: When required is True, raise an exception if settings dict is empty.
23612386 :type required: bool
@@ -2365,26 +2390,8 @@ cdef class Configuration(Object):
23652390
23662391 :rtype: None
23672392 """
2368- if pydantic is None :
2369- raise Error(
2370- " Unable to load pydantic configuration - pydantic is not installed. "
2371- " Install pydantic or install Dependency Injector with pydantic extras: "
2372- " \" pip install dependency-injector[pydantic]\" "
2373- )
2374-
2375- if isinstance (settings, CLASS_TYPES) and issubclass (settings, pydantic.BaseSettings):
2376- raise Error(
2377- " Got settings class, but expect instance: "
2378- " instead \" {0}\" use \" {0}()\" " .format(settings.__name__ )
2379- )
2380-
2381- if not isinstance (settings, pydantic.BaseSettings):
2382- raise Error(
2383- " Unable to recognize settings instance, expect \" pydantic.BaseSettings\" , "
2384- " got {0} instead" .format(settings)
2385- )
23862393
2387- self .from_dict(settings.dict( ** kwargs), required = required)
2394+ self .from_dict(pydantic_settings_to_dict(settings, kwargs), required = required)
23882395
23892396 def from_dict (self , options , required = UNDEFINED):
23902397 """ Load configuration from the dictionary.
0 commit comments