Skip to content

Fix reuse-model generating type aliases instead of class inheritance#2853

Merged
koxudaxi merged 1 commit intomainfrom
fix/reuse-model-type-alias-2639
Dec 30, 2025
Merged

Fix reuse-model generating type aliases instead of class inheritance#2853
koxudaxi merged 1 commit intomainfrom
fix/reuse-model-type-alias-2639

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Dec 29, 2025

Fixes: #2639

Summary by CodeRabbit

  • Bug Fixes
    • Fixed type alias generation to produce explicit subclass declarations instead of simple aliases in generated models, improving type identity handling and compatibility with type checkers.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 29, 2025

📝 Walkthrough

Walkthrough

The changes update expected test output files to reflect the conversion of generated type aliases to explicit subclass declarations. Two test files now show type references being generated as proper subclass definitions rather than simple aliases, maintaining inheritance while establishing distinct types.

Changes

Cohort / File(s) Summary
Type alias to subclass conversions
tests/data/expected/main/json/json_reuse_model_pydantic2.py, tests/data/expected/main/jsonschema/allof_root_model_constraints_merge_pydantic_v2.py
Replaced type alias declarations with explicit subclass definitions: ArmLeft, RefToObjectNoPropsAllOf, and RefToNestedAllOfAllOf are now generated as proper subclasses inheriting from their parent types rather than simple aliases.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • PR #2838: Converts generated models from simple type aliases to actual subclass declarations, mirroring this PR's alias-to-subclass transformation pattern.
  • PR #2843: Fixes deep allOf inheritance resolution to ensure classes are generated as distinct subclasses rather than mere aliases.
  • PR #2676: Addresses allOf/$ref root-model merging to produce proper subclassed models instead of losing constraints or emitting aliases.

Suggested labels

breaking-change-analyzed, breaking-change

Poem

A rabbit hops through test data spry,
Where aliases once did loosely lie,
Now subclasses stand tall and true,
With proper inheritance shining through! 🐰

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main change: fixing reuse-model to generate class inheritance instead of type aliases.
Linked Issues check ✅ Passed The changes directly address issue #2639 by replacing type aliases with proper class inheritance in Pydantic v2 model generation, meeting the core requirement.
Out of Scope Changes check ✅ Passed All changes are focused on test data files that reflect the fix for type alias to class inheritance conversion in Pydantic v2 model generation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/reuse-model-type-alias-2639

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f7a6c9 and 43d27c5.

⛔ Files ignored due to path filters (1)
  • src/datamodel_code_generator/model/template/pydantic_v2/BaseModel.jinja2 is excluded by none and included by none
📒 Files selected for processing (2)
  • tests/data/expected/main/json/json_reuse_model_pydantic2.py
  • tests/data/expected/main/jsonschema/allof_root_model_constraints_merge_pydantic_v2.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). (9)
  • GitHub Check: py312-black22 on Ubuntu
  • GitHub Check: py312-isort5 on Ubuntu
  • GitHub Check: Analyze (python)
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.14 on Windows
  • GitHub Check: 3.10 on Windows
  • GitHub Check: 3.11 on Windows
  • GitHub Check: 3.13 on Windows
  • GitHub Check: benchmarks
🔇 Additional comments (3)
tests/data/expected/main/json/json_reuse_model_pydantic2.py (1)

16-17: LGTM! Subclass correctly replaces type alias.

The change from ArmLeft = ArmRight to class ArmLeft(ArmRight): pass aligns with the PR objective. This creates a distinct type with its own identity while inheriting all fields from ArmRight, which is the correct behavior for Pydantic v2 model reuse.

tests/data/expected/main/jsonschema/allof_root_model_constraints_merge_pydantic_v2.py (2)

113-114: LGTM! Consistent pattern with empty subclass inheritance.

This change follows the same pattern as RefToObjectNoPropsAllOf, creating a distinct type through inheritance. The consistency across the file is appropriate for the allOf schema construct.


97-98: LGTM! This change correctly converts the type alias to an explicit subclass.

The empty subclass pattern works correctly with Pydantic v2. The test suite validates the generated output through file comparison, which confirms the models are structured correctly for the allOf JSON Schema construct.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

📚 Docs Preview: https://pr-2853.datamodel-code-generator.pages.dev

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Dec 29, 2025

CodSpeed Performance Report

Merging #2853 will not alter performance

Comparing fix/reuse-model-type-alias-2639 (43d27c5) with main (0f7a6c9)

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

Summary

✅ 11 untouched
⏩ 98 skipped1

Footnotes

  1. 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.

@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 29, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.50%. Comparing base (0f7a6c9) to head (43d27c5).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2853   +/-   ##
=======================================
  Coverage   99.50%   99.50%           
=======================================
  Files          90       90           
  Lines       14824    14824           
  Branches     1777     1777           
=======================================
  Hits        14750    14750           
  Misses         38       38           
  Partials       36       36           
Flag Coverage Δ
unittests 99.50% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@koxudaxi koxudaxi merged commit 7a4709c into main Dec 30, 2025
37 checks passed
@koxudaxi koxudaxi deleted the fix/reuse-model-type-alias-2639 branch December 30, 2025 00:42
@github-actions
Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: Breaking changes detected

Reasoning: This PR changes the code generation output for Pydantic v2 when using the --reuse-model option. Previously, when a model would just be an empty subclass (no additional fields, config, or description), the template would generate a type alias (e.g., ArmLeft = ArmRight) as a memory optimization. Now it always generates a proper class inheritance (e.g., class ArmLeft(ArmRight): pass). This is a breaking change because: 1) Users' generated code output will change - any code that relied on the type alias form will now get a subclass instead. This affects type identity semantics (ArmLeft is now a distinct type from ArmRight, rather than an alias). 2) Users who have custom Jinja2 templates based on the old pydantic_v2/BaseModel.jinja2 template may need to update them if they were using or modifying the conditional alias logic that was removed.

Content for Release Notes

Code Generation Changes

  • Type aliases now generate as class inheritance - When using --reuse-model (Pydantic v2 only), models that would previously generate as type aliases (ChildModel = ParentModel) now generate as explicit subclasses (class ChildModel(ParentModel): pass). This change improves type checker compatibility and maintains proper type identity, but may affect code that relied on type alias semantics or compared types directly. (Fix reuse-model generating type aliases instead of class inheritance #2853)

    Before:

    ArmLeft = ArmRight

    After:

    class ArmLeft(ArmRight):
        pass

Custom Template Update Required

  • Pydantic v2 BaseModel.jinja2 template structure changed - If you have a custom template that extends or modifies the default pydantic_v2/BaseModel.jinja2 template, you need to update it. The conditional block that generated type aliases ({% if base_class != "BaseModel" and ... %}{{ class_name }} = {{ base_class }}{% else %}...{% endif %}) has been removed. Templates should now always generate class declarations. (Fix reuse-model generating type aliases instead of class inheritance #2853)

This analysis was performed by Claude Code Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 1, 2026

🎉 Released in 0.51.0

This PR is now available in the latest release. See the release notes for details.

@ilovelinux ilovelinux linked an issue Jan 2, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Empty models are not generated but aliased Pydantic schemav2 creates unexpected MyOtherModel = MyModel - still

1 participant