Skip to content

Fix type alias template crash with reuse_model on empty fields#3060

Merged
koxudaxi merged 4 commits intokoxudaxi:mainfrom
butvinm:fix/type-statement-empty-fields-crash
Apr 4, 2026
Merged

Fix type alias template crash with reuse_model on empty fields#3060
koxudaxi merged 4 commits intokoxudaxi:mainfrom
butvinm:fix/type-statement-empty-fields-crash

Conversation

@butvinm
Copy link
Copy Markdown
Contributor

@butvinm butvinm commented Mar 22, 2026

Fixes #3059

create_reuse_model() creates models with fields=[] and base_classes=[base_ref]. Class-based templates (BaseModel) handle this naturally (class Foo(Bar): pass), but all six type alias templates unconditionally accessed fields[0], causing a Jinja2 UndefinedError. The fix guards fields[0] access and falls back to base_class when fields is empty.

Templates fixed: TypeStatement.jinja2, TypeAliasType.jinja2, TypeAliasAnnotation.jinja2, UnionTypeStatement.jinja2, UnionTypeAliasAnnotation.jinja2, UnionTypeAliasType.jinja2.

Before (bug)

jinja2.exceptions.UndefinedError: list object has no element 0

After (fix)

type Foo = str

type Bar = Foo

Summary by CodeRabbit

  • Tests
    • Added a regression test covering OpenAPI code generation with model reuse and type-alias options, validating output for Pydantic v2 models targeting Python 3.14.
    • Added an expected-output fixture to verify correct generation of type aliases (e.g., Foo → str, Bar → Foo).

Guard fields[0] access in TypeStatement, TypeAliasType, TypeAliasAnnotation,
and UnionTypeStatement templates. When fields is empty (reuse model), fall
back to base_class, producing e.g. `type Foo = Bar`.

Fixes koxudaxi#3059

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1583bda1-3d8d-46f2-bceb-06c7639b1b14

📥 Commits

Reviewing files that changed from the base of the PR and between 569f969 and 1ad2e58.

⛔ Files ignored due to path filters (1)
  • tests/data/openapi/reuse_model_with_type_alias.json is excluded by !tests/data/**/*.json and included by none
📒 Files selected for processing (2)
  • tests/data/expected/main/openapi/reuse_model_with_type_alias.py
  • tests/main/openapi/test_main_openapi.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/main/openapi/test_main_openapi.py

📝 Walkthrough

Walkthrough

Added a new expected fixture containing two type aliases and a regression test that verifies code generation with --reuse-model and --use-type-alias for Pydantic V2 / Python 3.14.

Changes

Cohort / File(s) Summary
Expected Fixture
tests/data/expected/main/openapi/reuse_model_with_type_alias.py
Added file with generated metadata comments and two type aliases: Foo = str, Bar = Foo.
Regression Test
tests/main/openapi/test_main_openapi.py
Added test_main_reuse_model_with_type_alias (skipped for Py3.14 black) that runs generation with --reuse-model and --use-type-alias, targeting Python 3.14 and asserting the expected output.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

breaking-change-analyzed

Poem

🐰
I nibble lines of generated code,
Foo becomes str along my road,
Bar hops after, linked and true,
Reuse and alias — that's the view,
A tiny hop for devs anew.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds test coverage for the fix but does not include the actual template modifications (#3059 requires changes to six Jinja2 templates to guard fields[0] access. Include the actual template modifications (TypeStatement.jinja2, TypeAliasType.jinja2, TypeAliasAnnotation.jinja2, UnionTypeStatement.jinja2, UnionTypeAliasAnnotation.jinja2, UnionTypeAliasType.jinja2) that guard fields[0] access and fall back to base_class when fields is empty.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main fix: preventing type alias template crashes when reuse_model creates models with empty fields.
Out of Scope Changes check ✅ Passed All changes are in scope: test fixture and test function directly validate the type alias generation fix for the empty fields case.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Mar 22, 2026

Merging this PR will not alter performance

⚠️ 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.

✅ 11 untouched benchmarks
⏩ 98 skipped benchmarks1


Comparing butvinm:fix/type-statement-empty-fields-crash (1ad2e58) with main (7e1a5c7)

Open in CodSpeed

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.

butvinm and others added 2 commits March 22, 2026 04:54
…AliasType

These two union templates had the identical unguarded fields[0] access.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Black 22/23 can't parse Python 3.14 type statement syntax.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (7e1a5c7) to head (1ad2e58).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #3060   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           86        86           
  Lines        18011     18014    +3     
  Branches      2075      2075           
=========================================
+ Hits         18011     18014    +3     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

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.

@butvinm butvinm marked this pull request as ready for review March 22, 2026 03:08
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/main/openapi/test_main_openapi.py`:
- Around line 5217-5236: The test test_main_reuse_model_with_type_alias calls
run_main_and_assert but misses the expected_file parameter, causing it to look
for reuse_model_type_alias.py instead of the fixture; update the call to
run_main_and_assert (inside test_main_reuse_model_with_type_alias) to include
expected_file="reuse_model_with_type_alias.py" so the test uses the correct
expected fixture when asserting output.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d862bc58-c5f1-443e-b85f-2ccdf605eb5c

📥 Commits

Reviewing files that changed from the base of the PR and between 7e1a5c7 and 569f969.

⛔ Files ignored due to path filters (7)
  • src/datamodel_code_generator/model/template/TypeAliasAnnotation.jinja2 is excluded by none and included by none
  • src/datamodel_code_generator/model/template/TypeAliasType.jinja2 is excluded by none and included by none
  • src/datamodel_code_generator/model/template/TypeStatement.jinja2 is excluded by none and included by none
  • src/datamodel_code_generator/model/template/UnionTypeAliasAnnotation.jinja2 is excluded by none and included by none
  • src/datamodel_code_generator/model/template/UnionTypeAliasType.jinja2 is excluded by none and included by none
  • src/datamodel_code_generator/model/template/UnionTypeStatement.jinja2 is excluded by none and included by none
  • tests/data/openapi/reuse_model_type_alias.json is excluded by !tests/data/**/*.json and included by none
📒 Files selected for processing (2)
  • tests/data/expected/main/openapi/reuse_model_with_type_alias.py
  • tests/main/openapi/test_main_openapi.py

Comment thread tests/main/openapi/test_main_openapi.py
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@koxudaxi koxudaxi merged commit 5dcbc09 into koxudaxi:main Apr 4, 2026
38 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 4, 2026

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: This PR is a pure bug fix. All 6 type alias Jinja2 templates previously crashed with jinja2.exceptions.UndefinedError when reuse_model created models with empty fields (accessing fields[0] unconditionally). The fix adds guards (if fields) and falls back to base_class when fields is empty. No previously-working code paths are affected — the changed code path previously produced a crash, not valid output. No API, CLI, default behavior, or template variable contract changes were made. Users with custom copies of these templates are unaffected since the template variable interface (fields, base_class, class_name, etc.) remains identical.


This analysis was performed by Claude Code Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 4, 2026

🎉 Released in 0.56.0

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

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.

TypeStatement.jinja2 crashes with "list object has no element 0" when use_type_alias=True + reuse_model=True on large specs

2 participants