Conversation
WalkthroughMigrate internal Pydantic v1 APIs to version-compatible adapters (model_validate/model_dump/model_copy/get_fields_set), add TargetPydanticVersion enum and CLI/config flag --target-pydantic-version, thread that option through generators and parsers, update models/tests/docs/expected outputs for Pydantic v2/v2.11 compatibility. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant CLI as CLI
participant Main as run_generate / generate
participant Parser as Parser (JsonSchema/OpenAPI/GraphQL)
participant Util as util (model_validate/model_dump/model_copy/get_fields_set)
participant ModelGen as Template Renderer
rect rgba(200,230,201,0.5)
CLI->>Main: parse args (incl. --target-pydantic-version)
Main->>Parser: instantiate(parser_config, target_pydantic_version)
end
rect rgba(187,222,251,0.5)
Parser->>Util: model_validate(raw schema/object)
Util-->>Parser: validated instance
Parser->>Util: model_dump / get_fields_set / model_copy (for merges, hashes, constraints)
Util-->>Parser: serialized/copy results
end
rect rgba(255,249,196,0.5)
Parser->>ModelGen: render templates (config influenced by target_pydantic_version)
ModelGen-->>Main: rendered code files
Main->>CLI: write outputs
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/datamodel_code_generator/model/pydantic/__init__.py (1)
40-44: Good compatibility layer, but remove unused noqa directive.The
dict()method correctly provides template compatibility by delegating tomodel_dump. However, the# noqa: PLC0415directive on line 42 is unnecessary based on static analysis.🔎 Remove unused noqa directive
def dict(self, **kwargs: Any) -> dict[str, Any]: # type: ignore[override] """Version-compatible dict method for templates.""" - from datamodel_code_generator.util import model_dump # noqa: PLC0415 + from datamodel_code_generator.util import model_dump return model_dump(self, **kwargs)src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
180-197: LGTM! Correct Pydantic v2.11+ compatibility handling.The conditional
CONFIG_ATTRIBUTESproperly handles the deprecation ofpopulate_by_namein favor ofvalidate_by_namefor Pydantic v2.11+. This ensures generated code uses the correct ConfigDict parameter based on the Pydantic version.Static analysis reports the
# noqa: FBT003directives as unused. These could be removed for cleaner code, though they don't cause issues.🔎 Optional cleanup of unused noqa directives
CONFIG_ATTRIBUTES: ClassVar[list[ConfigAttribute]] = ( [ - ConfigAttribute("allow_population_by_field_name", "validate_by_name", False), # noqa: FBT003 - ConfigAttribute("populate_by_name", "validate_by_name", False), # noqa: FBT003 - ConfigAttribute("allow_mutation", "frozen", True), # noqa: FBT003 - ConfigAttribute("frozen", "frozen", False), # noqa: FBT003 - ConfigAttribute("use_attribute_docstrings", "use_attribute_docstrings", False), # noqa: FBT003 + ConfigAttribute("allow_population_by_field_name", "validate_by_name", False), + ConfigAttribute("populate_by_name", "validate_by_name", False), + ConfigAttribute("allow_mutation", "frozen", True), + ConfigAttribute("frozen", "frozen", False), + ConfigAttribute("use_attribute_docstrings", "use_attribute_docstrings", False), ] if PYDANTIC_V2_11 else [ - ConfigAttribute("allow_population_by_field_name", "populate_by_name", False), # noqa: FBT003 - ConfigAttribute("populate_by_name", "populate_by_name", False), # noqa: FBT003 - ConfigAttribute("allow_mutation", "frozen", True), # noqa: FBT003 - ConfigAttribute("frozen", "frozen", False), # noqa: FBT003 - ConfigAttribute("use_attribute_docstrings", "use_attribute_docstrings", False), # noqa: FBT003 + ConfigAttribute("allow_population_by_field_name", "populate_by_name", False), + ConfigAttribute("populate_by_name", "populate_by_name", False), + ConfigAttribute("allow_mutation", "frozen", True), + ConfigAttribute("frozen", "frozen", False), + ConfigAttribute("use_attribute_docstrings", "use_attribute_docstrings", False), ] )src/datamodel_code_generator/parser/jsonschema.py (1)
1801-1803: Consider usingmodel_copy()wrapper for consistency (optional).These lines use inline
PYDANTIC_V2checks to choose between.copy()and.model_copy(). For consistency with the rest of the file, consider using themodel_copy()wrapper fromutil.py:new_type = model_copy(inherited_type, deep=True)This would align with the migration pattern used elsewhere in the file.
Also applies to: 1817-1817, 1836-1836
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
pyproject.tomlsrc/datamodel_code_generator/model/base.pysrc/datamodel_code_generator/model/msgspec.pysrc/datamodel_code_generator/model/pydantic/__init__.pysrc/datamodel_code_generator/model/pydantic/base_model.pysrc/datamodel_code_generator/model/pydantic_v2/__init__.pysrc/datamodel_code_generator/model/pydantic_v2/base_model.pysrc/datamodel_code_generator/parser/base.pysrc/datamodel_code_generator/parser/jsonschema.pysrc/datamodel_code_generator/parser/openapi.pysrc/datamodel_code_generator/util.pytests/data/expected/main/jsonschema/root_model_config_populate_by_name.pytests/data/expected/main/jsonschema/use_generic_base_class_populate_by_name.pytests/data/expected/main/openapi/allow_population_by_field_name_pydantic_v2.py
🧰 Additional context used
🧬 Code graph analysis (11)
src/datamodel_code_generator/model/msgspec.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)
tests/data/expected/main/openapi/allow_population_by_field_name_pydantic_v2.py (2)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
BaseModel(170-332)src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-47)
src/datamodel_code_generator/model/base.py (1)
src/datamodel_code_generator/util.py (3)
model_copy(181-185)model_dump(160-164)model_validate(167-171)
src/datamodel_code_generator/util.py (2)
src/datamodel_code_generator/reference.py (1)
_BaseModel(81-138)src/datamodel_code_generator/__main__.py (1)
parse_obj(123-125)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (2)
src/datamodel_code_generator/util.py (6)
field_validator(117-133)model_validate(167-171)model_validator(57-62)model_validator(66-72)model_validator(76-80)model_validator(83-114)src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-47)
src/datamodel_code_generator/model/pydantic/base_model.py (3)
src/datamodel_code_generator/util.py (2)
model_dump(160-164)model_validate(167-171)src/datamodel_code_generator/model/pydantic/__init__.py (1)
Config(27-44)src/datamodel_code_generator/__main__.py (2)
Config(108-494)Config(134-138)
src/datamodel_code_generator/parser/openapi.py (1)
src/datamodel_code_generator/util.py (3)
BaseModel(142-146)model_dump(160-164)model_validate(167-171)
src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)
src/datamodel_code_generator/parser/base.py (1)
src/datamodel_code_generator/util.py (3)
camel_to_snake(154-157)model_copy(181-185)model_dump(160-164)
src/datamodel_code_generator/model/pydantic/__init__.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)
src/datamodel_code_generator/parser/jsonschema.py (2)
src/datamodel_code_generator/util.py (3)
get_fields_set(174-178)model_dump(160-164)model_validate(167-171)src/datamodel_code_generator/__main__.py (1)
parse_obj(123-125)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/model/pydantic_v2/base_model.py
183-183: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
184-184: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
185-185: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
186-186: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
187-187: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
191-191: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
192-192: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
193-193: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
194-194: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
195-195: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic_v2/__init__.py
31-31: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
32-32: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
33-33: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic/__init__.py
42-42: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: 3.10 on macOS
- GitHub Check: 3.12 on macOS
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.12 on Windows
- GitHub Check: py312-isort6 on Ubuntu
- GitHub Check: 3.10 on Windows
- GitHub Check: 3.14 on Windows
- GitHub Check: 3.13 on Windows
- GitHub Check: benchmarks
🔇 Additional comments (36)
pyproject.toml (1)
223-224: LGTM! Excellent refinement of deprecation warning suppression.The change from global ignores to a targeted test-only ignore for
parse_objis a best practice. This ensures production code is clean while allowing test code to legitimately use deprecated Pydantic methods for verification purposes.tests/data/expected/main/jsonschema/root_model_config_populate_by_name.py (1)
20-20: LGTM! Correct Pydantic v2.11+ ConfigDict parameter.The test expectation correctly reflects the migration from
populate_by_nametovalidate_by_namein generated code, aligning with Pydantic v2.11+ deprecations.tests/data/expected/main/jsonschema/use_generic_base_class_populate_by_name.py (1)
13-13: LGTM! Consistent ConfigDict parameter migration.Test expectation correctly updated to use
validate_by_name, consistent with Pydantic v2.11+ API changes.src/datamodel_code_generator/model/msgspec.py (2)
50-50: LGTM! Correct import for version-compatible utility.The
model_dumpimport provides version-compatible model serialization, properly used on line 393.
393-393: LGTM! Correct migration to version-compatible API.The change from
self.constraints.dict()tomodel_dump(self.constraints)properly uses the compatibility utility that handles both Pydantic v1 and v2 automatically.src/datamodel_code_generator/model/pydantic/__init__.py (1)
9-9: LGTM! Required import for method signature.The
Anyimport is needed for the newdict()method's type annotations.src/datamodel_code_generator/model/pydantic/base_model.py (3)
28-28: LGTM! Required imports for version-compatible APIs.The
model_dumpandmodel_validateimports are properly used on lines 203 and 406 for Pydantic v1/v2 compatibility.
203-203: LGTM! Correct constraint extraction with version-compatible API.The migration to
model_dump(self.constraints, exclude_unset=True)properly maintains the exclusion behavior while providing Pydantic v1/v2 compatibility.
406-406: LGTM! Correct Config construction with version-compatible API.The change from
Config.parse_obj(config_parameters)tomodel_validate(Config, config_parameters)properly migrates to the version-compatible validation utility.src/datamodel_code_generator/parser/openapi.py (6)
52-52: LGTM! Comprehensive imports for version-compatible APIs.The imports of
BaseModel,model_dump, andmodel_validatefrom the util module support the API migration throughout this file.
502-502: LGTM! Correct reference resolution with version-compatible validation.The use of
model_validate(object_type, ref_obj)properly constructs the resolved object using the compatibility utility.
621-621: LGTM! Correct media object construction in dict comprehension.The migration to
model_validate(MediaObject, v)properly constructs MediaObject instances from response content with version compatibility.
728-728: LGTM! Correct constraint extraction with version-compatible API.The use of
model_dump(object_schema)properly extracts the schema dictionary for constraint handling.
777-777: LGTM! Correct operation construction with version-compatible validation.The migration to
model_validate(Operation, raw_operation)properly constructs the Operation instance from the raw dictionary.
798-798: LGTM! Correct request body construction with version-compatible validation.The use of
model_validate(RequestBodyObject, ref_model)properly constructs the RequestBodyObject from the resolved reference model.src/datamodel_code_generator/model/pydantic_v2/base_model.py (2)
28-28: LGTM! Required imports for v2.11+ compatibility.The
PYDANTIC_V2_11flag andmodel_validateutility are properly used for conditional configuration mapping and version-compatible validation.
258-258: LGTM! Correct ConfigDict construction with version-compatible API.The migration to
model_validate(ConfigDict, config_parameters)properly constructs the ConfigDict instance using the compatibility utility.src/datamodel_code_generator/model/pydantic_v2/__init__.py (3)
9-9: LGTM!The
Anyimport is correctly added to support the newdictmethod signature.
31-33: LGTM!The new fields correctly support Pydantic v2.11+ migration, providing both deprecated (
populate_by_name) and new (validate_by_name,validate_by_alias) field names for compatibility. The inline deprecation notes are helpful for users.Regarding the static analysis hints about unused
noqadirectives: these can be safely ignored as the directives may be needed in certain environments where the UP045 rule is enabled.
45-47: LGTM!The
dictmethod provides backward compatibility by delegating tomodel_dump, which is consistent with the version-compatible utility pattern established inutil.py. This ensures ConfigDict works seamlessly in templates across Pydantic versions.src/datamodel_code_generator/model/base.py (4)
40-40: LGTM!The import of version-compatible utilities (
model_copy,model_dump,model_validate) fromutil.pyenables safe migration from Pydantic v1 to v2 APIs throughout this file.
90-93: LGTM!The replacement of
self.dict()withmodel_dump(self)correctly migrates to the version-compatible API while preserving the constraint-checking logic.
96-120: LGTM!The migration from
dict(by_alias=True)tomodel_dump(..., by_alias=True)and fromparse_objtomodel_validatecorrectly updates the deprecated Pydantic v1 APIs while preserving the constraint-merging logic.
377-387: LGTM!The systematic replacement of
.copy()calls withmodel_copy()correctly migrates to the version-compatible API. The deep-copy semantics are preserved, with proper handling of parent references, extras, data types, and dict keys.tests/data/expected/main/openapi/allow_population_by_field_name_pydantic_v2.py (1)
10-84: LGTM!The test expectations correctly reflect the migration from
populate_by_name=Truetovalidate_by_name=Truein ConfigDict for Pydantic v2.11+. All six model classes (Pet, User, Error, Api, Event, Result) are consistently updated, which aligns with the broader PR objective of fixing Pydantic v2 deprecation warnings.src/datamodel_code_generator/parser/base.py (6)
75-75: LGTM!The import of version-compatible utilities (
model_copy,model_dump) fromutil.pyenables consistent migration from Pydantic v1 to v2 APIs throughout the parser module.
297-331: LGTM!The replacement of
item.dict()withmodel_dump(item)on line 328 correctly migrates BaseModel serialization to the version-compatible API, preserving the hashable conversion logic used for model deduplication.
633-645: LGTM!The replacement of
.copy()withmodel_copy()on lines 640 and 644 correctly migrates to the version-compatible API. The deep-copy semantics for DataType objects are preserved, with proper handling of references and nested data types.
1438-1453: LGTM!The replacement of
data_type.copy()withmodel_copy(data_type)on line 1441 correctly migrates to the version-compatible API while preserving the set conversion logic for unique_items constraints.
1625-1744: LGTM!The replacement of
root_type_field.data_type.copy()withmodel_copy(root_type_field.data_type)on line 1661 correctly migrates to the version-compatible API. The complex root model collapsing logic, including constraint merging and discriminator handling, is preserved.
1795-1835: LGTM!The replacement of
.copy()calls withmodel_copy()on lines 1818, 1824, and 1829 correctly migrates to the version-compatible API. The field inheritance logic is preserved, with proper handling of references, nested data types, and parent relationships.src/datamodel_code_generator/parser/jsonschema.py (3)
79-81: LGTM! Clean compatibility imports.The new compatibility wrappers from
util.pyare properly imported and will enable seamless migration between Pydantic v1 and v2 APIs.
413-418: Correct migration toget_fields_set()wrapper.The replacement of direct
__fields_set__attribute access with the compatibility wrapper correctly handles the difference between Pydantic v1 (__fields_set__) and v2 (model_fields_set).
1040-1040: Systematic and correct API migration.The replacement of deprecated APIs is consistent throughout:
.dict()→model_dump()with proper kwargs propagation.parse_obj()→model_validate()with correct class-first signatureAll changes correctly eliminate Pydantic v2 deprecation warnings while maintaining v1 compatibility.
Also applies to: 1091-1091, 1179-1179, 1193-1198
src/datamodel_code_generator/util.py (2)
25-25: Version detection flag added correctly.The
PYDANTIC_V2_11flag follows the same pattern as the existingPYDANTIC_V2flag and enables feature detection for Pydantic 2.11+. According to the AI summary, this is used in other modules for v2.11-specific features.
159-185: Excellent compatibility layer design.The four new compatibility wrappers provide a clean, unified interface across Pydantic v1 and v2:
model_dump(): replaces.dict()(v1) /.model_dump()(v2)model_validate(): replaces.parse_obj()(v1) /.model_validate()(v2)get_fields_set(): replaces.__fields_set__(v1) /.model_fields_set(v2)model_copy(): replaces.copy()(v1) /.model_copy()(v2)The implementation is type-safe, properly propagates kwargs, and eliminates deprecation warnings while maintaining backward compatibility. This centralizes version-specific logic and makes the codebase cleaner.
CodSpeed Performance ReportMerging #2747 will not alter performanceComparing Summary
Footnotes
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/datamodel_code_generator/model/pydantic/__init__.py (1)
40-48: Version-compatible dict method looks correct.The implementation properly delegates to
model_dumpfor Pydantic v2 and falls back to the parent classdictmethod for v1. The local import ofPYDANTIC_V2is appropriate to avoid circular dependencies.Optional: Remove unused noqa directive
Static analysis indicates the
noqa: PLC0415directive on line 44 may be unused if that rule isn't currently enabled in your linting configuration.- from datamodel_code_generator.util import PYDANTIC_V2 # noqa: PLC0415 + from datamodel_code_generator.util import PYDANTIC_V2src/datamodel_code_generator/model/pydantic_v2/__init__.py (2)
31-33: Good addition of v2.11+ compatibility fields.The new
validate_by_nameandvalidate_by_aliasfields properly support Pydantic v2.11+ wherepopulate_by_namewas deprecated. The inline comments clearly document the version transitions.Optional: Remove unused noqa directives
Static analysis indicates the
noqa: UP045directives may be unused if that rule isn't currently enabled:- populate_by_name: Optional[bool] = None # noqa: UP045 # deprecated in v2.11+ - validate_by_name: Optional[bool] = None # noqa: UP045 # v2.11+ - validate_by_alias: Optional[bool] = None # noqa: UP045 # v2.11+ + populate_by_name: Optional[bool] = None # deprecated in v2.11+ + validate_by_name: Optional[bool] = None # v2.11+ + validate_by_alias: Optional[bool] = None # v2.11+
45-51: Version-compatible dict method looks correct.The implementation properly delegates to
model_dumpfor Pydantic v2 and falls back to the parent classdictmethod for v1, consistent with the same pattern used in the v1 Config class.Optional: Remove unused noqa directive
Static analysis indicates the
noqa: PLC0415directive may be unused:- from datamodel_code_generator.util import PYDANTIC_V2 # noqa: PLC0415 + from datamodel_code_generator.util import PYDANTIC_V2
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
pyproject.tomlsrc/datamodel_code_generator/model/pydantic/__init__.pysrc/datamodel_code_generator/model/pydantic_v2/__init__.pytests/parser/test_jsonschema.pytests/parser/test_openapi.py
💤 Files with no reviewable changes (1)
- pyproject.toml
🧰 Additional context used
🧬 Code graph analysis (4)
tests/parser/test_openapi.py (2)
src/datamodel_code_generator/util.py (1)
model_validate(167-171)src/datamodel_code_generator/parser/openapi.py (3)
ParameterObject(110-121)MediaObject(102-107)ResponseObject(144-149)
tests/parser/test_jsonschema.py (1)
src/datamodel_code_generator/util.py (2)
model_dump(160-164)model_validate(167-171)
src/datamodel_code_generator/model/pydantic/__init__.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)
src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/model/pydantic/__init__.py
44-44: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic_v2/__init__.py
31-31: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
32-32: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
33-33: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
47-47: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: py312-black24 on Ubuntu
- GitHub Check: py312-isort5 on Ubuntu
- GitHub Check: py312-isort6 on Ubuntu
- GitHub Check: 3.12 on Windows
- GitHub Check: py312-black22 on Ubuntu
- GitHub Check: 3.10 on Windows
- GitHub Check: 3.11 on Windows
- GitHub Check: Analyze (python)
- GitHub Check: benchmarks
🔇 Additional comments (2)
tests/parser/test_openapi.py (1)
27-27: LGTM! Clean migration to Pydantic v2 validation API.The migration from
parse_objtomodel_validateis implemented correctly throughout the test file. The utility function provides version-compatible validation and all usages follow the correct pattern:model_validate(Class, data).Also applies to: 142-142, 186-186, 240-240, 750-751, 836-837, 875-875, 939-942, 975-975
tests/parser/test_jsonschema.py (1)
28-28: LGTM! Comprehensive migration to Pydantic v2 APIs.The test file has been consistently updated to use the compatibility utilities:
model_validatereplacesparse_objfor object constructionmodel_dumpreplacesdictfor object serialization/comparisonAll usages follow the correct patterns and maintain test functionality while eliminating deprecation warnings.
Also applies to: 57-57, 97-97, 126-135, 263-263, 286-286, 433-435, 534-534, 858-858, 866-873, 882-889, 898-905, 944-944, 967-967, 974-974, 984-986, 997-999, 1009-1011, 1019-1028, 1036-1045, 1052-1061, 1068-1077, 1085-1094, 1102-1111, 1119-1128, 1135-1151
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
182-183: Remove unusednoqadirectives.Ruff reports these
# noqa: FBT003directives are unused. The FBT003 rule (Boolean positional argument in function definition) doesn't apply to NamedTuple instantiations with boolean values.🔎 Proposed fix
- ConfigAttribute("allow_population_by_field_name", "validate_by_name", False), # noqa: FBT003 - ConfigAttribute("populate_by_name", "validate_by_name", False), # noqa: FBT003 + ConfigAttribute("allow_population_by_field_name", "validate_by_name", False), + ConfigAttribute("populate_by_name", "validate_by_name", False),
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/datamodel_code_generator/model/pydantic_v2/base_model.pytests/model/pydantic/test_types.pytests/parser/test_openapi.py
🧰 Additional context used
🧬 Code graph analysis (2)
tests/model/pydantic/test_types.py (3)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)src/datamodel_code_generator/model/pydantic/types.py (1)
get_data_int_type(248-272)src/datamodel_code_generator/parser/base.py (1)
data_type(1037-1039)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (2)
src/datamodel_code_generator/util.py (1)
model_validate(167-171)src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-51)
🪛 GitHub Actions: Lint
tests/parser/test_openapi.py
[error] 1-1: Ruff formatting hook failed: 1 error fixed by the hook (files modified).
[error] 24-24: Import cleanup by pre-commit: removed 'model_dump' import; only 'model_validate' remains.
🪛 Ruff (0.14.10)
src/datamodel_code_generator/model/pydantic_v2/base_model.py
182-182: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
183-183: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: 3.11 on Ubuntu
- GitHub Check: py312-isort6 on Ubuntu
- GitHub Check: py312-pydantic1 on Ubuntu
- GitHub Check: 3.10 on Windows
- GitHub Check: 3.12 on Windows
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.13 on Windows
- GitHub Check: 3.14 on Windows
- GitHub Check: Analyze (python)
- GitHub Check: benchmarks
🔇 Additional comments (4)
tests/model/pydantic/test_types.py (1)
27-27: LGTM! Proper migration to version-compatible serialization.The import and usage of
model_dump()correctly replaces the deprecated.dict()method for comparing DataType objects in tests, aligning with the PR's goal to eliminate Pydantic v2 deprecation warnings.Also applies to: 147-149
tests/parser/test_openapi.py (1)
27-27: LGTM! Consistent migration tomodel_validate().The changes properly replace deprecated
parse_obj()calls with the version-compatiblemodel_validate()utility across all test cases (JsonSchemaObject, ParameterObject, MediaObject, ResponseObject), aligning with Pydantic v2 migration goals.Note: The pipeline correctly removed the unused
model_dumpimport from line 27.Also applies to: 142-142, 186-186, 240-240, 748-749, 834-836, 873-873, 937-940, 973-973
src/datamodel_code_generator/model/pydantic_v2/base_model.py (2)
28-28: LGTM: Version-compatible helper import added.The
model_validatehelper provides compatibility between Pydantic v1'sparse_objand v2'smodel_validate, properly addressing the deprecation warning.
248-248: LGTM: Deprecatedparse_objreplaced with version-compatible helper.The change from
ConfigDict.parse_obj(config_parameters)tomodel_validate(ConfigDict, config_parameters)properly uses the version-compatible helper to eliminate deprecation warnings while maintaining backward compatibility.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2747 +/- ##
==========================================
+ Coverage 99.37% 99.47% +0.09%
==========================================
Files 83 83
Lines 12399 12457 +58
Branches 1479 1487 +8
==========================================
+ Hits 12322 12391 +69
+ Misses 45 35 -10
+ Partials 32 31 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
180-197: Well-designed version-conditional configuration.The conditional
CONFIG_ATTRIBUTEScorrectly addresses backward compatibility:validate_by_nameis only used whenPYDANTIC_V2_11is True, falling back topopulate_by_namefor Pydantic 2.0–2.10. The explanatory comment is helpful.The
# noqa: FBT003directives are flagged as unused by Ruff since FBT003 isn't enabled. Consider removing them for cleaner code, or keep them if they're intentionally placed for consistency across the codebase.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/datamodel_code_generator/model/pydantic_v2/base_model.pysrc/datamodel_code_generator/parser/jsonschema.pytests/parser/test_openapi.py
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/parser/test_openapi.py
🧰 Additional context used
🧬 Code graph analysis (2)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (2)
src/datamodel_code_generator/util.py (2)
field_validator(117-133)model_validate(167-171)src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-51)
src/datamodel_code_generator/parser/jsonschema.py (6)
src/datamodel_code_generator/util.py (4)
get_fields_set(174-178)model_copy(181-185)model_dump(160-164)model_validate(167-171)src/datamodel_code_generator/model/msgspec.py (1)
field(297-302)src/datamodel_code_generator/model/pydantic/base_model.py (1)
field(91-105)src/datamodel_code_generator/model/base.py (1)
field(336-338)src/datamodel_code_generator/model/dataclass.py (1)
field(147-152)src/datamodel_code_generator/__main__.py (1)
parse_obj(123-125)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/model/pydantic_v2/base_model.py
183-183: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
184-184: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
185-185: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
186-186: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
187-187: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
191-191: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
192-192: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
193-193: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
194-194: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
195-195: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: py312-isort5 on Ubuntu
- GitHub Check: py312-black23 on Ubuntu
- GitHub Check: 3.11 on macOS
- GitHub Check: 3.13 on Windows
- GitHub Check: 3.11 on Ubuntu
- GitHub Check: 3.12 on Windows
- GitHub Check: 3.14 on Windows
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.10 on Windows
- GitHub Check: Analyze (python)
- GitHub Check: benchmarks
🔇 Additional comments (4)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (2)
28-28: LGTM!The imports for
PYDANTIC_V2_11andmodel_validateare correctly added to support version-conditional configuration and the deprecation fix.
255-259: LGTM!Replacing
ConfigDict.parse_obj()with the version-agnosticmodel_validate()helper properly addresses thePydanticDeprecatedSince20deprecation warning while maintaining backward compatibility with Pydantic v1.src/datamodel_code_generator/parser/jsonschema.py (2)
79-82: LGTM! Compatibility layer imports added correctly.The imports of
get_fields_set,model_copy,model_dump, andmodel_validatefrom the compatibility layer enable Pydantic v2 migration while maintaining backward compatibility with v1.
414-414: Excellent migration to Pydantic v2-compatible APIs.All deprecated Pydantic v1 APIs have been correctly replaced with compatibility layer helpers:
__fields_set__→get_fields_set().dict()→model_dump().parse_obj()→model_validate().copy()→model_copy()The changes are comprehensive, consistent, and correctly preserve all parameters (e.g.,
exclude_unset,by_alias,deep). All compatibility helpers properly route between Pydantic v1 and v2 APIs based on the PYDANTIC_V2 flag.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/datamodel_code_generator/__main__.py (1)
23-41: Config plumbing fortarget_pydantic_versionis sound; drop unusednoqaThe new
target_pydantic_version: Optional[TargetPydanticVersion]field onConfigand its pass‑through inrun_generate_from_config()cleanly expose the option togenerate()without altering existing call sites.Ruff correctly flags
# noqa: UP045on the field as unused; since the type isn’t using deprecatedOptional[...]syntax anymore, you can safely remove that directive to keep lint noise down.Also applies to: 374-383, 686-693
♻️ Duplicate comments (1)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
28-29: Version‑aware config mapping is correct; clean up unusednoqadirectivesThe split into
_CONFIG_ATTRIBUTES_V2vs_CONFIG_ATTRIBUTES_V2_11plus_get_config_attributes()gives the intended behavior:
- Default /
TargetPydanticVersion.V2(or unset) continues to emitpopulate_by_name, compatible with Pydantic 2.0–2.10.TargetPydanticVersion.V2_11switches bothallow_population_by_field_nameandpopulate_by_nametovalidate_by_name, avoiding deprecation warnings on 2.11+ as advertised by the enum docstring.- Building
ConfigDictviamodel_validate(ConfigDict, config_parameters)correctly routes through the v1/v2‑compatible helper and removesparse_objdeprecations.Stylistically, Ruff flags all the
# noqa: FBT003on the_CONFIG_ATTRIBUTES_*entries and# noqa: PLC0415on the local TargetPydanticVersion import as unused. Since there’s no active FBT003/PLC0415 rule, you can drop thosenoqas to satisfy RUF100 without changing behavior.Also applies to: 170-195, 232-243, 255-260, 279-290
🧹 Nitpick comments (4)
docs/cli-reference/model-customization.md (1)
26-26:--target-pydantic-versiondocs are clear and aligned with implementationThe new table entry and dedicated section describe the flag, its values (
2vs2.11), and the generated output consistently with the CLI argument definition and TargetPydanticVersion enum. No changes needed; just keep this text in sync if additional Pydantic targets are added later.Also applies to: 4651-4729
src/datamodel_code_generator/cli_options.py (1)
74-74: CLI metadata entry for--target-pydantic-versionis correctOption is registered once with the MODEL category and matches the parser flag name; this will integrate cleanly into the generated docs/navigation.
src/datamodel_code_generator/arguments.py (1)
17-31:--target-pydantic-versionargument wiring is coherentImporting
TargetPydanticVersionand defining--target-pydantic-versionin the model options group with constrained choices ties the CLI neatly to the enum. The help text matches the documented behavior for"2"vs"2.11"; just keep this description in sync with any future changes to the defaulting logic whenargs.target_pydantic_versionisNone.Also applies to: 275-282
src/datamodel_code_generator/__init__.py (1)
324-333: TargetPydanticVersion enum is clear; consider explicit exportThe enum definition and docstring are consistent with the intended “v2 vs v2.11+” split and give a clean hook for version‑specific behavior.
Optionally, consider adding
TargetPydanticVersionto__all__so it’s part of the explicit public surface forfrom datamodel_code_generator import *and tooling that inspects__all__.Optional diff to export TargetPydanticVersion
__all__ = [ "MAX_VERSION", "MIN_VERSION", @@ "ModuleSplitMode", "PythonVersion", "ReadOnlyWriteOnlyModelType", + "TargetPydanticVersion", "generate", ]
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/data/jsonschema/allof_list_any_inheritance.jsonis excluded by!tests/data/**/*.jsonand included by none
📒 Files selected for processing (17)
docs/cli-reference/index.mddocs/cli-reference/model-customization.mddocs/cli-reference/quick-reference.mdsrc/datamodel_code_generator/__init__.pysrc/datamodel_code_generator/__main__.pysrc/datamodel_code_generator/arguments.pysrc/datamodel_code_generator/cli_options.pysrc/datamodel_code_generator/model/pydantic_v2/base_model.pysrc/datamodel_code_generator/parser/base.pysrc/datamodel_code_generator/parser/graphql.pysrc/datamodel_code_generator/parser/jsonschema.pysrc/datamodel_code_generator/parser/openapi.pytests/data/expected/main/jsonschema/allof_list_any_inheritance.pytests/data/expected/main/jsonschema/use_generic_base_class_target_pydantic_v2_11.pytests/data/expected/main_kr/target_pydantic_version/v2_11.pytests/main/jsonschema/test_main_jsonschema.pytests/test_main_kr.py
✅ Files skipped from review due to trivial changes (1)
- docs/cli-reference/quick-reference.md
🧰 Additional context used
🧬 Code graph analysis (11)
tests/test_main_kr.py (2)
tests/conftest.py (1)
freeze_time(285-288)tests/main/conftest.py (2)
output_file(98-100)run_main_and_assert(244-408)
tests/data/expected/main/jsonschema/use_generic_base_class_target_pydantic_v2_11.py (2)
src/datamodel_code_generator/reference.py (1)
_BaseModel(81-138)src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-51)
src/datamodel_code_generator/parser/graphql.py (1)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)
src/datamodel_code_generator/__main__.py (1)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)
src/datamodel_code_generator/parser/base.py (2)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)src/datamodel_code_generator/util.py (3)
camel_to_snake(154-157)model_copy(181-185)model_dump(160-164)
src/datamodel_code_generator/arguments.py (1)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)
src/datamodel_code_generator/parser/openapi.py (2)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)src/datamodel_code_generator/util.py (3)
BaseModel(142-146)model_dump(160-164)model_validate(167-171)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (3)
src/datamodel_code_generator/util.py (1)
model_validate(167-171)src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-51)src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)
src/datamodel_code_generator/parser/jsonschema.py (3)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)src/datamodel_code_generator/util.py (4)
get_fields_set(174-178)model_copy(181-185)model_dump(160-164)model_validate(167-171)src/datamodel_code_generator/model/pydantic/base_model.py (1)
field(91-105)
tests/main/jsonschema/test_main_jsonschema.py (1)
tests/main/conftest.py (2)
output_file(98-100)run_main_and_assert(244-408)
tests/data/expected/main_kr/target_pydantic_version/v2_11.py (2)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
BaseModel(170-345)src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-51)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/__main__.py
382-382: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic_v2/base_model.py
183-183: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
184-184: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
185-185: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
186-186: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
187-187: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
190-190: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
191-191: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
192-192: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
193-193: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
194-194: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
285-285: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: benchmarks
🔇 Additional comments (13)
tests/data/expected/main_kr/target_pydantic_version/v2_11.py (1)
1-22: Expected v2.11 output looks consistentGenerated
Personmodel (includingmodel_config = ConfigDict(validate_by_name=True)and field types) is consistent with the new CLI docs and test expectations; no issues spotted.docs/cli-reference/index.md (1)
14-14: Index updates correctly reflect new model optionThe Model Customization count (
30) and the added--target-pydantic-versionentry under the “T” section both match the new CLI option wiring; looks consistent.Also applies to: 155-157
tests/test_main_kr.py (1)
1562-1598: Newtest_target_pydantic_versionfollows existing CLI-doc test patternsThe test and its
@pytest.mark.cli_docmetadata correctly exercise--target-pydantic-version 2.11together with--allow-population-by-field-nameand assert against the new expected file; structure matches the rest of this suite. You’ll just want to ensure CI runs with a Pydantic version that acceptsConfigDict(validate_by_name=...)so validation of generated code doesn’t fail at import time.src/datamodel_code_generator/__init__.py (1)
413-415: generate(): threading target_pydantic_version into parsers looks correctAdding
target_pydantic_version: TargetPydanticVersion | None = Nonetogenerate()and forwarding it intoparser_class(...)viatarget_pydantic_version=target_pydantic_versionis consistent with the rest of the configuration plumbing and is backward compatible (the new argument is optional and keyword‑only).Also applies to: 763-765
tests/data/expected/main/jsonschema/use_generic_base_class_target_pydantic_v2_11.py (1)
1-18: Expected v2.11 output fixture looks consistentThe generated
BaseModelwrapper withmodel_config = ConfigDict(validate_by_name=True)and theSimplemodel shape align with the new--target-pydantic-version 2.11behavior and existinguse_generic_base_classfixtures. No issues spotted.tests/main/jsonschema/test_main_jsonschema.py (1)
3910-3941: New JSON Schema tests cover the right behaviors; confirm runtime version expectationsBoth additions look good:
test_main_use_generic_base_class_target_pydantic_v2_11cleanly exercises--use-generic-base-classtogether with--target-pydantic-version 2.11and the existing--allow-population-by-field-nameflag against the new expected fixture.test_main_allof_list_any_inheritancetargets the allOf +List[Any]inheritance case forpydantic_v2.BaseModel, matching the new expected output.One thing to double‑check: these tests assume the installed Pydantic version (and the new
--target-pydantic-versionplumbing) can successfully compile and, if validation is enabled, execute the generated code targeting 2.11. If you still run the test suite against Pydantic < 2.11 anywhere, it may be worth guarding this test with a version check/skip or documenting that the test suite now requires ≥2.11.src/datamodel_code_generator/parser/graphql.py (1)
16-29: GraphQLParser correctly threads target_pydantic_version through to the base ParserImporting
TargetPydanticVersion, adding an optionaltarget_pydantic_versionparameter toGraphQLParser.__init__, and forwarding it intosuper().__init__(...)keeps the GraphQL path aligned with the JSON Schema/OpenAPI parsers while remaining backward compatible. No further GraphQL‑specific handling seems necessary here.Also applies to: 99-203, 204-303
src/datamodel_code_generator/parser/openapi.py (2)
20-36: Threadingtarget_pydantic_versioninto OpenAPIParser looks correctImporting
TargetPydanticVersionand adding thetarget_pydantic_versionkwarg, then forwarding it unchanged intosuper().__init__, cleanly hooks OpenAPIParser into the new version‑aware pipeline without altering existing behavior when the argument is omitted. No issues from a constructor/API perspective.Also applies to: 182-188, 287-388
53-54: Use ofmodel_validate/model_dumpwrappers is consistent and non‑breakingSwitching from direct
parse_obj/dictcalls tomodel_validate/model_dumpviadatamodel_code_generator.utilinresolve_object,parse_responses,parse_all_parameters, andparse_operationpreserves behavior while eliminating Pydantic v2 deprecations. The conversions are applied only to Pydantic models (Reference/Media/RequestBody/Operation/JsonSchema), so this remains type‑safe.Also applies to: 501-507, 620-637, 732-754, 780-808
tests/data/expected/main/jsonschema/allof_list_any_inheritance.py (1)
1-19: Expected output fixture looks consistentThe generated Pydantic v2 models (list field override and wrapper Model) match the described allOf/list/any inheritance scenario and are structurally sound as a golden file.
src/datamodel_code_generator/parser/base.py (2)
25-36: Pydantic wrapper usage (model_dump/model_copy) preserves behavior while removing deprecationsThe changes to:
to_hashable→to_hashable(model_dump(item))forBaseModelinstances,_copy_data_types,_create_set_from_list,__collapse_root_models, and__override_required_field→ usingmodel_copy(...),are all applied to Pydantic‑backed types (DataType, DataModelField, etc.) and mirror the previous
.dict()/.copy()behavior while routing through the v1/v2‑compatible helpers. This should eliminate Pydantic v2 deprecation warnings without changing deduplication, copying, or collapsing semantics.Also applies to: 76-77, 298-333, 634-647, 1448-1455, 1669-1673, 1823-1845
25-36:target_pydantic_versionis threaded correctly into parser state and template dataAdding the
target_pydantic_version: TargetPydanticVersion | Nonekwarg toParser.__init__, storing it onself, and mirroring the existing pattern for config flags:
- when
use_generic_base_classis true, settinggeneric_base_class_config["target_pydantic_version"], and- otherwise, setting
extra_template_data[ALL_MODEL]["target_pydantic_version"],gives the model layer enough information to choose between populate_by_name vs validate_by_name without polluting the generated
ConfigDict. Behavior is unchanged when the option is omitted.Also applies to: 672-681, 779-799, 859-897
src/datamodel_code_generator/parser/jsonschema.py (1)
32-32: LGTM! Systematic Pydantic v2 migration using compatibility utilities.The changes comprehensively migrate from Pydantic v1 deprecated APIs to v2-compatible versions:
__fields_set__→get_fields_set()for accessing set fields (lines 415, 420, 458).dict()→model_dump()for serialization (~20+ occurrences).parse_obj()→model_validate()for deserialization (~15+ occurrences).copy()→model_copy()for deep copying (lines 1804, 1818, 1837)- Added
target_pydantic_versionparameter support (lines 623, 725)All replacements use the version-compatible utility functions from
util.py, ensuring backward compatibility with Pydantic v1 while eliminating v2 deprecation warnings. The migration is consistent, preserves all parameters (exclude_unset,by_alias,deep), and introduces no behavioral changes.Also applies to: 80-83, 415-415, 420-420, 458-458, 623-623, 725-725, 1044-1044, 1095-1095, 1183-1183, 1197-1202, 1212-1212, 1226-1226, 1241-1244, 1249-1249, 1263-1263, 1521-1531, 1561-1561, 1640-1642, 1672-1682, 1692-1716, 1804-1804, 1818-1818, 1837-1837, 2479-2479, 2609-2609, 2674-2674, 3071-3071, 3216-3216, 3229-3229, 3235-3235, 3255-3255
038c6fe to
e44b5b8
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
src/datamodel_code_generator/model/base.py (1)
377-387: Consider makingcopy_deepexplicitly deep (or tightening ownership links)
copy_deepnow usesmodel_copy(self)and manually copiesextras,data_type, nesteddata_types, anddict_key. That avoids most aliasing, but:
model_copyis shallow by default, so any other BaseModel attributes on the field (if added later) will still share references.- The copied
data_type’sparentwill still point at the original field, not the newcopiedinstance.To better match the docstring and future‑proof this helper, you could:
- Pass
deep=Trueinto themodel_copycalls, and/or- Reattach the parent explicitly, e.g.
copied.data_type.parent = copiedif that invariant is expected.Not strictly required by the current tests, but it would make the semantics of “deep copy” less surprising.
src/datamodel_code_generator/model/pydantic/__init__.py (1)
9-9: Config.dict override looks correct; drop the unusednoqamarkerThe
Config.dictoverride cleanly dispatches tomodel_dumpwhen running under Pydantic v2 and falls back toBaseModel.dictfor v1, which should eliminate v2 deprecation warnings while keeping templates working the same way.The inline import of
PYDANTIC_V2is fine here, but# noqa: PLC0415on that line is now flagged as unused by Ruff (RUF100). You can safely remove thatnoqacomment.Also applies to: 40-48
src/datamodel_code_generator/parser/base.py (2)
634-646:model_copyusage for internal types appears sound but assumes.model_copysupportReplacing direct
.copy()calls onDataTypeandDataModelFieldBaseinstances with the version‑awaremodel_copyhelper keeps shallow/deep behaviour the same in these helpers (you still recurse manually where deep copies are needed) and removes Pydantic v2 deprecation warnings.This does rely on all of these internal types implementing
.model_copy()in Pydantic v2 environments (or otherwise providing a compatiblemodel_copyattribute). If any of them are non‑pydantic classes that only define.copy(),model_copywould now raise at runtime whenPYDANTIC_V2is true.If not already guaranteed elsewhere, consider either:
- Narrowing
model_copy’s use to explicitly pydantic models, or- Making
model_copymore defensive, e.g. falling back to.copy()whenobjlacks.model_copy, or- Adding lightweight
.model_copy()shims on the relevant internal model classes.This would harden things against future refactors where a non‑pydantic type might slip into these code paths.
Also applies to: 1448-1455, 1670-1671, 1827-1839
679-783:target_pydantic_versionthreading into parser config is cleanAdding
target_pydantic_versiontoParser.__init__, storing it onself, and then pushing it into eithergeneric_base_class_configorextra_template_data[ALL_MODEL]gives templates everything they need without affecting existing callers (keyword‑only, defaultNone).The only behavioural nuance is the
if target_pydantic_version:truthiness check—this is fine for the current enum values but could be made a bit more explicit (is not None) to avoid surprises if an ever‑falsy enum value is introduced.Also applies to: 892-897
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/data/jsonschema/allof_list_any_inheritance.jsonis excluded by!tests/data/**/*.jsonand included by none
📒 Files selected for processing (27)
docs/cli-reference/index.mddocs/cli-reference/model-customization.mddocs/cli-reference/quick-reference.mdpyproject.tomlsrc/datamodel_code_generator/__init__.pysrc/datamodel_code_generator/__main__.pysrc/datamodel_code_generator/arguments.pysrc/datamodel_code_generator/cli_options.pysrc/datamodel_code_generator/model/base.pysrc/datamodel_code_generator/model/msgspec.pysrc/datamodel_code_generator/model/pydantic/__init__.pysrc/datamodel_code_generator/model/pydantic/base_model.pysrc/datamodel_code_generator/model/pydantic_v2/__init__.pysrc/datamodel_code_generator/model/pydantic_v2/base_model.pysrc/datamodel_code_generator/parser/base.pysrc/datamodel_code_generator/parser/graphql.pysrc/datamodel_code_generator/parser/jsonschema.pysrc/datamodel_code_generator/parser/openapi.pysrc/datamodel_code_generator/util.pytests/data/expected/main/jsonschema/allof_list_any_inheritance.pytests/data/expected/main/jsonschema/use_generic_base_class_target_pydantic_v2_11.pytests/data/expected/main_kr/target_pydantic_version/v2_11.pytests/main/jsonschema/test_main_jsonschema.pytests/model/pydantic/test_types.pytests/parser/test_jsonschema.pytests/parser/test_openapi.pytests/test_main_kr.py
💤 Files with no reviewable changes (1)
- pyproject.toml
✅ Files skipped from review due to trivial changes (1)
- docs/cli-reference/quick-reference.md
🚧 Files skipped from review as they are similar to previous changes (6)
- tests/model/pydantic/test_types.py
- tests/data/expected/main/jsonschema/use_generic_base_class_target_pydantic_v2_11.py
- src/datamodel_code_generator/model/pydantic/base_model.py
- tests/data/expected/main/jsonschema/allof_list_any_inheritance.py
- docs/cli-reference/index.md
- src/datamodel_code_generator/model/msgspec.py
🧰 Additional context used
🧬 Code graph analysis (15)
tests/parser/test_jsonschema.py (1)
src/datamodel_code_generator/util.py (2)
model_dump(160-164)model_validate(167-171)
tests/data/expected/main_kr/target_pydantic_version/v2_11.py (2)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
BaseModel(170-345)src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-51)
tests/main/jsonschema/test_main_jsonschema.py (1)
tests/main/conftest.py (2)
output_file(98-100)run_main_and_assert(244-408)
src/datamodel_code_generator/parser/base.py (3)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)src/datamodel_code_generator/util.py (3)
camel_to_snake(154-157)model_copy(181-185)model_dump(160-164)src/datamodel_code_generator/reference.py (1)
reference(76-78)
src/datamodel_code_generator/util.py (2)
src/datamodel_code_generator/reference.py (1)
_BaseModel(81-138)src/datamodel_code_generator/__main__.py (1)
parse_obj(124-126)
tests/parser/test_openapi.py (2)
src/datamodel_code_generator/util.py (2)
model_dump(160-164)model_validate(167-171)src/datamodel_code_generator/parser/openapi.py (3)
ParameterObject(111-122)MediaObject(103-108)ResponseObject(145-150)
src/datamodel_code_generator/model/base.py (1)
src/datamodel_code_generator/util.py (3)
model_copy(181-185)model_dump(160-164)model_validate(167-171)
src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)
src/datamodel_code_generator/parser/jsonschema.py (3)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)src/datamodel_code_generator/util.py (4)
get_fields_set(174-178)model_copy(181-185)model_dump(160-164)model_validate(167-171)src/datamodel_code_generator/__main__.py (1)
parse_obj(124-126)
src/datamodel_code_generator/parser/graphql.py (1)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)
src/datamodel_code_generator/arguments.py (1)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)
src/datamodel_code_generator/model/pydantic/__init__.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)
tests/test_main_kr.py (2)
tests/conftest.py (1)
freeze_time(285-288)tests/main/conftest.py (2)
output_file(98-100)run_main_and_assert(244-408)
src/datamodel_code_generator/parser/openapi.py (2)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)src/datamodel_code_generator/util.py (3)
BaseModel(142-146)model_dump(160-164)model_validate(167-171)
src/datamodel_code_generator/__main__.py (1)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(324-332)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/model/pydantic_v2/base_model.py
183-183: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
184-184: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
185-185: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
186-186: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
187-187: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
190-190: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
191-191: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
192-192: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
193-193: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
194-194: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
285-285: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic_v2/__init__.py
31-31: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
32-32: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
33-33: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
47-47: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic/__init__.py
44-44: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/__main__.py
382-382: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
- GitHub Check: py312-black23 on Ubuntu
- GitHub Check: py312-black24 on Ubuntu
- GitHub Check: py312-isort5 on Ubuntu
- GitHub Check: py312-isort7 on Ubuntu
- GitHub Check: py312-pydantic1 on Ubuntu
- GitHub Check: 3.12 on macOS
- GitHub Check: 3.10 on Windows
- GitHub Check: 3.13 on macOS
- GitHub Check: 3.12 on Windows
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.10 on macOS
- GitHub Check: 3.14 on Windows
- GitHub Check: 3.14 on macOS
- GitHub Check: 3.12 on Ubuntu
- GitHub Check: 3.13 on Windows
- GitHub Check: Analyze (python)
- GitHub Check: benchmarks
🔇 Additional comments (41)
src/datamodel_code_generator/arguments.py (1)
17-31: CLI wiring for--target-pydantic-versionlooks consistentImporting
TargetPydanticVersionand exposing--target-pydantic-versionwithchoices=[v.value for v in TargetPydanticVersion]anddefault=Noneis coherent with the enum definition and downstream Config handling. Help text matches the described semantics for"2"vs"2.11".Also applies to: 275-282
docs/cli-reference/model-customization.md (1)
26-27: Documentation for--target-pydantic-versionis aligned and clearThe new table entry and section correctly describe the
2vs2.11behaviors and match the CLI help andTargetPydanticVersionenum semantics, with a concrete example showingConfigDict(validate_by_name=True).Also applies to: 4651-4731
src/datamodel_code_generator/cli_options.py (1)
70-76: CLI metadata correctly includes--target-pydantic-versionAdding
"--target-pydantic-version"toCLI_OPTION_METAunderOptionCategory.MODELkeeps documentation metadata in sync with argparse and the new docs section.src/datamodel_code_generator/__main__.py (2)
23-41: Target Pydantic version propagation through Config andgenerate()looks correctImporting
TargetPydanticVersion, addingtarget_pydantic_version: Optional[TargetPydanticVersion] = NoneonConfig, and forwarding it intogenerate()wires the new CLI/config knob cleanly through the main execution path. Assuminggenerate()treatsNoneas “use the default v2 behavior”, this should be backward compatible.Please double‑check that
generate()and any downstream logic gracefully handletarget_pydantic_version=Noneso that runs without the option continue to behave as before.Also applies to: 374-385, 686-692
382-382: Keep the# noqa: UP045directiveUP045 is enabled when targeting Python 3.10 or later, and by default is also enabled for earlier Python versions if
from __future__ import annotationsis present. The file requiresfrom __future__ import annotationsvia thelint.isort.required-importsconfiguration, which means UP045 is active in this codebase. The noqa directive correctly suppresses the rule and should not be removed.Likely an incorrect or invalid review comment.
tests/parser/test_jsonschema.py (1)
28-35: Pydantic v1/v2 migration correctly implemented in JSON Schema testsThe switch from
parse_objtomodel_validateand from.dict()tomodel_dump()is correctly applied throughout the test file. Themodel_validatehelpers provide version-compatible abstraction, allowing the tests to work across both Pydantic versions. The test imports and usage patterns at lines 28–35 and throughout the file (54–136, 257–287, 433–435, 855–969, 971–1152) are sound and consistent.tests/test_main_kr.py (1)
1562-1598: New--target-pydantic-versionCLI-doc test is well integratedThe test and its
pytest.mark.cli_docmetadata line up with existing patterns (person.json input, pydantic_v2 output, expected v2.11-specific golden file) and provide clear coverage for the new flag without introducing extra complexity.src/datamodel_code_generator/model/base.py (1)
40-41: Constraint serialization/merge now correctly uses version-aware helpersUsing
model_dump/model_validateinstead of direct.dict()/.parse_obj()and filtering withv is not Nonepreserves falsy-but-valid constraint values while removing Pydantic v2 deprecation paths. The merge logic (root constraints overlaid by field constraints withby_alias=True) remains straightforward and consistent.Also applies to: 90-121
tests/main/jsonschema/test_main_jsonschema.py (1)
3910-3942: New JSON Schema tests nicely cover Pydantic 2.11 + allOf edge casesBoth tests reuse the established
run_main_and_assertpattern and add focused coverage: one for--use-generic-base-classunder--target-pydantic-version 2.11, and one for allOf inheritance withList[Any]usingpydantic_v2.BaseModel. This should help guard against regressions in the new Pydantic‑version‑aware behavior.src/datamodel_code_generator/parser/graphql.py (1)
27-27: LGTM! Clean parameter forwarding.The
TargetPydanticVersionparameter is correctly imported, added to the signature with a backward-compatible default ofNone, and forwarded to the parent class. This follows the same pattern used across other parsers in the PR.Also applies to: 201-201, 302-302
src/datamodel_code_generator/parser/openapi.py (4)
32-32: LGTM! Proper imports for version compatibility.The imports of
TargetPydanticVersion,model_dump, andmodel_validatealign with the PR's objective to eliminate Pydantic v2 deprecation warnings by using version-compatible helpers.Also applies to: 53-53
285-285: LGTM! Parameter forwarding implemented correctly.The
target_pydantic_versionparameter is properly added to the signature and forwarded to the parentJsonSchemaParser, maintaining consistency with other parsers in the codebase.Also applies to: 387-387
505-505: LGTM! Deprecated API successfully replaced.All instances of
.parse_obj()have been correctly replaced withmodel_validate(), which provides version-compatible model validation without triggering Pydantic v2 deprecation warnings.Also applies to: 624-624, 801-801
731-731: LGTM! Deprecated.dict()replaced withmodel_dump().The constraints extraction now uses
model_dump(object_schema)instead ofobject_schema.dict(), eliminating the PydanticDeprecatedSince20 warning while maintaining identical functionality.tests/parser/test_openapi.py (5)
27-27: LGTM! Proper test utility imports.The imports of
model_dumpandmodel_validateenable the test suite to use version-compatible APIs, aligning with the broader PR migration.
142-142: LGTM! Test object construction migrated correctly.All
JsonSchemaObject.parse_obj()calls have been properly replaced withmodel_validate(JsonSchemaObject, ...), ensuring tests run without Pydantic v2 deprecation warnings.Also applies to: 186-186, 240-240
748-749: LGTM! Parameter object construction updated.The test now uses
model_validate(ParameterObject, ...)instead ofParameterObject.parse_obj(), consistent with the PR's migration to version-compatible helpers.Also applies to: 873-873, 973-973
834-836: LGTM! Response/media object construction migrated.All
MediaObject.parse_obj()andResponseObject.parse_obj()calls have been replaced withmodel_validate(), maintaining test correctness while eliminating deprecation warnings.Also applies to: 937-940
588-588: LGTM! Model resolver test updated correctly.The change from
v.dict(exclude=...)tomodel_dump(v, exclude=...)successfully addresses the past review comment and eliminates the deprecation warning. The addition of"children"to the exclude set is appropriate for the model resolver test context.src/datamodel_code_generator/__init__.py (3)
324-332: LGTM! Well-defined version targeting enum.The
TargetPydanticVersionenum is properly documented with clear descriptions of the differences between V2 (populate_by_name) and V2_11 (validate_by_name). This provides a clean API for users to control generated code compatibility.
413-413: LGTM! API extension and parameter forwarding.The
target_pydantic_versionparameter is correctly added to the publicgenerate()API with a backward-compatible default ofNoneand properly forwarded to parser construction, enabling version-specific code generation throughout the pipeline.Also applies to: 763-763
917-917: LGTM! Public API export updated.
TargetPydanticVersionis correctly added to__all__, making it part of the public API for downstream consumers.src/datamodel_code_generator/model/pydantic_v2/__init__.py (2)
31-33: LGTM! Pydantic 2.11+ fields added.The addition of
validate_by_nameandvalidate_by_aliasfields (with appropriate deprecation note forpopulate_by_name) enables the ConfigDict to represent both v2.0-2.10 and v2.11+ configuration options, supporting the version-targeting feature.
45-51: LGTM! Template compatibility method.The
dict()method provides a compatibility layer for templates that may call.dict()on ConfigDict instances. By delegating tomodel_dump()in Pydantic v2, this ensures generated templates work correctly regardless of which method they use.src/datamodel_code_generator/model/pydantic_v2/base_model.py (3)
182-195: LGTM! Version-specific configuration mappings.The dual config attribute mappings correctly differentiate between Pydantic 2.0-2.10 (using
populate_by_name) and 2.11+ (usingvalidate_by_name). This enables version-targeted code generation while maintaining clarity in the implementation.
237-290: LGTM! Version selection logic with safe defaults.The
_get_config_attributes()method correctly selects the appropriate config mapping based ontarget_pydantic_version, defaulting to V2-compatible (populate_by_name) when not specified. This ensures backward compatibility while enabling opt-in support for Pydantic 2.11+ features.
258-258: LGTM! Deprecated API replaced.The change from
ConfigDict.parse_obj()tomodel_validate(ConfigDict, ...)eliminates the deprecation warning while maintaining identical validation behavior.tests/data/expected/main_kr/target_pydantic_version/v2_11.py (1)
1-22: LGTM! Expected output validates version-targeting feature.This expected test output correctly demonstrates Pydantic 2.11+ code generation with
validate_by_name=Truein the ConfigDict (line 14), confirming that theTargetPydanticVersion.V2_11option produces the appropriate configuration for newer Pydantic versions.src/datamodel_code_generator/util.py (5)
25-25: LGTM! Version detection flag added.The
PYDANTIC_V2_11flag enables runtime detection of Pydantic 2.11+ installations, supporting version-specific behavior throughout the codebase.
160-164: LGTM! Version-compatible serialization helper.The
model_dump()helper provides clean delegation to.model_dump()in Pydantic v2 or.dict()in v1, eliminating deprecation warnings while maintaining a consistent API.
167-171: LGTM! Version-compatible validation helper.The
model_validate()helper correctly delegates to.model_validate()in Pydantic v2 or.parse_obj()in v1, providing the compatibility layer needed to eliminate PydanticDeprecatedSince20 warnings.
174-178: LGTM! Version-compatible fields set accessor.The
get_fields_set()helper correctly accesses.model_fields_setin v2 or.__fields_set__in v1, providing a clean abstraction over the version-specific field tracking APIs.
181-185: LGTM! Version-compatible copy helper.The
model_copy()helper properly delegates to.model_copy()in Pydantic v2 or.copy()in v1, completing the set of version-compatible utilities needed for the migration.src/datamodel_code_generator/parser/base.py (1)
25-36: Centralizing Pydantic helpers viamodel_dumplooks correctImporting
TargetPydanticVersionand switchingto_hashable(BaseModel)to use the sharedmodel_dumpwrapper keeps all version‑specific logic inutiland preserves prior semantics of hashing models via their serialized dicts. No issues spotted here.You may want to quickly scan for any remaining direct
.dict()/.model_dump()uses on pydantic models outsideutil/parsers to ensure all deprecation‑prone call sites have been migrated consistently.Also applies to: 76-76, 328-330
src/datamodel_code_generator/parser/jsonschema.py (7)
24-38: Importing TargetPydanticVersion and compat Pydantic shims is consistent with the base parserSwitching JsonSchemaParser to import
TargetPydanticVersionand to use theBaseModel,field_validator,model_dump,model_validate, etc., fromdatamodel_code_generator.utilkeeps all Pydantic‑version handling centralized and avoids direct v1‑only API usage.Class bases (
Discriminator,JsonSchemaObject) now correctly use the compatBaseModelalias.If you haven’t already, it’s worth confirming that all other parser modules (OpenAPI, GraphQL, etc.) are also using these compat imports exclusively, so there are no lingering
parse_obj/dict/copycalls on Pydantic models.Also applies to: 76-85
412-421:get_fields_set–based checks for defaults/constraints/ref‑keywords preserve intentUpdating
has_default,has_constraint, andhas_ref_with_schema_keywordsto useget_fields_set(self)rather than directly touching__fields_set__(or v2 internals) keeps the same behaviour while removing v2 deprecation warnings:
has_default: now true when"default"was explicitly provided (includingNone) or when adefault_factoryis present in extras.has_constraint: continues to detect any of the known constraint fields being explicitly set.has_ref_with_schema_keywords: still correctly ignores pure metadata keys and focuses on schema‑affecting keywords co‑occurring with$ref.This looks like a faithful v1→v2 migration.
Given the intricacies of Pydantic’s
fields_set/model_fields_setsemantics with aliased fields, you may want to ensure tests cover cases like$refanddefaultset via their JSON aliases (e.g. raw input containing$ref/default) under both Pydantic v1 and v2.Also applies to: 450-465
523-626: JsonSchemaParser now cleanly exposestarget_pydantic_versionAdding
target_pydantic_version: TargetPydanticVersion | None = Noneto JsonSchemaParser’s constructor and passing it straight through toParser.__init__integrates JSON Schema parsing with the new configuration surface without altering existing call sites (argument is keyword‑only and optional).No behavioural concerns here; it just enables templates and model generation to vary by requested Pydantic target.
Please verify that the CLI/config layer actually wires the new
--target-pydantic-versionoption (or equivalent) into this parameter for JSON Schema inputs, and that tests cover bothV2andV2_11flows.Also applies to: 723-726
1044-1045: Usingmodel_dumpfor constraint dictionaries keeps behaviour unifiedSeveral places now build “constraints” dicts via
model_dumpinstead of.dict():
get_object_field:constraints = model_dump(field)when constraints are applicable.get_data_type’s_get_data_typekwarg expansion for non‑field_constraintsmode.parse_array_fields:constraints = model_dump(obj)with optional removal ofminItems/maxItemsfor fixed‑length tuples.parse_root_typeand_parse_multiple_types_with_properties:constraints = model_dump(obj) if self.field_constraints else {}.Because the helper forwards kwargs unchanged to
.dict()/.model_dump(), and you mostly use the default options here, semantics should closely match prior behaviour while avoiding deprecations.It’s worth double‑checking that no Pydantic v2‑only keyword differences sneak in here (e.g. if you later start using
mode="json"or similar), and that constraint‑sensitive tests (hostname pattern, numeric bounds, array length, etc.) still pass under both Pydantic v1 and v2.Also applies to: 1091-1096, 2480-2497, 2610-2612, 2675-2677
1172-1184: Ref/allOf/combined‑schema merging logic migrates cleanly tomodel_dump/model_validateAll of the ref/merge helpers have been updated to route through the compat wrappers:
_load_ref_schema_objectnow usesmodel_validate(self.SCHEMA_OBJECT_TYPE, target_schema)._merge_ref_with_schema,_merge_primitive_schemas,_merge_primitive_schemas_for_allof,_merge_properties_with_parent_constraints,_merge_all_of_object,_schema_signature, andparse_combined_schemanow consistently usemodel_dump(..., exclude_unset=True, by_alias=True)for dict materialization andmodel_validate(self.SCHEMA_OBJECT_TYPE, merged_dict)to rebuild schema objects.This keeps all JSON‑schema merging behaviour centralized around the Pydantic adapters, which should eliminate v1 deprecation warnings while preserving the previous deep‑merge and precedence rules.
Given how subtle allOf/anyOf/oneOf and
$refinteractions can be, I’d recommend ensuring there are regression tests that:
- Exercise
$ref+ local keywords merge cases (including nested allOf), and- Run under both Pydantic v1 and v2 to confirm no behavioural drift from the original
.dict()/.parse_obj()based logic.Also applies to: 1196-1203, 1209-1213, 1215-1227, 1239-1245, 1246-1264, 1511-1532, 1558-1562, 1639-1643, 1672-1683, 1692-1717
1805-1819:model_copyfor inherited field types in_parse_object_common_partWhen resolving inherited field types (both the plain
Anyoverride and theList[Any]case), you now cloneinherited_type(and the wrapper) viamodel_copy(..., deep=True)before adjusting flags likeis_optional,is_dict,is_list,is_set, andkwargs.This is a good use of the compat helper and clearly preserves the intent to avoid mutating the original parent type while reusing its structure as a base.
As with
model_copyusages inbase.py, please confirm that theDataTypeinstances flowing through here are pydantic‑model‑like (or otherwise implement.model_copy) in Pydantic v2; if not, consider the defensive patterns mentioned in thebase.pycomment.Also applies to: 1837-1839
3071-3072: Usingmodel_validateinstead ofparse_objfor all raw→schema conversionsEvery place that previously parsed raw dicts into
JsonSchemaObjectinstances now goes through the compatmodel_validatehelper:
parse_raw_obj: top‑level raw schema elements._parse_file: root object, per‑definition objects, selected sub‑objects, and reserved JSON‑pointer targets.This is exactly the right abstraction for Pydantic v1/v2 bridging and keeps construction paths uniform.
Since this path touches all JSON Schema inputs, make sure you have tests that feed in schemas with:
- Extra/unknown keys intended to end up in
extras, and- Various combinations of
$id,$ref, and definitions,and run them under both Pydantic versions to confirm
extrasand id/ref resolution still behave as before.Also applies to: 3217-3231, 3255-3255
🤖 Generated by GitHub Actions
…Of list inheritance
e44b5b8 to
9bb3eaa
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/datamodel_code_generator/__main__.py (1)
23-41: CLI config threading fortarget_pydantic_versionis correct; drop unusednoqaThe new
Config.target_pydantic_versionfield and its propagation viarun_generate_from_config()intogenerate(..., target_pydantic_version=...)look sound and align with the top-level API.Minor: Ruff flags the
# noqa: UP045on Line 382 as unused. Since UP045 isn’t enabled, you can remove that directive to avoid RUF100 noise.If you keep UP045 suppressed intentionally, consider enabling UP045 in Ruff or adjusting config so this
noqais actually effective.Also applies to: 382-383, 675-693
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
170-188: Version-aware BaseModel config mapping is correct; clean up unusednoqatagsThe split into
_CONFIG_ATTRIBUTES_V2(usingpopulate_by_name) and_CONFIG_ATTRIBUTES_V2_11(usingvalidate_by_name) plus_get_config_attributes()keyed offextra_template_data["target_pydantic_version"]gives you the right knobs to generate either pre‑2.11 or 2.11+ configs without breaking older Pydantic v2 installations. SwappingConfigDict.parse_obj(...)formodel_validate(ConfigDict, ...)also removes theparse_objdeprecation cleanly.Minor: Ruff points out that the
# noqa: FBT003comments on the_CONFIG_ATTRIBUTES_*entries and# noqa: PLC0415on the local import in_get_config_attributes()are unused (the corresponding rules aren’t enabled). You can safely drop thosenoqadirectives.If you prefer to keep these
noqatags, consider enablingFBT003/PLC0415in your Ruff config so they serve a purpose.Also applies to: 189-195, 197-260, 279-291
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/data/jsonschema/allof_list_any_inheritance.jsonis excluded by!tests/data/**/*.jsonand included by none
📒 Files selected for processing (27)
docs/cli-reference/index.mddocs/cli-reference/model-customization.mddocs/cli-reference/quick-reference.mdpyproject.tomlsrc/datamodel_code_generator/__init__.pysrc/datamodel_code_generator/__main__.pysrc/datamodel_code_generator/arguments.pysrc/datamodel_code_generator/cli_options.pysrc/datamodel_code_generator/model/base.pysrc/datamodel_code_generator/model/msgspec.pysrc/datamodel_code_generator/model/pydantic/__init__.pysrc/datamodel_code_generator/model/pydantic/base_model.pysrc/datamodel_code_generator/model/pydantic_v2/__init__.pysrc/datamodel_code_generator/model/pydantic_v2/base_model.pysrc/datamodel_code_generator/parser/base.pysrc/datamodel_code_generator/parser/graphql.pysrc/datamodel_code_generator/parser/jsonschema.pysrc/datamodel_code_generator/parser/openapi.pysrc/datamodel_code_generator/util.pytests/data/expected/main/jsonschema/allof_list_any_inheritance.pytests/data/expected/main/jsonschema/use_generic_base_class_target_pydantic_v2_11.pytests/data/expected/main_kr/target_pydantic_version/v2_11.pytests/main/jsonschema/test_main_jsonschema.pytests/model/pydantic/test_types.pytests/parser/test_jsonschema.pytests/parser/test_openapi.pytests/test_main_kr.py
💤 Files with no reviewable changes (1)
- pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (11)
- tests/model/pydantic/test_types.py
- tests/parser/test_jsonschema.py
- tests/data/expected/main/jsonschema/allof_list_any_inheritance.py
- src/datamodel_code_generator/model/msgspec.py
- src/datamodel_code_generator/model/pydantic/base_model.py
- docs/cli-reference/quick-reference.md
- src/datamodel_code_generator/cli_options.py
- tests/main/jsonschema/test_main_jsonschema.py
- tests/data/expected/main_kr/target_pydantic_version/v2_11.py
- docs/cli-reference/model-customization.md
- src/datamodel_code_generator/parser/openapi.py
🧰 Additional context used
🧬 Code graph analysis (10)
tests/data/expected/main/jsonschema/use_generic_base_class_target_pydantic_v2_11.py (2)
src/datamodel_code_generator/reference.py (1)
_BaseModel(81-138)src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-51)
src/datamodel_code_generator/util.py (2)
src/datamodel_code_generator/reference.py (1)
_BaseModel(81-138)src/datamodel_code_generator/__main__.py (1)
parse_obj(124-126)
src/datamodel_code_generator/parser/graphql.py (1)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(325-333)
src/datamodel_code_generator/arguments.py (1)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(325-333)
tests/parser/test_openapi.py (2)
src/datamodel_code_generator/util.py (2)
model_dump(160-164)model_validate(167-171)src/datamodel_code_generator/parser/openapi.py (3)
ParameterObject(111-122)MediaObject(103-108)ResponseObject(145-150)
src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)
src/datamodel_code_generator/parser/jsonschema.py (2)
src/datamodel_code_generator/util.py (4)
get_fields_set(174-178)model_copy(181-185)model_dump(160-164)model_validate(167-171)src/datamodel_code_generator/__main__.py (1)
parse_obj(124-126)
src/datamodel_code_generator/model/base.py (2)
src/datamodel_code_generator/model/pydantic_v2/__init__.py (1)
ConfigDict(26-51)src/datamodel_code_generator/util.py (3)
model_copy(181-185)model_dump(160-164)model_validate(167-171)
src/datamodel_code_generator/__main__.py (1)
src/datamodel_code_generator/__init__.py (1)
TargetPydanticVersion(325-333)
src/datamodel_code_generator/model/pydantic/__init__.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(160-164)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/model/pydantic_v2/base_model.py
183-183: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
184-184: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
185-185: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
186-186: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
187-187: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
190-190: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
191-191: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
192-192: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
193-193: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
194-194: Unused noqa directive (non-enabled: FBT003)
Remove unused noqa directive
(RUF100)
285-285: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic_v2/__init__.py
31-31: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
32-32: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
33-33: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
47-47: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/__main__.py
382-382: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic/__init__.py
43-43: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.11 on macOS
- GitHub Check: 3.14 on macOS
- GitHub Check: 3.10 on Windows
- GitHub Check: 3.13 on macOS
- GitHub Check: 3.12 on macOS
- GitHub Check: 3.12 on Windows
- GitHub Check: 3.13 on Windows
- GitHub Check: 3.14 on Windows
- GitHub Check: benchmarks
- GitHub Check: Analyze (python)
🔇 Additional comments (28)
docs/cli-reference/index.md (1)
14-14: LGTM!The documentation updates correctly reflect the new
--target-pydantic-versionCLI option. The Model Customization count is properly updated from 29 to 30, and the option is listed in the correct alphabetical order under the T section.Also applies to: 155-156
tests/data/expected/main/jsonschema/use_generic_base_class_target_pydantic_v2_11.py (1)
1-18: LGTM!The golden file correctly demonstrates the expected output for
--target-pydantic-version 2.11with--use-generic-base-class. The use ofvalidate_by_name=Trueis the correct Pydantic 2.11+ configuration that replaces the deprecatedpopulate_by_name.src/datamodel_code_generator/model/pydantic_v2/__init__.py (2)
31-33: Good additions for Pydantic 2.11+ compatibility.The new
validate_by_nameandvalidate_by_aliasfields correctly support Pydantic 2.11+ config options, and the deprecation note onpopulate_by_nameprovides helpful context.
45-51: Version-compatible dict method looks correct.The method properly delegates to
model_dump()when running under Pydantic v2, maintaining backward compatibility with v1'sdict()method.tests/test_main_kr.py (1)
1562-1598: LGTM!The new test follows the established patterns in the test file. The
@pytest.mark.cli_docdecorator is properly configured with matching CLI arguments, and the docstring clearly explains the version-specific config differences between Pydantic 2.0 and 2.11+.src/datamodel_code_generator/arguments.py (1)
275-282: LGTM!The new
--target-pydantic-versionargument is well-defined with clear help text explaining the differences between Pydantic 2.0+ (populate_by_name) and 2.11+ (validate_by_name). The logical placement after--target-python-versionand default ofNoneallows the system to auto-detect or use explicit user preference.src/datamodel_code_generator/model/base.py (3)
40-40: Good migration to version-compatible utilities.The imports of
model_copy,model_dump, andmodel_validatefrom the util module enable consistent v1/v2 compatibility across the codebase.
90-120: LGTM - Correctly migrated constraint handling.The changes properly replace deprecated Pydantic v1 APIs:
self.dict()→model_dump(self)a.dict(by_alias=True)→model_dump(a, by_alias=True)constraints_class.parse_obj(...)→model_validate(constraints_class, ...)These changes directly address the deprecation warnings mentioned in issue #1823.
377-387: LGTM - Deep copy implementation updated correctly.Using
model_copy()wrapper instead of direct.copy()calls ensures compatibility with both Pydantic v1 (.copy()) and v2 (.model_copy()).src/datamodel_code_generator/model/pydantic/__init__.py (1)
39-47: LGTM - Version-compatible dict method.The
dict()method implementation mirrors the one inpydantic_v2/__init__.py, providing a consistent interface for templates regardless of which Pydantic version is installed at runtime.src/datamodel_code_generator/parser/graphql.py (1)
27-27: LGTM!The
target_pydantic_versionparameter is correctly threaded through the GraphQL parser, maintaining consistency with other parser implementations (JSON Schema, OpenAPI). The parameter is properly typed and forwarded to the base class.Also applies to: 202-202, 303-303
src/datamodel_code_generator/__init__.py (1)
325-334: TargetPydanticVersion enum and generate() propagation look consistentThe new
TargetPydanticVersionenum, its addition to thegenerate()signature, forwarding intoparser_class(...), and export via__all__are all wired coherently and match how the v2/v2.11 behavior is selected downstream. I don't see behavioral regressions here.Please double-check that the CLI/docs clearly describe the allowed values (
"2"/"2.11") and that tests cover both enum cases end-to-end.Also applies to: 414-415, 661-666, 764-765, 918-919
src/datamodel_code_generator/parser/jsonschema.py (3)
24-38: JsonSchemaObject now uses version-compatible field-set helpers correctlySwitching
has_default,has_constraint, andhas_ref_with_schema_keywordsto useget_fields_set(self)instead of touching Pydantic internals directly is the right way to support both v1 (__fields_set__) and v2 (model_fields_set). The logic (checking"default"/constraint fields minus metadata-only keys) is preserved, so behavior should match existing semantics while removing v2 deprecation warnings.Please confirm via tests that schemas with and without explicit
default/constraint keys still behave the same across Pydantic v1 and v2.Also applies to: 77-86, 200-222, 416-422, 451-466
517-523: JsonSchemaParsertarget_pydantic_versionpropagation is aligned with the new APIThe constructor’s new
target_pydantic_version: TargetPydanticVersion | Noneparameter and its forwarding tosuper().__init__(..., target_pydantic_version=target_pydantic_version, ...)match the top-levelgenerate()signature and Base parser expectations. This keeps the JSON Schema path in sync with the OpenAPI/GraphQL parsers and ensures templates can see the selected Pydantic version.Please ensure tests cover both
None,V2, andV2_11when using the JSON Schema parser, especially around generatedmodel_configflags.Also applies to: 524-625, 628-727
1045-1097: Migration tomodel_dump/model_validate/model_copyremoves Pydantic v2 deprecations without changing behaviorAcross the parser, replacing direct
.dict()/.parse_obj()/ manual copying with the util helpers (model_dump,model_validate,model_copy) is done carefully:
- All places that previously used
dict(..., exclude_unset=True, by_alias=True)now callmodel_dump(..., exclude_unset=True, by_alias=True).- Schema merge paths (
_load_ref_schema_object,_merge_ref_with_schema, primitive/allOf merges, property-constraint merges, combined-schema parsing) recreateJsonSchemaObjectviamodel_validate(self.SCHEMA_OBJECT_TYPE, ...), which mirrors the oldparse_objbehavior.- Constraint/call-site semantics (e.g., hostname pattern injection, deep merges,
schema_signature) are unchanged apart from the compatibility wrapper.This should clean up Pydantic v2 deprecation warnings while preserving the existing JSON Schema handling.
It’s worth running the JSON Schema test suite once against both Pydantic v1 and v2.11+ to confirm no behavioral drift in edge cases like allOf merges, constraint-only schemas, and JSON pointer resolution.
Also applies to: 1173-1204, 1205-1228, 1472-1489, 1522-1533, 1582-1645, 1673-1684, 1693-1741, 2611-2621, 2675-2686, 3072-3073, 3218-3237, 3239-3244, 3253-3257
src/datamodel_code_generator/util.py (1)
22-26: Pydantic v1/v2 compatibility helpers are well-factoredThe new
PYDANTIC_V2_11flag plusmodel_dump,model_validate,get_fields_set, andmodel_copywrappers provide a clean, centralized way to bridge Pydantic v1 and v2 APIs (dict/parse_obj/__fields_set__/copyvsmodel_dump/model_validate/model_fields_set/model_copy). The implementations look correct and match Pydantic’s semantics, so callers can use the v2-style interface everywhere without triggering deprecation warnings on v2 or breaking v1.Please confirm that all remaining direct uses of
.dict(),.parse_obj(),.__fields_set__, and.copy()on Pydantic models have been migrated to these helpers, so no v2 deprecation warnings slip through.Also applies to: 152-158, 160-185
src/datamodel_code_generator/parser/base.py (7)
35-35: LGTM! Version-compatible utilities imported correctly.The imports for
TargetPydanticVersion,model_copy, andmodel_dumpare correctly added and used throughout the file to replace deprecated Pydantic v1 APIs. This aligns with the PR objective to eliminate deprecation warnings.Also applies to: 76-76
329-329: LGTM! Deprecated.dict()replaced with version-compatible utility.The change from
item.dict()tomodel_dump(item)correctly migrates away from the deprecated Pydantic v1 API to the version-compatible utility function.
634-646: LGTM! Deprecated.copy()replaced with version-compatible utility.The changes from
data_type_.copy()tomodel_copy(data_type_)correctly migrate to the version-compatible API while preserving the deep copy semantics for DataType objects.
779-779: LGTM! New parameter correctly threaded through configuration.The
target_pydantic_versionparameter is:
- Optional (defaults to None) for backward compatibility
- Correctly stored on the Parser instance
- Properly propagated to either
generic_base_class_configorextra_template_data[ALL_MODEL]based on theuse_generic_base_classflagThis enables version-specific behavior for Pydantic v2 compatibility without breaking existing usage.
Also applies to: 783-783, 892-896
1448-1456: LGTM! Deprecated.copy()replaced with version-compatible utility.The change from
data_type.copy()tomodel_copy(data_type)correctly uses the version-compatible API in the_create_set_from_listmethod.
1669-1671: LGTM! Deprecated.copy()replaced with version-compatible utility.The change from
root_type_field.data_type.copy()tomodel_copy(root_type_field.data_type)correctly migrates to the version-compatible API in the__collapse_root_modelsmethod.
1804-1844: LGTM! Deprecated.copy()replaced with version-compatible utility.Multiple calls to
.copy()have been correctly replaced withmodel_copy()in the__override_required_fieldmethod:
- Line 1827:
model_copy(original_field)- Line 1833:
model_copy(original_field.data_type)- Line 1838:
model_copy(original_field.data_type)All changes correctly use the version-compatible API.
tests/parser/test_openapi.py (5)
27-27: LGTM! Version-compatible utilities imported correctly.The imports for
model_dumpandmodel_validateare correctly added. Both utilities are actively used throughout the test file to replace deprecated Pydantic v1 APIs (parse_objanddictmethods).
142-142: LGTM! Deprecated.parse_obj()replaced with version-compatible utility.The migration from
JsonSchemaObject.parse_obj(source_obj)tomodel_validate(JsonSchemaObject, source_obj)correctly replaces the deprecated Pydantic v1 API across multiple test functions (test_parse_object,test_parse_array,test_parse_root_type).Also applies to: 186-186, 240-240
587-590: LGTM! Deprecated.dict()replaced with version-compatible utility.The change from
v.dict(exclude=...)tomodel_dump(v, exclude=...)correctly migrates to the version-compatible API. The addition of"children"to the exclusion set is intentional (as noted in past review comments) and prevents issues with circular references or unstable test comparisons.
748-749: LGTM! Deprecated.parse_obj()replaced with version-compatible utility.The migration from
ParameterObject.parse_obj(...)tomodel_validate(ParameterObject, ...)is correctly applied across multiple test functions. The changes maintain the same functionality while using the version-compatible API.Also applies to: 873-873, 973-973
834-836: LGTM! Deprecated.parse_obj()replaced with version-compatible utility.The migration to
model_validate(MediaObject, ...)andmodel_validate(ResponseObject, ...)correctly replaces the deprecated Pydantic v1 API in dictionary comprehensions. The changes maintain functional equivalence while using version-compatible utilities.Also applies to: 938-940
Fixes: #1823, #2527, #2429, #2213
Summary by CodeRabbit
New Features
Refactor
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.