Skip to content

fix: migrate Pydantic v1 validators to Pydantic v2 style (#929)#1783

Open
frankentini wants to merge 1 commit intoNVIDIA-NeMo:developfrom
frankentini:feat/pydantic-v2-model-validators
Open

fix: migrate Pydantic v1 validators to Pydantic v2 style (#929)#1783
frankentini wants to merge 1 commit intoNVIDIA-NeMo:developfrom
frankentini:feat/pydantic-v2-model-validators

Conversation

@frankentini
Copy link
Copy Markdown

@frankentini frankentini commented Apr 12, 2026

Summary

Fixes #929.

Replaces all deprecated Pydantic v1 @root_validator and @validator decorators with their Pydantic v2 equivalents (@model_validator / @field_validator) across three core modules. This eliminates the PydanticDeprecatedSince20 warnings users see when running with Pydantic ≥ 2.0 and ensures forward compatibility with Pydantic v3.

Changes

nemoguardrails/eval/models.py

  • @root_validator(pre=True)@model_validator(mode='before') on InteractionSet.instantiate_expected_output
  • @root_validator(pre=False, skip_on_failure=True)@model_validator(mode='after') on EvalConfig.validate_policy_ids; updated method signature to take self and return self per Pydantic v2 convention
  • Updated import: root_validatormodel_validator

nemoguardrails/rails/llm/options.py

  • @root_validator(pre=True, allow_reuse=True)@model_validator(mode='before') on GenerationOptions.check_fields
  • Updated import: root_validatormodel_validator

nemoguardrails/rails/llm/config.py

  • Converted all 6 remaining @root_validator usages to @model_validator(mode='before'):
    • TaskPrompt.check_fields
    • RailsConfig.check_model_exists_for_input_rails
    • RailsConfig.check_model_exists_for_output_rails
    • RailsConfig.check_prompt_exist_for_self_check_rails
    • RailsConfig.check_output_parser_exists
    • RailsConfig.check_jailbreak_detection_config
    • RailsConfig.fill_in_default_values_for_v2_x
  • @validator('models')@field_validator('models') on RailsConfig.validate_models_api_key_env_var
  • Removed deprecated root_validator and validator from pydantic imports; added field_validator

Notes

  • nemoguardrails/llm/providers/trtllm/llm.py uses pydantic.v1 explicitly for LangChain compatibility and is intentionally left unchanged.
  • All three files pass Python AST parsing. The behavioural contracts of all validators are preserved exactly.

Summary by CodeRabbit

  • Refactor
    • Updated internal validation mechanisms to align with current standards, improving code maintainability and system reliability while preserving all existing functionality.

Replace deprecated @root_validator and @validator decorators with
the Pydantic v2 equivalents to eliminate PydanticDeprecatedSince20
warnings and prepare for Pydantic v3 compatibility.

Changes:
- nemoguardrails/eval/models.py: replace root_validator(pre=True) with
  model_validator(mode='before') and root_validator(pre=False) with
  model_validator(mode='after'); update validate_policy_ids to use
  self instead of values dict
- nemoguardrails/rails/llm/options.py: replace root_validator with
  model_validator(mode='before') in GenerationOptions.check_fields
- nemoguardrails/rails/llm/config.py: replace all root_validator
  usages with model_validator(mode='before'); replace @validator('models')
  with @field_validator('models'); remove root_validator and validator
  from pydantic imports; add field_validator import

Note: nemoguardrails/llm/providers/trtllm/llm.py intentionally uses
pydantic.v1 for LangChain compatibility and is left unchanged.

Closes NVIDIA-NeMo#929
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 12, 2026

Greptile Summary

This PR correctly migrates all @root_validator and @validator usages to their Pydantic v2 equivalents (@model_validator / @field_validator) across three files, applying the correct mode='before'/mode='after' semantics, @classmethod placement, and updated signatures. The skip_on_failure=True semantics of EvalConfig.validate_policy_ids are preserved because mode='after' validators in Pydantic v2 are skipped automatically when field validation fails.

  • eval/models.py still calls cls.parse_obj() in two from_path methods (lines 163, 326) — parse_obj is also deprecated in Pydantic v2 and will keep emitting PydanticDeprecatedSince20 warnings; the replacement is cls.model_validate().

Confidence Score: 5/5

Safe to merge — all validator migrations are semantically correct; remaining findings are P2 cleanup in a pre-existing code path.

All @root_validator and @validator migrations are correct: proper mode selection, @classmethod placement, and signature updates. The only open items are two pre-existing cls.parse_obj() calls in eval/models.py that were not in scope for this PR but are still Pydantic v2 deprecated; they are P2 cleanup, not correctness issues.

nemoguardrails/eval/models.py — two lingering cls.parse_obj() calls at lines 163 and 326 should be updated to cls.model_validate() to fully eliminate PydanticDeprecatedSince20 warnings in this file.

Important Files Changed

Filename Overview
nemoguardrails/eval/models.py Correctly migrates root_validator to model_validator(mode='before'/'after') and adds @classmethod; two deprecated cls.parse_obj() calls at lines 163 and 326 are left over and still emit PydanticDeprecatedSince20 warnings.
nemoguardrails/rails/llm/config.py All six @root_validator validators correctly migrated to @model_validator(mode='before') @classmethod; @validator('models') correctly migrated to @field_validator('models') @classmethod; old imports removed.
nemoguardrails/rails/llm/options.py @root_validator(pre=True, allow_reuse=True) correctly migrated to @model_validator(mode='before') @classmethod; import updated; no issues found.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Raw input dict] --> B{model_validator mode=before}
    B --> |"InteractionSet.instantiate_expected_output\nTaskPrompt.check_fields\nRailsConfig.check_*\nGenerationOptions.check_fields"| C[Transform / validate raw values]
    C --> D[Pydantic field-level validation]
    D --> E{Validation errors?}
    E -- Yes --> F[ValidationError raised\nmode=after skipped]
    E -- No --> G{field_validator}
    G --> |"RailsConfig.validate_models_api_key_env_var"| H[Validate specific field]
    H --> I{model_validator mode=after}
    I --> |"EvalConfig.validate_policy_ids\nself = model instance"| J[Cross-field validation]
    J --> K[Return self / ValidationError]
Loading

Comments Outside Diff (2)

  1. nemoguardrails/eval/models.py, line 163 (link)

    P2 Deprecated parse_obj not replaced

    The PR's goal is to eliminate PydanticDeprecatedSince20 warnings, but two cls.parse_obj() calls in this file remain — lines 163 and 326. parse_obj is deprecated in Pydantic v2 and produces the same class of warning the PR targets; the replacement is cls.model_validate().

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: nemoguardrails/eval/models.py
    Line: 163
    
    Comment:
    **Deprecated `parse_obj` not replaced**
    
    The PR's goal is to eliminate `PydanticDeprecatedSince20` warnings, but two `cls.parse_obj()` calls in this file remain — lines 163 and 326. `parse_obj` is deprecated in Pydantic v2 and produces the same class of warning the PR targets; the replacement is `cls.model_validate()`.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
  2. nemoguardrails/eval/models.py, line 326 (link)

    P2 Deprecated parse_obj not replaced (second occurrence)

    Same issue as line 163 — cls.parse_obj() is a Pydantic v1 deprecated API and will still emit PydanticDeprecatedSince20 warnings.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: nemoguardrails/eval/models.py
    Line: 326
    
    Comment:
    **Deprecated `parse_obj` not replaced (second occurrence)**
    
    Same issue as line 163 — `cls.parse_obj()` is a Pydantic v1 deprecated API and will still emit `PydanticDeprecatedSince20` warnings.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: nemoguardrails/eval/models.py
Line: 163

Comment:
**Deprecated `parse_obj` not replaced**

The PR's goal is to eliminate `PydanticDeprecatedSince20` warnings, but two `cls.parse_obj()` calls in this file remain — lines 163 and 326. `parse_obj` is deprecated in Pydantic v2 and produces the same class of warning the PR targets; the replacement is `cls.model_validate()`.

```suggestion
        return cls.model_validate(config_obj)
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: nemoguardrails/eval/models.py
Line: 326

Comment:
**Deprecated `parse_obj` not replaced (second occurrence)**

Same issue as line 163 — `cls.parse_obj()` is a Pydantic v1 deprecated API and will still emit `PydanticDeprecatedSince20` warnings.

```suggestion
        return cls.model_validate(output_obj)
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: migrate Pydantic v1 validators to P..." | Re-trigger Greptile

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 12, 2026

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: b7ab73ff-7e87-49a2-a70d-f557409677e0

📥 Commits

Reviewing files that changed from the base of the PR and between b78f48b and 3b046f3.

📒 Files selected for processing (3)
  • nemoguardrails/eval/models.py
  • nemoguardrails/rails/llm/config.py
  • nemoguardrails/rails/llm/options.py

📝 Walkthrough

Walkthrough

The pull request migrates deprecated Pydantic v1-style validators to Pydantic v2-style across three core files. Instances of @root_validator are replaced with @model_validator, and @validator is replaced with @field_validator, updating method signatures and return values accordingly.

Changes

Cohort / File(s) Summary
Pydantic Validator Migration
nemoguardrails/eval/models.py, nemoguardrails/rails/llm/config.py, nemoguardrails/rails/llm/options.py
Replaced deprecated @root_validator decorators with @model_validator(mode="before") or @model_validator(mode="after"), and @validator with @field_validator. Updated method signatures to use explicit @classmethod and adjusted return statements to return self instead of values dict where applicable.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 change: migrating Pydantic v1 validators to v2 style across the codebase.
Linked Issues check ✅ Passed The PR fulfills issue #929 by systematically replacing deprecated @root_validator and @validator decorators with Pydantic v2 equivalents (@model_validator and @field_validator) across all three specified modules.
Out of Scope Changes check ✅ Passed All changes are scoped to replacing deprecated Pydantic v1 validators with v2 equivalents; the PR intentionally excludes nemoguardrails/llm/providers/trtllm/llm.py for LangChain compatibility.
Test Results For Major Changes ✅ Passed PR contains minor maintenance changes migrating Pydantic v1 validators to v2 equivalents with 28 net lines changed and no functional changes.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

feature: Update Pydantic to v2.10.5 and remove Deprecated validators

1 participant