Upgrade to Pydantic v2 (#775)

* Upgrade to Pydantic v2
* Stop testing against Pydantic v1

Closes #520
This commit is contained in:
Simon Willison 2025-02-26 10:05:54 -08:00 committed by GitHub
parent e46cb7e761
commit 849c65fe9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 9 additions and 26 deletions

View file

@ -12,7 +12,6 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
pydantic: ["==1.10.2", ">=2.0.0"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
@ -24,7 +23,6 @@ jobs:
- name: Install dependencies
run: |
pip install -e '.[test]'
pip install 'pydantic${{ matrix.pydantic }}'
- name: Run tests
run: |
pytest

View file

@ -1197,9 +1197,9 @@ def models_list(options, async_, query):
model_with_aliases.model if not async_ else model_with_aliases.async_model
)
output = str(model) + extra
if options and model.Options.schema()["properties"]:
if options and model.Options.model_json_schema()["properties"]:
output += "\n Options:"
for name, field in model.Options.schema()["properties"].items():
for name, field in model.Options.model_json_schema()["properties"].items():
any_of = field.get("anyOf")
if any_of is None:
any_of = [{"type": field.get("type", "str")}]
@ -1413,7 +1413,7 @@ def templates_show(name):
template = load_template(name)
click.echo(
yaml.dump(
dict((k, v) for k, v in template.dict().items() if v is not None),
dict((k, v) for k, v in template.model_dump().items() if v is not None),
indent=4,
default_flow_style=False,
)

View file

@ -13,14 +13,7 @@ import httpx
import openai
import os
try:
# Pydantic 2
from pydantic import field_validator, Field # type: ignore
except ImportError:
# Pydantic 1
from pydantic.fields import Field
from pydantic.class_validators import validator as field_validator # type: ignore [no-redef]
from pydantic import field_validator, Field
from typing import AsyncGenerator, List, Iterable, Iterator, Optional, Union
import json

View file

@ -23,7 +23,7 @@ from typing import (
from .utils import mimetype_from_path, mimetype_from_string, token_usage_string
from abc import ABC, abstractmethod
import json
from pydantic import BaseModel
from pydantic import BaseModel, ConfigDict
from ulid import ULID
CONVERSATION_NAME_LENGTH = 32
@ -499,7 +499,6 @@ class AsyncResponse(_BaseResponse):
return chunk
if not hasattr(self, "_generator"):
if isinstance(self.model, AsyncModel):
self._generator = self.model.execute(
self.prompt,
@ -618,10 +617,7 @@ class AsyncResponse(_BaseResponse):
class Options(BaseModel):
# Note: using pydantic v1 style Configs,
# these are also compatible with pydantic v2
class Config:
extra = "forbid"
model_config = ConfigDict(extra="forbid")
_Options = Options

View file

@ -1,4 +1,4 @@
from pydantic import BaseModel
from pydantic import BaseModel, ConfigDict
import string
from typing import Optional, Any, Dict, List, Tuple
@ -13,8 +13,7 @@ class Template(BaseModel):
extract: Optional[bool] = None
extract_last: Optional[bool] = None
class Config:
extra = "forbid"
model_config = ConfigDict(extra="forbid")
class MissingVariables(Exception):
pass

View file

@ -1,5 +1,2 @@
[pytest]
filterwarnings =
ignore:The `schema` method is deprecated.*:DeprecationWarning
ignore:Support for class-based `config` is deprecated*:DeprecationWarning
asyncio_default_fixture_loop_scope = function

View file

@ -41,7 +41,7 @@ setup(
"click-default-group>=1.2.3",
"sqlite-utils>=3.37",
"sqlite-migrate>=0.1a2",
"pydantic>=1.10.2",
"pydantic>=2.0.0",
"PyYAML",
"pluggy",
"python-ulid",