Skip to content

Pydantic Plugin: Implement Annotated with Field constraints support #27

@genro

Description

@genro

Context

Add support for Pydantic's Annotated type with Field constraints in the plugin:

from typing import Annotated
from pydantic import Field

@sw
def create_user(
    name: Annotated[str, Field(min_length=2, max_length=50)],
    age: Annotated[int, Field(ge=0, le=120)],
    email: Annotated[str, Field(pattern=r'^[\w\.-]+@[\w\.-]+\.\w+$')]
):
    ...

Implementation Plan

1. Analyze Current Plugin

  • Review PydanticPlugin.on_decore to understand how signature and type hints are extracted
  • Identify the exact point where parameters are converted into the fields map for create_model()

2. Handle Annotated Types

Create a helper function _resolve_annotation(annotation) -> tuple[type, FieldInfo|None]:

  • Use typing.get_origin / typing.get_args to check if annotation is Annotated
  • Return the base type (first argument) and the first FieldInfo object if present
  • Support chains like Annotated[int, Field(...), SomeMetadata], ignoring non-Field metadata
  • Return (type, None) for non-Annotated types

Integrate the helper in the parameter loop:

  • If FieldInfo is present, use it for defaults and constraints instead of simple (hint, default)
  • Pass (hint, field_info) tuples to create_model() when available

3. Model Creation

  • When calling create_model(), pass tuples of (hint, field_info) when available
  • Fall back to (hint, default) or (hint, ...) for parameters without FieldInfo
  • Ensure backward compatibility: parameters without hints or non-Annotated continue to work

4. Tests

Add dedicated tests (in tests/plugins/test_pydantic.py or similar):

  • Decorate a handler with Annotated[str, Field(min_length=2)] and verify invalid input raises ValidationError
  • Cover at least:
    • String constraints (min_length, max_length, pattern)
    • Numeric constraints (ge, le, gt, lt)
    • Mixed: some parameters with Field, some without
  • Verify all existing tests continue to pass

5. Documentation

  • Update llm-docs/README.md or plugin-specific documentation to mention Annotated support
  • Add practical example from this issue (name, age with constraints)
  • Document that this provides fine-grained control for validation

Work Breakdown

  • 🔧 Implementation: Helper function + integration (~50 lines)
  • ✅ Tests: Comprehensive test cases covering constraints (~100 lines)
  • 📝 Documentation: Examples and usage guide

Related Issues

Priority

Medium - Natural enhancement of existing Pydantic plugin, no new dependencies required.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions