Skip to content

Add GenerateConfig class and auto-generate TypedDicts for type-safe config#2844

Merged
koxudaxi merged 36 commits intomainfrom
refactor/config-class
Dec 30, 2025
Merged

Add GenerateConfig class and auto-generate TypedDicts for type-safe config#2844
koxudaxi merged 36 commits intomainfrom
refactor/config-class

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Dec 28, 2025

Summary by CodeRabbit

  • New Features

    • generate() accepts a config object for end-to-end, config-driven generation
    • Introduces structured, typed configuration models (GenerateConfig, ParserConfig, ParseConfig) and corresponding TypedDict schemas for programmatic configuration
  • Chores

    • CI/workflow, pre-commit hook, datamodel-codegen profiles, and a new tox env added to validate generated config typings
    • Lint workflow skip list updated to include config-types
  • Tests

    • New tests for generation with config objects, template-data override behavior, and config/TypedDict consistency

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 28, 2025

Warning

Rate limit exceeded

@koxudaxi has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 3 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between abfc76c and fba28c9.

📒 Files selected for processing (1)
  • tests/main/test_public_api_signature_baseline.py
📝 Walkthrough

Walkthrough

Add Pydantic config models and TypedDicts, thread an optional GenerateConfig through generate(), add runtime model-rebuild support for Pydantic v2, and introduce CI/pre-commit/tox flows plus tests to generate/validate config TypedDicts.

Changes

Cohort / File(s) Summary
CI / Pre-commit / Tooling
'.github/workflows/config-types.yaml', '.github/workflows/lint.yaml', '.pre-commit-config.yaml', 'tox.ini', 'pyproject.toml'
New GitHub Actions workflow config-types; add config-types to lint SKIP env; add local pre-commit hook config-types; add testenv:config-types to tox; add datamodel-codegen profiles and update run.omit to include _types.
Public API & generate entrypoint
src/datamodel_code_generator/__init__.py
generate() signature gains `config: GenerateConfig
Pydantic config models & wiring
src/datamodel_code_generator/config.py
New Pydantic models GenerateConfig, ParserConfig, ParseConfig; _rebuild_config_models() wires runtime types for Pydantic v1/v2 and classmethods derive parser/parse configs from GenerateConfig.
TypedDict definitions & exports
src/datamodel_code_generator/_types/__init__.py, src/datamodel_code_generator/_types/generate_config_dict.py, src/datamodel_code_generator/_types/parse_config_dict.py, src/datamodel_code_generator/_types/parser_config_dict.py
New TypedDicts (GenerateConfigDict, ParseConfigDict, ParserConfigDict) with comprehensive optional fields and package-level re-exports.
Model schema loading / rebuild
src/datamodel_code_generator/__main__.py
Add _try_rebuild_model(obj: type) and invoke it from model-loading to support Pydantic v2 model_rebuild with a runtime types namespace (falls back when not applicable).
Tests
tests/main/test_main_general.py, tests/main/test_public_api_signature_baseline.py, tests/test_input_model.py
Add tests exercising generate() with a GenerateConfig object, baseline tests comparing TypedDicts ↔ Pydantic models and defaults, and an input-model test using GenerateConfig.
Misc packaging/dev files
'manifest_file', 'requirements.txt', 'pyproject.toml'
Update tooling/profile references and include _types outputs in run.omit for codegen flows.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User
    participant Generate as generate()
    participant ConfigModel as GenerateConfig
    participant Loader as __main__/_load_model_schema
    participant Parser as Parser/Codegen

    User->>Generate: call generate(input_, config=GenerateConfig(...))
    activate Generate
    Generate->>ConfigModel: validate/read config (model_dump / attributes)
    ConfigModel-->>Generate: return config values
    Note right of Generate: merge/override explicit kwargs with config values

    Generate->>Loader: load input models / _load_model_schema(obj)
    activate Loader
    Loader->>Loader: if obj has model_rebuild -> call _try_rebuild_model(obj)
    Loader-->>Generate: return model/schema
    deactivate Loader

    Generate->>Parser: build ParserConfig/ParseConfig and run parsing/generation
    activate Parser
    Parser-->>Generate: generated modules/text
    deactivate Parser

    Generate-->>User: return generated output
    deactivate Generate
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

breaking-change-analyzed

Poem

🐇 I nibbled through configs late at night,

TypedDicts sprouted tidy and bright,
GenerateConfig whispered the plan,
Models rebuilt — the pipeline ran,
CI hummed softly; the rabbit hopped light.

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 clearly describes the primary changes: introducing a GenerateConfig class and auto-generating TypedDicts for configuration, which aligns with the substantial additions across config.py, _types modules, and workflow configurations.
Docstring Coverage ✅ Passed Docstring coverage is 86.21% which is sufficient. The required threshold is 80.00%.

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-2844.datamodel-code-generator.pages.dev

Comment thread src/datamodel_code_generator/__init__.py Dismissed
Comment thread src/datamodel_code_generator/config.py Fixed
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Dec 28, 2025

CodSpeed Performance Report

Merging #2844 will not alter performance

Comparing refactor/config-class (fba28c9) with main (12fc77c)

⚠️ 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.52%. Comparing base (63d8804) to head (c308216).

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #2844    +/-   ##
========================================
  Coverage   99.52%   99.52%            
========================================
  Files          90       91     +1     
  Lines       14938    15360   +422     
  Branches     1788     1792     +4     
========================================
+ Hits        14867    15287   +420     
- Misses         38       39     +1     
- Partials       33       34     +1     
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.

@koxudaxi koxudaxi force-pushed the refactor/config-class branch from 9741888 to cf8553a Compare December 28, 2025 18:42
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: 2

♻️ Duplicate comments (1)
src/datamodel_code_generator/config.py (1)

11-11: Unused TypedDict imports flagged by static analysis.

These imports (GenerateConfigDict, ParseConfigDict, ParserConfigDict) are not used in this file. If they're intended for re-export, consider adding them to an __all__ list or moving them to __init__.py. Otherwise, they can be removed.

🧹 Nitpick comments (1)
src/datamodel_code_generator/__main__.py (1)

762-791: Consider removing unused noqa directives.

The static analysis indicates that the # noqa: PLC0415 directives on lines 768, 769, 772, and 774 are unused. This suggests the PLC0415 rule (import not at top of file) may not be enabled in the project's linter configuration.

🔎 Suggested fix
-        from datamodel_code_generator.model.base import DataModel, DataModelFieldBase  # noqa: PLC0415
-        from datamodel_code_generator.types import DataTypeManager, StrictTypes  # noqa: PLC0415
+        from datamodel_code_generator.model.base import DataModel, DataModelFieldBase
+        from datamodel_code_generator.types import DataTypeManager, StrictTypes

         try:
-            from datamodel_code_generator.model.pydantic_v2 import UnionMode  # noqa: PLC0415
+            from datamodel_code_generator.model.pydantic_v2 import UnionMode
         except ImportError:
-            from typing import Any  # noqa: PLC0415
+            from typing import Any
📜 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 19f1fb7 and cf8553a.

📒 Files selected for processing (14)
  • .github/workflows/config-types.yaml
  • .pre-commit-config.yaml
  • pyproject.toml
  • src/datamodel_code_generator/__init__.py
  • src/datamodel_code_generator/__main__.py
  • src/datamodel_code_generator/_types/__init__.py
  • src/datamodel_code_generator/_types/generate_config_dict.py
  • src/datamodel_code_generator/_types/parse_config_dict.py
  • src/datamodel_code_generator/_types/parser_config_dict.py
  • src/datamodel_code_generator/config.py
  • tests/main/test_main_general.py
  • tests/main/test_public_api_signature_baseline.py
  • tests/test_input_model.py
  • tox.ini
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-25T09:22:14.661Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2799
File: src/datamodel_code_generator/model/pydantic/__init__.py:43-43
Timestamp: 2025-12-25T09:22:14.661Z
Learning: In datamodel-code-generator project, defensive `# noqa: PLC0415` directives should be kept on lazy imports (imports inside functions/methods) even when Ruff reports them as unused via RUF100, to prepare for potential future Ruff configuration changes that might enable the import-outside-top-level rule.

Applied to files:

  • src/datamodel_code_generator/config.py
🧬 Code graph analysis (7)
src/datamodel_code_generator/__main__.py (5)
src/datamodel_code_generator/model/base.py (3)
  • class_name (847-849)
  • class_name (852-856)
  • model_rebuild (199-206)
src/datamodel_code_generator/model/pydantic/types.py (1)
  • DataTypeManager (171-372)
src/datamodel_code_generator/model/pydantic_v2/types.py (1)
  • DataTypeManager (70-167)
src/datamodel_code_generator/enums.py (2)
  • StrictTypes (199-206)
  • UnionMode (192-196)
src/datamodel_code_generator/parser/jsonschema.py (1)
  • model_rebuild (224-226)
src/datamodel_code_generator/__init__.py (1)
src/datamodel_code_generator/config.py (1)
  • GenerateConfig (78-208)
src/datamodel_code_generator/_types/generate_config_dict.py (3)
src/datamodel_code_generator/enums.py (15)
  • AllExportsCollisionStrategy (92-102)
  • AllExportsScope (81-89)
  • AllOfMergeMode (142-152)
  • CollapseRootModelsNameStrategy (131-139)
  • FieldTypeCollisionStrategy (105-113)
  • GraphQLScope (155-158)
  • InputFileType (35-45)
  • ModuleSplitMode (172-178)
  • NamingStrategy (116-128)
  • OpenAPIScope (70-78)
  • ReadOnlyWriteOnlyModelType (161-169)
  • ReuseScope (59-67)
  • TargetPydanticVersion (181-189)
  • UnionMode (192-196)
  • StrictTypes (199-206)
src/datamodel_code_generator/format.py (4)
  • DateClassType (60-65)
  • DatetimeClassType (50-57)
  • Formatter (171-177)
  • PythonVersion (68-140)
src/datamodel_code_generator/parser/__init__.py (1)
  • LiteralType (20-25)
src/datamodel_code_generator/_types/parse_config_dict.py (1)
src/datamodel_code_generator/enums.py (3)
  • AllExportsCollisionStrategy (92-102)
  • AllExportsScope (81-89)
  • ModuleSplitMode (172-178)
src/datamodel_code_generator/_types/__init__.py (3)
src/datamodel_code_generator/_types/generate_config_dict.py (1)
  • GenerateConfigDict (35-155)
src/datamodel_code_generator/_types/parse_config_dict.py (1)
  • ParseConfigDict (14-21)
src/datamodel_code_generator/_types/parser_config_dict.py (1)
  • ParserConfigDict (27-137)
src/datamodel_code_generator/config.py (5)
src/datamodel_code_generator/_types/generate_config_dict.py (1)
  • GenerateConfigDict (35-155)
src/datamodel_code_generator/_types/parse_config_dict.py (1)
  • ParseConfigDict (14-21)
src/datamodel_code_generator/parser/__init__.py (2)
  • DefaultPutDict (28-47)
  • LiteralType (20-25)
src/datamodel_code_generator/util.py (2)
  • is_pydantic_v2 (52-57)
  • model_dump (254-258)
src/datamodel_code_generator/model/__init__.py (1)
  • DataModelSet (25-35)
tests/main/test_public_api_signature_baseline.py (1)
src/datamodel_code_generator/config.py (1)
  • GenerateConfig (78-208)
🪛 GitHub Actions: Lint
tox.ini

[error] 1-1: Command 'tox' not found in the environment during config-types hook.

src/datamodel_code_generator/config.py

[error] 83-83: ruff: D106 Missing docstring in public nested class


[error] 216-216: ruff: D106 Missing docstring in public nested class


[error] 399-399: ruff: D106 Missing docstring in public nested class

🪛 Ruff (0.14.10)
src/datamodel_code_generator/__main__.py

768-768: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


769-769: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


772-772: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


774-774: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)

src/datamodel_code_generator/__init__.py

606-606: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)

src/datamodel_code_generator/config.py

437-437: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


438-438: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


441-441: Unused noqa directive (non-enabled: PLC0415)

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). (10)
  • GitHub Check: 3.11 on macOS
  • GitHub Check: py312-black24 on Ubuntu
  • GitHub Check: 3.10 on Windows
  • GitHub Check: 3.10 on macOS
  • GitHub Check: 3.10 on Ubuntu
  • GitHub Check: 3.11 on Windows
  • GitHub Check: 3.13 on Windows
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.14 on Windows
  • GitHub Check: benchmarks
🔇 Additional comments (18)
tests/test_input_model.py (1)

595-603: LGTM!

The test properly validates that GenerateConfig can be used as an input model and generates the expected TypedDict output with callable type annotations. The test follows the established patterns in this file and is correctly guarded with SKIP_PYDANTIC_V1.

.github/workflows/config-types.yaml (1)

1-29: LGTM!

The workflow is well-structured with appropriate path filters to trigger only when config-related files change. The use of astral-sh/setup-uv with caching and tox-uv follows modern Python CI patterns.

tests/main/test_main_general.py (1)

1972-1994: LGTM!

The test properly validates the new GenerateConfig-based API. The model_rebuild call with _types_namespace correctly resolves forward references for StrictTypes and UnionMode, which is necessary for Pydantic v2 models with deferred annotations.

tox.ini (1)

115-122: LGTM!

The new config-types environment is correctly configured with the three profile commands and appropriate dependency groups. The {posargs} usage allows the --check flag to be passed from CI.

Note: The pipeline failure ("Command 'tox' not found") appears to be a pre-commit hook configuration issue, not a problem with this tox configuration itself.

src/datamodel_code_generator/_types/parser_config_dict.py (1)

1-137: LGTM!

This auto-generated TypedDict correctly captures the parser configuration schema with appropriate NotRequired annotations for all optional fields. The imports from internal modules are necessary for proper type annotations.

src/datamodel_code_generator/__main__.py (1)

872-874: LGTM!

The integration of _try_rebuild_model before calling model_json_schema ensures that config models have their forward references properly resolved before schema generation. This is essential for models like GenerateConfig that reference types like StrictTypes and UnionMode.

tests/main/test_public_api_signature_baseline.py (2)

37-37: LGTM!

The GenerateConfig import is correctly placed under TYPE_CHECKING since it's only used for type annotations in the baseline signature.


49-49: LGTM!

The config parameter addition to the baseline signature correctly reflects the new generate() API, ensuring the signature baseline test will validate the new config-driven interface.

src/datamodel_code_generator/_types/__init__.py (1)

1-9: LGTM!

Clean public API surface for the auto-generated TypedDict configurations. The explicit __all__ list and descriptive module docstring follow best practices for public-facing package exports.

.pre-commit-config.yaml (1)

40-45: LGTM!

The new pre-commit hook follows the same pattern as the existing readme hook and correctly triggers TypedDict generation when config.py changes. The chained profile invocations ensure all three config TypedDicts stay in sync.

src/datamodel_code_generator/_types/parse_config_dict.py (1)

1-21: Auto-generated TypedDict looks correct.

This file is generated by datamodel-codegen and the fields align with the ParseConfig model in config.py. The types and imports are consistent with the enum definitions in the codebase.

pyproject.toml (1)

262-287: Well-structured configuration profiles.

The config-types-base profile provides sensible defaults (enum literals off, standard primitives, TypedDict output), and the three specific profiles correctly extend it with their respective input models and output paths. The type_overrides mapping ensures generated TypedDicts reference actual enum types rather than inlining literals.

src/datamodel_code_generator/_types/generate_config_dict.py (1)

1-155: Comprehensive auto-generated TypedDict.

This generated file correctly captures the full configuration surface of GenerateConfig. The imports properly reference enum types from their respective modules, and the NotRequired wrapper on all fields enables type-safe partial configuration. The generated output aligns with the source model.

src/datamodel_code_generator/__init__.py (2)

606-608: Keep the defensive # noqa: PLC0415 directive.

Based on project learnings, defensive # noqa: PLC0415 directives should be kept on lazy imports (imports inside functions/methods) even when Ruff reports them as unused via RUF100. This prepares for potential future Ruff configuration changes.


587-768: Config extraction logic is comprehensive and consistent.

The merge logic correctly prioritizes explicit parameters over config values using appropriate patterns for each type:

  • None checks for optional parameters
  • Equality checks against defaults for enum/non-boolean parameters
  • or for boolean flags (though see note about use_standard_collections)

The extra_template_data conversion from dict to defaultdict (lines 605-608) correctly bridges the type difference between GenerateConfig and the function's internal usage.

src/datamodel_code_generator/config.py (3)

437-441: Keep the defensive # noqa: PLC0415 directives.

Per project learnings, these directives should be retained on lazy imports to prepare for potential future Ruff configuration changes, even when currently reported as unused.


333-393: Well-designed factory method with proper field derivation.

The _from_generate_config factory elegantly:

  1. Uses field intersection (set(parser_fields) & set(generate_fields)) for automatic field mapping
  2. Applies business logic for computed fields (e.g., effective_dataclass_arguments, effective_enum_field_as_literal)
  3. Correctly handles the output_model_type-dependent defaults for enum behavior
  4. Filters the final dict to only valid ParserConfig fields

This approach is maintainable as new fields added to both configs will automatically propagate.


430-463: Correct forward reference resolution mechanism.

The rebuild function properly:

  1. Guards against redundant rebuilds with _CONFIG_MODELS_STATE
  2. Handles the optional UnionMode import gracefully (falls back to Any)
  3. Uses the appropriate Pydantic version-specific method (model_rebuild vs update_forward_refs)
  4. Includes all necessary types in the namespace for forward reference resolution

Comment thread src/datamodel_code_generator/__init__.py Outdated
Comment thread src/datamodel_code_generator/config.py Outdated
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/__main__.py (1)

766-794: Keep # noqa: PLC0415 directives for defensive purposes.

Based on learnings, the # noqa: PLC0415 directives on lines 772-778 should be kept even though Ruff reports them as unused (RUF100). These are defensive directives for lazy imports that protect against future Ruff configuration changes that might enable the import-outside-top-level rule.

Module name check may be too broad.

The check module in {"datamodel_code_generator.config", "config"} on line 771 includes the bare "config" string. This could match unrelated modules named config from other packages. Consider restricting to just the fully qualified module name unless there's a specific use case for the short form.

🔎 Suggested refinement
-    if module in {"datamodel_code_generator.config", "config"} and class_name in config_classes:
+    if module == "datamodel_code_generator.config" and class_name in config_classes:
📜 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 cf8553a and d0b6ced.

📒 Files selected for processing (5)
  • .github/workflows/lint.yaml
  • .pre-commit-config.yaml
  • pyproject.toml
  • src/datamodel_code_generator/__main__.py
  • src/datamodel_code_generator/config.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • .pre-commit-config.yaml
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-25T09:22:14.661Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2799
File: src/datamodel_code_generator/model/pydantic/__init__.py:43-43
Timestamp: 2025-12-25T09:22:14.661Z
Learning: In datamodel-code-generator project, defensive `# noqa: PLC0415` directives should be kept on lazy imports (imports inside functions/methods) even when Ruff reports them as unused via RUF100, to prepare for potential future Ruff configuration changes that might enable the import-outside-top-level rule.

Applied to files:

  • src/datamodel_code_generator/config.py
🧬 Code graph analysis (2)
src/datamodel_code_generator/__main__.py (1)
src/datamodel_code_generator/parser/jsonschema.py (1)
  • model_rebuild (224-226)
src/datamodel_code_generator/config.py (4)
src/datamodel_code_generator/parser/__init__.py (1)
  • DefaultPutDict (28-47)
src/datamodel_code_generator/util.py (3)
  • is_pydantic_v2 (52-57)
  • model_dump (254-258)
  • model_validate (261-265)
src/datamodel_code_generator/model/__init__.py (1)
  • DataModelSet (25-35)
src/datamodel_code_generator/parser/base.py (1)
  • parent (603-605)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/__main__.py

772-772: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


773-773: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


776-776: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


778-778: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)

src/datamodel_code_generator/config.py

439-439: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


440-440: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


443-443: Unused noqa directive (non-enabled: PLC0415)

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). (12)
  • GitHub Check: py312-pydantic1 on Ubuntu
  • GitHub Check: 3.14 on Windows
  • GitHub Check: py312-black23 on Ubuntu
  • GitHub Check: 3.11 on macOS
  • GitHub Check: py312-black24 on Ubuntu
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.10 on Windows
  • GitHub Check: 3.11 on Windows
  • GitHub Check: 3.13 on Ubuntu
  • GitHub Check: 3.13 on Windows
  • GitHub Check: benchmarks
  • GitHub Check: Analyze (python)
🔇 Additional comments (10)
src/datamodel_code_generator/__main__.py (2)

651-657: LGTM! Proper handling of types.UnionType for Python 3.10+ union syntax.

The implementation correctly detects UnionType (from X | Y syntax) and serializes it with the " | " separator format. The use of getattr(origin, "__name__", None) == "UnionType" is a safe way to check without importing types.UnionType which may not exist in all Python versions.


876-878: LGTM! Proper integration of model rebuild before schema generation.

The guard hasattr(obj, "model_rebuild") correctly ensures Pydantic v2 compatibility, and calling _try_rebuild_model before model_json_schema() ensures forward references are resolved.

pyproject.toml (2)

247-247: LGTM! Appropriate exclusion of generated type files from coverage.

Excluding src/datamodel_code_generator/_types/* from coverage is correct since these are auto-generated TypedDict files that don't need test coverage tracking.


262-287: Well-structured profile configuration for auto-generating config TypedDicts.

The profile hierarchy is clean:

  • config-types-base defines shared settings (formatters, type overrides, output model type)
  • Child profiles (generate-config-dict, parser-config-dict, parse-config-dict) extend the base with specific input-model and output paths

The comprehensive type_overrides mapping ensures enum types like InputFileType, DataModelType, etc., are preserved with their proper qualified paths in the generated TypedDicts.

src/datamodel_code_generator/config.py (6)

50-73: Well-designed conditional type alias handling for Pydantic v1/v2 compatibility.

The three-way branching (TYPE_CHECKING, is_pydantic_v2(), else) elegantly handles:

  • Static type checking with simple aliases
  • Pydantic v2 runtime with Annotated + WithJsonSchema for proper schema generation
  • Pydantic v1 fallback with plain types

This ensures proper JSON Schema output while maintaining type safety.


76-88: LGTM! Proper Pydantic v1/v2 configuration setup.

The conditional handling of model_config (v2) vs nested Config class (v1) is correct. The docstring at line 84 addresses the previous D106 pipeline failure.


335-393: Well-implemented factory method for ParserConfig creation.

The _from_generate_config classmethod properly:

  1. Computes effective values (effective_dataclass_arguments, effective_enum_field_as_literal, effective_set_default_enum_member)
  2. Uses field intersection to safely copy matching fields between configs
  3. Adds parser-specific fields (data_model_type, base_path, remote_text_cache, etc.)
  4. Uses version-compatible model_dump and model_validate utilities

248-248: Verify intentional default difference for use_standard_collections.

ParserConfig.use_standard_collections defaults to False while GenerateConfig.use_standard_collections defaults to True. When using _from_generate_config, the GenerateConfig value is copied, so this only affects direct ParserConfig instantiation.

Is this default difference intentional for the direct instantiation use case?


396-429: LGTM! Clean implementation of ParseConfig.

The class is focused on parse-time options with a straightforward _from_generate_config factory method using field intersection.


435-465: LGTM! Proper forward reference resolution with version compatibility.

The function correctly:

  1. Uses state tracking to avoid redundant rebuilds
  2. Builds a types namespace with all required types
  3. Handles UnionMode import failure gracefully
  4. Uses version-appropriate methods (model_rebuild vs update_forward_refs)

Keep # noqa: PLC0415 directives for defensive purposes.

Per learnings from this repository, the # noqa: PLC0415 directives on lines 439, 440, and 443 should be retained even though Ruff reports them as unused. These protect against future Ruff configuration changes that might enable the import-outside-top-level rule.

@koxudaxi koxudaxi force-pushed the refactor/config-class branch from d54165a to c12a383 Compare December 28, 2025 20:50
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/test_format.py (1)

165-179: Tests match implementation but stdin usage is missing required --stdin-filename argument

The test expectations correctly reflect the current implementation, but there's a critical issue: Ruff documentation explicitly requires --stdin-filename when reading from stdin. The current calls to ruff check --fix - and ruff format - are incomplete per Ruff's documented CLI behavior.

For stdin operations (lines 165-179, and the apply_ruff_lint, apply_ruff_formatter, apply_ruff_check_and_format methods), add the required --stdin-filename argument:

("ruff", "check", "--fix", "--stdin-filename", "input.py", "-")
("ruff", "format", "--stdin-filename", "input.py", "-")

Directory-based formatting tests (lines 216-235, 258-283, 302-330) are correct and need no changes.

🧹 Nitpick comments (3)
.pre-commit-config.yaml (1)

21-24: Ruff excludes and config-types hook are wired sensibly

Excluding both tests/data and src/datamodel_code_generator/_types/ from Ruff makes sense for test fixtures and generated TypedDicts, and the new config-types local hook is consistent with the existing readme hook pattern (fixed env, no filenames, tight files filter on config.py). This should keep the generated config types in sync without surprising other commits.

Also applies to: 40-45

src/datamodel_code_generator/__init__.py (2)

63-67: GenerateConfig integration and precedence logic look consistent

Importing GenerateConfig only under TYPE_CHECKING keeps runtime imports clean, and the new config parameter is threaded into generate() in a way that’s broadly consistent:

  • For most value/optional parameters (paths, enums, mappings), you use the “argument if provided, otherwise config” pattern (x = config.x if x is default/None else x), which keeps existing call sites stable while letting GenerateConfig act as a central default.
  • For booleans defaulting to False, flag = flag or config.flag sensibly treats config as the default and can’t distinguish explicit False from default False, which is expected with simple booleans.
  • For booleans defaulting to True (use_standard_collections, use_specialized_enum, use_union_operator), the config.value if param else False/param pattern preserves explicit False while letting config drive the default when callers leave the parameter at its default True. This matches the agreed pattern from earlier fixes in this module.
  • extra_template_data is correctly upgraded from a plain dict on the config into a defaultdict(dict, ...) only when no explicit extra_template_data is passed, and your tests exercise the “config vs direct override” behavior.

Overall, the config-driven path looks coherent and backwards compatible with existing generate() usage.

Also applies to: 451-575, 587-770


516-516: Wire graphql_scopes to GraphQLParser or remove the parameter from generate()

The graphql_scopes parameter is accepted and merged from GenerateConfig in generate() (line 678), but is not passed to GraphQLParser via kwargs when input_file_type == InputFileType.GraphQL (lines 845–857). Additionally, GraphQLParser.__init__ does not accept a graphql_scopes parameter. Either add graphql_scopes support to GraphQLParser and wire it through alongside data_model_scalar_type and data_model_union_type (lines 930–938), or remove the parameter from generate() to avoid confusion with unused configuration.

📜 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 15e4556 and 8d05fb0.

📒 Files selected for processing (17)
  • .github/workflows/config-types.yaml
  • .github/workflows/lint.yaml
  • .pre-commit-config.yaml
  • pyproject.toml
  • src/datamodel_code_generator/__init__.py
  • src/datamodel_code_generator/__main__.py
  • src/datamodel_code_generator/_types/__init__.py
  • src/datamodel_code_generator/_types/generate_config_dict.py
  • src/datamodel_code_generator/_types/parse_config_dict.py
  • src/datamodel_code_generator/_types/parser_config_dict.py
  • src/datamodel_code_generator/config.py
  • src/datamodel_code_generator/format.py
  • tests/main/test_main_general.py
  • tests/main/test_public_api_signature_baseline.py
  • tests/test_format.py
  • tests/test_input_model.py
  • tox.ini
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/datamodel_code_generator/_types/parser_config_dict.py
  • src/datamodel_code_generator/_types/parse_config_dict.py
  • .github/workflows/config-types.yaml
  • tox.ini
  • src/datamodel_code_generator/_types/init.py
  • tests/main/test_public_api_signature_baseline.py
  • .github/workflows/lint.yaml
  • pyproject.toml
  • src/datamodel_code_generator/_types/generate_config_dict.py
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-12-18T13:43:16.235Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2681
File: tests/cli_doc/test_cli_doc_coverage.py:82-82
Timestamp: 2025-12-18T13:43:16.235Z
Learning: In datamodel-code-generator project, Ruff preview mode is enabled via `lint.preview = true` in pyproject.toml. This enables preview rules like PLR6301 (no-self-use), so `noqa: PLR6301` directives are necessary and should not be removed even if RUF100 suggests they are unused.

Applied to files:

  • src/datamodel_code_generator/format.py
  • .pre-commit-config.yaml
📚 Learning: 2025-12-25T09:22:14.661Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2799
File: src/datamodel_code_generator/model/pydantic/__init__.py:43-43
Timestamp: 2025-12-25T09:22:14.661Z
Learning: In datamodel-code-generator project, defensive `# noqa: PLC0415` directives should be kept on lazy imports (imports inside functions/methods) even when Ruff reports them as unused via RUF100, to prepare for potential future Ruff configuration changes that might enable the import-outside-top-level rule.

Applied to files:

  • src/datamodel_code_generator/format.py
  • src/datamodel_code_generator/config.py
🧬 Code graph analysis (4)
src/datamodel_code_generator/__main__.py (2)
src/datamodel_code_generator/enums.py (1)
  • UnionMode (192-196)
src/datamodel_code_generator/parser/jsonschema.py (1)
  • model_rebuild (224-226)
tests/main/test_main_general.py (5)
src/datamodel_code_generator/config.py (1)
  • GenerateConfig (73-205)
src/datamodel_code_generator/enums.py (3)
  • UnionMode (192-196)
  • StrictTypes (199-206)
  • DataModelType (48-56)
src/datamodel_code_generator/model/base.py (1)
  • model_rebuild (200-207)
src/datamodel_code_generator/types.py (1)
  • model_rebuild (310-317)
src/datamodel_code_generator/__init__.py (1)
  • generate (451-1204)
tests/test_format.py (1)
tests/main/conftest.py (1)
  • output_dir (104-106)
src/datamodel_code_generator/__init__.py (2)
src/datamodel_code_generator/config.py (1)
  • GenerateConfig (73-205)
src/datamodel_code_generator/enums.py (5)
  • GraphQLScope (155-158)
  • InputFileType (35-45)
  • DataModelType (48-56)
  • ReuseScope (59-67)
  • AllOfMergeMode (142-152)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/__main__.py

785-785: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


786-786: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


789-789: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


791-791: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)

src/datamodel_code_generator/config.py

6-6: Unused noqa directive (non-enabled: TC003)

Remove unused noqa directive

(RUF100)

src/datamodel_code_generator/__init__.py

606-606: Unused noqa directive (non-enabled: PLC0415)

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). (11)
  • GitHub Check: 3.10 on Windows
  • GitHub Check: 3.12 on Ubuntu
  • GitHub Check: py312-pydantic1 on Ubuntu
  • GitHub Check: 3.14 on macOS
  • GitHub Check: 3.13 on macOS
  • GitHub Check: 3.13 on Windows
  • GitHub Check: 3.14 on Windows
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.11 on Windows
  • GitHub Check: benchmarks
  • GitHub Check: Analyze (python)
🔇 Additional comments (8)
src/datamodel_code_generator/__main__.py (1)

779-808: Config model model_rebuild helper looks correct and well-scoped

The _try_rebuild_model() helper and its use in _load_model_schema() cleanly handle the Pydantic v2 rebuild requirements for GenerateConfig / ParserConfig / ParseConfig without affecting arbitrary BaseModel subclasses. The curated _types_namespace (Path, DataModel*, DataTypeManager, StrictTypes, UnionMode/Any) matches the config models’ annotations, and the fallback to Any on UnionMode import failure keeps v1-compatible behavior. I don’t see issues with this approach or its invocation guard on hasattr(obj, "model_rebuild").

Also applies to: 889-891

tests/test_input_model.py (1)

609-617: New --input-model test for GenerateConfig covers the config-schema path well

This test nicely validates the --input-model datamodel_code_generator.config:GenerateConfig flow under Pydantic v2, including TypedDict generation and preservation of callable field types. The SKIP_PYDANTIC_V1 marker is appropriate given the hard dependency on model_json_schema.

tests/main/test_main_general.py (1)

9-10: Config-object tests correctly exercise the new generate(config=...) flow

The added pydantic / GenerateConfig imports and the two @pytest.mark.skipif(pydantic.VERSION < "2.0.0") tests give good coverage of the new config-driven path:

  • test_generate_with_config_object validates that core options (output_model_type, schema description, snake_case_field, field_constraints, extra_template_data) flow from a GenerateConfig instance into generate() and affect the output as expected.
  • test_generate_with_config_object_extra_template_data_override checks that an explicit extra_template_data argument wins over the config’s extra_template_data, matching the merge logic in generate().
  • The explicit GenerateConfig.model_rebuild(_types_namespace=...) before instantiation mirrors the runtime helper in __main__ and ensures forward refs are resolved under Pydantic v2.

Overall this is a solid, targeted verification of the public config parameter on generate().

Also applies to: 26-27, 1972-2019

src/datamodel_code_generator/format.py (1)

338-347: Ruff integration uses safe --fix operations only

The Ruff calls in apply_ruff_lint, apply_ruff_check_and_format, and format_directory all use ruff check --fix without --unsafe-fixes, which applies only safe transformations. This is the correct approach for a library's code formatter, avoiding potentially destructive rewrites while still auto-fixing straightforward issues. The subprocess wiring (stdin/stdout, cwd, return-code handling) remains consistent across all invocation patterns.

src/datamodel_code_generator/config.py (4)

41-71: Well-designed cross-version type compatibility.

The conditional type aliases elegantly handle Pydantic v1/v2 differences: simple aliases for type-checking and v1, while v2 uses Annotated with WithJsonSchema to make callable fields serializable. The x-python-type hints in the JSON schema provide clear documentation of the expected types.


73-206: Comprehensive configuration model with clean Pydantic v1/v2 compatibility.

The GenerateConfig model properly handles version differences with conditional model_config (v2) vs. nested Config class (v1). The nested Config class includes a docstring, addressing the previous pipeline failure. The extensive field set comprehensively covers code generation options.


208-331: Parser configuration follows consistent patterns.

The ParserConfig model maintains the same clean v1/v2 compatibility approach as GenerateConfig. The type-parameterized fields (e.g., data_model_type: type[DataModel]) leverage arbitrary_types_allowed=True to handle class types, and the nested Config class includes proper documentation.


333-352: Streamlined parse configuration completes the config model trio.

The ParseConfig model maintains consistency with the other config models while focusing on a smaller set of parse-time options. The use of format_ (with trailing underscore) correctly avoids conflict with the format keyword.

@koxudaxi koxudaxi force-pushed the refactor/config-class branch from 7d86135 to ef68905 Compare December 29, 2025 10:32
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/__init__.py (1)

588-770: Config propagation logic is correct.

The extensive config merging correctly handles different parameter types with appropriate patterns:

  • Boolean flags use or for False defaults
  • Optional parameters check is None
  • Parameters with non-None defaults check equality with default value
  • Special handling for use_standard_collections, use_specialized_enum, and use_union_operator preserves explicit False arguments while respecting config

The 200+ lines of repetitive merging code could benefit from abstraction (e.g., a helper function or dataclass-based merging), which would improve maintainability. However, the current implementation is functionally correct.

💡 Optional refactor idea

Consider extracting merge logic into a helper function that takes parameter metadata (name, default value, merge strategy) to reduce repetition. For example:

def _merge_config_param(
    param_name: str,
    param_value: Any,
    config_value: Any,
    default_value: Any,
    merge_strategy: Literal["or", "conditional", "special_bool"] = "conditional"
) -> Any:
    # Implement merge patterns based on strategy
    ...

This would consolidate the patterns and make future parameter additions easier.

📜 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 ead4e16 and ef68905.

📒 Files selected for processing (3)
  • src/datamodel_code_generator/__init__.py
  • src/datamodel_code_generator/__main__.py
  • tests/test_input_model.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/test_input_model.py
🧰 Additional context used
🧬 Code graph analysis (2)
src/datamodel_code_generator/__main__.py (4)
src/datamodel_code_generator/model/base.py (3)
  • class_name (848-850)
  • class_name (853-857)
  • model_rebuild (200-207)
src/datamodel_code_generator/model/pydantic_v2/types.py (1)
  • DataTypeManager (70-167)
src/datamodel_code_generator/enums.py (2)
  • StrictTypes (213-220)
  • UnionMode (192-196)
src/datamodel_code_generator/parser/jsonschema.py (1)
  • model_rebuild (224-226)
src/datamodel_code_generator/__init__.py (2)
src/datamodel_code_generator/config.py (1)
  • GenerateConfig (73-205)
src/datamodel_code_generator/enums.py (2)
  • InputFileType (35-45)
  • DataModelType (48-56)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/__main__.py

1079-1079: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


1080-1080: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


1083-1083: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)


1085-1085: Unused noqa directive (non-enabled: PLC0415)

Remove unused noqa directive

(RUF100)

src/datamodel_code_generator/__init__.py

607-607: Unused noqa directive (non-enabled: PLC0415)

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). (4)
  • GitHub Check: 3.13 on Windows
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.11 on Windows
  • GitHub Check: benchmarks
🔇 Additional comments (5)
src/datamodel_code_generator/__main__.py (2)

1185-1186: LGTM!

The integration of _try_rebuild_model is appropriate here. Rebuilding the model before schema generation ensures forward references are properly resolved for config models while remaining backward-compatible with the hasattr guard.


1073-1102: Clean up unused noqa directives.

The function logic looks good and correctly handles special rebuilding for config models. However, static analysis indicates unused noqa directives on lines 1079, 1080, 1083, and 1085.

🔎 Proposed fix
     if module in {"datamodel_code_generator.config", "config"} and class_name in config_classes:
-        from datamodel_code_generator.model.base import DataModel, DataModelFieldBase  # noqa: PLC0415
-        from datamodel_code_generator.types import DataTypeManager, StrictTypes  # noqa: PLC0415
+        from datamodel_code_generator.model.base import DataModel, DataModelFieldBase
+        from datamodel_code_generator.types import DataTypeManager, StrictTypes

         try:
-            from datamodel_code_generator.model.pydantic_v2 import UnionMode  # noqa: PLC0415
+            from datamodel_code_generator.model.pydantic_v2 import UnionMode
         except ImportError:  # pragma: no cover
-            from typing import Any  # noqa: PLC0415
+            from typing import Any

             runtime_union_mode = Any
⛔ Skipped due to learnings
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2799
File: src/datamodel_code_generator/model/pydantic/__init__.py:43-43
Timestamp: 2025-12-25T09:22:14.661Z
Learning: In datamodel-code-generator project, defensive `# noqa: PLC0415` directives should be kept on lazy imports (imports inside functions/methods) even when Ruff reports them as unused via RUF100, to prepare for potential future Ruff configuration changes that might enable the import-outside-top-level rule.
src/datamodel_code_generator/__init__.py (3)

64-64: LGTM!

Adding GenerateConfig to TYPE_CHECKING imports is the correct pattern for type hints, avoiding runtime circular import issues while providing proper type information.


517-517: LGTM!

Removing the noqa: TC001 comment is appropriate now that graphql_scopes is properly integrated with the config propagation logic and is actually used (line 679).


607-607: Remove unused noqa directive.

Static analysis indicates the noqa: PLC0415 directive on this line is not needed.

🔎 Proposed fix
-            from collections import defaultdict as _defaultdict  # noqa: PLC0415
+            from collections import defaultdict as _defaultdict
⛔ Skipped due to learnings
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2799
File: src/datamodel_code_generator/model/pydantic/__init__.py:43-43
Timestamp: 2025-12-25T09:22:14.661Z
Learning: In datamodel-code-generator project, defensive `# noqa: PLC0415` directives should be kept on lazy imports (imports inside functions/methods) even when Ruff reports them as unused via RUF100, to prepare for potential future Ruff configuration changes that might enable the import-outside-top-level rule.
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2681
File: tests/cli_doc/test_cli_doc_coverage.py:82-82
Timestamp: 2025-12-18T13:43:16.235Z
Learning: In datamodel-code-generator project, Ruff preview mode is enabled via `lint.preview = true` in pyproject.toml. This enables preview rules like PLR6301 (no-self-use), so `noqa: PLR6301` directives are necessary and should not be removed even if RUF100 suggests they are unused.

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

📜 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 ef68905 and 445bc44.

📒 Files selected for processing (3)
  • pyproject.toml
  • src/datamodel_code_generator/_types/generate_config_dict.py
  • src/datamodel_code_generator/_types/parser_config_dict.py
🧰 Additional context used
🧬 Code graph analysis (1)
src/datamodel_code_generator/_types/parser_config_dict.py (4)
src/datamodel_code_generator/enums.py (8)
  • AllOfMergeMode (142-152)
  • CollapseRootModelsNameStrategy (131-139)
  • FieldTypeCollisionStrategy (105-113)
  • NamingStrategy (116-128)
  • ReadOnlyWriteOnlyModelType (161-169)
  • ReuseScope (59-67)
  • StrictTypes (213-220)
  • TargetPydanticVersion (181-189)
src/datamodel_code_generator/format.py (1)
  • PythonVersion (68-140)
src/datamodel_code_generator/parser/__init__.py (2)
  • LiteralType (20-25)
  • DefaultPutDict (28-47)
src/datamodel_code_generator/_types/generate_config_dict.py (1)
  • DataclassArguments (36-46)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/_types/parser_config_dict.py

42-42: Undefined name datamodel_code_generator

(F821)


43-43: Undefined name datamodel_code_generator

(F821)


44-44: Undefined name datamodel_code_generator

(F821)


45-45: Undefined name datamodel_code_generator

(F821)


87-87: Undefined name DefaultPutDict

(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). (15)
  • GitHub Check: build-deploy
  • GitHub Check: py312-isort7 on Ubuntu
  • GitHub Check: py312-black23 on Ubuntu
  • GitHub Check: py312-pydantic1 on Ubuntu
  • GitHub Check: py312-isort6 on Ubuntu
  • GitHub Check: py312-black22 on Ubuntu
  • GitHub Check: 3.11 on Windows
  • GitHub Check: 3.13 on Ubuntu
  • GitHub Check: py312-black24 on Ubuntu
  • GitHub Check: 3.10 on Windows
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.13 on Windows
  • GitHub Check: benchmarks
  • GitHub Check: 3.14 on Windows
  • GitHub Check: Analyze (python)
🔇 Additional comments (6)
src/datamodel_code_generator/_types/parser_config_dict.py (1)

28-38: LGTM!

The DataclassArguments TypedDict is properly defined with all standard dataclass parameters correctly typed as optional booleans.

pyproject.toml (2)

247-247: LGTM! Coverage exclusion for generated types is appropriate.

Excluding the _types directory from coverage is correct since it contains auto-generated TypedDict definitions that don't require test coverage.


262-287: Input models are properly defined. All three Pydantic models referenced in the profiles—GenerateConfig (line 73), ParserConfig (line 208), and ParseConfig (line 333)—exist in src/datamodel_code_generator/config.py and are correctly structured as BaseModel subclasses with Pydantic v2/v1 compatibility.

src/datamodel_code_generator/_types/generate_config_dict.py (3)

1-33: LGTM! Import structure follows best practices.

The use of TYPE_CHECKING guards for type-only imports is excellent for minimizing runtime overhead. The imports are well-organized and NotRequired from typing_extensions ensures compatibility across Python versions.


36-46: LGTM! DataclassArguments TypedDict accurately mirrors dataclass parameters.

The TypedDict correctly represents all standard dataclasses.dataclass decorator parameters with appropriate NotRequired[bool] types.


49-169: LGTM! GenerateConfigDict provides comprehensive type-safe configuration.

The TypedDict correctly exposes a broad configuration surface with 120 fields covering all aspects of code generation. The consistent use of NotRequired allows partial configuration, which is appropriate for this use case.

Since this is auto-generated from the Pydantic GenerateConfig model, the types should stay in sync with the source model.

Comment thread src/datamodel_code_generator/_types/parser_config_dict.py Outdated
Comment thread src/datamodel_code_generator/_types/parser_config_dict.py Outdated
Add tests to ensure Config classes and generated TypedDicts remain in sync:
- Type matching tests for ParserConfigDict and ParseConfigDict
- Default value matching test for GenerateConfig vs generate() signature
- Runtime compatibility test verifying generate() produces identical output
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

📜 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 6d513e8 and 1aff1b7.

📒 Files selected for processing (1)
  • tests/main/test_public_api_signature_baseline.py
🧰 Additional context used
🪛 GitHub Actions: Lint
tests/main/test_public_api_signature_baseline.py

[error] 449-449: Ruff: N806 Variable UnionMode in function should be lowercase

⏰ 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). (11)
  • GitHub Check: 3.11 on Ubuntu
  • GitHub Check: 3.11 on Windows
  • GitHub Check: py312-black24 on Ubuntu
  • GitHub Check: py312-isort7 on Ubuntu
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.10 on Windows
  • GitHub Check: py312-pydantic1 on Ubuntu
  • GitHub Check: 3.13 on Windows
  • GitHub Check: 3.14 on Windows
  • GitHub Check: Analyze (python)
  • GitHub Check: benchmarks
🔇 Additional comments (7)
tests/main/test_public_api_signature_baseline.py (7)

8-9: LGTM!

The pytest import and GenerateConfig type import are appropriate additions for the expanded test suite.

Also applies to: 39-39


51-51: LGTM!

The addition of the optional config parameter to the baseline signature correctly reflects the new config-driven generation pathway.


331-355: LGTM!

The type normalization helper correctly handles the various type representation differences (ForwardRef, NotRequired, module prefixes, etc.) needed for cross-dictionary comparison.


321-328: LGTM!

The field alignment tests correctly validate that Config classes and their corresponding ConfigDict TypedDicts have matching field names using set comparison.

Also applies to: 371-378, 381-388


358-368: LGTM!

The type alignment tests correctly validate that field types match between Config classes and ConfigDict TypedDicts by normalizing and comparing type annotations.

Also applies to: 391-401, 404-414


417-438: LGTM!

The default value alignment test correctly validates that GenerateConfig defaults match the generate() signature, properly handling both required parameters and those with explicit defaults.


441-448: Well-structured functional equivalence test.

The test correctly validates that config-driven and kwargs-driven generation produce identical output, with appropriate version checks and conditional model rebuilding for Pydantic v2.

Also applies to: 459-483

Comment thread tests/main/test_public_api_signature_baseline.py
- Update GenerateConfig and ParserConfig to use defaultdict with
  Annotated/WithJsonSchema for Pydantic compatibility
- Regenerate TypedDicts with proper defaultdict type and import
- Update test normalization to handle Annotated types and collections prefix
@koxudaxi koxudaxi force-pushed the refactor/config-class branch from 0f26edb to 78e492e Compare December 30, 2025 07:44
koxudaxi and others added 2 commits December 30, 2025 07:46
Replace complex _normalize_type_str function and detailed type comparison
with simpler field count checks. The integration test
test_generate_with_config_produces_same_result_as_kwargs validates that
Config classes work correctly at runtime, making detailed type string
comparison unnecessary.

Also fix lint errors:
- N813: Restructure UnionMode import to avoid CamelCase-to-lowercase alias
- I001: Fix import sorting order

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment thread tests/main/test_public_api_signature_baseline.py Dismissed
Implement _normalize_type function using typing APIs (get_origin, get_args)
to normalize types for comparison between Config classes and generated
TypedDicts. Handles:
- Union types with sorted components
- Annotated and NotRequired wrappers
- ForwardRef string parsing
- Callable with list args
- Module prefix removal (collections.abc, typing, etc.)

Tests now verify:
1. Field names match
2. Field types match (normalized)
3. Default values match
4. Integration test validates runtime behavior

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@koxudaxi koxudaxi enabled auto-merge (squash) December 30, 2025 08:23
@koxudaxi koxudaxi merged commit cdf6132 into main Dec 30, 2025
35 of 36 checks passed
@koxudaxi koxudaxi deleted the refactor/config-class branch December 30, 2025 08:26
@github-actions
Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: This PR is purely additive - it adds a new optional config parameter to the generate() function and introduces new GenerateConfig, ParserConfig, and ParseConfig classes along with corresponding TypedDict schemas. All existing function signatures remain unchanged, no default values were modified, and no CLI options were altered. The new config parameter defaults to None, ensuring full backward compatibility. Existing code calling generate() will continue to work without any modifications.


This analysis was performed by Claude Code Action

koxudaxi added a commit that referenced this pull request Dec 30, 2025
…onfig (#2844)

* Add GenerateConfig class and auto-generate TypedDicts for type-safe config

* Add --unsafe-fixes to ruff-check formatter

* Skip config-types hook in lint workflow

* Fix UnionType serialization and skip tox-dependent hooks in lint CI

* Revert --unsafe-fixes and exclude _types from pre-commit ruff

* Regenerate config types after merging main

* Remove UnionType handling (should be separate PR)

* Pin Python 3.14 for config-types CI

* Remove unused _from_generate_config methods

* Fix use_standard_collections merge logic

* Fix coverage omit pattern for _types directory

* Regenerate TypedDicts after merging set/frozenset fix

* Add test for extra_template_data override and coverage pragmas

* Restore --unsafe-fixes flag in ruff commands

* Restore _try_rebuild_model and test_input_model_config_class after merge

* Use --input-model-ref-strategy to simplify config type generation

* Regenerate config types with improved reuse-foreign strategy

* Remove WithJsonSchema annotations - automatic handling works

* Add tests to ensure Config and ConfigDict fields/types match

* Add comprehensive Config/TypedDict compatibility tests

Add tests to ensure Config classes and generated TypedDicts remain in sync:
- Type matching tests for ParserConfigDict and ParseConfigDict
- Default value matching test for GenerateConfig vs generate() signature
- Runtime compatibility test verifying generate() produces identical output

* Use defaultdict for extra_template_data to match generate() signature

- Update GenerateConfig and ParserConfig to use defaultdict with
  Annotated/WithJsonSchema for Pydantic compatibility
- Regenerate TypedDicts with proper defaultdict type and import
- Update test normalization to handle Annotated types and collections prefix

* Fix N806 lint: rename UnionMode variable to lowercase

* Simplify type comparison tests for Config/TypedDict

Replace complex _normalize_type_str function and detailed type comparison
with simpler field count checks. The integration test
test_generate_with_config_produces_same_result_as_kwargs validates that
Config classes work correctly at runtime, making detailed type string
comparison unnecessary.

Also fix lint errors:
- N813: Restructure UnionMode import to avoid CamelCase-to-lowercase alias
- I001: Fix import sorting order

* Add type comparison tests for Config/TypedDict equivalence

Implement _normalize_type function using typing APIs (get_origin, get_args)
to normalize types for comparison between Config classes and generated
TypedDicts. Handles:
- Union types with sorted components
- Annotated and NotRequired wrappers
- ForwardRef string parsing
- Callable with list args
- Module prefix removal (collections.abc, typing, etc.)

Tests now verify:
1. Field names match
2. Field types match (normalized)
3. Default values match
4. Integration test validates runtime behavior

* Fix formatting

* Skip Config/TypedDict tests on Pydantic v1

* Add default value tests for ParserConfig and ParseConfig

* Use @PYDANTIC_V2_SKIP decorator for pydantic v2 tests

* Fix type normalization for types.UnionType (Python 3.10+)
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.

2 participants