Skip to content

Commit da7debb

Browse files
committed
Remove pydantic v1 runtime compat shims and update dependencies
1 parent ad5f527 commit da7debb

4 files changed

Lines changed: 9 additions & 208 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ dependencies = [
3535
"inflect>=4.1,<8",
3636
"isort>=4.3.21,<9",
3737
"jinja2>=2.10.1,<4",
38-
"packaging",
39-
"pydantic>=1.5",
38+
"pydantic>=2",
4039
"pyyaml>=6.0.1",
4140
"tomli>=2.2.1,<3; python_version<='3.11'",
4241
]

src/datamodel_code_generator/pydantic_patch.py

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 7 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,16 @@
1-
"""Utility functions and Pydantic version compatibility helpers.
2-
3-
Provides Pydantic version detection (PYDANTIC_V2), YAML/TOML loading,
4-
and version-compatible decorators (model_validator, field_validator).
5-
"""
1+
"""Utility functions for YAML/TOML loading and lazy BaseModel access."""
62

73
from __future__ import annotations
84

95
import re
106
import warnings
117
from functools import lru_cache
12-
from typing import TYPE_CHECKING, Any, Literal, TypeVar, overload
8+
from typing import TYPE_CHECKING, Any
139

1410
if TYPE_CHECKING:
1511
from collections.abc import Callable
1612
from pathlib import Path
1713

18-
from pydantic import BaseModel as _BaseModel
19-
2014
try:
2115
from tomllib import load as load_tomllib # type: ignore[ignoreMissingImports]
2216
except ImportError: # pragma: no cover
@@ -29,34 +23,6 @@ def load_toml(path: Path) -> dict[str, Any]:
2923
return load_tomllib(f)
3024

3125

32-
@lru_cache(maxsize=1)
33-
def get_pydantic_version() -> tuple[Any, bool, bool]:
34-
"""Get pydantic version info lazily. Returns (version, is_v2, is_v2_11)."""
35-
# Apply pydantic patch before importing pydantic
36-
from datamodel_code_generator.pydantic_patch import apply_patch # noqa: PLC0415
37-
38-
apply_patch()
39-
40-
import pydantic # noqa: PLC0415
41-
from packaging import version # noqa: PLC0415
42-
43-
pydantic_version = version.parse(pydantic.VERSION if isinstance(pydantic.VERSION, str) else str(pydantic.VERSION))
44-
is_v2 = version.parse("2.0b3") <= pydantic_version
45-
is_v2_11 = version.parse("2.11") <= pydantic_version
46-
return pydantic_version, is_v2, is_v2_11
47-
48-
49-
_is_v2: bool | None = None
50-
51-
52-
def is_pydantic_v2() -> bool:
53-
"""Check if pydantic v2 is installed."""
54-
global _is_v2 # noqa: PLW0603
55-
if _is_v2 is None:
56-
_is_v2 = get_pydantic_version()[1]
57-
return _is_v2
58-
59-
6026
_YAML_1_2_BOOL_PATTERN = re.compile(r"^(?:true|false|True|False|TRUE|FALSE)$")
6127
_YAML_DEPRECATED_BOOL_VALUES = {"True", "False", "TRUE", "FALSE"}
6228
# Pattern for scientific notation without decimal point (e.g., 1e-5, 1E+10)
@@ -117,121 +83,16 @@ class CustomSafeLoader(_SafeLoader): # type: ignore[valid-type,misc]
11783
return CustomSafeLoader
11884

11985

120-
Model = TypeVar("Model", bound="_BaseModel") # ty: ignore
121-
T = TypeVar("T")
122-
123-
124-
@overload
125-
def model_validator(
126-
mode: Literal["before"],
127-
) -> (
128-
Callable[[Callable[[type[Model], T], T]], Callable[[type[Model], T], T]]
129-
| Callable[[Callable[[Model, T], T]], Callable[[Model, T], T]]
130-
): ...
131-
132-
133-
@overload
134-
def model_validator(
135-
mode: Literal["after"],
136-
) -> (
137-
Callable[[Callable[[type[Model], T], T]], Callable[[type[Model], T], T]]
138-
| Callable[[Callable[[Model, T], T]], Callable[[Model, T], T]]
139-
| Callable[[Callable[[Model], Model]], Callable[[Model], Model]]
140-
): ...
141-
142-
143-
@overload
144-
def model_validator() -> (
145-
Callable[[Callable[[type[Model], T], T]], Callable[[type[Model], T], T]]
146-
| Callable[[Callable[[Model, T], T]], Callable[[Model, T], T]]
147-
| Callable[[Callable[[Model], Model]], Callable[[Model], Model]]
148-
): ...
149-
150-
151-
def model_validator( # ty: ignore
152-
mode: Literal["before", "after"] = "after",
153-
) -> (
154-
Callable[[Callable[[type[Model], T], T]], Callable[[type[Model], T], T]]
155-
| Callable[[Callable[[Model, T], T]], Callable[[Model, T], T]]
156-
| Callable[[Callable[[Model], Model]], Callable[[Model], Model]]
157-
):
158-
"""Decorate model validators for both Pydantic v1 and v2."""
159-
160-
@overload
161-
def inner(method: Callable[[type[Model], T], T]) -> Callable[[type[Model], T], T]: ...
162-
163-
@overload
164-
def inner(method: Callable[[Model, T], T]) -> Callable[[Model, T], T]: ...
165-
166-
@overload
167-
def inner(method: Callable[[Model], Model]) -> Callable[[Model], Model]: ...
168-
169-
def inner(
170-
method: Callable[[type[Model], T], T] | Callable[[Model, T], T] | Callable[[Model], Model],
171-
) -> Callable[[type[Model], T], T] | Callable[[Model, T], T] | Callable[[Model], Model]:
172-
if is_pydantic_v2():
173-
from pydantic import model_validator as model_validator_v2 # noqa: PLC0415
174-
175-
if mode == "before":
176-
return model_validator_v2(mode=mode)(classmethod(method)) # type: ignore[reportReturnType]
177-
return model_validator_v2(mode=mode)(method) # type: ignore[reportReturnType]
178-
from pydantic import root_validator # noqa: PLC0415 # pragma: no cover
179-
180-
return root_validator(method, pre=mode == "before") # ty: ignore # pragma: no cover
181-
182-
return inner
183-
184-
185-
def field_validator(
186-
field_name: str,
187-
*fields: str,
188-
mode: Literal["before", "after"] = "after",
189-
) -> Callable[[Any], Callable[[Any, Any], Any]]:
190-
"""Decorate field validators for both Pydantic v1 and v2."""
191-
192-
def inner(method: Callable[[Model, Any], Any]) -> Callable[[Model, Any], Any]:
193-
if is_pydantic_v2():
194-
from pydantic import field_validator as field_validator_v2 # noqa: PLC0415
195-
196-
return field_validator_v2(field_name, *fields, mode=mode)(method) # ty: ignore
197-
from pydantic import validator # noqa: PLC0415 # pragma: no cover
198-
199-
return validator(field_name, *fields, pre=mode == "before")(method) # ty: ignore # pragma: no cover
200-
201-
return inner
202-
203-
204-
@lru_cache(maxsize=1)
205-
def _get_config_dict() -> type:
206-
"""Get ConfigDict type lazily. Only used with pydantic v2."""
207-
from pydantic import ConfigDict # noqa: PLC0415
208-
209-
return ConfigDict
210-
211-
212-
class _ConfigDictProxy:
213-
"""Proxy for lazy ConfigDict access."""
214-
215-
def __call__(self, **kwargs: Any) -> Any:
216-
return _get_config_dict()(**kwargs)
217-
218-
219-
ConfigDict: type = _ConfigDictProxy() # type: ignore[assignment]
220-
221-
22286
@lru_cache(maxsize=1)
22387
def _get_base_model_class() -> type:
224-
"""Get version-compatible BaseModel class lazily."""
88+
"""Get BaseModel class with strict=False config lazily."""
22589
from pydantic import BaseModel as _PydanticBaseModel # noqa: PLC0415
90+
from pydantic import ConfigDict as _ConfigDict # noqa: PLC0415
22691

227-
if is_pydantic_v2():
228-
from pydantic import ConfigDict as _ConfigDict # noqa: PLC0415
92+
class _BaseModelV2(_PydanticBaseModel):
93+
model_config = _ConfigDict(strict=False)
22994

230-
class _BaseModelV2(_PydanticBaseModel):
231-
model_config = _ConfigDict(strict=False)
232-
233-
return _BaseModelV2
234-
return _PydanticBaseModel # pragma: no cover
95+
return _BaseModelV2
23596

23697

23798
_BaseModel: type | None = None
@@ -290,31 +151,3 @@ def camel_to_snake(string: str) -> str:
290151
"""Convert camelCase or PascalCase to snake_case."""
291152
subbed = _UNDER_SCORE_1.sub(r"\1_\2", string)
292153
return _UNDER_SCORE_2.sub(r"\1_\2", subbed).lower()
293-
294-
295-
def model_dump(obj: _BaseModel, **kwargs: Any) -> dict[str, Any]: # ty: ignore
296-
"""Version-compatible model serialization (dict/model_dump)."""
297-
if is_pydantic_v2():
298-
return obj.model_dump(**kwargs) # ty: ignore
299-
return obj.dict(**kwargs) # type: ignore[reportDeprecated] # pragma: no cover
300-
301-
302-
def model_validate(cls: type[Model], obj: Any) -> Model:
303-
"""Version-compatible model validation (parse_obj/model_validate)."""
304-
if is_pydantic_v2():
305-
return cls.model_validate(obj) # ty: ignore
306-
return cls.parse_obj(obj) # type: ignore[reportDeprecated] # pragma: no cover
307-
308-
309-
def get_fields_set(obj: _BaseModel) -> set[str]: # ty: ignore
310-
"""Version-compatible access to fields set (__fields_set__/model_fields_set)."""
311-
if is_pydantic_v2():
312-
return obj.model_fields_set # ty: ignore
313-
return obj.__fields_set__ # type: ignore[reportDeprecated] # pragma: no cover
314-
315-
316-
def model_copy(obj: Model, **kwargs: Any) -> Model:
317-
"""Version-compatible model copy (copy/model_copy)."""
318-
if is_pydantic_v2():
319-
return obj.model_copy(**kwargs) # ty: ignore
320-
return obj.copy(**kwargs) # type: ignore[reportDeprecated] # pragma: no cover

uv.lock

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)