Visitar URL original
Fix `constr()` for string fields carrying minItems/maxItems by DarkaMaul · Pull Request #3353 · datamodel-code-generator/datamodel-code-generator · GitHub
Skip to content

Fix constr() for string fields carrying minItems/maxItems - #3353

Merged
Koudai Aono (koxudaxi) merged 2 commits into
datamodel-code-generator:mainfrom
trail-of-forks:fix-constr-string-length
Jun 12, 2026
Merged

Koudai Aono (koxudaxi) merged 2 commits into
datamodel-code-generator:mainfrom
trail-of-forks:fix-constr-string-length

Conversation

@DarkaMaul

@DarkaMaul dm (DarkaMaul) commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

A pydantic v2 string field whose schema uses minItems/maxItems generated constr(min_items=..., max_items=...). constr has no min_items/max_items parameters , so building the model raises TypeError: constr() got an unexpected keyword argument 'min_items'

Add a regression test and fixture.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed JSON Schema constraint translation for Pydantic v2. String fields with minItems/maxItems constraints are now correctly mapped to appropriate length validation rules instead of incompatible item-count constraints.

A pydantic v2 string field whose schema uses `minItems`/`maxItems`
generated `constr(min_items=..., max_items=...)`. `constr` has no
`min_items`/`max_items` parameters (those are `min_length`/`max_length`),
so building the model raises `TypeError: constr() got an unexpected
keyword argument 'min_items'`. Import appears to succeed only because
`from __future__ import annotations` defers annotation evaluation; the
error surfaces on first validation/instantiation.

`minItems`/`maxItems` only ever reach the string constraint path
(`string_kwargs`), and the Field path (`validate_min_max_items`) and the
msgspec path already normalize them to length constraints for strings.
Map them to `min_length`/`max_length` so the `constr()` path is
consistent and the generated model is usable.

Add a regression test and fixture.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 81032b83-c04a-4a6e-bc8e-5440f54006db

📥 Commits

Reviewing files that changed from the base of the PR and between f594e26 and 2f21c84.

⛔ Files ignored due to path filters (1)
  • tests/data/jsonschema/string_min_max_items_compat.json is excluded by !tests/data/**/*.json and included by none
📒 Files selected for processing (3)
  • tests/data/expected/main/jsonschema/string_min_max_items_compat.py
  • tests/main/jsonschema/test_main_jsonschema.py
  • tests/main/payload_validation/constants.py
✅ Files skipped from review due to trivial changes (1)
  • tests/data/expected/main/jsonschema/string_min_max_items_compat.py

📝 Walkthrough

Walkthrough

This PR fixes the Pydantic v2 code generator to correctly map JSON Schema minItems/maxItems constraints to Pydantic string field length constraints (min_length/max_length) instead of item-count constraints. Changes include the mapping update, expected output fixture, integration test, and excluded-case documentation.

Changes

String Length Constraint Mapping

Layer / File(s) Summary
Constraint mapping fix and validation
src/datamodel_code_generator/model/pydantic_v2/types.py, tests/data/expected/main/jsonschema/string_min_max_items_compat.py, tests/main/jsonschema/test_main_jsonschema.py, tests/main/payload_validation/constants.py
The kwargs_schema_to_model mapping is adjusted to emit min_length and max_length for JSON Schema minItems/maxItems constraints. Expected output shows the generated Model class with constrained string field, integration test validates the CLI generation and correctness with execution, and excluded-case constant documents the stricter Pydantic behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A string length mapper hops with glee,
Swapping items for lengths, now working free!
From schema to Pydantic, the constraint flows right,
Min and max length shining bright! ✨

🚥 Pre-merge checks | ✅ 5
✅ 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 accurately describes the main fix: updating Pydantic v2's constr() constraint mapping to use min_length/max_length instead of min_items/max_items for string fields with minItems/maxItems schema constraints.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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

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.

@codspeed

codspeed Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 13.03%

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

❌ 10 regressed benchmarks
✅ 1 untouched benchmark
⏩ 98 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ WallTime test_perf_deep_nested 4.8 s 5.6 s -14.07%
❌ WallTime test_perf_openapi_large 2.8 s 3.2 s -13.96%
❌ WallTime test_perf_graphql_style_pydantic_v2 758 ms 879.2 ms -13.78%
❌ WallTime test_perf_aws_style_openapi_pydantic_v2 1.8 s 2.1 s -13.44%
❌ WallTime test_perf_all_options_enabled 5.1 s 5.8 s -13.13%
❌ WallTime test_perf_large_models_pydantic_v2 3.4 s 4 s -13.04%
❌ WallTime test_perf_kubernetes_style_pydantic_v2 2.5 s 2.9 s -12.57%
❌ WallTime test_perf_duplicate_names 1 s 1.2 s -12.53%
❌ WallTime test_perf_multiple_files_input 3.4 s 3.9 s -12.35%
❌ WallTime test_perf_stripe_style_pydantic_v2 1.9 s 2.2 s -11.43%

Tip

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


Comparing trail-of-forks:fix-constr-string-length (2f21c84) with main (cebebff)

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) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the fix. The implementation direction looks good, but CI is failing because this fixture is now picked up by the schema-derived payload validation tests.

minItems / maxItems are valid JSON Schema keywords, but they are inapplicable to type: string. So payloads like {"code": ""} are valid against the source JSON Schema, while the generated Pydantic model now rejects them via constr(min_length=2, max_length=5).

Could you please update the PR to:

  1. Rename the fixture/test to make this a compatibility case, not standard string length validation.
  2. Add force_exec_validation=True to the regression test so it verifies the generated model imports/builds successfully.
  3. Exclude this fixture from payload validation, with a reason like:
    compatibility fixture maps string minItems/maxItems to Pydantic length constraints, which is stricter than JSON Schema

…ty case

Per review on datamodel-code-generator#3353: minItems/maxItems are valid JSON Schema keywords but
inapplicable to type: string, so the generated constr(min_length=,
max_length=) is stricter than the source schema and payload validation
correctly flags the mismatch.

- Rename fixture/test/expected file to string_min_max_items_compat
- Add force_exec_validation=True so the test verifies the generated
  model imports and builds
- Exclude the fixture from payload validation with a reason

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@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 (2d379eb) to head (2f21c84).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main     #3353    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files          125       129     +4     
  Lines        28246     28549   +303     
  Branches      3449      3448     -1     
==========================================
+ Hits         28246     28549   +303     
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
Koudai Aono (koxudaxi) merged commit 6192212 into datamodel-code-generator:main Jun 12, 2026
50 of 51 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: PR #3353 is a bugfix. Previously, a pydantic v2 string field whose JSON Schema carried minItems/maxItems generated constr(min_items=..., max_items=...), which raised TypeError: constr() got an unexpected keyword argument 'min_items' on first validation/instantiation — i.e., the generated model was non-functional. The fix maps minItems/maxItems to min_length/max_length (src/datamodel_code_generator/model/pydantic_v2/types.py:264-265), producing valid constr(min_length=..., max_length=...), consistent with the already-correct Field and msgspec paths. Although the generated output changes for affected schemas, the old output was broken code that could not run, so no existing working user can be broken by it. No CLI options, Python API, default behavior, templates, error handling, or Python version support were altered (the rest of the PR is a regression test plus fixtures). Therefore this is a non-breaking bugfix.


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.

2 participants