Fix RootModel default value not being applied#2960
Conversation
📝 WalkthroughWalkthroughDefault values are added to Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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 |
Generated by GitHub Actions
|
📚 Docs Preview: https://pr-2960.datamodel-code-generator.pages.dev |
CodSpeed Performance ReportMerging this PR will degrade performance by 17.78%Comparing
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | WallTime | test_perf_deep_nested |
5.1 s | 6.2 s | -17.78% |
| ❌ | WallTime | test_perf_openapi_large |
2.5 s | 2.9 s | -15.91% |
| ❌ | WallTime | test_perf_duplicate_names |
849.3 ms | 1,021.7 ms | -16.88% |
| ❌ | WallTime | test_perf_graphql_style_pydantic_v2 |
703.2 ms | 850.9 ms | -17.36% |
| ❌ | WallTime | test_perf_complex_refs |
1.7 s | 2.1 s | -17.45% |
| ❌ | WallTime | test_perf_all_options_enabled |
5.7 s | 6.9 s | -16.96% |
| ❌ | WallTime | test_perf_large_models_pydantic_v2 |
3.1 s | 3.8 s | -17.63% |
| ❌ | WallTime | test_perf_kubernetes_style_pydantic_v2 |
2.2 s | 2.7 s | -17.06% |
| ❌ | WallTime | test_perf_aws_style_openapi_pydantic_v2 |
1.7 s | 2 s | -16.5% |
| ❌ | WallTime | test_perf_stripe_style_pydantic_v2 |
1.7 s | 2 s | -16.75% |
| ❌ | WallTime | test_perf_multiple_files_input |
3.2 s | 3.8 s | -17.18% |
Footnotes
-
98 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @tests/data/expected/main/jsonschema/has_default_value.py:
- Around line 27-28: The class Family defines __root__: list[ID] but the default
is raw strings ['abc','efg'], which leaves __root__ as strings at runtime;
replace the default with actual ID instances (or use a default_factory that
constructs a list of ID(...) objects) so __root__'s default matches the
annotated type ID and will be valid BaseModel instances when Family is
instantiated.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
docs/llms-full.txtis excluded by none and included by nonesrc/datamodel_code_generator/model/template/pydantic/BaseModel_root.jinja2is excluded by none and included by nonesrc/datamodel_code_generator/model/template/pydantic_v2/RootModel.jinja2is excluded by none and included by none
📒 Files selected for processing (10)
docs/cli-reference/model-customization.mddocs/cli-reference/template-customization.mdtests/data/expected/main/jsonschema/all_of_any_of_base_class_ref.pytests/data/expected/main/jsonschema/has_default_value.pytests/data/expected/main/openapi/nullable.pytests/data/expected/main/openapi/nullable_strict_nullable.pytests/data/expected/main/openapi/nullable_strict_nullable_use_union_operator.pytests/data/expected/main/openapi/referenced_default.pytests/data/expected/main/openapi/referenced_default_use_annotated.pytests/data/expected/main/openapi/use_default_kwarg.py
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2890
File: tests/data/expected/main/jsonschema/ref_nullable_with_constraint.py:14-15
Timestamp: 2026-01-02T08:25:22.111Z
Learning: The datamodel-code-generator currently generates RootModel subclasses with an explicit `root` field annotation (e.g., `class StringType(RootModel[str]): root: str`). This is existing behavior of the code generator and should not be flagged as an issue introduced by new changes.
📚 Learning: 2026-01-02T08:25:22.111Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2890
File: tests/data/expected/main/jsonschema/ref_nullable_with_constraint.py:14-15
Timestamp: 2026-01-02T08:25:22.111Z
Learning: The datamodel-code-generator currently generates RootModel subclasses with an explicit `root` field annotation (e.g., `class StringType(RootModel[str]): root: str`). This is existing behavior of the code generator and should not be flagged as an issue introduced by new changes.
Applied to files:
tests/data/expected/main/openapi/nullable_strict_nullable_use_union_operator.pytests/data/expected/main/jsonschema/all_of_any_of_base_class_ref.pytests/data/expected/main/openapi/referenced_default.pytests/data/expected/main/jsonschema/has_default_value.pytests/data/expected/main/openapi/referenced_default_use_annotated.pydocs/cli-reference/model-customization.mddocs/cli-reference/template-customization.mdtests/data/expected/main/openapi/nullable_strict_nullable.pytests/data/expected/main/openapi/nullable.pytests/data/expected/main/openapi/use_default_kwarg.py
⏰ 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). (4)
- GitHub Check: 3.10 on Windows
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.12 on Windows
- GitHub Check: 3.13 on Windows
🔇 Additional comments (11)
tests/data/expected/main/openapi/nullable_strict_nullable_use_union_operator.py (1)
59-60: LGTM!The default value addition for
Id.__root__is consistent with the PR objective and aligns with other root models in this file that already have defaults (Description,Name).tests/data/expected/main/openapi/use_default_kwarg.py (1)
59-60: LGTM!The default value for
Id.__root__correctly reflects the expected code generator output when default values are specified in the schema.docs/cli-reference/template-customization.md (1)
2628-2628: LGTM!The documentation example now correctly shows the default value
= 0forZoom.__root__, which matches the"default": 0specified in the input JSON schema (line 2502). This accurately demonstrates the fixed behavior.tests/data/expected/main/openapi/referenced_default_use_annotated.py (1)
12-13: LGTM!The default value
= 5forModelSettingB.rootis consistent with the usage pattern in theModelclass wheresettingAdefaults to5andsettingBusesModelSettingB(5)as its default factory.tests/data/expected/main/openapi/nullable.py (1)
59-60: LGTM!The default value addition completes the fix for
Id.__root__, consistent with other root models in this file that already correctly have their defaults applied.tests/data/expected/main/openapi/referenced_default.py (1)
10-11: LGTM!The default value
5is correctly within the constrained float range[0.0, 10.0], and is consistent with thedefault_factoryon line 16.tests/data/expected/main/openapi/nullable_strict_nullable.py (1)
59-60: LGTM!The default value
1correctly matches theinttype declaration.tests/data/expected/main/jsonschema/all_of_any_of_base_class_ref.py (1)
77-78: LGTM!The default value
0is valid for the constrained float range[0.0, 25.0]and is consistent with thedefault_factoryon line 21.docs/cli-reference/model-customization.md (1)
5031-5032: LGTM!The documentation example correctly reflects the new generator behavior for applying default values to root model fields.
tests/data/expected/main/jsonschema/has_default_value.py (2)
19-20: LGTM!The default value
'abc'correctly matches thestrtype for theIDroot model.
31-32: Type mismatch in generated code:list[Pet]default contains strings instead of Pet objects.This is the expected output generated from the JSON schema's FamilyPets definition, which specifies a default of
["taro", "shiro"](strings) for an array of Pet items. The generated code faithfully reproduces this mismatch:__root__: list[Pet] = ['taro', 'shiro'].Unlike the
Familyfield which useslist[ID]with string defaults (valid becauseIDis a root model wrappingstr),Petis a regular model with properties. Pydantic will attempt to coerce the string defaults toPetinstances during model instantiation, which will likely fail since strings cannot be automatically converted to objects.The schema definition itself contains this problematic default value combination.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2960 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 94 94
Lines 17738 17738
Branches 2038 2038
=========================================
Hits 17738 17738
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:
|
Breaking Change AnalysisResult: Breaking changes detected Reasoning: This PR is a bug fix that corrects RootModel default value handling. While it fixes incorrect behavior, it changes the generated code output for any schema that defines default values for root models. Users who rely on the current generated code (without defaults) or have custom templates will need to account for this change. The template logic change from Content for Release NotesCode Generation Changes
Custom Template Update Required
This analysis was performed by Claude Code Action |
|
🎉 Released in 0.53.0 This PR is now available in the latest release. See the release notes for details. |
Summary by CodeRabbit
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.