Skip to content

Use __qualname__ for nested class support and add DefaultPutDict test#2859

Merged
koxudaxi merged 1 commit intomainfrom
fix/generic-type-qualname
Dec 30, 2025
Merged

Use __qualname__ for nested class support and add DefaultPutDict test#2859
koxudaxi merged 1 commit intomainfrom
fix/generic-type-qualname

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Dec 30, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Improved qualified name generation for custom generic types to provide more accurate and consistent type name representations throughout generated code.
  • Tests

    • Added comprehensive test coverage for DefaultPutDict type support, ensuring proper import resolution and correct utilization in generated code output.

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

@github-actions
Copy link
Copy Markdown
Contributor

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 30, 2025

📝 Walkthrough

Walkthrough

This PR modifies the _get_origin_name function to use __qualname__ instead of __name__ for non-builtin/typing/collections.abc types, altering how qualified names are generated for custom generic origins. Supporting tests for DefaultPutDict are added to verify the updated behavior.

Changes

Cohort / File(s) Summary
Core Logic Change
src/datamodel_code_generator/__main__.py
Modified _get_origin_name() to fetch names from __qualname__ attribute (with fallback to __name__) for non-builtin types; updated docstring to reflect module.qualname format instead of module.name
Test Model Addition
tests/data/python/input_model/pydantic_models.py
Added import for DefaultPutDict and new Pydantic model ModelWithDefaultPutDict with two fields: cache: DefaultPutDict[str, str] and optional_cache: DefaultPutDict[str, int] | None
Test Case
tests/test_input_model.py
Added test function test_input_model_default_put_dict_import() to verify DefaultPutDict is correctly imported and used in generated output with proper type representations

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #2858: Also modifies _get_origin_name to change qualified name handling for non-builtin/custom generic types
  • #2851: Modifies _get_origin_name behavior for formatting origin/type names with different qualification approaches

Suggested labels

breaking-change-analyzed

Poem

🐰 Hop along, dear generated code!
From __name__ to __qualname__ we go,
DefaultPutDict now takes the stage,
Qualified names shine on the page!
A rabbit's test to prove it true—
Origins rendered, fresh and new!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes both main changes: using qualname for nested class support and adding a DefaultPutDict test, matching the changeset modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

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 Dec 30, 2025

CodSpeed Performance Report

Merging #2859 will not alter performance

Comparing fix/generic-type-qualname (54ab6e1) with main (a3cd521)

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

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.52%. Comparing base (a3cd521) to head (54ab6e1).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2859   +/-   ##
=======================================
  Coverage   99.52%   99.52%           
=======================================
  Files          90       90           
  Lines       14935    14938    +3     
  Branches     1788     1788           
=======================================
+ Hits        14864    14867    +3     
  Misses         38       38           
  Partials       33       33           
Flag Coverage Δ
unittests 99.52% <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.

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)
tests/data/python/input_model/pydantic_models.py (1)

108-119: LGTM! Consider minor cleanup of unused directive.

The new ModelWithDefaultPutDict model correctly tests the __qualname__ change for real-world generic types from the parser module. The structure follows the existing pattern for custom generic types.

🔎 Optional: Remove unused noqa directive

Ruff reports that the noqa: E402 directive is unused because E402 is not enabled. Consider removing it:

-from datamodel_code_generator.parser import DefaultPutDict  # noqa: E402
+from datamodel_code_generator.parser import DefaultPutDict

If the directive is intended for other linters (e.g., flake8), you can keep it. However, if only ruff is used, it's unnecessary.

📜 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 a3cd521 and 54ab6e1.

📒 Files selected for processing (3)
  • src/datamodel_code_generator/__main__.py
  • tests/data/python/input_model/pydantic_models.py
  • tests/test_input_model.py
🧰 Additional context used
🧬 Code graph analysis (1)
tests/data/python/input_model/pydantic_models.py (1)
src/datamodel_code_generator/parser/__init__.py (1)
  • DefaultPutDict (28-47)
🪛 Ruff (0.14.10)
tests/data/python/input_model/pydantic_models.py

111-111: Unused noqa directive (non-enabled: E402)

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). (2)
  • GitHub Check: combine coverage
  • GitHub Check: benchmarks
🔇 Additional comments (2)
src/datamodel_code_generator/__main__.py (1)

695-697: LGTM! Excellent improvement for nested class support.

The change to use __qualname__ with a fallback to __name__ correctly handles nested classes. For example, a nested generic like OuterClass.InnerClass[T] will now be properly represented as module.OuterClass.InnerClass[T] instead of module.InnerClass[T], avoiding potential name collisions and improving clarity.

The fallback ensures backward compatibility for any edge cases where __qualname__ might not be available.

tests/test_input_model.py (1)

744-756: LGTM! Well-structured test for DefaultPutDict support.

The test properly validates that DefaultPutDict from the parser module is correctly imported and represented in generated output. It mirrors the existing pattern for custom generic types and covers both non-optional and optional usage scenarios.

@koxudaxi koxudaxi merged commit 63d8804 into main Dec 30, 2025
37 checks passed
@koxudaxi koxudaxi deleted the fix/generic-type-qualname branch December 30, 2025 06:18
@github-actions
Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: This PR changes from using __name__ to __qualname__ for getting the name of generic origin types. While this does change generated code output for nested classes (e.g., module.NestedClass[str]module.OuterClass.NestedClass[str]), this is a bug fix rather than a breaking change. The previous behavior was incorrect - it generated unimportable names for nested classes since NestedClass alone cannot be imported from a module; only OuterClass.NestedClass can. Users whose code was working before would not have been using nested generic classes (since it was broken), so this fix enables a previously broken use case without breaking existing working code. The fallback to __name__ also ensures backward compatibility for types that don't have __qualname__.


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