Simplify Parser.__init__ signature using Unpack[ParserConfigDict]#2877
Simplify Parser.__init__ signature using Unpack[ParserConfigDict]#2877
Conversation
|
Warning Rate limit exceeded@koxudaxi has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 15 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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. 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughRefactors parser constructors to a config-driven API: parser classes now accept Changes
Sequence Diagram(s)(omitted — changes are API refactors without a multi-component sequential flow that benefits from a diagram) Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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. Comment |
CodSpeed Performance ReportMerging #2877 will not alter performanceComparing
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2877 +/- ##
========================================
Coverage 99.39% 99.39%
========================================
Files 91 91
Lines 15618 15820 +202
Branches 1836 1845 +9
========================================
+ Hits 15523 15724 +201
Misses 50 50
- Partials 45 46 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/datamodel_code_generator/parser/base.py (2)
685-685: Remove unusednoqadirective.The static analysis tool indicates that the
noqadirectives forPLR0012,PLR0914,PLR0915are unnecessary since these rules are not enabled. The function body has been significantly refactored.🔎 Proposed fix
- def __init__( # noqa: PLR0912, PLR0914, PLR0915 + def __init__(
702-710: Remove unusednoqadirectives for local imports.Static analysis indicates these
PLC0415suppressions are not needed since the rule is not enabled.🔎 Proposed fix
- from datamodel_code_generator.config import ParserConfig # noqa: PLC0415 + from datamodel_code_generator.config import ParserConfig if config is not None and options: msg = "Cannot specify both 'config' and keyword arguments. Use one or the other." raise ValueError(msg) if config is None: - from datamodel_code_generator import types as types_module # noqa: PLC0415 - from datamodel_code_generator.model import base as model_base # noqa: PLC0415 + from datamodel_code_generator import types as types_module + from datamodel_code_generator.model import base as model_basesrc/datamodel_code_generator/parser/graphql.py (1)
93-114: Consider extracting config values from kwargs before super() call.Lines 105-108 extract
use_standard_collectionsanduse_union_operatorfrom config or kwargs, but these values remain in kwargs when passed tosuper().__init__()(line 109). This means:
- Parent class receives these values in kwargs
- GraphQLParser then sets them as instance variables (lines 113-114)
If the parent Parser class also sets these from kwargs, they'll be set twice. Consider either:
- Removing them from kwargs before the super() call, or
- Confirming the parent class handles these and removing the redundant instance variable assignments
#!/bin/bash # Check if parent Parser class sets these instance variables from config/kwargs ast-grep --pattern $'class Parser($_): $$$ def __init__($$$): $$$ self.use_standard_collections = $$$ $$$'
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/datamodel_code_generator/parser/base.pysrc/datamodel_code_generator/parser/graphql.pysrc/datamodel_code_generator/parser/jsonschema.pysrc/datamodel_code_generator/parser/openapi.pytests/main/test_public_api_signature_baseline.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-25T09:23:08.506Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2799
File: src/datamodel_code_generator/util.py:49-66
Timestamp: 2025-12-25T09:23:08.506Z
Learning: In datamodel-code-generator, the is_pydantic_v2() and is_pydantic_v2_11() functions in src/datamodel_code_generator/util.py intentionally use global variable caching (_is_v2, _is_v2_11) on top of lru_cache for performance optimization. This dual-layer caching eliminates function call overhead and cache lookup overhead for frequently-called version checks. The PLW0603 linter warnings should be suppressed with # noqa: PLW0603 as this is a deliberate design choice.
Applied to files:
tests/main/test_public_api_signature_baseline.pysrc/datamodel_code_generator/parser/openapi.py
🧬 Code graph analysis (3)
src/datamodel_code_generator/parser/base.py (3)
src/datamodel_code_generator/util.py (1)
is_pydantic_v2(52-57)src/datamodel_code_generator/_types/parser_config_dict.py (1)
ParserConfigDict(33-144)src/datamodel_code_generator/config.py (1)
ParserConfig(196-319)
src/datamodel_code_generator/parser/jsonschema.py (2)
src/datamodel_code_generator/_types/parser_config_dict.py (1)
ParserConfigDict(33-144)src/datamodel_code_generator/config.py (1)
ParserConfig(196-319)
src/datamodel_code_generator/parser/graphql.py (3)
src/datamodel_code_generator/format.py (1)
DatetimeClassType(50-57)src/datamodel_code_generator/_types/parser_config_dict.py (1)
ParserConfigDict(33-144)src/datamodel_code_generator/config.py (1)
ParserConfig(196-319)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/parser/base.py
685-685: Unused noqa directive (non-enabled: PLR0912, PLR0914, PLR0915)
Remove unused noqa directive
(RUF100)
702-702: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
709-709: Unused noqa directive (non-enabled: PLC0415)
Remove unused noqa directive
(RUF100)
710-710: 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). (15)
- GitHub Check: py312-black23 on Ubuntu
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.11 on Ubuntu
- GitHub Check: 3.10 on macOS
- GitHub Check: py312-isort7 on Ubuntu
- GitHub Check: 3.10 on Ubuntu
- GitHub Check: 3.10 on Windows
- GitHub Check: py312-isort5 on Ubuntu
- GitHub Check: 3.12 on macOS
- GitHub Check: 3.13 on Windows
- GitHub Check: 3.14 on Windows
- GitHub Check: 3.14 on macOS
- GitHub Check: 3.12 on Windows
- GitHub Check: Analyze (python)
- GitHub Check: benchmarks
🔇 Additional comments (10)
src/datamodel_code_generator/parser/base.py (2)
704-731: Config construction logic looks correct.The branching between Pydantic v1 and v2 is properly handled:
- V2 uses
model_rebuildto resolve forward references andmodel_validatefor validation- V1 uses
update_forward_refsandconstructwith merged defaultsThe error handling for conflicting inputs (config + options) is clear.
73-80: Import organization looks good.The TYPE_CHECKING imports properly guard
ParserConfigDictandParserConfigto avoid runtime circular imports while still providing type hints.tests/main/test_public_api_signature_baseline.py (3)
503-559: Test implementation looks thorough and well-structured.The test properly validates:
- Key-set equality between baseline kwargs and
ParserConfigDict- Type matching using the
_types_matchutility- Default value matching for Pydantic v2 (with appropriate skip conditions for callables and missing fields)
The special handling for callable defaults at lines 555-556 is appropriate since
title_to_class_namein the baseline has a function default whileParserConfigusesNone.
549-559: Default comparison logic handles edge cases appropriately.The skip conditions are well-considered:
- Skipping
inspect.Parameter.emptyprevents false failures for required params- Skipping fields not in
model_fieldshandles cases where baseline has extra params- Skipping callable defaults with
Noneconfig handles thecustom_class_name_generator=title_to_class_namecaseThis ensures the test focuses on meaningful compatibility checks.
35-35: YamlValue import location is correct.The
YamlValuetype alias is properly defined indatamodel_code_generator.parser.baseand is correctly imported and used in the test file at line 187 for the_BaselineParser.__init__signature.src/datamodel_code_generator/parser/openapi.py (2)
169-188: Clean config-driven refactor for OpenAPIParser.The
__init__signature simplification looks good:
- Accepts
configobject or**kwargsviaUnpack[ParserConfigDict]- Properly sets
wrap_string_literal=Falsedefault when not provided (line 180-181)- Delegates to parent class correctly
The OpenAPI-specific parameters (
openapi_scopes,include_path_parameters,use_status_code_in_response_name) are preserved as explicit keyword arguments, which is appropriate since they're not part of the baseParserConfig.
44-46: TYPE_CHECKING imports properly organized.The new imports are correctly guarded and provide proper type hints for:
ParserConfigDict- for the**kwargstypeParserConfig- for theconfigparameter typeDataModelFieldBase- for return type annotation at line 270src/datamodel_code_generator/parser/jsonschema.py (2)
25-25: LGTM: Import additions support config-driven initialization.The
Unpackimport and TYPE_CHECKING imports are necessary for the new config-based initialization pattern, enabling proper type hints without runtime overhead.Also applies to: 86-89
630-640: Document or clarify the different default datetime classes between parsers.JsonSchemaParser defaults
target_datetime_classtoDatetimeClassType.Awaredatetime(line 639), while GraphQLParser defaults toDatetimeClassType.Datetime(src/datamodel_code_generator/parser/graphql.py:104). This difference exists but has no supporting documentation, tests, or code comments explaining the rationale. Clarify whether this intentional design choice is based on schema requirements or if these should be aligned.src/datamodel_code_generator/parser/graphql.py (1)
16-16: LGTM: Necessary imports for config-driven initialization.The import additions support the transition to config-based parser initialization, consistent with the broader refactoring across parser classes.
Also applies to: 22-22, 45-49
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/datamodel_code_generator/parser/jsonschema.py (1)
630-641: JsonSchemaParser.init cleanly adopts config+options while keeping datetime defaultsThe new
(source, *, config=None, **options)signature matches the shared Parser contract, and thetarget_datetime_class=Awaredatetimefallback for the “no config, no explicit option” case preserves legacy behavior for direct-kwargs callers. The only subtlety is that an explicittarget_datetime_class=Nonein the kwargs path will now also be treated as “use the default”, which is compatible with the previous API but worth remembering if you ever needNoneto be a distinct state.src/datamodel_code_generator/parser/graphql.py (1)
93-110: GraphQLParser.init now matches the unified ParserConfig API while preserving behaviorThe constructor’s
(source, *, config=None, data_model_scalar_type=..., data_model_union_type=..., **options)shape aligns with the base Parser, applies thetarget_datetime_class=Datetimedefault only for non-config callers, and cleanly derivesuse_standard_collections/use_union_operatorfrom either config or options before using them in later DataType construction. If you ever want to reduce duplication, you could instead rely onself.use_standard_collectionsandself.use_union_operatoras set bysuper().__init__, but the explicit computation here is perfectly valid.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/datamodel_code_generator/parser/graphql.pysrc/datamodel_code_generator/parser/jsonschema.pysrc/datamodel_code_generator/parser/openapi.pytests/main/test_main_general.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-25T09:23:08.506Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2799
File: src/datamodel_code_generator/util.py:49-66
Timestamp: 2025-12-25T09:23:08.506Z
Learning: In datamodel-code-generator, the is_pydantic_v2() and is_pydantic_v2_11() functions in src/datamodel_code_generator/util.py intentionally use global variable caching (_is_v2, _is_v2_11) on top of lru_cache for performance optimization. This dual-layer caching eliminates function call overhead and cache lookup overhead for frequently-called version checks. The PLW0603 linter warnings should be suppressed with # noqa: PLW0603 as this is a deliberate design choice.
Applied to files:
src/datamodel_code_generator/parser/openapi.py
🧬 Code graph analysis (2)
src/datamodel_code_generator/parser/openapi.py (5)
src/datamodel_code_generator/_types/parser_config_dict.py (1)
ParserConfigDict(33-144)src/datamodel_code_generator/config.py (1)
ParserConfig(196-319)src/datamodel_code_generator/enums.py (1)
OpenAPIScope(70-78)src/datamodel_code_generator/reference.py (1)
get(983-985)src/datamodel_code_generator/__main__.py (1)
get(148-150)
src/datamodel_code_generator/parser/graphql.py (3)
src/datamodel_code_generator/format.py (1)
DatetimeClassType(50-57)src/datamodel_code_generator/_types/parser_config_dict.py (1)
ParserConfigDict(33-144)src/datamodel_code_generator/config.py (1)
ParserConfig(196-319)
⏰ 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). (14)
- GitHub Check: 3.10 on Windows
- GitHub Check: py312-pydantic1 on Ubuntu
- GitHub Check: 3.12 on Windows
- GitHub Check: 3.10 on macOS
- GitHub Check: py312-black22 on Ubuntu
- GitHub Check: py312-black24 on Ubuntu
- GitHub Check: 3.11 on Windows
- GitHub Check: py312-isort7 on Ubuntu
- GitHub Check: 3.14 on Ubuntu
- GitHub Check: 3.14 on Windows
- GitHub Check: 3.11 on macOS
- GitHub Check: 3.13 on Windows
- GitHub Check: Analyze (python)
- GitHub Check: benchmarks
🔇 Additional comments (6)
tests/main/test_main_general.py (2)
1998-2015: Config+kwargs conflict test still accurately validates generate() semanticsPassing a config object and an extra GenerateConfig-backed kwarg (
field_constraints=True) keeps this test aligned with the new config/options mutual-exclusion logic without changing its intent.
2018-2036: Good coverage for Parser config/options mutual exclusion via JsonSchemaParserThis test correctly rebuilds
ParserConfigwith the needed type namespace and asserts that combiningconfigwith a ParserConfigDict-style kwarg raises the expectedValueError, exercising the generalized Parser initialization path.src/datamodel_code_generator/parser/openapi.py (2)
19-20: Typing imports align OpenAPIParser with the shared config surfaceBringing in
Unpackand type-onlyParserConfig/ParserConfigDictcleanly documents the new config-based API for OpenAPIParser without affecting runtime behavior.Also applies to: 41-47
169-183: Config-aware OpenAPIParser.init preserves previous wrap_string_literal defaultingThe new signature
(source, *, config=None, ..., **options)matches the base Parser API, and thewrap_string_literal=Falsefallback is only applied when no config and no explicit option are provided, which keeps legacy direct-kwargs behavior while leavingParserConfig.wrap_string_literalfree to use its own tri-state semantics.src/datamodel_code_generator/parser/jsonschema.py (1)
25-26: Typing extensions and TYPE_CHECKING imports look consistent with the new APIUsing
Unpackplus type-onlyParserConfig/ParserConfigDictgives JsonSchemaParser a fully-typed config/options surface without introducing extra runtime imports.Also applies to: 85-90
src/datamodel_code_generator/parser/graphql.py (1)
16-36: Typing and helper imports correctly wire GraphQLParser into the shared config/type systemThe added Unpack, DatetimeClassType, Types, and TYPE_CHECKING-only ParserConfig/ParserConfigDict/DataModel imports are consistent with the new config-driven initialization and with how this parser builds DataType instances.
Also applies to: 44-50
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tests/main/test_public_api_signature_baseline.py (1)
549-555: Consider adding explanatory comment for callable defaults handling.The special case at lines 551-552 skips comparison when the baseline has a callable default (e.g.,
title_to_class_nameforcustom_class_name_generator) while theParserConfighasNone. While this is reasonable—Pydantic models typically can't store function references as defaults—a brief comment would help future maintainers understand why this divergence is acceptable.📝 Suggested comment
for name, param in baseline_params.items(): config_default = ParserConfig.model_fields[name].default + # Skip callable defaults: Pydantic configs store None, functions provided at instantiation if callable(param.default) and config_default is None: continue assert config_default == param.default, (
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
tests/main/test_public_api_signature_baseline.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-25T09:23:08.506Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2799
File: src/datamodel_code_generator/util.py:49-66
Timestamp: 2025-12-25T09:23:08.506Z
Learning: In datamodel-code-generator, the is_pydantic_v2() and is_pydantic_v2_11() functions in src/datamodel_code_generator/util.py intentionally use global variable caching (_is_v2, _is_v2_11) on top of lru_cache for performance optimization. This dual-layer caching eliminates function call overhead and cache lookup overhead for frequently-called version checks. The PLW0603 linter warnings should be suppressed with # noqa: PLW0603 as this is a deliberate design choice.
Applied to files:
tests/main/test_public_api_signature_baseline.py
🧬 Code graph analysis (1)
tests/main/test_public_api_signature_baseline.py (4)
src/datamodel_code_generator/_types/parser_config_dict.py (1)
ParserConfigDict(33-144)src/datamodel_code_generator/util.py (1)
is_pydantic_v2(52-57)src/datamodel_code_generator/config.py (1)
ParserConfig(196-319)src/datamodel_code_generator/parser/jsonschema.py (1)
model_rebuild(218-220)
⏰ 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: py312-black24 on Ubuntu
- GitHub Check: 3.13 on Windows
- GitHub Check: py312-isort5 on Ubuntu
- GitHub Check: 3.10 on Windows
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.12 on Windows
- GitHub Check: 3.11 on Ubuntu
- GitHub Check: 3.14 on Windows
- GitHub Check: benchmarks
- GitHub Check: Analyze (python)
🔇 Additional comments (2)
tests/main/test_public_api_signature_baseline.py (2)
35-35: LGTM: Import cleanup reflects config-driven API shift.The removal of
Parserfrom imports is appropriate since the test now validates backward compatibility viaParserConfigDictrather than inspectingParser.__init__directly.
503-532: LGTM: Robust backward compatibility validation.The rewritten test correctly validates that
ParserConfigDictmaintains backward compatibility by ensuring:
- All baseline parameter names are present in the TypedDict
- Types match after normalization (handling Union ordering differences)
The filtering of 'config' at line 513 is forward-compatible with the new signature pattern
config: ParserConfig | None, **options: Unpack[ParserConfigDict].
Breaking Change AnalysisResult: Breaking changes detected Reasoning: The PR changes the Parser class hierarchy signatures from explicit keyword parameters (~100 parameters) to a simplified pattern using Content for Release NotesAPI/CLI Changes
This analysis was performed by Claude Code Action |
|
🎉 Released in 0.51.0 This PR is now available in the latest release. See the release notes for details. |
Summary by CodeRabbit
Breaking Changes
New Features
Refactor
Tests
✏️ Tip: You can customize this high-level summary in your review settings.