48
48
except ImportError :
49
49
yaml = None
50
50
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
+
51
56
try :
52
- import pydantic
57
+ from pydantic_settings import BaseSettings as PydanticSettings
53
58
except 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
+
55
70
56
71
from .errors import (
57
72
Error,
@@ -149,6 +164,31 @@ cdef int ASYNC_MODE_DISABLED = 2
149
164
cdef set __iscoroutine_typecache = set ()
150
165
cdef tuple __COROUTINE_TYPES = asyncio.coroutines._COROUTINE_TYPES if asyncio else tuple ()
151
166
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
+
152
192
153
193
cdef class Provider(object ):
154
194
""" Base provider class.
@@ -1786,36 +1826,20 @@ cdef class ConfigurationOption(Provider):
1786
1826
Loaded configuration is merged recursively over existing configuration.
1787
1827
1788
1828
: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)
1790
1831
1791
1832
:param required: When required is True, raise an exception if settings dict is empty.
1792
1833
:type required: bool
1793
1834
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).
1795
1837
:type kwargs: Dict[Any, Any]
1796
1838
1797
1839
:rtype: None
1798
1840
"""
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
- )
1805
1841
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)
1819
1843
1820
1844
def from_dict (self , options , required = UNDEFINED):
1821
1845
""" Load configuration from the dictionary.
@@ -2355,7 +2379,8 @@ cdef class Configuration(Object):
2355
2379
Loaded configuration is merged recursively over existing configuration.
2356
2380
2357
2381
: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)
2359
2384
2360
2385
:param required: When required is True, raise an exception if settings dict is empty.
2361
2386
:type required: bool
@@ -2365,26 +2390,8 @@ cdef class Configuration(Object):
2365
2390
2366
2391
:rtype: None
2367
2392
"""
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
- )
2386
2393
2387
- self .from_dict(settings.dict( ** kwargs), required = required)
2394
+ self .from_dict(pydantic_settings_to_dict(settings, kwargs), required = required)
2388
2395
2389
2396
def from_dict (self , options , required = UNDEFINED):
2390
2397
""" Load configuration from the dictionary.
0 commit comments