Skip to content

Fix pydantic constraint rendering#3289

Merged
koxudaxi merged 17 commits into
mainfrom
fix-pydantic-constraint-rendering
Jun 10, 2026
Merged

Fix pydantic constraint rendering#3289
koxudaxi merged 17 commits into
mainfrom
fix-pydantic-constraint-rendering

Conversation

@koxudaxi

@koxudaxi koxudaxi commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Deterministic, robust Python-literal rendering for defaults, constraints, and generated field arguments; preserves special floats, tuples, and stable set ordering.
    • Improved numeric-constraint normalization for integer-safe handling and Decimal-aware type hints.
    • Safer regex literal handling for generated patterns.
  • Bug Fixes

    • Regex patterns with escaped quotes now produce valid, importable code.
    • Non-finite numeric defaults (inf/NaN) render as valid Python expressions.
  • Tests

    • Added integration tests for regex handling, integer-constraint safety, and non-finite value rendering.

@coderabbitai

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

Centralizes safe Python literal rendering (PythonCode, represent_python_value) and Fraction-based integer-constraint normalization, integrates them into base and Pydantic field/type generation (including regex literal validation), and adds integration tests plus updated expected generated outputs.

Changes

Python value representation and constraint handling

Layer / File(s) Summary
Core value representation and constraint normalization utilities
src/datamodel_code_generator/python_literal.py, src/datamodel_code_generator/types.py
Adds PythonCode and represent_python_value() for deterministic rendering of Python literals and special floats; adds normalize_integer_constraint(s) using Fraction, updates DataType.type_hint to render callable kwargs with represent_python_value(), and enables Decimal import detection.
Base field default representation
src/datamodel_code_generator/model/base.py, src/datamodel_code_generator/model/__init__.py
DataModelFieldBase.represented_default now uses represent_python_value() for default rendering; UNDEFINED import adjusted.
Pydantic base field constraints and defaults
src/datamodel_code_generator/model/pydantic_base.py
Adds _INTEGER_CONSTRAINTS, replaces strict-constraint helper with _get_strict_field_constraint() that normalizes/casts integer-vs-float constraint values, and renders Field(...) kwargs and defaults using represent_python_value().
Pydantic v2 type-specific constraints
src/datamodel_code_generator/model/pydantic_v2/types.py
Adds _get_regex_literal() validated via ast, uses normalize_integer_constraints() in get_data_int_type(), and routes pattern constraints through the regex literal helper; hostname pattern mapping updated.
Integration tests for generated code rendering
tests/main/test_main_general.py
Adds helpers to generate/import Pydantic v2 code and three integration tests covering escaped-quote regex patterns, integer constraints from decimals, and non-finite numeric defaults rendering/evaluation.
Updated expected generated outputs
tests/data/expected/...
Expected outputs updated to use Decimal('...') for condecimal constraints and inline float('...') for special float defaults/constraints.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

breaking-change-analyzed

Suggested reviewers

  • ilovelinux

Poem

A rabbit trims the Python lines,
I stitch raw code with tidy rhyme,
Fractions keep constraints aligned,
Regex literals checked in time,
Tests clap paws — the models shine! 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.76% 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 'Fix pydantic constraint rendering' directly and clearly describes the main objective of the pull request, which involves fixing how Pydantic field constraints and defaults are rendered in generated code.
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.

✏️ 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-pydantic-constraint-rendering

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.

Comment thread src/datamodel_code_generator/model/base.py Fixed
Comment thread src/datamodel_code_generator/model/pydantic_base.py Fixed
Comment thread src/datamodel_code_generator/model/pydantic_base.py Fixed
Comment thread src/datamodel_code_generator/types.py Fixed
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

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

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

codspeed-hq Bot commented Jun 9, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 11.78%

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

❌ 5 regressed benchmarks
✅ 6 untouched benchmarks
⏩ 98 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
WallTime test_perf_all_options_enabled 5.1 s 5.8 s -12.37%
WallTime test_perf_openapi_large 2.6 s 3 s -12.11%
WallTime test_perf_complex_refs 1.9 s 2.1 s -11.85%
WallTime test_perf_kubernetes_style_pydantic_v2 2.4 s 2.7 s -11.44%
WallTime test_perf_aws_style_openapi_pydantic_v2 1.7 s 1.9 s -11.14%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix-pydantic-constraint-rendering (c336673) with main (9fa06c7)

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.

Comment thread src/datamodel_code_generator/types.py Outdated
@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (9fa06c7) to head (c336673).

Additional details and impacted files
@@            Coverage Diff             @@
##              main     #3289    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files          115       116     +1     
  Lines        26017     26173   +156     
  Branches      3284      3310    +26     
==========================================
+ Hits         26017     26173   +156     
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.

Comment thread src/datamodel_code_generator/model/pydantic_base.py
Comment thread src/datamodel_code_generator/python_literal.py Fixed
@koxudaxi koxudaxi merged commit 48ff21b into main Jun 10, 2026
50 of 51 checks passed
@koxudaxi koxudaxi deleted the fix-pydantic-constraint-rendering branch June 10, 2026 04:56
@github-actions

Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: Breaking changes detected

Reasoning: This PR changes generated code output in multiple ways: (1) non-finite floats use float() calls instead of math imports, (2) decimal constraints use Decimal() objects, (3) integer fractional constraints are normalized, (4) msgspec now renders array length constraints that were previously ignored, and (5) msgspec required nullable fields no longer get default None. The msgspec.jinja2 template also changed its default rendering condition. These are breaking changes because users regenerating models will see different output, and the msgspec nullable field change alters the runtime constructor signature of generated Struct classes.

Content for Release Notes

Code Generation Changes

  • Non-finite float values now use float() calls instead of math imports - Generated code previously rendered inf, -inf, and nan (with from math import inf, nan). Now renders float('inf'), float('-inf'), and float('nan') without the math import. Semantically equivalent but changes generated output. (Fix pydantic constraint rendering #3289)
  • Decimal constraint arguments now use Decimal() objects - condecimal() constraints previously used bare int/float values (e.g., condecimal(ge=0, le=1000)). Now uses Decimal objects (e.g., condecimal(ge=Decimal('0'), le=Decimal('1000'))) with an added from decimal import Decimal import in generated code. (Fix pydantic constraint rendering #3289)
  • Integer fields with fractional constraints are normalized to integer-safe bounds - Fractional constraint values on integer types are now converted: gt: 0.5 becomes ge: 1, lt: 2.5 becomes le: 2, and multiple_of: 1 is dropped entirely. Previously these fractional values were passed through as-is to conint() or Field(). (Fix pydantic constraint rendering #3289)
  • msgspec array length constraints are now rendered - min_items and max_items schema constraints on array fields are now emitted as Meta(min_length=..., max_length=...) annotations in msgspec output. Previously these constraints were silently ignored. (Fix pydantic constraint rendering #3289)
  • msgspec required nullable fields no longer get default = None - Required nullable fields in msgspec Structs previously received a = None default assignment. Now they are rendered without a default, requiring callers to provide the value explicitly. (Fix pydantic constraint rendering #3289)

Custom Template Update Required

  • msgspec.jinja2 template default value condition changed - The condition for rendering default value assignments changed from not field.required or field.use_default_with_required or field.data_type.is_optional or field.nullable to not field.required or field.use_default_with_required. Custom templates derived from the built-in msgspec template may need to be updated. (Fix pydantic constraint rendering #3289)

This analysis was performed by Claude Code Action

@github-actions

Copy link
Copy Markdown
Contributor

🎉 Released in 0.62.0

This PR is now available in the latest release. See the release notes for details.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants