Skip to content

Commit 352a2db

Browse files
committed
Support pydantic 2 settings
In pydantic 2, the BaseSettings class was exported to a standalone package. This change preserves support pydantic 1 while adding support pydantic 2. All error related to loading pydantic settings reflect the structure of pydantic 2.
1 parent a76045c commit 352a2db

File tree

2 files changed

+38
-18
lines changed

2 files changed

+38
-18
lines changed

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ def _open(filename):
7575
"yaml": [
7676
"pyyaml",
7777
],
78-
"pydantic": [
79-
"pydantic",
78+
"pydantic-settings": [
79+
"pydantic-settings",
8080
],
8181
"flask": [
8282
"flask",

src/dependency_injector/providers.pyx

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ try:
4848
except ImportError:
4949
yaml = None
5050

51+
52+
try:
53+
import pydantic_settings
54+
except ImportError:
55+
pydantic_settings = None
56+
57+
5158
try:
5259
import pydantic
5360
except ImportError:
@@ -61,6 +68,17 @@ from .errors import (
6168
cimport cython
6269

6370

71+
if pydantic_settings:
72+
pydantic_settings_pkg = pydantic_settings
73+
using_pydantic_2 = True
74+
elif pydantic and pydantic.version.VERSION.startswith("1"):
75+
pydantic_settings_pkg = pydantic.settings
76+
using_pydantic_2 = False
77+
else:
78+
pydantic_settings_pkg = None
79+
using_pydantic_2 = None
80+
81+
6482
if sys.version_info[0] == 3: # pragma: no cover
6583
CLASS_TYPES = (type,)
6684
else: # pragma: no cover
@@ -1796,26 +1814,27 @@ cdef class ConfigurationOption(Provider):
17961814
17971815
:rtype: None
17981816
"""
1799-
if pydantic is None:
1817+
if pydantic_settings_pkg is None:
18001818
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]\""
1819+
"Unable to load pydantic-settings configuration - pydantic-settings is not installed. "
1820+
"Install pydantic-settings or install Dependency Injector with pydantic-settings extras: "
1821+
"\"pip install dependency-injector[pydantic-settings]\""
18041822
)
18051823

1806-
if isinstance(settings, CLASS_TYPES) and issubclass(settings, pydantic.BaseSettings):
1824+
if isinstance(settings, CLASS_TYPES) and issubclass(settings, pydantic_settings_pkg.BaseSettings):
18071825
raise Error(
18081826
"Got settings class, but expect instance: "
18091827
"instead \"{0}\" use \"{0}()\"".format(settings.__name__)
18101828
)
18111829

1812-
if not isinstance(settings, pydantic.BaseSettings):
1830+
if not isinstance(settings, pydantic_settings_pkg.BaseSettings):
18131831
raise Error(
1814-
"Unable to recognize settings instance, expect \"pydantic.BaseSettings\", "
1832+
"Unable to recognize settings instance, expect \"pydantic_settings.BaseSettings\", "
18151833
"got {0} instead".format(settings)
18161834
)
18171835

1818-
self.from_dict(settings.dict(**kwargs), required=required)
1836+
settings_dict = settings.model_dump(**kwargs) if using_pydantic_2 else settings.dict(**kwargs)
1837+
self.from_dict(settings_dict, required=required)
18191838

18201839
def from_dict(self, options, required=UNDEFINED):
18211840
"""Load configuration from the dictionary.
@@ -2365,26 +2384,27 @@ cdef class Configuration(Object):
23652384
23662385
:rtype: None
23672386
"""
2368-
if pydantic is None:
2387+
if pydantic_settings_pkg is None:
23692388
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]\""
2389+
"Unable to load pydantic-settings configuration - pydantic-settings is not installed. "
2390+
"Install pydantic-settings or install Dependency Injector with pydantic-settings extras: "
2391+
"\"pip install dependency-injector[pydantic-settings]\""
23732392
)
23742393

2375-
if isinstance(settings, CLASS_TYPES) and issubclass(settings, pydantic.BaseSettings):
2394+
if isinstance(settings, CLASS_TYPES) and issubclass(settings, pydantic_settings_pkg.BaseSettings):
23762395
raise Error(
23772396
"Got settings class, but expect instance: "
23782397
"instead \"{0}\" use \"{0}()\"".format(settings.__name__)
23792398
)
23802399

2381-
if not isinstance(settings, pydantic.BaseSettings):
2400+
if not isinstance(settings, pydantic_settings_pkg.BaseSettings):
23822401
raise Error(
2383-
"Unable to recognize settings instance, expect \"pydantic.BaseSettings\", "
2402+
"Unable to recognize settings instance, expect \"pydantic_settings.BaseSettings\", "
23842403
"got {0} instead".format(settings)
23852404
)
23862405

2387-
self.from_dict(settings.dict(**kwargs), required=required)
2406+
settings_dict = settings.model_dump(**kwargs) if using_pydantic_2 else settings.dict(**kwargs)
2407+
self.from_dict(settings_dict, required=required)
23882408

23892409
def from_dict(self, options, required=UNDEFINED):
23902410
"""Load configuration from the dictionary.

0 commit comments

Comments
 (0)