Skip to content

Fix nested type imports in x-python-type override#2842

Merged
koxudaxi merged 2 commits intomainfrom
fix/nested-type-imports
Dec 28, 2025
Merged

Fix nested type imports in x-python-type override#2842
koxudaxi merged 2 commits intomainfrom
fix/nested-type-imports

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Dec 28, 2025

Fixes: #2841

When using x-python-type with nested types like Callable[[Iterable[str]], str], the Iterable was not being imported. This PR adds logic to extract all type names from the type annotation string and add imports for any that are in PYTHON_TYPE_IMPORTS.

Summary by CodeRabbit

  • New Features
    • Enhanced Python type-annotation handling to automatically detect and add imports for nested types referenced in custom x-python-type annotations.
  • Tests
    • Added tests verifying nested-type import generation for both known and unknown/custom nested types and updated generated type-hint outputs accordingly.

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 28, 2025

📝 Walkthrough

Walkthrough

Adds regex-based extraction of type names from x-python-type strings and extends the JSON Schema parser to collect/import nested types referenced inside x-python-type annotations; includes tests and expected outputs for nested built-in and unknown custom nested types.

Changes

Cohort / File(s) Summary
Core parser
src/datamodel_code_generator/parser/jsonschema.py
Added import re and a new helper _extract_all_type_names(self, type_str: str) -> list[str]. Enhanced _get_python_type_override() to iterate extracted type names and append corresponding nested imports to the returned DataType.
Generated expectations
tests/data/expected/main/jsonschema/x_python_type_nested_imports.py, tests/data/expected/main/jsonschema/x_python_type_nested_unknown_type.py
New expected output files showing TypedDict Model with callback: NotRequired[Callable[[Iterable[str]], str]] and callback: NotRequired[Callable[[MyCustomType[str]], str]] respectively.
Tests
tests/main/jsonschema/test_main_jsonschema.py
Added test_x_python_type_nested_imports and test_x_python_type_nested_unknown_type to assert nested-type import generation and handling of unknown nested types.

Sequence Diagram(s)

(Skipped — changes are localized to parser import-collection logic and tests; no new multi-component sequential flow requiring visualization.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I nibble through type strings with cheer,
Regex whiskers find names near,
I gather imports, one by one,
So nested types can run and fun—
Tiny hops, big tidy code!

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 title clearly and concisely summarizes the main change: fixing nested type imports within x-python-type overrides, which aligns with the changeset.
Linked Issues check ✅ Passed The PR implements the core objective from issue #2841: enabling automatic import resolution for nested types in x-python-type overrides by extracting type names and adding corresponding imports.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing nested type imports in x-python-type: the regex extraction logic, nested import collection, test cases for nested imports and unknown types are all within scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ 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/nested-type-imports

📜 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 ce639fb and 44c32db.

⛔ Files ignored due to path filters (1)
  • tests/data/jsonschema/x_python_type_nested_unknown_type.json is excluded by !tests/data/**/*.json and included by none
📒 Files selected for processing (2)
  • tests/data/expected/main/jsonschema/x_python_type_nested_unknown_type.py
  • tests/main/jsonschema/test_main_jsonschema.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/main/jsonschema/test_main_jsonschema.py
🧰 Additional context used
🧬 Code graph analysis (1)
tests/data/expected/main/jsonschema/x_python_type_nested_unknown_type.py (1)
src/datamodel_code_generator/model/typed_dict.py (1)
  • TypedDict (49-114)
🪛 Ruff (0.14.10)
tests/data/expected/main/jsonschema/x_python_type_nested_unknown_type.py

14-14: Undefined name MyCustomType

(F821)

⏰ 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-pydantic1 on Ubuntu
  • GitHub Check: py312-isort5 on Ubuntu
  • GitHub Check: py312-black23 on Ubuntu
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.13 on Windows
  • GitHub Check: py312-black24 on Ubuntu
  • GitHub Check: 3.10 on Windows
  • GitHub Check: 3.14 on Ubuntu
  • GitHub Check: 3.14 on Windows
  • GitHub Check: 3.11 on Windows
  • GitHub Check: benchmarks
  • GitHub Check: Analyze (python)
🔇 Additional comments (3)
tests/data/expected/main/jsonschema/x_python_type_nested_unknown_type.py (3)

1-4: LGTM!

The generated file header is correctly formatted and provides useful metadata about the source schema file and generation timestamp.


5-10: LGTM!

The imports are correct and follow best practices:

  • __future__.annotations enables postponed evaluation for forward references
  • Callable is imported from collections.abc (modern Python standard)
  • All imported types are used in the model definition

13-14: LGTM! The undefined type is intentional for this test case.

This test validates the parser's behavior when encountering unknown nested types in x-python-type annotations. The MyCustomType is intentionally left undefined to ensure:

  • The parser extracts nested type names correctly
  • Known types (Callable) are imported
  • Unknown types are preserved as-is without causing crashes

The Ruff F821 warning is expected and should be ignored for this test expected output file.


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

github-actions Bot commented Dec 28, 2025

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

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: 0

🧹 Nitpick comments (1)
src/datamodel_code_generator/parser/jsonschema.py (1)

1338-1343: Remove unused noqa directive.

The # noqa: PLR6301 comment is unnecessary since the PLR6301 rule is not enabled, as indicated by static analysis.

🔎 Suggested fix
-    def _extract_all_type_names(self, type_str: str) -> list[str]:  # noqa: PLR6301
+    def _extract_all_type_names(self, type_str: str) -> list[str]:
📜 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 0b07112 and ce639fb.

⛔ Files ignored due to path filters (1)
  • tests/data/jsonschema/x_python_type_nested_imports.json is excluded by !tests/data/**/*.json and included by none
📒 Files selected for processing (3)
  • src/datamodel_code_generator/parser/jsonschema.py
  • tests/data/expected/main/jsonschema/x_python_type_nested_imports.py
  • tests/main/jsonschema/test_main_jsonschema.py
🧰 Additional context used
🧬 Code graph analysis (3)
tests/main/jsonschema/test_main_jsonschema.py (2)
tests/test_main_kr.py (1)
  • output_file (44-46)
tests/main/conftest.py (2)
  • output_file (98-100)
  • run_main_and_assert (244-408)
tests/data/expected/main/jsonschema/x_python_type_nested_imports.py (1)
src/datamodel_code_generator/model/typed_dict.py (1)
  • TypedDict (49-114)
src/datamodel_code_generator/parser/jsonschema.py (3)
src/datamodel_code_generator/types.py (1)
  • DataType (296-805)
src/datamodel_code_generator/imports.py (1)
  • append (74-89)
src/datamodel_code_generator/parser/base.py (1)
  • data_type (1094-1096)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/parser/jsonschema.py

1338-1338: Unused noqa directive (non-enabled: PLR6301)

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.13 on Ubuntu
  • GitHub Check: 3.13 on Windows
  • GitHub Check: py312-isort7 on Ubuntu
  • GitHub Check: 3.12 on Windows
  • GitHub Check: py312-pydantic1 on Ubuntu
  • GitHub Check: 3.10 on Windows
  • GitHub Check: 3.11 on Windows
  • GitHub Check: benchmarks
  • GitHub Check: Analyze (python)
🔇 Additional comments (4)
src/datamodel_code_generator/parser/jsonschema.py (2)

11-11: LGTM!

The re import is correctly added to support the new _extract_all_type_names method.


1368-1379: LGTM! The nested import collection logic correctly addresses the issue.

The implementation properly extracts nested type names and adds corresponding imports from PYTHON_TYPE_IMPORTS. The approach of extending result.data_types with import-carrying DataType instances ensures the generated code will include the necessary imports.

Note: If the same type appears multiple times in an annotation (e.g., Callable[[Iterable[str], Iterable[int]], str]), duplicate DataType entries will be created. This is harmless since the import system deduplicates via sets in Imports.append().

tests/main/jsonschema/test_main_jsonschema.py (1)

7036-7044: New x-python-type nested imports test is consistent and targeted

The test wiring (input path, fixtures, extra_args) matches the existing x_python_type_* tests and cleanly exercises the new nested-import behavior for Callable[[Iterable[str]], str]. No issues from a test-structure perspective.

tests/data/expected/main/jsonschema/x_python_type_nested_imports.py (1)

1-14: Expected TypedDict output correctly models nested Callable imports

The generated stub cleanly includes all required imports (Callable, Iterable, TypedDict, NotRequired) and the Model definition matches the intended callback: NotRequired[Callable[[Iterable[str]], str]] shape. This aligns with the new nested x-python-type handling.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Dec 28, 2025

CodSpeed Performance Report

Merging #2842 will not alter performance

Comparing fix/nested-type-imports (44c32db) with main (0b07112)

⚠️ 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 28, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.49%. Comparing base (0b07112) to head (44c32db).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2842   +/-   ##
=======================================
  Coverage   99.49%   99.49%           
=======================================
  Files          90       90           
  Lines       14336    14353   +17     
  Branches     1713     1717    +4     
=======================================
+ Hits        14264    14281   +17     
  Misses         37       37           
  Partials       35       35           
Flag Coverage Δ
unittests 99.49% <100.00%> (+<0.01%) ⬆️

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 95cd6d5 into main Dec 28, 2025
38 checks passed
@koxudaxi koxudaxi deleted the fix/nested-type-imports branch December 28, 2025 17:53
@github-actions
Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: This PR is a bug fix that adds missing import statements for nested types in x-python-type annotations. Previously, using x-python-type with nested types like Callable[[Iterable[str]], str] would generate code missing the Iterable import, causing the generated code to fail. The changes are: (1) a new private method _extract_all_type_names() to parse type strings, and (2) enhanced _get_python_type_override() to collect and add imports for nested types. Both are internal implementation changes. The output change is additive (adds missing required imports) which fixes invalid generated code - this is a bug fix, not a breaking change. No CLI/API changes, no template changes required, no default behavior changes for correctly working code.


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.

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.

1 participant