Skip to content

Commit

Permalink
Upgrade to Pydantic v2 (#775)
Browse files Browse the repository at this point in the history
* Upgrade to Pydantic v2
* Stop testing against Pydantic v1

Closes #520
  • Loading branch information
simonw authored Feb 26, 2025
1 parent e46cb7e commit 849c65f
Show file tree
Hide file tree
Showing 7 changed files with 9 additions and 26 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand All @@ -24,7 +23,6 @@ jobs:
- name: Install dependencies
run: |
pip install -e '.[test]'
pip install 'pydantic${{ matrix.pydantic }}'
- name: Run tests
run: |
pytest
Expand Down
6 changes: 3 additions & 3 deletions llm/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")}]
Expand Down Expand Up @@ -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,
)
Expand Down
9 changes: 1 addition & 8 deletions llm/default_plugins/openai_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,7 @@
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
Expand Down
8 changes: 2 additions & 6 deletions llm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
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
Expand Down Expand Up @@ -499,7 +499,6 @@ async def __anext__(self) -> str:
return chunk

if not hasattr(self, "_generator"):

if isinstance(self.model, AsyncModel):
self._generator = self.model.execute(
self.prompt,
Expand Down Expand Up @@ -618,10 +617,7 @@ def __repr__(self):


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
Expand Down
5 changes: 2 additions & 3 deletions llm/templates.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pydantic import BaseModel
from pydantic import BaseModel, ConfigDict
import string
from typing import Optional, Any, Dict, List, Tuple

Expand All @@ -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
Expand Down
3 changes: 0 additions & 3 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def get_long_description():
"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",
Expand Down

0 comments on commit 849c65f

Please sign in to comment.