Skip to content

Add support for multiple base classes in base_class_map and customBasePath#2916

Merged
koxudaxi merged 3 commits intomainfrom
feature/multiple-base-classes
Jan 4, 2026
Merged

Add support for multiple base classes in base_class_map and customBasePath#2916
koxudaxi merged 3 commits intomainfrom
feature/multiple-base-classes

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Jan 4, 2026

Fixes: #1918
Fixes: #2494

Summary by CodeRabbit

  • New Features

    • Base class configuration now accepts either a single string or a list of strings, allowing multiple custom base classes for generated models.
    • base_class_map and custom_base_path options accept list-based specifications in addition to single-string values.
  • Tests

    • Added coverage for list-valued base class mappings and empty-list scenarios.
  • Documentation

    • Expanded CLI and JSON Schema docs with examples, priority rules, and guidance for single vs. multiple base-class usage.

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 4, 2026

📝 Walkthrough

Walkthrough

Type annotations and handling for base-class configuration were broadened to accept either a string or a list of strings. Changes touch configuration types, parser resolution logic, model constructors, and tests to support multiple custom base classes and empty-list semantics.

Changes

Cohort / File(s) Summary
Configuration & CLI entry
src/datamodel_code_generator/__main__.py, src/datamodel_code_generator/config.py, src/datamodel_code_generator/_types/generate_config_dict.py, src/datamodel_code_generator/_types/parser_config_dicts.py
base_class_map type widened from `dict[str, str]
Parser base resolution
src/datamodel_code_generator/parser/base.py
self.base_class_map updated to accept list values; _resolve_base_class() signature and logic changed to accept/return str | list[str] | None; added internal normalize() to dedupe and collapse single-item lists.
JSON Schema parser model
src/datamodel_code_generator/parser/jsonschema.py
JsonSchemaObject.custom_base_path field broadened from Optional[str] to str | list[str] | None (alias customBasePath).
Core base-class handling
src/datamodel_code_generator/model/base.py
set_base_class() and related logic updated to accept custom_base_class: str | list[str] | None, build a list of bases, create imports for each, and construct multiple BaseClassDataType instances.
Model constructors
src/datamodel_code_generator/model/dataclass.py, .../enum.py, .../msgspec.py, .../pydantic/base_model.py, .../pydantic_v2/base_model.py, .../pydantic_v2/dataclass.py, .../scalar.py, .../typed_dict.py, .../union.py
custom_base_class parameter types expanded from str | None to str | list[str] | None in various model __init__ signatures; values are passed through to base-class handling.
Tests & expected outputs
tests/main/jsonschema/test_main_jsonschema.py, tests/main/test_public_api_signature_baseline.py, tests/data/expected/.../base_class_map_list.py, .../base_class_map_empty_list.py, .../custom_base_paths_list.py, tests/data/expected/main/input_model/config_class.py
New tests and expected model outputs for list-valued and empty-list scenarios; baseline signatures and expected TypedDict types updated to reflect list support.
Docs
docs/cli-reference/model-customization.md, docs/jsonschema.md
CLI and JSON Schema docs extended with examples and explanation for single vs. multiple base classes, priority order, and usage notes.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as CLI / Config
  participant Parser as Parser
  participant Resolver as _resolve_base_class
  participant Model as DataModel.set_base_class
  participant Importer as Import collection

  CLI->>Parser: provide base_class_map / customBasePath
  Parser->>Resolver: resolve base for class_name (may be str|list)
  alt base_class_map hit
    Resolver-->>Parser: return str | list[str] | None
  else custom_base_path present
    Resolver-->>Parser: normalize custom_base_path -> str | list[str] | None
  else fallback base-class
    Resolver-->>Parser: return base_class or None
  end
  Parser->>Model: pass resolved custom_base_class (str | list)
  Model->>Importer: for each base in list -> create Import and BaseClassDataType
  Model-->>Parser: attach base_classes and _additional_imports
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • #2832: Updates the public API signature baseline for base_class_map, matching the same type widening in this PR.
  • #2877: Touches parser configuration and parser initialization surfaces that overlap with ParserConfigDict / parser changes here.
  • #2726: Modifies base-class handling in the parser, related to resolution logic adjusted in this PR.

Suggested labels

breaking-change-analyzed, breaking-change

Suggested reviewers

  • ilovelinux

Poem

🐰 I hopped through configs, lists in paw,

Now mixins join classes—oh what a draw!
From one to many, imports neatly spun,
Multiple bases, all tidy and fun. ✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding support for multiple base classes in base_class_map and customBasePath.
Linked Issues check ✅ Passed The PR comprehensively addresses both linked issues: #1918 (selective base class application via base_class_map) and #2494 (multiple base class support via list values in base_class_map/customBasePath).
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objectives: type broadening for base_class_map/customBasePath to support lists, updated config/parser signatures, test cases, and documentation.
Docstring Coverage ✅ Passed Docstring coverage is 80.77% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent 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 e39ef18 and 43ab40b.

⛔ Files ignored due to path filters (1)
  • docs/llms-full.txt is excluded by none and included by none
📒 Files selected for processing (3)
  • docs/cli-reference/model-customization.md
  • docs/jsonschema.md
  • tests/main/jsonschema/test_main_jsonschema.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/main/jsonschema/test_main_jsonschema.py
🔇 Additional comments (1)
docs/jsonschema.md (1)

127-205: Excellent documentation for customBasePath feature.

The new section provides clear, comprehensive coverage of the customBasePath extension for JSON Schema:

  • Well-structured with separate examples for single and multiple base classes
  • Accurate Python code output demonstrating correct import statements and inheritance syntax
  • Helpful note about mixin behavior and BaseModel requirements (lines 191–193)
  • Clear priority resolution explanation aligning with the broader base-class system

The examples are realistic and demonstrate both common use cases (single inheritance and mixin composition).


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 Jan 4, 2026

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

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Jan 4, 2026

CodSpeed Performance Report

Merging #2916 will not alter performance

Comparing feature/multiple-base-classes (43ab40b) with main (1b931d5)

⚠️ 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 Jan 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (1b931d5) to head (43ab40b).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #2916   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           93        93           
  Lines        16865     16888   +23     
  Branches      1952      1958    +6     
=========================================
+ Hits         16865     16888   +23     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

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 (3)
src/datamodel_code_generator/__main__.py (1)

502-502: Aligns with multi-base support; drop the new # noqa: UP045 to satisfy lint

The widened type Optional[dict[str, str | list[str]]] correctly matches the new multi-base-class semantics used elsewhere. However, Ruff flags the newly added # noqa: UP045 here as an unused directive (RUF100); consider removing it on this line while leaving existing legacy UP045 suppressions unchanged.

tests/main/jsonschema/test_main_jsonschema.py (1)

2988-3000: Clarify “empty list” behavior in docstring

The scenario uses a list of empty strings (["", ""]) to trigger fallback behavior, whereas the docstring says “empty strings list (falls back to default)” and the function name suggests an “empty list”. Consider tightening the wording to something like “list of empty strings” or, if supported, using an actual empty list ([]) in the JSON to better match the name.

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

1041-1050: Consider clarifying the deduplication logic.

The list comprehension on line 1046 uses a side-effect pattern (not seen.add(v)) for deduplication that, while correct, is non-obvious:

result = [v for v in value if isinstance(v, str) and v and v not in seen and not seen.add(v)]

This works because set.add() returns None, making not None evaluate to True. While this is a known Python idiom, it can be confusing to readers.

🔎 Alternative implementation for clarity
         def normalize(value: str | list[str] | None) -> str | list[str] | None:
             if value is None:  # pragma: no cover
                 return None
             if isinstance(value, list):
                 seen: set[str] = set()
-                result = [v for v in value if isinstance(v, str) and v and v not in seen and not seen.add(v)]  # type: ignore[func-returns-value]
+                result: list[str] = []
+                for v in value:
+                    if isinstance(v, str) and v and v not in seen:
+                        seen.add(v)
+                        result.append(v)
                 if not result:
                     return None
                 return result[0] if len(result) == 1 else result
             return value or None
📜 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 1b931d5 and e39ef18.

⛔ Files ignored due to path filters (3)
  • tests/data/jsonschema/base_class_map_empty_list.json is excluded by !tests/data/**/*.json and included by none
  • tests/data/jsonschema/base_class_map_list.json is excluded by !tests/data/**/*.json and included by none
  • tests/data/jsonschema/custom_base_paths_list.json is excluded by !tests/data/**/*.json and included by none
📒 Files selected for processing (22)
  • src/datamodel_code_generator/__main__.py
  • src/datamodel_code_generator/_types/generate_config_dict.py
  • src/datamodel_code_generator/_types/parser_config_dicts.py
  • src/datamodel_code_generator/config.py
  • src/datamodel_code_generator/model/base.py
  • src/datamodel_code_generator/model/dataclass.py
  • src/datamodel_code_generator/model/enum.py
  • src/datamodel_code_generator/model/msgspec.py
  • src/datamodel_code_generator/model/pydantic/base_model.py
  • src/datamodel_code_generator/model/pydantic_v2/base_model.py
  • src/datamodel_code_generator/model/pydantic_v2/dataclass.py
  • src/datamodel_code_generator/model/scalar.py
  • src/datamodel_code_generator/model/typed_dict.py
  • src/datamodel_code_generator/model/union.py
  • src/datamodel_code_generator/parser/base.py
  • src/datamodel_code_generator/parser/jsonschema.py
  • tests/data/expected/main/input_model/config_class.py
  • tests/data/expected/main/jsonschema/base_class_map_empty_list.py
  • tests/data/expected/main/jsonschema/base_class_map_list.py
  • tests/data/expected/main/jsonschema/custom_base_paths_list.py
  • tests/main/jsonschema/test_main_jsonschema.py
  • tests/main/test_public_api_signature_baseline.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-02T08:25:19.839Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2890
File: tests/data/expected/main/jsonschema/ref_nullable_with_constraint.py:14-15
Timestamp: 2026-01-02T08:25:19.839Z
Learning: The datamodel-code-generator currently generates RootModel subclasses with an explicit `root` field annotation (e.g., `class StringType(RootModel[str]): root: str`). This is existing behavior of the code generator and should not be flagged as an issue introduced by new changes.

Applied to files:

  • src/datamodel_code_generator/model/scalar.py
  • src/datamodel_code_generator/__main__.py
  • tests/data/expected/main/jsonschema/base_class_map_empty_list.py
🧬 Code graph analysis (4)
tests/data/expected/main/jsonschema/custom_base_paths_list.py (3)
tests/data/expected/main/jsonschema/base_class_map_empty_list.py (1)
  • User (16-17)
tests/data/expected/main/jsonschema/base_class_map_list.py (1)
  • User (18-19)
src/datamodel_code_generator/model/base.py (1)
  • name (838-840)
src/datamodel_code_generator/model/base.py (2)
src/datamodel_code_generator/imports.py (3)
  • Import (20-38)
  • from_full_path (35-38)
  • append (74-89)
src/datamodel_code_generator/types.py (1)
  • from_import (496-520)
tests/data/expected/main/jsonschema/base_class_map_list.py (2)
tests/data/expected/main/jsonschema/base_class_map_empty_list.py (2)
  • Model (12-13)
  • User (16-17)
tests/data/expected/main/jsonschema/custom_base_paths_list.py (1)
  • User (10-12)
tests/data/expected/main/jsonschema/base_class_map_empty_list.py (1)
tests/data/expected/main/jsonschema/base_class_map_list.py (2)
  • Model (14-15)
  • User (18-19)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/__main__.py

502-502: Unused noqa directive (non-enabled: UP045)

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). (19)
  • GitHub Check: py312-black24 on Ubuntu
  • GitHub Check: py312-isort6 on Ubuntu
  • GitHub Check: 3.10 on Windows
  • GitHub Check: py312-isort7 on Ubuntu
  • GitHub Check: 3.11 on Windows
  • GitHub Check: py312-pydantic1 on Ubuntu
  • GitHub Check: 3.13 on Windows
  • GitHub Check: 3.14 on Windows
  • GitHub Check: 3.10 on macOS
  • GitHub Check: py312-isort5 on Ubuntu
  • GitHub Check: py312-black23 on Ubuntu
  • GitHub Check: py312-black22 on Ubuntu
  • GitHub Check: 3.13 on Ubuntu
  • GitHub Check: 3.11 on macOS
  • GitHub Check: 3.11 on Ubuntu
  • GitHub Check: 3.12 on Windows
  • GitHub Check: 3.10 on Ubuntu
  • GitHub Check: benchmarks
  • GitHub Check: Analyze (python)
🔇 Additional comments (25)
src/datamodel_code_generator/model/msgspec.py (1)

135-162: LGTM! Consistent type widening for multiple base class support.

The parameter type has been appropriately widened to str | list[str] | None and passed through to the parent class, consistent with the broader pattern across model constructors.

src/datamodel_code_generator/model/pydantic/base_model.py (2)

289-317: LGTM! BaseModelBase type widening aligns with model base classes.

The custom_base_class parameter type has been correctly widened to support multiple base classes.


346-371: LGTM! BaseModel type widening aligns with parent class.

The custom_base_class parameter type has been correctly widened and passed through to BaseModelBase.__init__().

src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)

248-273: LGTM! Pydantic v2 BaseModel type widening aligns with v1.

The custom_base_class parameter type has been correctly widened to support multiple base classes, consistent with the Pydantic v1 implementation.

src/datamodel_code_generator/model/pydantic_v2/dataclass.py (1)

46-76: LGTM! DataClass type widening completes the consistent pattern.

The custom_base_class parameter type has been correctly widened to str | list[str] | None, completing the consistent update across all model constructors.

src/datamodel_code_generator/model/typed_dict.py (1)

63-90: The parent DataModel class properly handles the str | list[str] type for custom_base_class through the set_base_class() method, which uses isinstance() checks to normalize both single strings and lists of base class names into the internal base_class_list. TypedDict correctly delegates to this parent implementation without requiring any additional handling.

src/datamodel_code_generator/model/enum.py (1)

54-54: Type widening aligns with parent DataModel.

The custom_base_class parameter type has been correctly widened to support multiple base classes. This change is consistent with the broader PR objective and relies on the parent DataModel class to handle list values appropriately.

tests/data/expected/main/input_model/config_class.py (1)

125-125: Expected test output correctly reflects the type widening.

This generated test expectation file properly reflects the broadened base_class_map type to support multiple base classes via str | list[str].

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

49-49: Type change consistent with GenerateConfigDict.

The base_class_map type widening in ParserConfigDict aligns with the corresponding change in GenerateConfigDict. The parser implementation must handle both string and list values appropriately.

Verification of the parser's base_class_map handling logic has already been requested for the GenerateConfigDict file. The same verification applies here to ensure the parser correctly processes both single and multiple base class specifications.

src/datamodel_code_generator/model/dataclass.py (1)

61-61: No action needed—parent DataModel class properly handles list[str] for custom_base_class.

The parent DataModel class in src/datamodel_code_generator/model/base.py already accepts str | list[str] | None at line 646 and correctly implements support for multiple base classes. The set_base_class() method (lines 787–790) explicitly handles both string and list cases: lists are used directly, and strings are wrapped in a list before being assigned to base_classes.

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

49-49: Implementation already properly handles base_class_map resolution for strings, lists, and edge cases.

The _resolve_base_class() method in src/datamodel_code_generator/parser/base.py (lines 1036-1056) includes comprehensive logic via its normalize() helper function that:

  • Handles both single strings and lists of strings correctly
  • Treats empty lists as no base class (filters empty strings and returns None if all items are removed)
  • Maintains proper inheritance order (single-item lists collapse to strings, multi-item lists remain as lists)

Resolution priority is documented: base_class_map > customBasePath > base_class.

tests/data/expected/main/jsonschema/custom_base_paths_list.py (1)

1-12: Fixture correctly exercises list-valued customBasePath

User(AuditMixin, TimestampMixin) cleanly reflects a schema with customBasePath as a list; fields and imports look consistent with the rest of the expected outputs.

src/datamodel_code_generator/config.py (1)

86-86: Config base_class_map types now consistently support multiple bases

Using dict[str, str | list[str]] | None for both GenerateConfig.base_class_map and ParserConfig.base_class_map keeps the public config models aligned with the new multi-inheritance behavior and matches how aliases already allow str | list[str] values.

Also applies to: 228-228

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

364-364: JsonSchemaObject.custom_base_path correctly widened for multiple custom bases

Allowing custom_base_path: str | list[str] | None matches how this field is only forwarded into _resolve_base_class, and enables customBasePath to be a list in schemas while remaining backward compatible with string values.

tests/data/expected/main/jsonschema/base_class_map_list.py (1)

1-23: Expected output for list-valued base_class_map is consistent

The generated Model, User(AuditMixin, TimestampMixin), and Admin(AdminBase) classes align with a base_class_map that assigns multiple bases to User, a single custom base to Admin, and leaves the root Model on BaseModel. This fixture looks correct and self-consistent.

tests/data/expected/main/jsonschema/base_class_map_empty_list.py (1)

1-17: LGTM! Test fixture correctly demonstrates empty list behavior.

This test fixture appropriately shows that when base_class_map contains an empty list for the User model, it inherits only from the default BaseModel without additional mixins. This contrasts correctly with base_class_map_list.py where User inherits from multiple base classes.

src/datamodel_code_generator/model/scalar.py (1)

51-51: Type broadening is consistent with union model changes.

The custom_base_class parameter type widening to str | list[str] | None mirrors the identical change in union.py and enables scalar type models to inherit from multiple custom base classes. The parameter is correctly passed through to the parent DataModel class.

tests/main/test_public_api_signature_baseline.py (1)

68-68: Type signature updates are correct and properly implemented for multiple base class support.

The baseline signatures at lines 68 and 204 correctly match the actual implementation in config.py and base.py. The widening of base_class_map from dict[str, str] to dict[str, str | list[str]] is backward-compatible and fully supported by the _resolve_base_class() method, which properly:

  • Normalizes both str and list[str] values
  • Deduplicates entries in lists and removes empty strings
  • Applies priority: base_class_map > custom_base_path > base_class
  • Returns a single string if a list contains only one element, otherwise returns the list
src/datamodel_code_generator/model/union.py (1)

36-36: Parent signature already supports list[str] - implementation properly handles both str and list[str] for custom base classes.

The custom_base_class parameter signature matches the parent DataModel class, which already supports str | list[str] | None. The set_base_class() method correctly handles both forms: wrapping a single string in a list, and passing through an existing list directly. Both are converted to BaseClassDataType objects for template rendering.

tests/main/jsonschema/test_main_jsonschema.py (2)

2962-2970: Good coverage for customBasePath list semantics

This mirrors the existing single-base custom_base_path test and cleanly covers the list variant using fixtures, consistent with the rest of the suite.


2973-2985: Solid regression test for list-valued base_class_map

This test exercises mixed usage (list for User, string for Admin) via --base-class-map, which is exactly what’s needed to validate multiple inheritance support and backward compatibility.

src/datamodel_code_generator/model/base.py (2)

646-646: LGTM: Type annotation updated to support multiple base classes.

The signature change to accept str | list[str] | None properly enables the multiple inheritance feature requested in issues #1918 and #2494.


783-801: LGTM: Clean refactor to support multiple base classes.

The logic correctly handles all three input forms (None, string, list) and properly creates imports and base class data types for each. The early return on empty list is a good optimization.

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

783-783: LGTM: Type annotation updated for base_class_map.

The type change to dict[str, str | list[str]] | None aligns with the broader PR objective to support multiple base classes per model in the mapping.


1052-1056: LGTM: Resolution priority is clear and correctly implemented.

The priority order (base_class_map > custom_base_path > base_class) aligns with the docstring and provides proper fallback behavior. The normalization is consistently applied to inputs that may be lists.

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)
docs/cli-reference/model-customization.md (1)

1123-1187: Missing expected output in --base-class-map example section.

The examples section (lines 1153-1186) provides an Input Schema but shows an error message instead of actual generated code. Line 1185 displays > **Error:** File not found: base_class_map.py where the Python output should be.

Provide the expected generated code output demonstrating how multiple and/or single base classes are applied to the Person, Animal, and Car models based on the --base-class-map configuration.

🔎 Expected fix: Add proper example output

Replace lines 1183-1186 with actual generated Python code showing the three models (Person, Animal, Car) inheriting from their specified base classes. For example:

# generated by datamodel-codegen:
#   filename:  schema.json
#   timestamp: 2019-07-26T00:00:00+00:00

from __future__ import annotations

from custom.bases import PersonBase, AnimalBase
from pydantic import BaseModel


class Person(PersonBase):
    name: str


class Animal(AnimalBase):
    species: str


class Car(BaseModel):
    model: str

Alternatively, if the intent is to show multiple base classes in the output, adjust both the command and example accordingly to demonstrate that feature.

📜 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 e39ef18 and 43ab40b.

⛔ Files ignored due to path filters (1)
  • docs/llms-full.txt is excluded by none and included by none
📒 Files selected for processing (3)
  • docs/cli-reference/model-customization.md
  • docs/jsonschema.md
  • tests/main/jsonschema/test_main_jsonschema.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/main/jsonschema/test_main_jsonschema.py
🔇 Additional comments (1)
docs/jsonschema.md (1)

127-205: Excellent documentation for customBasePath feature.

The new section provides clear, comprehensive coverage of the customBasePath extension for JSON Schema:

  • Well-structured with separate examples for single and multiple base classes
  • Accurate Python code output demonstrating correct import statements and inheritance syntax
  • Helpful note about mixin behavior and BaseModel requirements (lines 191–193)
  • Clear priority resolution explanation aligning with the broader base-class system

The examples are realistic and demonstrate both common use cases (single inheritance and mixin composition).

@koxudaxi koxudaxi merged commit 960f7f9 into main Jan 4, 2026
40 checks passed
@koxudaxi koxudaxi deleted the feature/multiple-base-classes branch January 4, 2026 05:50
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 4, 2026

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: This PR is backwards compatible. The changes extend existing functionality without breaking existing usage:

  1. Type signature changes are additive: The base_class_map parameter type changed from dict[str, str] to dict[str, str | list[str]]. Existing code passing dict[str, str] will continue to work since str is still accepted.

  2. custom_base_class parameter expanded: Changed from str | None to str | list[str] | None. Existing code passing a single string will work as before.

  3. customBasePath schema extension expanded: Now accepts either a string or list of strings. Existing schemas using a single string value are unaffected.

  4. Default behavior unchanged: When not using the new list feature, the code generates identical output. The empty list edge case falls back to the default BaseModel, maintaining expected behavior.

  5. No template changes: Jinja2 templates are unchanged, so custom templates don't need updates.

  6. CLI interface unchanged: The --base-class-map option continues to accept JSON, and the expanded type naturally supports both formats.

  7. Python version unchanged: No changes to supported Python versions.

All existing configurations, API calls, and CLI usage patterns will produce the same output as before. The new list syntax is purely additive functionality.


This analysis was performed by Claude Code Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jan 5, 2026

🎉 Released in 0.52.2

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.

Support inheritance of multiple custom models Base class for main object, not for properties

1 participant