Fix DataType deepcopy infinite recursion with circular references#2852
Fix DataType deepcopy infinite recursion with circular references#2852
Conversation
📝 WalkthroughWalkthroughAdds Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks and finishing touches✅ Passed checks (3 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 |
|
📚 Docs Preview: https://pr-2852.datamodel-code-generator.pages.dev |
CodSpeed Performance ReportMerging #2852 will not alter performanceComparing
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2852 +/- ##
========================================
Coverage 99.50% 99.50%
========================================
Files 90 90
Lines 14489 14689 +200
Branches 1736 1754 +18
========================================
+ Hits 14417 14617 +200
Misses 37 37
Partials 35 35
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)
tests/test_types.py (1)
243-274: Good coverage for edge cases.Both tests appropriately cover:
memo=Noneinitialization (line 252)- Memo cache hit returning the same object (lines 269-274)
The
# noqacomments are flagged by static analysis as unnecessary for the current Ruff configuration. You may optionally remove them for cleaner code, though keeping them is harmless if you want to guard against other linters.Optional: Remove unused noqa directives
- from datamodel_code_generator.model.base import DataModelFieldBase # noqa: F401 + from datamodel_code_generator.model.base import DataModelFieldBaseApply similar changes to lines 166, 190, 217, 246, 262, and remove
# noqa: PLC2801from lines 252, 269, 274.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/datamodel_code_generator/types.pytests/test_types.py
🧰 Additional context used
🧬 Code graph analysis (2)
src/datamodel_code_generator/types.py (1)
src/datamodel_code_generator/util.py (1)
is_pydantic_v2(52-57)
tests/test_types.py (1)
src/datamodel_code_generator/types.py (1)
DataType(297-838)
🪛 Ruff (0.14.10)
tests/test_types.py
166-166: Unused noqa directive (non-enabled: F401)
Remove unused noqa directive
(RUF100)
190-190: Unused noqa directive (non-enabled: F401)
Remove unused noqa directive
(RUF100)
217-217: Unused noqa directive (non-enabled: F401)
Remove unused noqa directive
(RUF100)
246-246: Unused noqa directive (non-enabled: F401)
Remove unused noqa directive
(RUF100)
252-252: Unused noqa directive (non-enabled: PLC2801)
Remove unused noqa directive
(RUF100)
262-262: Unused noqa directive (non-enabled: F401)
Remove unused noqa directive
(RUF100)
269-269: Unused noqa directive (non-enabled: PLC2801)
Remove unused noqa directive
(RUF100)
274-274: Unused noqa directive (non-enabled: PLC2801)
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). (12)
- GitHub Check: py312-isort6 on Ubuntu
- GitHub Check: py312-pydantic1 on Ubuntu
- GitHub Check: py312-isort7 on Ubuntu
- GitHub Check: 3.14 on Ubuntu
- GitHub Check: 3.12 on macOS
- GitHub Check: 3.14 on Windows
- GitHub Check: 3.13 on Windows
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.10 on Windows
- GitHub Check: 3.12 on Windows
- GitHub Check: benchmarks
- GitHub Check: Analyze (python)
🔇 Additional comments (4)
tests/test_types.py (3)
157-182: Good test coverage for circular reference handling.This test correctly validates that:
- Deepcopy doesn't cause infinite recursion
- Excluded fields (
parent,children) are set toNonein the copy- Non-excluded fields (
type) are properly copied
185-209: Solid test for deep copy independence.The test correctly validates that:
- Nested
data_typesstructure is preserved- Modifying the original doesn't affect the copy (line 208-209)
212-240: Excellent memoization behavior test.The assertion on line 240 correctly validates that memoization returns the same copied object when the original shared DataType is encountered multiple times during deepcopy traversal.
src/datamodel_code_generator/types.py (1)
358-388: Well-implemented deepcopy with proper cycle handling.The two-phase approach (shallow construct first, then deep copy fields) correctly prevents infinite recursion by registering the new object in memo before recursing into nested fields. Setting
childrenandparenttoNoneis intentional and explicitly tested behavior—it breaks circular references in the parent-children graph relationship. This is documented in the existing docstring and validated by the test suite, which confirmschildren is Noneafter deepcopy.
Breaking Change AnalysisResult: No breaking changes detected Reasoning: This PR adds a This analysis was performed by Claude Code Action |
|
🎉 Released in 0.51.0 This PR is now available in the latest release. See the release notes for details. |
Summary by CodeRabbit
New Features
Tests
✏️ Tip: You can customize this high-level summary in your review settings.