Skip to content

Strip Field None defaults with metadata#3476

Merged
koxudaxi merged 1 commit into
mainfrom
fix/strip-default-none-field
Jun 23, 2026
Merged

Strip Field None defaults with metadata#3476
koxudaxi merged 1 commit into
mainfrom
fix/strip-default-none-field

Conversation

@koxudaxi

@koxudaxi koxudaxi commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Fixes: #1816

Summary by CodeRabbit

  • Bug Fixes

    • Improved --strip-default-none behavior for Pydantic v1/v2 generation by omitting Field(None, ...) defaults only when the default is an actual None and the field type is not optional, resulting in more accurate required/default semantics in generated OpenAPI/Pydantic code.
  • Tests

    • Added a regression test covering Pydantic v2 stripping behavior and updated OpenAPI/Pydantic expected outputs to match the revised Field(...) declarations.

@coderabbitai

coderabbitai Bot commented Jun 22, 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

DataModelField in pydantic_base.py gains a _should_strip_default_none_from_field helper that returns True when strip_default_none is set, the rendered default is "None", and the field type is not optional. __str__ now uses this helper to conditionally omit the None positional argument from Field(...) output. Related expected output fixtures are updated and a new Pydantic v2 test case is added.

Changes

strip_default_none Field rendering fix

Layer / File(s) Summary
DataModelField helper and __str__ wiring
src/datamodel_code_generator/model/pydantic_base.py
Adds _should_strip_default_none_from_field(default_repr) that returns True when strip_default_none is enabled, default_repr == "None", and the field type is not optional. __str__ now conditionally omits the None default from field_arguments based on this helper.
Updated and new expected output fixtures
tests/data/expected/main/jsonschema/root_in_enum.py, tests/data/expected/main/openapi/pyproject.py, tests/data/expected/main/openapi/with_strip_default_none.py, tests/data/expected/main/openapi/strip_default_none_pydantic_v2.py
Removes explicit None defaults from Field(...) in root_in_enum, with_strip_default_none, and pyproject fixtures. Adds strip_default_none_pydantic_v2.py defining Issue1816Model with metadata-only, explicit non-None default, and plain optional fields.
New Pydantic v2 strip_default_none test
tests/main/openapi/test_main_openapi.py
Adds test_main_openapi_pydantic_v2_strip_default_none_field_metadata that generates from strip_default_none_pydantic_v2.yaml with --output-model-type pydantic_v2.BaseModel and asserts output matches the new fixture.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

safe-to-fix

Suggested reviewers

  • ilovelinux

Poem

🐇 Hop hop, no more None where it shouldn't be,
The field strips its default and runs free!
Optional stays optional, required stays true,
A helper decides what the Field args should do.
Fixtures updated, tests pass with a cheer —
The rabbit approves: the schema is clear! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% 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.
Title check ✅ Passed The title 'Strip Field None defaults with metadata' directly describes the main change: removing None defaults from Field definitions that contain metadata, which is the core fix for issue #1816.
Linked Issues check ✅ Passed The PR successfully addresses issue #1816 by implementing the strip-default-none functionality for fields with metadata. The changes demonstrate removal of Field(None, ...) defaults across multiple test files while preserving optional type annotations.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the strip-default-none feature for fields with metadata. The modifications to the core logic, test fixtures, and test cases are all aligned with the stated objective.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/strip-default-none-field

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.

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

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

Comment thread src/datamodel_code_generator/model/pydantic_base.py Fixed
@codspeed-hq

codspeed-hq Bot commented Jun 22, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 11.53%

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

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 10 untouched benchmarks
⏩ 98 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime test_perf_stripe_style_pydantic_v2 1.8 s 1.6 s +11.53%

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 fix/strip-default-none-field (347f6f1) with main (48335d0)

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 koxudaxi force-pushed the fix/strip-default-none-field branch 3 times, most recently from c944dc0 to 7c514cf Compare June 22, 2026 15:45
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

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

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #3476   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          151       151           
  Lines        32484     32494   +10     
  Branches      3780      3783    +3     
=========================================
+ Hits         32484     32494   +10     
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.

@koxudaxi koxudaxi force-pushed the fix/strip-default-none-field branch from 7c514cf to 9541ed5 Compare June 22, 2026 15:52
@koxudaxi koxudaxi force-pushed the fix/strip-default-none-field branch from 9541ed5 to 347f6f1 Compare June 23, 2026 00:32
@koxudaxi koxudaxi merged commit 9745f5b into main Jun 23, 2026
63 checks passed
@koxudaxi koxudaxi deleted the fix/strip-default-none-field branch June 23, 2026 00:46
@github-actions

Copy link
Copy Markdown
Contributor

🎉 Released in 0.65.1

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Strip default None from model fields when converting from yaml swagger to pydantic model

2 participants