Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Anthropics Anthropic sdk python Pydantic Compat

From Leeroopedia
Knowledge Sources
Domains SDK_Architecture, Compatibility
Last Updated 2026-02-15 12:00 GMT

Overview

The _compat.py module provides a compatibility layer that abstracts the differences between Pydantic v1 and Pydantic v2/v3, allowing the Anthropic SDK to work seamlessly with either version.

Description

Pydantic underwent a major rewrite between v1 and v2, renaming and restructuring many core APIs. This module detects the installed Pydantic version at import time using the PYDANTIC_V1 flag (set by checking pydantic.VERSION.startswith("1.")) and provides unified wrapper functions that delegate to the correct version-specific API.

The module covers several categories of compatibility: type introspection functions (get_args, get_origin, is_union, is_literal_type, is_typeddict), parsing functions (parse_date, parse_datetime), model operations (model_dump, model_json, model_parse, model_parse_json, model_copy, parse_obj), field inspection (field_is_required, field_get_default, field_outer_type), model metadata (get_model_config, get_model_fields), generic model base classes, and cached property types. For v1, functions delegate to Pydantic's legacy APIs (e.g., model.parse_obj(), model.dict()); for v2+, they use the modern equivalents (e.g., model.model_validate(), model.model_dump()).

The module also provides a GenericModel base class that inherits from pydantic.generics.GenericModel in v1 and directly from pydantic.BaseModel in v2 (where the distinction is no longer required), along with a ConfigDict re-export and typed_cached_property for settable cached properties.

Usage

This module is used internally throughout the SDK whenever Pydantic model operations are needed. SDK developers should import compat wrappers from this module instead of calling Pydantic APIs directly to maintain cross-version support.

Code Reference

Source Location

Signature

PYDANTIC_V1: bool  # True if pydantic.VERSION starts with "1."

def parse_obj(model: type[_ModelT], value: object) -> _ModelT: ...
def field_is_required(field: FieldInfo) -> bool: ...
def field_get_default(field: FieldInfo) -> Any: ...
def field_outer_type(field: FieldInfo) -> Any: ...
def get_model_config(model: type[pydantic.BaseModel]) -> Any: ...
def get_model_fields(model: type[pydantic.BaseModel]) -> dict[str, FieldInfo]: ...
def model_copy(model: _ModelT, *, deep: bool = False) -> _ModelT: ...
def model_json(model: pydantic.BaseModel, *, indent: int | None = None) -> str: ...
def model_parse_json(model: type[_ModelT], data: str | bytes) -> _ModelT: ...
def model_dump(
    model: pydantic.BaseModel,
    *,
    exclude: IncEx | None = None,
    exclude_unset: bool = False,
    exclude_defaults: bool = False,
    warnings: bool = True,
    mode: Literal["json", "python"] = "python",
    by_alias: bool | None = None,
) -> dict[str, Any]: ...
def model_parse(model: type[_ModelT], data: Any) -> _ModelT: ...

class GenericModel(pydantic.BaseModel): ...

# Re-exported type introspection (sourced from pydantic v1 or _utils for v2):
def get_args(t: type[Any]) -> tuple[Any, ...]: ...
def is_union(tp: type[Any] | None) -> bool: ...
def get_origin(t: type[Any]) -> type[Any] | None: ...
def is_literal_type(type_: type[Any]) -> bool: ...
def is_typeddict(type_: type[Any]) -> bool: ...
def parse_date(value: date | StrBytesIntFloat) -> date: ...
def parse_datetime(value: Union[datetime, StrBytesIntFloat]) -> datetime: ...

Import

# Internal SDK usage only
from anthropic._compat import (
    PYDANTIC_V1,
    model_dump,
    model_json,
    model_parse,
    model_copy,
    parse_obj,
    get_model_fields,
    field_is_required,
    GenericModel,
    ConfigDict,
)

I/O Contract

Version Detection

Flag Type Value
PYDANTIC_V1 bool True when pydantic.VERSION starts with "1.", False otherwise

Model Operation Mapping

Compat Function Pydantic v1 Delegation Pydantic v2+ Delegation
parse_obj(model, value) model.parse_obj(value) model.model_validate(value)
model_dump(model, ...) model.dict(...) model.model_dump(...)
model_json(model, indent) model.json(indent=indent) model.model_dump_json(indent=indent)
model_parse_json(model, data) model.parse_raw(data) model.model_validate_json(data)
model_parse(model, data) model.parse_obj(data) model.model_validate(data)
model_copy(model, deep) model.copy(deep=deep) model.model_copy(deep=deep)
get_model_fields(model) model.__fields__ model.model_fields
get_model_config(model) model.__config__ model.model_config
field_is_required(field) field.required field.is_required()
field_get_default(field) field.get_default() field.get_default() (maps PydanticUndefined to None)
field_outer_type(field) field.outer_type_ field.annotation

GenericModel Base Class

Pydantic Version GenericModel Inherits From
v1 pydantic.generics.GenericModel + pydantic.BaseModel
v2+ pydantic.BaseModel (generic distinction no longer needed)

Usage Examples

from anthropic._compat import model_dump, model_parse, PYDANTIC_V1

import pydantic

class MyModel(pydantic.BaseModel):
    name: str
    value: int

# Parse data into a model (works with both v1 and v2)
instance = model_parse(MyModel, {"name": "test", "value": 42})

# Dump model to dict (works with both v1 and v2)
data = model_dump(instance, exclude_unset=True)
# -> {"name": "test", "value": 42}

# Check which version is in use
if PYDANTIC_V1:
    print("Using Pydantic v1 compatibility layer")
else:
    print("Using Pydantic v2+ native APIs")

Related Pages

Related Implementations

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment