Add --validators option for Pydantic v2 field validators#2906
Add --validators option for Pydantic v2 field validators#2906
Conversation
|
Warning Rate limit exceeded@koxudaxi has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 55 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughAdds a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as __main__.py
participant Config as Config/ParserConfig
participant Parser as parser.base
participant Model as pydantic_v2.BaseModel
participant Template as Template Engine
User->>CLI: run with --validators <file.json>
CLI->>CLI: _load_validators_config(file)
Note right of CLI: parse JSON -> ValidatorsConfig (Pydantic v2)
CLI->>Config: pass validators mapping into run_generate_from_config
Config->>Parser: init with validators in config
Parser->>Parser: for each model, attach validators -> extra_template_data[model]
Parser->>Model: hand off extra_template_data
Model->>Model: _process_validators() -> prepare imports, method names, metadata
Model->>Template: provide prepared_validators in template context
Template-->>User: rendered model with `@field_validator` methods
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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 |
|
📚 Docs Preview: https://pr-2906.datamodel-code-generator.pages.dev |
CodSpeed Performance ReportMerging #2906 will not alter performanceComparing
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2906 +/- ##
========================================
Coverage 99.38% 99.38%
========================================
Files 92 93 +1
Lines 16400 16536 +136
Branches 1947 1959 +12
========================================
+ Hits 16299 16435 +136
Misses 52 52
Partials 49 49
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🤖 Generated by GitHub Actions
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/datamodel_code_generator/validators.py (1)
28-34: Consider adding validation for field specification.
ValidatorDefinitionallows bothfieldandfieldsto beNone. While the downstream_process_validatorsmethod handles this gracefully by skipping validators without fields, you could add a Pydantic model validator to catch this at configuration load time with a clearer error message.🔎 Optional: Add model validator for early detection
class ValidatorDefinition(BaseModel): """Definition of a single validator.""" field: str | None = None fields: list[str] | None = None function: str mode: ValidatorMode = ValidatorMode.AFTER + + @model_validator(mode='after') + def check_fields_specified(self) -> 'ValidatorDefinition': + if not self.field and not self.fields: + raise ValueError("At least one of 'field' or 'fields' must be specified") + return selftests/main/jsonschema/test_main_jsonschema.py (2)
7655-7716: Validators happy‑path tests and CLI doc metadata are well‑structuredThe new
test_field_validatorsandtest_field_validators_multi_fieldscover the primary behaviors of--validatorsfor Pydantic v2 (single and multi‑field validators), and usingskip_code_validation=Trueis a pragmatic choice since generated validator callables may not exist in the test environment. Decorating withPYDANTIC_V2_SKIPavoids accidental failures when v2 isn’t installed.One minor doc consistency nit: in the
cli_docmetadata you use a fully qualified path (tests/data/jsonschema/field_validators_config.json), whereas other CLI docs typically use paths rooted at the test‑data subtree (e.g.,aliases/...,default_values/...). If the docs tooling assumes a particular root, you may want to align this path with the existing convention; otherwise it’s fine to leave as‑is.
7719-7760: Error‑path coverage for invalid validators config is solid; consider encoding consistencyBoth
test_validators_invalid_jsonandtest_validators_invalid_structureexercise the key failure modes for--validators(JSON parse error vs structurally invalid config) and assert on clear stderr messages withExit.ERROR, which is exactly what’s needed.For consistency with the rest of this file (and to avoid any locale‑dependent surprises), you might want to add
encoding="utf-8"to the twoPath.write_text(...)calls that create the temporary invalid JSON files, matching earlier tests that write temp inputs.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
src/datamodel_code_generator/model/template/pydantic_v2/BaseModel.jinja2is excluded by none and included by nonetests/data/jsonschema/field_validators.jsonis excluded by!tests/data/**/*.jsonand included by nonetests/data/jsonschema/field_validators_config.jsonis excluded by!tests/data/**/*.jsonand included by nonetests/data/jsonschema/field_validators_multi_fields_config.jsonis excluded by!tests/data/**/*.jsonand included by none
📒 Files selected for processing (21)
docs/cli-reference/index.mddocs/cli-reference/quick-reference.mddocs/cli-reference/template-customization.mddocs/validators.mdsrc/datamodel_code_generator/__main__.pysrc/datamodel_code_generator/_types/generate_config_dict.pysrc/datamodel_code_generator/_types/parser_config_dicts.pysrc/datamodel_code_generator/arguments.pysrc/datamodel_code_generator/cli_options.pysrc/datamodel_code_generator/config.pysrc/datamodel_code_generator/model/pydantic_v2/base_model.pysrc/datamodel_code_generator/model/pydantic_v2/imports.pysrc/datamodel_code_generator/parser/base.pysrc/datamodel_code_generator/prompt_data.pysrc/datamodel_code_generator/validators.pytests/data/expected/main/input_model/config_class.pytests/data/expected/main/jsonschema/field_validators.pytests/data/expected/main/jsonschema/field_validators_multi_fields.pytests/main/jsonschema/test_main_jsonschema.pytests/main/test_public_api_signature_baseline.pytests/test_infer_input_type.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-25T09:23:08.506Z
Learnt from: koxudaxi
Repo: koxudaxi/datamodel-code-generator PR: 2799
File: src/datamodel_code_generator/util.py:49-66
Timestamp: 2025-12-25T09:23:08.506Z
Learning: In datamodel-code-generator, the is_pydantic_v2() and is_pydantic_v2_11() functions in src/datamodel_code_generator/util.py intentionally use global variable caching (_is_v2, _is_v2_11) on top of lru_cache for performance optimization. This dual-layer caching eliminates function call overhead and cache lookup overhead for frequently-called version checks. The PLW0603 linter warnings should be suppressed with # noqa: PLW0603 as this is a deliberate design choice.
Applied to files:
src/datamodel_code_generator/__main__.py
🧬 Code graph analysis (11)
src/datamodel_code_generator/model/pydantic_v2/imports.py (1)
src/datamodel_code_generator/imports.py (2)
Import(20-38)from_full_path(35-38)
tests/main/test_public_api_signature_baseline.py (1)
src/datamodel_code_generator/validators.py (1)
ModelValidators(37-40)
tests/data/expected/main/input_model/config_class.py (2)
src/datamodel_code_generator/validators.py (3)
ModelValidators(37-40)ValidatorMode(19-25)ValidatorDefinition(28-34)src/datamodel_code_generator/_types/generate_config_dict.py (2)
ValidatorDefinition(173-177)ModelValidatorsModel(180-181)
tests/main/jsonschema/test_main_jsonschema.py (3)
src/datamodel_code_generator/util.py (1)
is_pydantic_v2(52-57)tests/main/conftest.py (2)
output_file(99-101)run_main_and_assert(245-409)src/datamodel_code_generator/__main__.py (1)
Exit(129-135)
tests/data/expected/main/jsonschema/field_validators.py (4)
src/datamodel_code_generator/reference.py (1)
validate_name(1158-1160)src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
BaseModel(203-441)src/datamodel_code_generator/util.py (1)
field_validator(175-191)tests/data/expected/main/jsonschema/field_validators_multi_fields.py (1)
User(12-20)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (2)
src/datamodel_code_generator/imports.py (3)
Import(20-38)append(74-89)from_full_path(35-38)src/datamodel_code_generator/reference.py (4)
reference(77-79)ModelResolver(511-1217)get(1019-1021)add(931-1017)
src/datamodel_code_generator/_types/generate_config_dict.py (2)
src/datamodel_code_generator/validators.py (3)
ModelValidators(37-40)ValidatorMode(19-25)ValidatorDefinition(28-34)tests/data/expected/main/input_model/config_class.py (2)
ValidatorDefinition(251-255)ModelValidatorsModel(258-259)
src/datamodel_code_generator/config.py (1)
src/datamodel_code_generator/validators.py (1)
ModelValidators(37-40)
src/datamodel_code_generator/parser/base.py (1)
src/datamodel_code_generator/util.py (1)
model_dump(254-258)
src/datamodel_code_generator/__main__.py (1)
src/datamodel_code_generator/validators.py (2)
ValidatorsConfig(46-47)ModelValidators(37-40)
tests/data/expected/main/jsonschema/field_validators_multi_fields.py (4)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
BaseModel(203-441)src/datamodel_code_generator/util.py (1)
field_validator(175-191)tests/data/expected/main/jsonschema/field_validators.py (1)
User(12-25)src/datamodel_code_generator/model/base.py (1)
name(828-830)
🪛 Ruff (0.14.10)
src/datamodel_code_generator/config.py
49-49: Unused noqa directive (non-enabled: TC001)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/__main__.py
42-42: Unused noqa directive (non-enabled: TC003)
Remove unused noqa directive
(RUF100)
507-507: Unused noqa directive (non-enabled: UP045)
Remove unused noqa directive
(RUF100)
1293-1293: Unused noqa directive (non-enabled: T201)
Remove unused noqa directive
(RUF100)
🔇 Additional comments (42)
src/datamodel_code_generator/prompt_data.py (1)
145-145: LGTM!The new
--validatorsoption description is clear, concise, and correctly placed in alphabetical order.tests/data/expected/main/jsonschema/field_validators_multi_fields.py (1)
1-20: LGTM!The generated test fixture correctly demonstrates multi-field validator syntax for Pydantic v2. The validator properly delegates to an external function and follows the expected decorator ordering (
@field_validator→@classmethod).src/datamodel_code_generator/validators.py (1)
43-51: LGTM!The runtime version check for
ValidatorsConfigis appropriate. The pattern correctly handles Pydantic v1/v2 compatibility by setting the config toNonewhen RootModel is unavailable, which aligns with the v2-only validators feature scope.tests/data/expected/main/jsonschema/field_validators.py (1)
1-25: LGTM!The generated test fixture correctly demonstrates both
beforeandaftervalidator modes for Pydantic v2. The naming convention (validate_name_validator,validate_email_validator) and external function delegation are consistent with the generator's implementation in_process_validators.src/datamodel_code_generator/cli_options.py (1)
214-214: LGTM!The
--validatorsoption metadata is correctly categorized underOptionCategory.TEMPLATE, which aligns with other template customization options like--extra-template-dataand--class-decorators.docs/cli-reference/index.md (2)
15-15: LGTM!Template Customization option count correctly updated to 19 to reflect the new
--validatorsoption.
222-222: LGTM!The
--validatorsdocumentation link is correctly placed in alphabetical order and follows the established pattern for CLI reference entries.tests/test_infer_input_type.py (1)
48-49: LGTM!The validator configuration files are correctly excluded from JSON Schema inference tests since they contain validator configuration data rather than JSON Schema definitions.
src/datamodel_code_generator/_types/parser_config_dicts.py (3)
33-40: LGTM! Type definitions align with validators module.The new
ValidatorDefinitionDictand imports correctly mirror the structure from the validators module, enabling type-safe configuration of field validators across the codebase.
54-54: LGTM! ParserConfigDict correctly extended with validators support.The validators field addition enables propagation of validator configuration through the parser initialization flow.
183-184: LGTM! ModelValidatorsDict provides clean structure for config files.This TypedDict enables structured validators configuration in JSON/YAML files with proper type hints.
docs/cli-reference/quick-reference.md (2)
153-153: LGTM! CLI option documented in Template Customization category.The --validators option is correctly categorized and documented with clear description indicating Pydantic v2 specificity.
351-351: LGTM! Alphabetical index entry added.The alphabetical index correctly references the --validators option for easy lookup.
tests/main/test_public_api_signature_baseline.py (3)
54-54: LGTM! Import added for type checking.The ModelValidators import correctly supports type annotations in the baseline signatures.
73-73: LGTM! Baseline signature updated for backward compatibility testing.The validators parameter addition with None default ensures the public API surface is tested for compatibility.
209-209: LGTM! Parser baseline signature updated.The validators parameter in the Parser baseline ensures backward compatibility testing for parser initialization.
tests/data/expected/main/input_model/config_class.py (4)
12-12: LGTM! Import reflects expected generated code.The ModelValidators import in the test expectation file correctly represents how the feature should appear in generated configuration code.
114-114: LGTM! ValidatorMode type alias defined.The Literal type alias for ValidatorMode matches the expected generated output structure.
130-130: LGTM! validators field added to GenerateConfig.The validators field in the test expectation correctly demonstrates the config structure with proper typing.
251-259: LGTM! Validator TypedDict definitions match expected structure.The ValidatorDefinition and ModelValidatorsModel TypedDicts correctly represent the expected generated output for validators configuration.
src/datamodel_code_generator/config.py (3)
91-91: LGTM! GenerateConfig extended with validators field.The validators field addition enables per-model validator configuration with proper typing and backward-compatible None default.
233-233: LGTM! ParserConfig extended with validators field.The validators field addition in ParserConfig mirrors the GenerateConfig structure, enabling validator configuration propagation through parser initialization.
49-49: No action needed—the TC001 suppression is correct.
ModelValidatorsis used in type annotations (lines 91, 233) that Pydantic evaluates at runtime. Thenoqa: TC001directive properly suppresses the type-checking-only-import warning because the import is required at runtime. This pattern is consistently applied throughout the codebase (lines 40, 47, and other files) and is the correct approach for Pydantic usage.src/datamodel_code_generator/arguments.py (1)
879-884:--validatorsoption wiring looks consistentThe new
--validatorsPath argument is placed in the right group, has a clear help string, and matches the style of other JSON-based template options. No issues from the CLI side.src/datamodel_code_generator/model/pydantic_v2/imports.py (1)
23-25: New Pydantic v2 import constants align with existing patternThe added
IMPORT_FIELD_VALIDATOR,IMPORT_VALIDATION_INFO, andIMPORT_VALIDATOR_FUNCTION_WRAP_HANDLERfollow the sameImport.from_full_pathpattern as the other Pydantic v2 symbols and are appropriate for the validator feature.Please confirm that all three names are available from the top-level
pydanticpackage in the minimum Pydantic v2 version you support, so these imports don’t break older 2.x environments.docs/cli-reference/template-customization.md (2)
24-24: Option index entry for--validatorsis clear and correctly linkedThe new row integrates well with the existing options table and points to the right
#validatorsanchor, with a concise description tailored to Pydantic v2 models.
2696-2772:--validatorssection is consistent with behavior and other docsThe description, usage example, and generated output for
--validatorsalign with the JSON config format and Pydantic v2 validator usage documented elsewhere. The cross‑link to “Field Validators” keeps duplication minimal and discoverability good.src/datamodel_code_generator/model/pydantic_v2/base_model.py (3)
15-34: LGTM! Imports are well-organized.The imports for validator support are appropriately added and correctly structured with the conditional imports for different validator modes.
300-301: LGTM! Appropriate placement of validator processing.The
_process_validators()call is correctly positioned at the end of__init__, after all other initialization and config processing is complete.
351-399: Well-implemented validator processing logic.The implementation correctly handles:
- Multiple fields per validator
- Unique method name generation via ModelResolver
- Conditional imports based on validator modes per Pydantic v2 semantics
- Both simple function names (e.g.,
"my_validator") and fully-qualified paths (e.g.,"module.my_validator")The ValidationInfo import exclusion for plain mode (line 396-397) aligns with Pydantic v2 behavior: plain validators do not receive ValidationInfo, only wrap mode does.
src/datamodel_code_generator/_types/generate_config_dict.py (3)
38-38: LGTM! Correct import placement.The imports are correctly placed within the
TYPE_CHECKINGblock for runtime efficiency.
54-54: LGTM! The validators field is appropriately typed.The
Mapping[str, ModelValidators]type correctly represents the model-name-to-validators mapping structure.
173-181: LGTM! TypedDict definitions correctly mirror the Pydantic models.The
ValidatorDefinitionandModelValidatorsModelTypedDicts provide static type checking for dict-based configurations, complementing the Pydantic models used for runtime validation. TheNotRequiredwrappers correctly reflect the optional nature offield,fields, andmode.tests/main/jsonschema/test_main_jsonschema.py (1)
27-45: Pydantic v2 skip marker wiring looks goodImporting
is_pydantic_v2and centralizing the skip condition inPYDANTIC_V2_SKIPmirrors the existing skip-marker pattern and cleanly scopes these tests to environments that actually have Pydantic v2. No issues from a correctness or maintainability perspective.src/datamodel_code_generator/__main__.py (8)
42-42: LGTM! Import organization is correct.The imports are properly organized:
Mappingis correctly imported at runtime (not underTYPE_CHECKING) for Pydantic's needsValidationErroris used in the_load_validators_configfunctionModelValidatorsis appropriately placed underTYPE_CHECKINGas it's only used in type annotationsThe static analysis hint about unused
noqa: TC003on line 42 can be safely ignored—the comment indicates this is intentional for Pydantic compatibility.Also applies to: 49-49, 96-96, 103-105
183-185: LGTM! Config field addition follows existing patterns.The
validatorsfield is correctly integrated:
- Added to the
field_validatordecorator alongside other file-based configuration fields- Type annotation matches the pattern used for similar fields (
Optional[TextIOBase])- The
validate_filevalidator will handle path resolution and file opening consistentlyAlso applies to: 507-507
898-923: LGTM! Validators config loading is well-implemented.The
_load_validators_confighelper function correctly:
- Checks for Pydantic v2 availability before using
ValidatorsConfig- Provides a clear, actionable error message when Pydantic v2 is required
- Handles JSON parsing and validation errors with informative messages
- Accesses
.rooton theValidatorsConfigRootModel to extract the underlying dictThe error handling is comprehensive and follows the patterns established in the codebase.
934-934: LGTM! Parameter addition is well-typed.The
validatorsparameter is correctly added with:
- Appropriate immutable type (
Mapping[str, ModelValidators] | None)- Sensible position in the function signature
- Optional nature matching the feature's optional usage
1064-1064: LGTM! Parameter propagation is complete.The
validatorsparameter is correctly passed through to thegenerate()function, completing the configuration pathway from CLI/config file to code generation.
1291-1294: LGTM! Validators config loading follows established patterns.The validators configuration loading is properly integrated into the main flow:
- Uses the new
_load_validators_confighelper function- Error handling is consistent with other configuration loading (aliases, default_values, etc.)
- Errors are reported to stderr with appropriate exit code
1340-1340: LGTM! Validators config integration is complete.The loaded
validators_configis correctly passed torun_generate_from_config, completing the integration pathway from configuration file to code generation logic.
42-42: Remove this comment. Thenoqadirectives are intentional and correct.Line 42's
noqa: TC003has an explicit comment explaining it: "pydantic needs it"—Pydantic requires runtime access to these types despite them being imported fromcollections.abc.Line 507's
noqa: UP045and the ~100+ similar suppressions throughout the codebase represent a deliberate choice to useOptional[X]syntax rather thanX | None, consistent with the project's established pattern of preserving such directives despite RUF100 warnings.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
370-373: Consider clarifying the fields extraction logic.The current logic handles both
"fields"(list) and"field"(single value) by usingorwith list filtering. While functional, it could be more explicit about the expected structure.🔎 Alternative approach for clarity
- fields = validator.get("fields") or [validator.get("field")] - fields = [f for f in fields if f] + # Support both "fields" (list) and "field" (single string) + fields_value = validator.get("fields") or validator.get("field") + if not fields_value: + continue + fields = fields_value if isinstance(fields_value, list) else [fields_value] - if not fields: - continuetests/main/jsonschema/test_main_jsonschema.py (1)
7700-7778: Good coverage of validator config variants; minor helper-usage nitThese three tests nicely cover multi-field validators,
wrapmode, and skipping entries without afieldkey, and the string checks on the generated file verify the intended behavior without over-coupling to full golden files.If you want tighter consistency with the rest of the suite, you could optionally rewrite
test_field_validators_with_no_field_skippedto userun_main_and_assert(..., skip_code_validation=True)plus explicit output inspection, but the currentrun_main_with_argsapproach is perfectly serviceable.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/datamodel_code_generator/model/pydantic_v2/base_model.pysrc/datamodel_code_generator/parser/base.pytests/data/expected/main/jsonschema/field_validators_wrap_mode.pytests/main/jsonschema/test_main_jsonschema.py
🚧 Files skipped from review as they are similar to previous changes (1)
- src/datamodel_code_generator/parser/base.py
🧰 Additional context used
🧬 Code graph analysis (3)
tests/data/expected/main/jsonschema/field_validators_wrap_mode.py (2)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (1)
BaseModel(213-447)src/datamodel_code_generator/util.py (1)
field_validator(175-191)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (3)
src/datamodel_code_generator/model/pydantic/base_model.py (2)
imports(268-276)validator(86-89)src/datamodel_code_generator/imports.py (3)
Import(20-38)append(74-89)from_full_path(35-38)src/datamodel_code_generator/reference.py (3)
reference(77-79)ModelResolver(511-1217)add(931-1017)
tests/main/jsonschema/test_main_jsonschema.py (3)
src/datamodel_code_generator/util.py (1)
is_pydantic_v2(52-57)tests/main/conftest.py (2)
output_file(99-101)run_main_and_assert(245-409)src/datamodel_code_generator/__main__.py (1)
Exit(129-135)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: benchmarks
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.14 on Windows
- GitHub Check: 3.12 on macOS
- GitHub Check: 3.13 on macOS
- GitHub Check: py312-isort5 on Ubuntu
- GitHub Check: 3.13 on Windows
- GitHub Check: 3.10 on macOS
- GitHub Check: 3.10 on Windows
- GitHub Check: 3.12 on Windows
- GitHub Check: 3.14 on macOS
- GitHub Check: Analyze (python)
🔇 Additional comments (10)
src/datamodel_code_generator/model/pydantic_v2/base_model.py (4)
15-15: LGTM! Import additions support the validator feature.The new imports (IMPORT_ANY, IMPORT_FIELD_VALIDATOR, IMPORT_VALIDATION_INFO, IMPORT_VALIDATOR_FUNCTION_WRAP_HANDLER, ModelResolver) are all used appropriately in the
_process_validatorsmethod to support Pydantic v2 field validators.Also applies to: 27-34
310-311: LGTM! Appropriate placement of validator processing.Calling
_process_validators()at the end of__init__ensures validators are processed after configuration setup and before template rendering.
361-365: LGTM! Method structure is sound.The method signature and early-return pattern are appropriate for processing optional validator configurations.
396-406: LGTM! Conditional import logic correctly matches Pydantic v2 validator signatures.The code appropriately adds imports based on detected validator modes:
IMPORT_VALIDATION_INFOis added for non-plain modes (which receive ValidationInfo)IMPORT_VALIDATOR_FUNCTION_WRAP_HANDLERis added only for wrap modeThis aligns with Pydantic v2's validator function signatures.
tests/data/expected/main/jsonschema/field_validators_wrap_mode.py (3)
19-22: LGTM! Model fields are correctly defined.The field definitions follow Pydantic v2 conventions with appropriate type constraints and the modern union syntax.
1-3: Standard generated file header.The header correctly identifies the source schema file, which is helpful for tracing the origin of generated code.
24-29: Wrap mode field validator is correctly implemented.The validator follows Pydantic v2 conventions:
- Correct decorator order (
@field_validatorbefore@classmethod)- Proper signature with
handler: ValidatorFunctionWrapHandlerandinfo: ValidationInfo- Appropriate delegation to external validation logic
All required imports are present and types are correct for wrap mode operation.
tests/main/jsonschema/test_main_jsonschema.py (3)
27-27: Pydantic version gating helpers are correctly wiredUsing
is_pydantic_v2()inPYDANTIC_V2_SKIP/PYDANTIC_V1_ONLYgives the right behavior for enabling v2-only tests and v1-only tests, and matches the existing*_SKIPmarker pattern in this module.Also applies to: 45-46
7654-7697: Solid happy-path coverage for--validatorsincluding CLI docsThe
test_field_validatorssetup cleanly exercises the new--validatorsoption end-to-end (including@cli_docmetadata), andskip_code_validation=Trueis an appropriate way to avoid depending on real validator implementations while still asserting the golden output.
7786-7847: Error handling around--validatorsis well exercisedThe invalid-JSON and invalid-structure tests correctly assert both non-OK exits and clear diagnostics, and
test_validators_requires_pydantic_v2(gated byPYDANTIC_V1_ONLY) nicely locks in the requirement that--validatorsonly be used with Pydantic v2.
Breaking Change AnalysisResult: No breaking changes detected Reasoning: This PR adds a new opt-in feature ( This analysis was performed by Claude Code Action |
|
🎉 Released in 0.52.1 This PR is now available in the latest release. See the release notes for details. |
Fixes: #464
Summary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.