Fix pydantic v2 dataclass lookaround regex engine#3370
Conversation
…patterns Pydantic v2's default rust regex engine cannot compile lookaround assertions, so BaseModel generation injects ConfigDict(regex_engine="python-re") when a field pattern contains one. The pydantic_v2.dataclass path lacked this handling, so generated dataclasses raised SchemaError at class-build time. Hoist the lookaround detection from BaseModel into a shared has_lookaround_pattern helper and apply it on the DataClass config path as well. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lass-lookaround-regex-engine # Conflicts: # src/datamodel_code_generator/model/pydantic_v2/base_model.py # src/datamodel_code_generator/model/pydantic_v2/dataclass.py
Verifies the generated dataclass actually builds at runtime, since the bug manifests as a SchemaError at class-build time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughThe PR refactors lookaround pattern detection into a shared module-level helper function, removes the duplicated class method from BaseModel, and applies the helper to DataClass configuration. Unit tests validate edge cases with referenced aliases, while integration test fixtures and parametrized test cases demonstrate end-to-end behavior for both OpenAPI and JSONSchema schemas with default and field-constraints modes. ChangesRegex Lookaround Pattern Detection and Configuration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@tests/main/openapi/test_main_openapi.py`:
- Around line 1897-1919: Add the same Black-compatibility skip decorator used on
the neighboring Pydantic v2 BaseModel test to the dataclass test: annotate
test_main_openapi_pattern_with_lookaround_pydantic_v2_dataclass with
`@pytest.mark.skipif`(black.__version__.split(".")[0] < "22", reason="Black <22
incompatible with pydantic_v2.dataclass formatting/parsing"), ensuring the black
symbol is available in the test module; this will skip the dataclass OpenAPI
test when Black major version is less than 22.
🪄 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: 439addbd-8850-4c27-a24e-f8d5ec025a42
📒 Files selected for processing (5)
src/datamodel_code_generator/model/pydantic_v2/base_model.pysrc/datamodel_code_generator/model/pydantic_v2/dataclass.pytests/data/expected/main/openapi/pattern_with_lookaround_pydantic_v2_dataclass.pytests/data/expected/main/openapi/pattern_with_lookaround_pydantic_v2_dataclass_field_constraints.pytests/main/openapi/test_main_openapi.py
Merging this PR will not alter performance
|
koxudaxi
left a comment
There was a problem hiding this comment.
Thank you for creating this PR. I left one review comment.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3370 +/- ##
===========================================
Coverage 100.00% 100.00%
===========================================
Files 129 140 +11
Lines 28549 30240 +1691
Branches 3448 3569 +121
===========================================
+ Hits 28549 30240 +1691
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
A string field whose lookaround pattern lives in a generated type alias or root type (e.g. `value: LookaroundAlias | None`) produced a pydantic v2 dataclass without `ConfigDict(regex_engine="python-re")`, so it failed at import with a SchemaError under pydantic's default rust regex engine. - `has_lookaround_pattern()` gains an opt-in `follow_references` that walks into referenced models. References are only linked after `__init__`, so the dataclass applies it lazily (memoized) via `imports`/`render`. - Drop the now-passing dataclass lookaround payload-validation exclusions (lookaround_anyof_nullable, lookaround_dict, lookaround_union_types, nested_lookaround_array); keep lookaround_mixed_constraints, whose root-level oneOf has no consuming dataclass to carry the config. - Add unit tests covering the alias-detection path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
e93ae63 to
25e6341
Compare
The dataclass regex_engine unit tests hand-built the internal Reference graph and asserted on render() string fragments, testing the implementation rather than observable behavior (the negative case only proved "did not crash"). - Replace test_data_class_regex_engine_via_referenced_alias with an end-to-end fixture test driving lookaround_anyof_nullable.json through pydantic_v2.dataclass, with force_exec_validation so the generated module must import under pydantic's default rust regex engine -- the exact failure this PR fixes. - Replace the "skips reference without fields" render() test with a direct has_lookaround_pattern() contract test for the sourceless-reference branch, which no generated schema exercises. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
b6a6fdd to
f1ff0bc
Compare
Breaking Change AnalysisResult: No breaking changes detected Reasoning: PR #3370 is a bug fix for the pydantic v2 dataclass output path. Previously, pydantic v2 dataclasses whose fields (or referenced type aliases/root types) used regex lookaround assertions were generated WITHOUT ConfigDict(regex_engine="python-re"), so the generated code failed at class-build time with a SchemaError under pydantic's default rust regex engine. The PR now emits that config for the dataclass path, mirroring existing BaseModel behavior. The only change to generated output affects code that was previously non-importable/broken, so no working user setup can be broken by it. Supporting changes are non-breaking: has_lookaround_pattern() is an internal helper (not public API), and its new follow_references parameter is opt-in with a default of False that preserves prior behavior. There are no CLI option changes, no default-behavior changes to existing valid output, no required template updates, no Python version drop, and no error-handling contract changes. This analysis was performed by Claude Code Action |
|
🎉 Released in 0.64.1 This PR is now available in the latest release. See the release notes for details. |
A string field whose schema pattern uses a lookaround assertion
((?=,(?!,(?<=,(?<!), generated with--output-model-type pydantic_v2.dataclass, producedconstr(pattern=...)withoutConfigDict(regex_engine="python-re").Pydantic v2's default rust regex engine cannot compile lookaround, so building the generated dataclass raises
SchemaErrorat class definition time. Thepydantic_v2.BaseModeloutput already handles this case.Summary by CodeRabbit
python-reregex engine when needed.