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: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
pydantic: ["==1.10.2", ">=2.0.0"]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
@ -24,7 +23,6 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
pip install -e '.[test]' pip install -e '.[test]'
pip install 'pydantic${{ matrix.pydantic }}'
- name: Run tests - name: Run tests
run: | run: |
pytest 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 model_with_aliases.model if not async_ else model_with_aliases.async_model
) )
output = str(model) + extra output = str(model) + extra
if options and model.Options.schema()["properties"]: if options and model.Options.model_json_schema()["properties"]:
output += "\n Options:" 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") any_of = field.get("anyOf")
if any_of is None: if any_of is None:
any_of = [{"type": field.get("type", "str")}] any_of = [{"type": field.get("type", "str")}]
@ -1413,7 +1413,7 @@ def templates_show(name):
template = load_template(name) template = load_template(name)
click.echo( click.echo(
yaml.dump( 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, indent=4,
default_flow_style=False, default_flow_style=False,
) )

View file

@ -13,14 +13,7 @@ import httpx
import openai import openai
import os import os
try: from pydantic import field_validator, Field
# 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 typing import AsyncGenerator, List, Iterable, Iterator, Optional, Union from typing import AsyncGenerator, List, Iterable, Iterator, Optional, Union
import json import json

View file

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

View file

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

View file

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

View file

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