Skip to content

Fix allOf partial override to inherit parent constraints and add --allof-merge-mode option#2671

Merged
koxudaxi merged 9 commits intomainfrom
fix/allof-partial-override-constraint-inheritance
Dec 16, 2025
Merged

Fix allOf partial override to inherit parent constraints and add --allof-merge-mode option#2671
koxudaxi merged 9 commits intomainfrom
fix/allof-partial-override-constraint-inheritance

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Dec 16, 2025

Summary

  • Fix bug where parent property constraints were not inherited when child partially overrides a property in allOf schemas
  • Add --allof-merge-mode option to control field merging behavior in allOf schemas

Summary by CodeRabbit

  • New Features

    • Added a CLI option --allof-merge-mode with modes: constraints (default), all, none to control how allOf fields are merged.
  • Documentation

    • Updated command help and docs to describe the new merge-mode options and behavior.
  • Tests

    • Added tests and example schemas/models covering allOf merge modes, inheritance/overrides, and unique-items handling.

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 16, 2025

Walkthrough

A new CLI option --allof-merge-mode (values: constraints, all, none) was added and propagated into the public generate() API, Config, and parser constructors. JSON Schema parsing gained helpers to merge parent/child property schemas and now applies merged items during allOf processing according to the selected mode.

Changes

Cohort / File(s) Summary
Documentation
README.md, docs/index.md
Documented the new --allof-merge-mode CLI option and described its three modes.
Public API & Enum
src/datamodel_code_generator/__init__.py
Added AllOfMergeMode enum (constraints, all, none) and allof_merge_mode parameter to generate(), defaulting to Constraints.
CLI wiring
src/datamodel_code_generator/__main__.py, src/datamodel_code_generator/arguments.py
Added CLI argument --allof-merge-mode, added allof_merge_mode to Config, and passed it into generate().
Parser base & exposure
src/datamodel_code_generator/parser/base.py
Parser constructor gained allof_merge_mode param, stored as self.allof_merge_mode, and AllOfMergeMode added to exports.
JSON Schema parser logic
src/datamodel_code_generator/parser/jsonschema.py
JsonSchemaParser.__init__ accepts allof_merge_mode; added _merge_property_schemas() and _merge_properties_with_parent_constraints(); updated allOf handling to use merged items for non-$ref items.
OpenAPI & GraphQL parsers
src/datamodel_code_generator/parser/openapi.py, src/datamodel_code_generator/parser/graphql.py
Constructors updated to accept and forward allof_merge_mode to the base parser.
Test inputs (OpenAPI)
tests/data/openapi/*.yaml
Added multiple OpenAPI test fixtures exercising allOf compositions, defaults, uniqueItems, boolean properties, multiple parents, and merge-mode scenarios.
Expected generated outputs
tests/data/expected/main/openapi/*.py
New expected Pydantic model files reflecting merged constraints/defaults and overridden fields for various merge behaviors and uniqueItems handling (v1/v2).
Tests
tests/main/openapi/test_main_openapi.py
Added several allOf-focused tests covering partial overrides, merge modes (all, none), boolean/empty-parent cases, multiple parents, and uniqueItems behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CLI as CLI (argparse)
  participant Config as Config
  participant Generate as generate()
  participant ParserFactory as Parser (OpenAPI/GraphQL/JsonSchema)
  participant JsonParser as JsonSchemaParser
  participant Fields as parse_object_fields

  CLI->>Config: parse args (includes --allof-merge-mode)
  Config->>Generate: call generate(allof_merge_mode)
  Generate->>ParserFactory: construct parser(allof_merge_mode)
  ParserFactory->>JsonParser: instantiate with allof_merge_mode
  JsonParser->>JsonParser: parse schemas
  alt allOf item is non-$ref
    JsonParser->>JsonParser: _merge_properties_with_parent_constraints(parent_refs)
    JsonParser->>Fields: parse_object_fields(merged_item)
  else $ref item
    JsonParser->>Fields: parse_object_fields(all_of_item)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay special attention to:
    • src/datamodel_code_generator/parser/jsonschema.py — new merging helpers and updated allOf flow (modes correctness, edge cases, nested/recursive allOf).
    • CLI/API wiring consistency: default, help text, and choices in arguments and Config.
    • Tests and expected outputs for Pydantic v1/v2 differences and uniqueItems handling.

Poem

🐇 I nibble on schemas late at night,
I stitch parent rules by lantern light,
Constraints, all, or none — I pick the way,
Hopping through merges till break of day,
A tiny rabbit cheering code to play!

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 two main changes: fixing allOf partial override constraint inheritance and adding the --allof-merge-mode option.
Docstring Coverage ✅ Passed Docstring coverage is 95.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/allof-partial-override-constraint-inheritance

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.

@koxudaxi koxudaxi marked this pull request as ready for review December 16, 2025 02:53
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Dec 16, 2025

CodSpeed Performance Report

Merging #2671 will not alter performance

Comparing fix/allof-partial-override-constraint-inheritance (5039f6e) with main (b72471d)

Summary

✅ 50 untouched
⏩ 3 skipped1

Footnotes

  1. 3 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.

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

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

1389-1431: Consider narrowing exception handling or adding logging.

Line 1400 uses a broad except Exception which silently continues on any error. While this prevents crashes when loading parent refs fails, it could hide legitimate issues (e.g., malformed schemas, I/O errors).

Consider either:

  1. Catching more specific exceptions (e.g., KeyError, ValueError)
  2. Adding debug logging when an exception occurs
-            except Exception:  # noqa: BLE001, S112
+            except (KeyError, ValueError, TypeError) as e:  # noqa: S112
+                # Parent schema could not be loaded, skip constraint merging
                 continue

Alternatively, if you want to keep the broad catch for robustness:

-            except Exception:  # noqa: BLE001, S112
+            except Exception:  # noqa: BLE001, S112
+                # Log at debug level for troubleshooting
+                # import logging; logging.debug(f"Could not load parent ref {ref}: {e}")
                 continue
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b458594 and 871a14c.

📒 Files selected for processing (14)
  • README.md (1 hunks)
  • docs/index.md (1 hunks)
  • src/datamodel_code_generator/__init__.py (3 hunks)
  • src/datamodel_code_generator/__main__.py (3 hunks)
  • src/datamodel_code_generator/arguments.py (2 hunks)
  • src/datamodel_code_generator/parser/base.py (3 hunks)
  • src/datamodel_code_generator/parser/jsonschema.py (6 hunks)
  • src/datamodel_code_generator/parser/openapi.py (3 hunks)
  • tests/data/expected/main/openapi/allof_materialize_defaults.py (1 hunks)
  • tests/data/expected/main/openapi/allof_partial_override_unique_items.py (1 hunks)
  • tests/data/expected/main/openapi/allof_partial_override_unique_items_pydantic_v2.py (1 hunks)
  • tests/data/openapi/allof_materialize_defaults.yaml (1 hunks)
  • tests/data/openapi/allof_partial_override_unique_items.yaml (1 hunks)
  • tests/main/openapi/test_main_openapi.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (10)
tests/main/openapi/test_main_openapi.py (2)
tests/main/conftest.py (2)
  • output_file (94-96)
  • run_main_and_assert (196-352)
tests/test_main_kr.py (1)
  • output_file (37-39)
src/datamodel_code_generator/parser/base.py (1)
src/datamodel_code_generator/__init__.py (1)
  • AllOfMergeMode (273-283)
src/datamodel_code_generator/__init__.py (3)
src/datamodel_code_generator/model/msgspec.py (1)
  • Constraints (158-163)
src/datamodel_code_generator/model/pydantic/base_model.py (1)
  • Constraints (35-47)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
  • Constraints (43-61)
src/datamodel_code_generator/parser/openapi.py (1)
src/datamodel_code_generator/__init__.py (1)
  • AllOfMergeMode (273-283)
tests/data/expected/main/openapi/allof_materialize_defaults.py (2)
src/datamodel_code_generator/model/base.py (1)
  • name (583-585)
src/datamodel_code_generator/parser/base.py (1)
  • Child (563-569)
src/datamodel_code_generator/__main__.py (1)
src/datamodel_code_generator/__init__.py (1)
  • AllOfMergeMode (273-283)
src/datamodel_code_generator/arguments.py (1)
src/datamodel_code_generator/__init__.py (1)
  • AllOfMergeMode (273-283)
src/datamodel_code_generator/parser/jsonschema.py (1)
src/datamodel_code_generator/__init__.py (1)
  • AllOfMergeMode (273-283)
tests/data/expected/main/openapi/allof_partial_override_unique_items.py (2)
tests/data/expected/parser/openapi/openapi_parser_parse_modular/bar.py (1)
  • Field (6-7)
tests/data/expected/main/openapi/allof_partial_override_unique_items_pydantic_v2.py (2)
  • Thing (12-13)
  • Person (16-17)
tests/data/expected/main/openapi/allof_partial_override_unique_items_pydantic_v2.py (1)
tests/data/expected/main/openapi/allof_partial_override_unique_items.py (2)
  • Thing (12-13)
  • Person (16-17)
🪛 Checkov (3.2.334)
tests/data/openapi/allof_partial_override_unique_items.yaml

[high] 1-26: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)


[medium] 11-16: Ensure that arrays have a maximum number of items

(CKV_OPENAPI_21)

tests/data/openapi/allof_materialize_defaults.yaml

[high] 1-28: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)

🪛 GitHub Actions: Test
src/datamodel_code_generator/__init__.py

[error] 616-616: GraphQLParser.init() got an unexpected keyword argument 'allof_merge_mode'. This indicates a mismatch between parser API and its usage (likely due to version/API changes).

src/datamodel_code_generator/__main__.py

[error] 1-1: GraphQLParser.init() got an unexpected keyword argument 'allof_merge_mode' during code generation. This indicates a mismatch between the GraphQL parser implementation and the code that invokes it (likely an API incompatibility between dependencies).

⏰ 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). (1)
  • GitHub Check: benchmarks
🔇 Additional comments (19)
README.md (1)

365-370: LGTM! Clear documentation for the new CLI option.

The help text clearly describes the three merge modes (constraints, all, none) and their behavior for allOf schemas.

src/datamodel_code_generator/arguments.py (2)

21-21: LGTM! Correct import of AllOfMergeMode.


426-434: LGTM! Proper CLI argument definition.

The argument correctly uses the AllOfMergeMode enum values as choices and provides clear help text.

docs/index.md (1)

357-362: LGTM! Documentation is consistent with README.

tests/data/openapi/allof_partial_override_unique_items.yaml (1)

1-24: LGTM! Appropriate test fixture for allOf partial override behavior.

The OpenAPI schema correctly defines a base Thing schema with uniqueItems constraint and a Person schema that uses allOf to override the tags field with a default value. This properly tests the constraint inheritance behavior.

Note: The static analysis warnings about missing security and maxItems are false positives for test data and can be safely ignored.

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

22-22: LGTM! Correct import of AllOfMergeMode.


239-239: LGTM! Proper parameter definition.

The allof_merge_mode parameter is correctly typed with AllOfMergeMode and has the appropriate default value of AllOfMergeMode.Constraints.


333-333: LGTM! Correct parameter forwarding.

The allof_merge_mode parameter is properly forwarded to the parent class initializer.

tests/data/openapi/allof_materialize_defaults.yaml (1)

1-26: LGTM! Appropriate test fixture for allOf default materialization.

This OpenAPI schema properly tests how default values and constraints are inherited and merged in allOf compositions. The Parent schema defines defaults and minimum constraints, while the Child schema extends it with additional maximum constraints.

Note: The static analysis warning about missing global security is a false positive for test data and can be safely ignored.

tests/data/expected/main/openapi/allof_materialize_defaults.py (1)

1-19: AllOf defaults fixture matches intended merge semantics

Parent/Child models correctly reflect merged constraints and inherited defaults for the all merge mode; structure and imports are consistent with other expected OpenAPI fixtures.

tests/main/openapi/test_main_openapi.py (1)

1827-1845: New allOf tests are well-scoped and consistent with existing patterns

  • test_main_openapi_allof_partial_override_unique_items parametrization over output model types plus --use-unique-items-as-set mirrors the style of other OpenAPI tests and directly targets the uniqueItems inheritance bug.
  • test_main_openapi_allof_merge_mode_all cleanly exercises the new --allof-merge-mode all option against a dedicated YAML/expected pair.

No issues spotted with arguments, paths, or expectations.

Also applies to: 1848-1857

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

26-34: Parser now exposes allOf merge mode cleanly

Importing AllOfMergeMode, threading it through Parser.__init__ with a default of Constraints, and storing it as self.allof_merge_mode are straightforward and maintain backward compatibility while giving concrete parsers the configuration they need.

Also applies to: 647-740, 761-875

src/datamodel_code_generator/__init__.py (1)

273-284: The review comment is incorrect—GraphQLParser already accepts and properly forwards the allof_merge_mode parameter.

GraphQLParser.init at line 155 includes allof_merge_mode: AllOfMergeMode = AllOfMergeMode.Constraints, and forwards it to the base Parser class at line 250 via super().__init__(). The unconditional passing of allof_merge_mode at line 674 in generate() does not cause a failure because the parameter is already properly wired in the GraphQL parser. Neither of the suggested fixes is necessary—the parameter integration is complete and functional.

Likely an incorrect or invalid review comment.

src/datamodel_code_generator/__main__.py (2)

23-38: LGTM: Import addition is correct.

The AllOfMergeMode import is properly added alongside other enum imports from the package.


425-425: LGTM: Config field addition is correct.

The allof_merge_mode field with default AllOfMergeMode.Constraints follows the established pattern for other config options.

src/datamodel_code_generator/parser/jsonschema.py (4)

24-36: LGTM: Import addition is correct.

The AllOfMergeMode import is properly placed with other imports from datamodel_code_generator.


1371-1387: LGTM: Merge logic for property schemas is well-implemented.

The three merge modes are correctly handled:

  • NoMerge: Returns child dict without parent fields
  • Constraints: Excludes annotation fields (default, examples, example) from parent
  • All: Merges all fields from parent

The recursive merge on line 1384 correctly handles nested property schemas.


1730-1755: LGTM: Integration of parent constraint merging in allOf processing.

The changes correctly:

  1. Compute parent_refs upfront from all $ref items in allOf
  2. For non-ref items, merge child properties with parent constraints before processing
  3. Use the merged item for parse_object_fields

This ensures child schemas inherit constraints from parent schemas according to the selected merge mode.


566-566: LGTM: Constructor parameter addition follows established pattern.

The allof_merge_mode parameter is correctly added with the appropriate default value (AllOfMergeMode.Constraints) at line 566 and passed to the parent constructor at line 660. The Parser base class in base.py has been updated to accept the parameter (line 702) and store it as an instance attribute (line 801). The parameter is actively used in the implementation (lines 1373, 1377).

Comment thread src/datamodel_code_generator/__main__.py
Comment thread tests/data/expected/main/openapi/allof_partial_override_unique_items.py Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 16, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.50%. Comparing base (b72471d) to head (5039f6e).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2671      +/-   ##
==========================================
- Coverage   99.61%   99.50%   -0.11%     
==========================================
  Files          76       76              
  Lines       10666    10731      +65     
  Branches     1303     1316      +13     
==========================================
+ Hits        10625    10678      +53     
- Misses         21       32      +11     
- Partials       20       21       +1     
Flag Coverage Δ
unittests 99.50% <100.00%> (-0.11%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

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

1398-1401: Consider narrowing the exception handling or adding a warning.

The bare except Exception with continue silently swallows any error when loading parent schemas. While this prevents failures for edge cases like circular references or invalid refs, it could also mask legitimate issues (e.g., malformed schemas, encoding errors).

Consider either:

  1. Catching more specific exceptions (e.g., KeyError, ValueError)
  2. Logging a warning when an exception occurs
             try:
                 parent_schema = self._load_ref_schema_object(ref)
-            except Exception:  # pragma: no cover  # noqa: BLE001, S112
+            except (KeyError, NotImplementedError) as exc:  # pragma: no cover
+                warn(f"Could not load parent schema {ref}: {exc}", stacklevel=2)
                 continue
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 06bcace and 5039f6e.

📒 Files selected for processing (12)
  • src/datamodel_code_generator/parser/jsonschema.py (6 hunks)
  • tests/data/expected/main/openapi/allof_merge_mode_none.py (1 hunks)
  • tests/data/expected/main/openapi/allof_multiple_parents_same_property.py (1 hunks)
  • tests/data/expected/main/openapi/allof_parent_bool_property.py (1 hunks)
  • tests/data/expected/main/openapi/allof_parent_no_properties.py (1 hunks)
  • tests/data/expected/main/openapi/allof_property_bool_schema.py (1 hunks)
  • tests/data/openapi/allof_merge_mode_none.yaml (1 hunks)
  • tests/data/openapi/allof_multiple_parents_same_property.yaml (1 hunks)
  • tests/data/openapi/allof_parent_bool_property.yaml (1 hunks)
  • tests/data/openapi/allof_parent_no_properties.yaml (1 hunks)
  • tests/data/openapi/allof_property_bool_schema.yaml (1 hunks)
  • tests/main/openapi/test_main_openapi.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (8)
tests/data/expected/main/openapi/allof_property_bool_schema.py (2)
tests/data/expected/main/openapi/allof_merge_mode_none.py (2)
  • Parent (12-13)
  • Child (16-17)
tests/data/expected/main/openapi/allof_parent_no_properties.py (1)
  • Child (16-17)
tests/data/openapi/allof_parent_no_properties.yaml (2)
tests/data/expected/parser/openapi/openapi_parser_parse_allof/output.py (5)
  • AllOfNested2 (75-76)
  • AllOfNested1 (79-80)
  • AllOfNested3 (71-72)
  • AllOfref (19-20)
  • AllOfCombine (28-30)
tests/data/expected/parser/openapi/openapi_parser_parse_alias/__init__.py (5)
  • AllOfRef (52-53)
  • AnyOfCombine (61-62)
  • AllOfCombine (56-58)
  • AllOfObj (30-32)
  • AnyOfCombineInRoot (81-83)
tests/data/openapi/allof_merge_mode_none.yaml (2)
tests/data/expected/parser/openapi/openapi_parser_parse_allof/output.py (7)
  • AllOfNested2 (75-76)
  • AllOfNested3 (71-72)
  • AllOfNested1 (79-80)
  • AllOfref (19-20)
  • AllOfobj (23-25)
  • AllOfCombine (28-30)
  • AnyOfCombine (33-34)
tests/data/expected/parser/openapi/openapi_parser_parse_alias/__init__.py (1)
  • AllOfCombine (56-58)
tests/main/openapi/test_main_openapi.py (1)
tests/main/conftest.py (2)
  • output_file (94-96)
  • run_main_and_assert (196-352)
src/datamodel_code_generator/parser/jsonschema.py (1)
src/datamodel_code_generator/__init__.py (1)
  • AllOfMergeMode (273-283)
tests/data/expected/main/openapi/allof_parent_bool_property.py (1)
tests/data/expected/main/openapi/allof_multiple_parents_same_property.py (1)
  • Child (21-23)
tests/data/expected/main/openapi/allof_multiple_parents_same_property.py (1)
tests/data/expected/main/openapi/allof_parent_bool_property.py (1)
  • Child (17-18)
tests/data/expected/main/openapi/allof_parent_no_properties.py (2)
tests/data/expected/main/openapi/allof_merge_mode_none.py (1)
  • Child (16-17)
tests/data/expected/main/openapi/allof_property_bool_schema.py (1)
  • Child (16-18)
🪛 Checkov (3.2.334)
tests/data/openapi/allof_parent_no_properties.yaml

[high] 1-19: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)

tests/data/openapi/allof_merge_mode_none.yaml

[high] 1-22: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)

tests/data/openapi/allof_parent_bool_property.yaml

[high] 1-22: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)

tests/data/openapi/allof_multiple_parents_same_property.yaml

[high] 1-33: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)

tests/data/openapi/allof_property_bool_schema.yaml

[high] 1-22: Ensure that the global security field has rules defined

(CKV_OPENAPI_4)

⏰ 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). (13)
  • GitHub Check: 3.10 on Windows
  • GitHub Check: 3.10 on macOS
  • GitHub Check: 3.11 on Windows
  • GitHub Check: 3.11 on macOS
  • GitHub Check: 3.12 on macOS
  • GitHub Check: 3.13 on macOS
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.9 on Windows
  • GitHub Check: 3.14 on Windows
  • GitHub Check: 3.14 on macOS
  • GitHub Check: 3.13 on Windows
  • GitHub Check: Analyze (python)
  • GitHub Check: benchmarks
🔇 Additional comments (20)
tests/data/openapi/allof_merge_mode_none.yaml (1)

1-20: LGTM!

This test fixture correctly demonstrates the allOf partial override scenario where the child adds maxLength: 100 without redeclaring the full property schema. The missing type: string in the child's name property is intentional to test constraint inheritance behavior.

The Checkov warning about missing global security field is a false positive for test fixtures.

src/datamodel_code_generator/parser/jsonschema.py (3)

566-566: LGTM!

The allof_merge_mode parameter is correctly added with a sensible default of AllOfMergeMode.Constraints and properly threaded to the superclass.


1371-1387: LGTM!

The merge logic correctly implements all three modes:

  • NoMerge: Returns child dict without parent fields
  • Constraints: Merges all except annotation fields (default, examples, example)
  • All (implicit when not NoMerge or Constraints): Merges everything

The recursive merge for nested dicts properly maintains mode semantics.


1730-1755: LGTM!

The integration correctly:

  1. Collects all $ref paths upfront as potential parent schemas
  2. Merges child properties with parent constraints before parsing
  3. Uses the merged item for field parsing while preserving original required extraction

This ensures constraint inheritance works for partial property overrides in allOf schemas.

tests/data/openapi/allof_parent_no_properties.yaml (1)

1-17: LGTM!

Good edge case test for the merge logic when the parent schema has no properties. This validates that _merge_properties_with_parent_constraints correctly handles empty parents without errors.

The Checkov warning about missing global security field is a false positive for test fixtures.

tests/data/openapi/allof_property_bool_schema.yaml (1)

1-20: LGTM!

This test fixture validates an important edge case: boolean property schemas (allowed: true). In JSON Schema, true as a property schema means "any value is allowed." The implementation correctly handles this at line 1412 of jsonschema.py where non-JsonSchemaObject properties are passed through unchanged.

The Checkov warning about missing global security field is a false positive for test fixtures.

tests/data/expected/main/openapi/allof_merge_mode_none.py (1)

16-17: Expected output for merge mode "none" shows incorrect constraint inheritance.

With --allof-merge-mode none, the Child.name field should not inherit the parent's min_length=1 constraint. The input YAML specifies only maxLength: 100 for Child.name, so the generated field should reflect that (or be a plain Optional[str]), not include min_length=1 from the Parent class definition.

The current expected output violates the "none" merge mode semantics, which explicitly means "do not merge any fields from parent properties." Either the expected output file is incorrect, or the implementation has a flaw where fields with incomplete constraint specifications fall back to inheriting the entire parent field type instead of respecting the merge mode.

tests/data/openapi/allof_parent_bool_property.yaml (1)

1-20: LGTM! Test data correctly exercises boolean schema in allOf.

This test case properly validates handling of boolean property schemas (allowed: true) within allOf compositions, which is an edge case worth testing.

Note: The static analysis warning about missing global security is a false positive for test data files.

tests/data/openapi/allof_multiple_parents_same_property.yaml (1)

1-31: LGTM! Well-designed test for multiple parent constraint merging.

This test case validates the important scenario where multiple parents define the same property with different constraints (minLength: 1 vs 5), ensuring the generator correctly merges to the most restrictive constraint.

tests/data/expected/main/openapi/allof_parent_no_properties.py (1)

1-17: LGTM! Expected output correctly represents empty parent scenario.

The generated code properly handles the edge case of a parent schema with no properties, creating an empty base class and child with inherited structure.

tests/data/expected/main/openapi/allof_property_bool_schema.py (1)

1-18: LGTM! Constraint inheritance correctly implemented.

The Child class properly inherits the min_length=1 constraint from Parent and combines it with the child's max_length=100, demonstrating the fix for partial override constraint inheritance.

tests/data/expected/main/openapi/allof_parent_bool_property.py (1)

1-18: LGTM! Parent field inheritance working correctly.

The Child class properly inherits both the allowed field and the min_length constraint on name from Parent, while adding its own max_length constraint.

tests/data/expected/main/openapi/allof_multiple_parents_same_property.py (1)

21-23: LGTM! Constraint merging correctly selects most restrictive values.

The Child class correctly merges constraints from multiple parents:

  • Takes min_length=5 (more restrictive than Parent1's min_length=1)
  • Combines age constraints from Parent2 (ge=0) with child's own (le=150)

Note: Child inherits from BaseModel directly rather than from Parent1/Parent2, which is the expected behavior for allOf composition with multiple parents.

tests/main/openapi/test_main_openapi.py (7)

1827-1846: LGTM! Well-structured parametrized test.

The test properly validates uniqueItems inheritance across both Pydantic versions with appropriate flags (--use-unique-items-as-set).


1848-1858: LGTM! Merge mode "all" test correctly configured.

The test validates that --allof-merge-mode all properly merges parent defaults, which is the core functionality of this PR.


1860-1870: LGTM! Merge mode "none" test correctly configured.

The test validates that --allof-merge-mode none skips parent constraint merging, providing the opposite behavior to "all" mode.


1872-1881: LGTM! Boolean schema property test is correctly structured.

The test validates proper handling of boolean property schemas (e.g., allowed: true) in allOf compositions, an important edge case.


1883-1892: LGTM! Empty parent edge case properly tested.

The test validates correct handling of allOf when the parent schema has no properties, an edge case that could cause issues if not handled properly.


1894-1903: LGTM! Parent boolean property test correctly structured.

The test validates that boolean property schemas in parent classes are properly inherited by children in allOf compositions.


1905-1914: LGTM! Multiple parent constraint merging properly tested.

The test validates the critical scenario where multiple parents define the same property with different constraints, ensuring the generator correctly merges to the most restrictive values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant