Skip to content

Simplify Parser.__init__ signature using Unpack[ParserConfigDict]#2877

Merged
koxudaxi merged 6 commits intomainfrom
enhance-parser-signature-test
Dec 30, 2025
Merged

Simplify Parser.__init__ signature using Unpack[ParserConfigDict]#2877
koxudaxi merged 6 commits intomainfrom
enhance-parser-signature-test

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Dec 30, 2025

Summary by CodeRabbit

  • Breaking Changes

    • Parser constructors now accept a single config object plus option bags; supplying both config and explicit options raises an error. Public init signatures simplified to config + **options.
  • New Features

    • Per-parser flags exposed: use_standard_collections and use_union_operator (GraphQL).
    • Defaulting behavior for datetime handling and string-wrap applied when no config is provided.
  • Refactor

    • Unified, config-driven initialization across parsers; reduced explicit constructor surface.
  • Tests

    • Added/updated tests validating config-vs-kwargs behavior and public API compatibility.

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 30, 2025

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 @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 2378674 and f95c139.

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

Walkthrough

Refactors parser constructors to a config-driven API: parser classes now accept config: ParserConfig | None plus **options: Unpack[ParserConfigDict]. Internal defaults and per-instance flags derive from config or options; tests added/updated to validate mutual-exclusion of config with explicit kwargs and preserve legacy defaults when appropriate.

Changes

Cohort / File(s) Summary
Parser base
src/datamodel_code_generator/parser/base.py
Replaced long keyword-only Parser.__init__ with `config: ParserConfig
GraphQL parser
src/datamodel_code_generator/parser/graphql.py
Constructor simplified to accept config + **options; defaulted target_datetime_class when no config provided; forwards **options to super(); added per-instance flags use_standard_collections and use_union_operator.
JSON Schema parser
src/datamodel_code_generator/parser/jsonschema.py
Constructor consolidated to config + **options; defaulting for target_datetime_class when config is None; added typing_extensions.Unpack and TYPE_CHECKING imports for ParserConfigDict/ParserConfig.
OpenAPI parser
src/datamodel_code_generator/parser/openapi.py
Constructor reduced to config, openapi_scopes, include_path_parameters, and **options; conditional default for wrap_string_literal when no config; typing imports adjusted to use Unpack and config types.
Public API signature test
tests/main/test_public_api_signature_baseline.py
Test updated to compare baseline keyword-only params to ParserConfigDict keys/types; uses ParserConfig model fields and includes Pydantic v2-specific rebuild/validation checks for defaults.
General tests
tests/main/test_main_general.py
Added tests: ensure error when both config and explicit kwargs are supplied; verify explicit target_datetime_class and wrap_string_literal behavior for respective parsers.
Project metadata
manifest_file, pyproject.toml, requirements.txt
Minor manifest/metadata adjustments referenced (no functional details shown).

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

breaking-change-analyzed, breaking-change

Suggested reviewers

  • ilovelinux

Poem

🐰 I hopped from kwargs into tidy config,
Packed options snug, no more constructor big.
Parsers now listen to one gentle tap,
I nibble code crumbs beside the map.
🥕

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 the main change: refactoring Parser.init to use a config-driven approach with Unpack[ParserConfigDict] instead of numerous explicit parameters.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% 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 30, 2025

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Dec 30, 2025

CodSpeed Performance Report

Merging #2877 will not alter performance

Comparing enhance-parser-signature-test (f95c139) with main (0610118)

⚠️ 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.39%. Comparing base (0610118) to head (f95c139).
⚠️ Report is 1 commits behind head on main.

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     
Flag Coverage Δ
unittests 99.39% <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 changed the title Add type and default value checks to test_parser_signature_matches_baseline Simplify Parser.__init__ signature using Unpack[ParserConfigDict] Dec 30, 2025
Comment thread src/datamodel_code_generator/parser/base.py Dismissed
Comment thread src/datamodel_code_generator/parser/base.py Dismissed
Comment thread src/datamodel_code_generator/parser/base.py Dismissed
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 (3)
src/datamodel_code_generator/parser/base.py (2)

685-685: Remove unused noqa directive.

The static analysis tool indicates that the noqa directives for PLR0012, PLR0914, PLR0915 are 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 unused noqa directives for local imports.

Static analysis indicates these PLC0415 suppressions 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_base
src/datamodel_code_generator/parser/graphql.py (1)

93-114: Consider extracting config values from kwargs before super() call.

Lines 105-108 extract use_standard_collections and use_union_operator from config or kwargs, but these values remain in kwargs when passed to super().__init__() (line 109). This means:

  1. Parent class receives these values in kwargs
  2. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 0610118 and aaaeadf.

📒 Files selected for processing (5)
  • src/datamodel_code_generator/parser/base.py
  • src/datamodel_code_generator/parser/graphql.py
  • src/datamodel_code_generator/parser/jsonschema.py
  • src/datamodel_code_generator/parser/openapi.py
  • 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
  • src/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_rebuild to resolve forward references and model_validate for validation
  • V1 uses update_forward_refs and construct with merged defaults

The error handling for conflicting inputs (config + options) is clear.


73-80: Import organization looks good.

The TYPE_CHECKING imports properly guard ParserConfigDict and ParserConfig to 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:

  1. Key-set equality between baseline kwargs and ParserConfigDict
  2. Type matching using the _types_match utility
  3. 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_name in the baseline has a function default while ParserConfig uses None.


549-559: Default comparison logic handles edge cases appropriately.

The skip conditions are well-considered:

  • Skipping inspect.Parameter.empty prevents false failures for required params
  • Skipping fields not in model_fields handles cases where baseline has extra params
  • Skipping callable defaults with None config handles the custom_class_name_generator=title_to_class_name case

This ensures the test focuses on meaningful compatibility checks.


35-35: YamlValue import location is correct.

The YamlValue type alias is properly defined in datamodel_code_generator.parser.base and 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 config object or **kwargs via Unpack[ParserConfigDict]
  • Properly sets wrap_string_literal=False default 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 base ParserConfig.


44-46: TYPE_CHECKING imports properly organized.

The new imports are correctly guarded and provide proper type hints for:

  • ParserConfigDict - for the **kwargs type
  • ParserConfig - for the config parameter type
  • DataModelFieldBase - for return type annotation at line 270
src/datamodel_code_generator/parser/jsonschema.py (2)

25-25: LGTM: Import additions support config-driven initialization.

The Unpack import 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_class to DatetimeClassType.Awaredatetime (line 639), while GraphQLParser defaults to DatetimeClassType.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

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 (2)
src/datamodel_code_generator/parser/jsonschema.py (1)

630-641: JsonSchemaParser.init cleanly adopts config+options while keeping datetime defaults

The new (source, *, config=None, **options) signature matches the shared Parser contract, and the target_datetime_class=Awaredatetime fallback for the “no config, no explicit option” case preserves legacy behavior for direct-kwargs callers. The only subtlety is that an explicit target_datetime_class=None in 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 need None to be a distinct state.

src/datamodel_code_generator/parser/graphql.py (1)

93-110: GraphQLParser.init now matches the unified ParserConfig API while preserving behavior

The constructor’s (source, *, config=None, data_model_scalar_type=..., data_model_union_type=..., **options) shape aligns with the base Parser, applies the target_datetime_class=Datetime default only for non-config callers, and cleanly derives use_standard_collections / use_union_operator from either config or options before using them in later DataType construction. If you ever want to reduce duplication, you could instead rely on self.use_standard_collections and self.use_union_operator as set by super().__init__, but the explicit computation here is perfectly valid.

📜 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 aaaeadf and 66728e5.

📒 Files selected for processing (4)
  • src/datamodel_code_generator/parser/graphql.py
  • src/datamodel_code_generator/parser/jsonschema.py
  • src/datamodel_code_generator/parser/openapi.py
  • tests/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() semantics

Passing 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 JsonSchemaParser

This test correctly rebuilds ParserConfig with the needed type namespace and asserts that combining config with a ParserConfigDict-style kwarg raises the expected ValueError, exercising the generalized Parser initialization path.

src/datamodel_code_generator/parser/openapi.py (2)

19-20: Typing imports align OpenAPIParser with the shared config surface

Bringing in Unpack and type-only ParserConfig/ParserConfigDict cleanly 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 defaulting

The new signature (source, *, config=None, ..., **options) matches the base Parser API, and the wrap_string_literal=False fallback is only applied when no config and no explicit option are provided, which keeps legacy direct-kwargs behavior while leaving ParserConfig.wrap_string_literal free 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 API

Using Unpack plus type-only ParserConfig/ParserConfigDict gives 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 system

The 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

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

🧹 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_name for custom_class_name_generator) while the ParserConfig has None. 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

📥 Commits

Reviewing files that changed from the base of the PR and between 4da9041 and 2378674.

📒 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 Parser from imports is appropriate since the test now validates backward compatibility via ParserConfigDict rather than inspecting Parser.__init__ directly.


503-532: LGTM: Robust backward compatibility validation.

The rewritten test correctly validates that ParserConfigDict maintains backward compatibility by ensuring:

  1. All baseline parameter names are present in the TypedDict
  2. 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].

Comment thread tests/main/test_public_api_signature_baseline.py
@koxudaxi koxudaxi merged commit 0c5d538 into main Dec 30, 2025
37 checks passed
@koxudaxi koxudaxi deleted the enhance-parser-signature-test branch December 30, 2025 21:06
@github-actions
Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: Breaking changes detected

Reasoning: The PR changes the Parser class hierarchy signatures from explicit keyword parameters (~100 parameters) to a simplified pattern using config: ParserConfig | None plus **options: Unpack[ParserConfigDict]. This is a breaking change because: 1) Users who were passing both a config object and keyword arguments will now get a ValueError, and 2) Users who subclass these parsers and override init may need to update their code. However, the common case of just using keyword arguments is preserved through the TypedDict-based **options pattern.

Content for Release Notes

API/CLI Changes

  • Parser signature simplified to config + options pattern - Parser.__init__, JsonSchemaParser.__init__, OpenAPIParser.__init__, and GraphQLParser.__init__ now accept either a config: ParserConfig object OR keyword arguments via **options: Unpack[ParserConfigDict], but not both simultaneously. Passing both raises a ValueError. Existing code using only keyword arguments continues to work unchanged. (Simplify Parser.__init__ signature using Unpack[ParserConfigDict] #2877)

    # Before: Could potentially mix config with kwargs (undefined behavior)
    parser = JsonSchemaParser(source="{}", config=some_config, field_constraints=True)
    
    # After: Raises ValueError - must use one approach or the other
    parser = JsonSchemaParser(source="{}", config=some_config)  # Use config object
    # OR
    parser = JsonSchemaParser(source="{}", field_constraints=True)  # Use keyword args
  • Subclass compatibility - Code that subclasses Parser, JsonSchemaParser, OpenAPIParser, or GraphQLParser may need updates if they override __init__ and call super().__init__() with explicit parameter lists. The new signature uses **options: Unpack[ParserConfigDict] instead of explicit parameters. (Simplify Parser.__init__ signature using Unpack[ParserConfigDict] #2877)


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.

2 participants