Visitar URL original
Fix nullable JSON Schema const enums by koxudaxi · Pull Request #3355 · datamodel-code-generator/datamodel-code-generator · GitHub
Skip to content

Fix nullable JSON Schema const enums - #3355

Merged
Koudai Aono (koxudaxi) merged 9 commits into
mainfrom
refactor/jsonschema-method-extraction
Jun 13, 2026
Merged

Koudai Aono (koxudaxi) merged 9 commits into
mainfrom
refactor/jsonschema-method-extraction

Conversation

@koxudaxi

@koxudaxi Koudai Aono (koxudaxi) commented Jun 12, 2026 •

Copy link
Copy Markdown
Member

No description provided.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Refactors JSONSchemaParser internals: extracts combined anyOf/oneOf const-enum detection, centralizes root combined-type handling with early-empty detection, and decomposes enum generation into helpers for member extraction, field building, enum creation, and nullable-root registration.

Changes

Enum & Root Handling

Layer / File(s) Summary
Combined const-pattern enum detection
src/datamodel_code_generator/parser/jsonschema.py
Adds _parse_combined_const_enum to extract const-backed enums from anyOf/oneOf and route to literal or regular enum generation.
parse_item anyOf/oneOf hook
src/datamodel_code_generator/parser/jsonschema.py
Updates parse_item to call the combined-const detector and return the combined-const enum DataType when applicable.
Root combined-type handling
src/datamodel_code_generator/parser/jsonschema.py
Adds _parse_root_combined_type and updates parse_root_type to create a Reference for combined roots and choose the resulting DataType, including early EmptyDataType return.
Enum member extraction & nullable detection
src/datamodel_code_generator/parser/jsonschema.py
Adds _get_enum_members_and_nullable to separate member extraction and nullable handling.
Enum fields construction & empty-enum handling
src/datamodel_code_generator/parser/jsonschema.py
Adds _build_enum_fields and _parse_empty_enum to construct enum fields and handle empty/nullable-only enum roots.
Enum DataType creation & pipeline
src/datamodel_code_generator/parser/jsonschema.py
Adds _create_enum_data_type, _register_nullable_enum_root_model, and rewrites parse_enum to use the new helper pipeline end-to-end while preserving its public signature.
Tests and expected output
tests/data/expected/main/jsonschema/oneof_const_enum_int_nullable.py, tests/main/jsonschema/test_main_jsonschema.py, tests/parser/test_jsonschema.py
Adds expected generated enum + nullable RootModel, new generator test for oneOf+const nullable int enum, and replaces an x-python-import metadata unit test with a broader empty/incomplete metadata test.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

breaking-change-analyzed

Poem

🐰 I hop through schemas, tidy each rule,
I gather const branches into one neat pool,
Roots gain References, enums find their name,
Nullable wrappers registered without fame,
A small carrot of tests to prove my claim.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title 'Fix nullable JSON Schema const enums' directly describes the main change: fixing handling of nullable const enums in JSON Schema parsing, which is reflected across the parser refactoring, new test file, and test additions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/jsonschema-method-extraction

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

github-actions Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

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

@codspeed

codspeed Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 29.29%

⚠️ 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.

⚡ 11 improved benchmarks
⏩ 98 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ WallTime test_perf_multiple_files_input 3.4 s 2.6 s +31.62%
⚡ WallTime test_perf_duplicate_names 995.1 ms 762.5 ms +30.49%
⚡ WallTime test_perf_kubernetes_style_pydantic_v2 2.5 s 1.9 s +30.28%
⚡ WallTime test_perf_complex_refs 1.8 s 1.4 s +29.92%
⚡ WallTime test_perf_openapi_large 2.7 s 2.1 s +29.89%
⚡ WallTime test_perf_stripe_style_pydantic_v2 1.9 s 1.5 s +29.34%
⚡ WallTime test_perf_aws_style_openapi_pydantic_v2 1.7 s 1.3 s +29.1%
⚡ WallTime test_perf_graphql_style_pydantic_v2 740 ms 575 ms +28.69%
⚡ WallTime test_perf_deep_nested 4.7 s 3.7 s +28.64%
⚡ WallTime test_perf_all_options_enabled 5 s 3.9 s +28.23%
⚡ WallTime test_perf_large_models_pydantic_v2 3.3 s 2.6 s +26.12%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing refactor/jsonschema-method-extraction (1d73747) with main (6192212)

Open in CodSpeed

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. ↩

@koxudaxi
Koudai Aono (koxudaxi) force-pushed the refactor/jsonschema-method-extraction branch 2 times, most recently from 56a6e91 to c0c289a Compare June 12, 2026 12:35
@koxudaxi
Koudai Aono (koxudaxi) force-pushed the refactor/jsonschema-method-extraction branch from c0c289a to 5621972 Compare June 12, 2026 12:46

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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

4141-4150: ⚡ Quick win

Deduplicate combined const-enum handling in parse_item.

anyOf and oneOf currently duplicate the same const-enum extraction/build/dispatch flow even though _parse_combined_const_enum already encapsulates it. Reusing the helper here avoids drift between inline-item and root-level combined parsing paths.

♻️ Suggested refactor
         if item.anyOf:
-            const_enum_data = self._extract_const_enum_from_combined(item.anyOf, item.type)
-            if const_enum_data is not None:
-                enum_values, varnames, descriptions, enum_type, nullable = const_enum_data
-                synthetic_obj = self._create_synthetic_enum_obj(
-                    item, enum_values, varnames, descriptions, enum_type, nullable
-                )
-                if self.should_parse_enum_as_literal(synthetic_obj, property_name=name, property_obj=item):
-                    return self.parse_enum_as_literal(synthetic_obj)
-                return self.parse_enum(name, synthetic_obj, get_special_path("enum", path), singular_name=singular_name)
+            if combined_const_enum := self._parse_combined_const_enum(
+                name,
+                item,
+                item.anyOf,
+                get_special_path("enum", path),
+                singular_name=singular_name,
+            ):
+                return combined_const_enum
             return self.data_type(data_types=self.parse_any_of(name, item, get_special_path("anyOf", path)))
         if item.oneOf:
-            const_enum_data = self._extract_const_enum_from_combined(item.oneOf, item.type)
-            if const_enum_data is not None:
-                enum_values, varnames, descriptions, enum_type, nullable = const_enum_data
-                synthetic_obj = self._create_synthetic_enum_obj(
-                    item, enum_values, varnames, descriptions, enum_type, nullable
-                )
-                if self.should_parse_enum_as_literal(synthetic_obj, property_name=name, property_obj=item):
-                    return self.parse_enum_as_literal(synthetic_obj)
-                return self.parse_enum(name, synthetic_obj, get_special_path("enum", path), singular_name=singular_name)
+            if combined_const_enum := self._parse_combined_const_enum(
+                name,
+                item,
+                item.oneOf,
+                get_special_path("enum", path),
+                singular_name=singular_name,
+            ):
+                return combined_const_enum
             return self.data_type(data_types=self.parse_one_of(name, item, get_special_path("oneOf", path)))

Also applies to: 4152-4161

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/datamodel_code_generator/parser/jsonschema.py` around lines 4141 - 4150,
Replace the duplicated const-enum extraction/dispatch logic in the anyOf/oneOf
branches by calling the existing helper _parse_combined_const_enum and returning
its result when present; specifically, instead of re-running
_extract_const_enum_from_combined / _create_synthetic_enum_obj and then calling
should_parse_enum_as_literal / parse_enum_as_literal / parse_enum, invoke
self._parse_combined_const_enum(...) with the same inputs (item.anyOf or
item.oneOf, item.type, name, item, path, singular_name as needed) and if it
returns a non-None value return that, otherwise fall back to the existing
data_type(...) with self.parse_any_of(...) (or self.parse_one_of(...)) so you
remove duplicated logic around _extract_const_enum_from_combined,
_create_synthetic_enum_obj, should_parse_enum_as_literal, parse_enum_as_literal,
and parse_enum.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/datamodel_code_generator/parser/jsonschema.py`:
- Around line 4613-4624: When building enum member names in the block inside
parser/jsonschema.py (the branch that sets default and field_name when obj.type
!= "string"), handle enum_part == None specially: if enum_part is None set
default = None (a real Python None) and set field_name to a stable "null" token
(e.g. f"{prefix}_null" or just "null") instead of using Python's "None" repr;
update the branch that currently computes field_name (the else branch that calls
_get_field_name_from_dict_enum and uses prefix = obj.type ...) so it checks "if
enum_part is None" first and returns a "null"-based name and None default to
ensure nullable non-string const-enums are represented as optional values rather
than creating members like integer_None.

---

Nitpick comments:
In `@src/datamodel_code_generator/parser/jsonschema.py`:
- Around line 4141-4150: Replace the duplicated const-enum extraction/dispatch
logic in the anyOf/oneOf branches by calling the existing helper
_parse_combined_const_enum and returning its result when present; specifically,
instead of re-running _extract_const_enum_from_combined /
_create_synthetic_enum_obj and then calling should_parse_enum_as_literal /
parse_enum_as_literal / parse_enum, invoke self._parse_combined_const_enum(...)
with the same inputs (item.anyOf or item.oneOf, item.type, name, item, path,
singular_name as needed) and if it returns a non-None value return that,
otherwise fall back to the existing data_type(...) with self.parse_any_of(...)
(or self.parse_one_of(...)) so you remove duplicated logic around
_extract_const_enum_from_combined, _create_synthetic_enum_obj,
should_parse_enum_as_literal, parse_enum_as_literal, and parse_enum.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 46d744de-2729-4581-80c9-1669d7fee1e2

📥 Commits

Reviewing files that changed from the base of the PR and between c0c289a and 5621972.

📒 Files selected for processing (1)
  • src/datamodel_code_generator/parser/jsonschema.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

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

4141-4150: ⚡ Quick win

Deduplicate combined const-enum handling in parse_item.

anyOf and oneOf currently duplicate the same const-enum extraction/build/dispatch flow even though _parse_combined_const_enum already encapsulates it. Reusing the helper here avoids drift between inline-item and root-level combined parsing paths.

♻️ Suggested refactor
         if item.anyOf:
-            const_enum_data = self._extract_const_enum_from_combined(item.anyOf, item.type)
-            if const_enum_data is not None:
-                enum_values, varnames, descriptions, enum_type, nullable = const_enum_data
-                synthetic_obj = self._create_synthetic_enum_obj(
-                    item, enum_values, varnames, descriptions, enum_type, nullable
-                )
-                if self.should_parse_enum_as_literal(synthetic_obj, property_name=name, property_obj=item):
-                    return self.parse_enum_as_literal(synthetic_obj)
-                return self.parse_enum(name, synthetic_obj, get_special_path("enum", path), singular_name=singular_name)
+            if combined_const_enum := self._parse_combined_const_enum(
+                name,
+                item,
+                item.anyOf,
+                get_special_path("enum", path),
+                singular_name=singular_name,
+            ):
+                return combined_const_enum
             return self.data_type(data_types=self.parse_any_of(name, item, get_special_path("anyOf", path)))
         if item.oneOf:
-            const_enum_data = self._extract_const_enum_from_combined(item.oneOf, item.type)
-            if const_enum_data is not None:
-                enum_values, varnames, descriptions, enum_type, nullable = const_enum_data
-                synthetic_obj = self._create_synthetic_enum_obj(
-                    item, enum_values, varnames, descriptions, enum_type, nullable
-                )
-                if self.should_parse_enum_as_literal(synthetic_obj, property_name=name, property_obj=item):
-                    return self.parse_enum_as_literal(synthetic_obj)
-                return self.parse_enum(name, synthetic_obj, get_special_path("enum", path), singular_name=singular_name)
+            if combined_const_enum := self._parse_combined_const_enum(
+                name,
+                item,
+                item.oneOf,
+                get_special_path("enum", path),
+                singular_name=singular_name,
+            ):
+                return combined_const_enum
             return self.data_type(data_types=self.parse_one_of(name, item, get_special_path("oneOf", path)))

Also applies to: 4152-4161

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/datamodel_code_generator/parser/jsonschema.py` around lines 4141 - 4150,
Replace the duplicated const-enum extraction/dispatch logic in the anyOf/oneOf
branches by calling the existing helper _parse_combined_const_enum and returning
its result when present; specifically, instead of re-running
_extract_const_enum_from_combined / _create_synthetic_enum_obj and then calling
should_parse_enum_as_literal / parse_enum_as_literal / parse_enum, invoke
self._parse_combined_const_enum(...) with the same inputs (item.anyOf or
item.oneOf, item.type, name, item, path, singular_name as needed) and if it
returns a non-None value return that, otherwise fall back to the existing
data_type(...) with self.parse_any_of(...) (or self.parse_one_of(...)) so you
remove duplicated logic around _extract_const_enum_from_combined,
_create_synthetic_enum_obj, should_parse_enum_as_literal, parse_enum_as_literal,
and parse_enum.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/datamodel_code_generator/parser/jsonschema.py`:
- Around line 4613-4624: When building enum member names in the block inside
parser/jsonschema.py (the branch that sets default and field_name when obj.type
!= "string"), handle enum_part == None specially: if enum_part is None set
default = None (a real Python None) and set field_name to a stable "null" token
(e.g. f"{prefix}_null" or just "null") instead of using Python's "None" repr;
update the branch that currently computes field_name (the else branch that calls
_get_field_name_from_dict_enum and uses prefix = obj.type ...) so it checks "if
enum_part is None" first and returns a "null"-based name and None default to
ensure nullable non-string const-enums are represented as optional values rather
than creating members like integer_None.

---

Nitpick comments:
In `@src/datamodel_code_generator/parser/jsonschema.py`:
- Around line 4141-4150: Replace the duplicated const-enum extraction/dispatch
logic in the anyOf/oneOf branches by calling the existing helper
_parse_combined_const_enum and returning its result when present; specifically,
instead of re-running _extract_const_enum_from_combined /
_create_synthetic_enum_obj and then calling should_parse_enum_as_literal /
parse_enum_as_literal / parse_enum, invoke self._parse_combined_const_enum(...)
with the same inputs (item.anyOf or item.oneOf, item.type, name, item, path,
singular_name as needed) and if it returns a non-None value return that,
otherwise fall back to the existing data_type(...) with self.parse_any_of(...)
(or self.parse_one_of(...)) so you remove duplicated logic around
_extract_const_enum_from_combined, _create_synthetic_enum_obj,
should_parse_enum_as_literal, parse_enum_as_literal, and parse_enum.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 46d744de-2729-4581-80c9-1669d7fee1e2

📥 Commits

Reviewing files that changed from the base of the PR and between c0c289a and 5621972.

📒 Files selected for processing (1)
  • src/datamodel_code_generator/parser/jsonschema.py
🛑 Comments failed to post (1)
src/datamodel_code_generator/parser/jsonschema.py (1)

4613-4624: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Nullable non-string const-enums can be emitted with a real None enum member.

When combined const-enum extraction includes a nullable branch, non-string enums can flow here with None still present, producing members like integer_None instead of optional enum behavior. This conflicts with the nullable const-enum contract validated by tests/main/jsonschema/test_main_jsonschema.py and tests/data/expected/main/jsonschema/oneof_const_enum_nullable.py.

🐛 Suggested fix
 def _get_enum_members_and_nullable(self, obj: JsonSchemaObject) -> tuple[list[Any], bool]:  # noqa: PLR6301
-    if None in obj.enum and obj.type == "string":
-        # Nullable is valid in only OpenAPI
+    if None in obj.enum:
+        # Treat `None` as nullable enum branch regardless of primitive subtype.
         return [e for e in obj.enum if e is not None], True
     return obj.enum, False
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/datamodel_code_generator/parser/jsonschema.py` around lines 4613 - 4624,
When building enum member names in the block inside parser/jsonschema.py (the
branch that sets default and field_name when obj.type != "string"), handle
enum_part == None specially: if enum_part is None set default = None (a real
Python None) and set field_name to a stable "null" token (e.g. f"{prefix}_null"
or just "null") instead of using Python's "None" repr; update the branch that
currently computes field_name (the else branch that calls
_get_field_name_from_dict_enum and uses prefix = obj.type ...) so it checks "if
enum_part is None" first and returns a "null"-based name and None default to
ensure nullable non-string const-enums are represented as optional values rather
than creating members like integer_None.

@codecov

codecov Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

Codecov Report

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

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #3355   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          129       129           
  Lines        28549     28554    +5     
  Branches      3448      3449    +1     
=========================================
+ Hits         28549     28554    +5     
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 Harness.
📢 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/parser/test_jsonschema.py (1)

68-74: ⚡ Quick win

Consider testing the symmetric incomplete case and the success path.

The test covers empty metadata and one incomplete case (module without name), but the test name suggests comprehensive coverage. Consider adding:

  1. The symmetric incomplete case: {"name": "Status"} without module should also raise the same error.
  2. The success path: Both module and name provided should return a validated path string.
🧪 Suggested additional test cases
 def test_get_x_python_import_path_handles_empty_and_incomplete_metadata() -> None:
     """Test x-python-import accepts an empty object but rejects partial metadata."""
     parser = JsonSchemaParser("")
 
     assert parser._get_x_python_import_path({}) is None
     with pytest.raises(Error, match="x-python-import requires both module and name"):
         parser._get_x_python_import_path({"module": "os"})
+    with pytest.raises(Error, match="x-python-import requires both module and name"):
+        parser._get_x_python_import_path({"name": "Status"})
+    
+    # Success path: both module and name provided
+    result = parser._get_x_python_import_path({"module": "myapp.enums", "name": "Status"})
+    assert result == "myapp.enums.Status"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/parser/test_jsonschema.py` around lines 68 - 74, Update the
test_get_x_python_import_path_handles_empty_and_incomplete_metadata test to also
assert that the symmetric incomplete case (calling
JsonSchemaParser._get_x_python_import_path with {"name": "Status"}) raises the
same Error with message "x-python-import requires both module and name", and add
a success assertion that providing both keys (e.g. {"module": "os", "name":
"Path"}) returns the expected import path string (call the same
parser._get_x_python_import_path and assert the returned value equals the
validated path you expect). Ensure you reference the existing test function name
and the JsonSchemaParser._get_x_python_import_path method when adding these
assertions so they sit in the same test and cover empty, both incomplete
permutations, and the valid case.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/parser/test_jsonschema.py`:
- Around line 68-74: Update the
test_get_x_python_import_path_handles_empty_and_incomplete_metadata test to also
assert that the symmetric incomplete case (calling
JsonSchemaParser._get_x_python_import_path with {"name": "Status"}) raises the
same Error with message "x-python-import requires both module and name", and add
a success assertion that providing both keys (e.g. {"module": "os", "name":
"Path"}) returns the expected import path string (call the same
parser._get_x_python_import_path and assert the returned value equals the
validated path you expect). Ensure you reference the existing test function name
and the JsonSchemaParser._get_x_python_import_path method when adding these
assertions so they sit in the same test and cover empty, both incomplete
permutations, and the valid case.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2ef8f157-eaff-4550-8198-328dac237296

📥 Commits

Reviewing files that changed from the base of the PR and between 5621972 and a85dfe8.

⛔ Files ignored due to path filters (1)
  • tests/data/jsonschema/oneof_const_enum_int_nullable.yaml is excluded by !tests/data/**/*.yaml and included by none
📒 Files selected for processing (4)
  • src/datamodel_code_generator/parser/jsonschema.py
  • tests/data/expected/main/jsonschema/oneof_const_enum_int_nullable.py
  • tests/main/jsonschema/test_main_jsonschema.py
  • tests/parser/test_jsonschema.py
✅ Files skipped from review due to trivial changes (1)
  • tests/data/expected/main/jsonschema/oneof_const_enum_int_nullable.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/datamodel_code_generator/parser/jsonschema.py

@koxudaxi Koudai Aono (koxudaxi) changed the title Refactor JSON Schema parser method bodies Deduplicate JSON Schema const enum parsing Jun 12, 2026
@koxudaxi Koudai Aono (koxudaxi) changed the title Deduplicate JSON Schema const enum parsing Fix nullable JSON Schema const enums Jun 12, 2026
@koxudaxi
Koudai Aono (koxudaxi) enabled auto-merge (squash) June 12, 2026 14:11
@koxudaxi
Koudai Aono (koxudaxi) merged commit f553197 into main Jun 13, 2026
83 of 120 checks passed
@koxudaxi
Koudai Aono (koxudaxi) deleted the refactor/jsonschema-method-extraction branch June 13, 2026 03:46
@github-actions

Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: NOTE: The prepared diff/context/deleted-lines files under /home/runner/work/_temp/release-draft-pr/ were inaccessible in this session — every access route (Read tool permission, Bash cat/cp/ls/python, and the gh PR-diff fallback) was blocked by the sandbox/permission layer, and the repo is a single root commit with no parent, so no git-derived diff was possible. Determination is therefore based on the merged commit metadata for PR #3355 rather than the line-level diff. The PR is titled "Fix nullable JSON Schema const enums" with squashed subcommits describing internal JSON Schema parser refactoring ("method bodies", "footprint", "method extraction edges", "x-python-import metadata paths") and "Scope nullable enum handling to combined schemas." This is a bug fix correcting generated output for a narrow edge case (nullable const enums in combined schemas) plus internal refactoring. No evidence of removed CLI options, removed/renamed public Python API symbols, Jinja2 template contract changes, dropped Python versions, or a default-behavior flip affecting previously-correct output. Such edge-case output fixes are recorded as fixes, not breaking changes, under this project's CHANGELOG conventions. Caveat: because line-level removals could not be inspected, a breaking change cannot be ruled out with full certainty, but no available evidence indicates one.


This analysis was performed by Claude Code Action

@github-actions

Copy link
Copy Markdown
Contributor

🎉 Released in 0.64.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.

1 participant