Skip to content

Commit

Permalink
chore(internal): bump pydantic dependency (#1413)
Browse files Browse the repository at this point in the history
  • Loading branch information
stainless-bot committed May 13, 2024
1 parent 906ece0 commit 3480e50
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 26 deletions.
8 changes: 4 additions & 4 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ attrs==23.1.0
azure-core==1.30.1
# via azure-identity
azure-identity==1.15.0
black==24.4.0
black==24.4.2
# via inline-snapshot
certifi==2023.7.22
# via httpcore
Expand All @@ -39,7 +39,7 @@ click==8.1.7
# via inline-snapshot
colorlog==6.7.0
# via nox
cryptography==42.0.5
cryptography==42.0.7
# via azure-identity
# via msal
# via pyjwt
Expand Down Expand Up @@ -111,9 +111,9 @@ py==1.11.0
# via pytest
pycparser==2.22
# via cffi
pydantic==2.4.2
pydantic==2.7.1
# via openai
pydantic-core==2.10.1
pydantic-core==2.18.2
# via pydantic
pyjwt==2.8.0
# via msal
Expand Down
8 changes: 4 additions & 4 deletions requirements.lock
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ numpy==1.26.4
# via openai
# via pandas
# via pandas-stubs
pandas==2.2.1
pandas==2.2.2
# via openai
pandas-stubs==2.2.1.240316
# via openai
pydantic==2.4.2
pydantic==2.7.1
# via openai
pydantic-core==2.10.1
pydantic-core==2.18.2
# via pydantic
python-dateutil==2.9.0.post0
# via pandas
Expand All @@ -53,7 +53,7 @@ sniffio==1.3.0
# via openai
tqdm==4.66.1
# via openai
types-pytz==2024.1.0.20240203
types-pytz==2024.1.0.20240417
# via pandas-stubs
typing-extensions==4.8.0
# via openai
Expand Down
20 changes: 16 additions & 4 deletions src/openai/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
from ._constants import RAW_RESPONSE_HEADER

if TYPE_CHECKING:
from pydantic_core.core_schema import ModelField, ModelFieldsSchema
from pydantic_core.core_schema import ModelField, LiteralSchema, ModelFieldsSchema

__all__ = ["BaseModel", "GenericModel"]

Expand Down Expand Up @@ -251,7 +251,9 @@ def model_dump(
exclude_defaults: bool = False,
exclude_none: bool = False,
round_trip: bool = False,
warnings: bool = True,
warnings: bool | Literal["none", "warn", "error"] = True,
context: dict[str, Any] | None = None,
serialize_as_any: bool = False,
) -> dict[str, Any]:
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump
Expand Down Expand Up @@ -279,6 +281,10 @@ def model_dump(
raise ValueError("round_trip is only supported in Pydantic v2")
if warnings != True:
raise ValueError("warnings is only supported in Pydantic v2")
if context is not None:
raise ValueError("context is only supported in Pydantic v2")
if serialize_as_any != False:
raise ValueError("serialize_as_any is only supported in Pydantic v2")
return super().dict( # pyright: ignore[reportDeprecated]
include=include,
exclude=exclude,
Expand All @@ -300,7 +306,9 @@ def model_dump_json(
exclude_defaults: bool = False,
exclude_none: bool = False,
round_trip: bool = False,
warnings: bool = True,
warnings: bool | Literal["none", "warn", "error"] = True,
context: dict[str, Any] | None = None,
serialize_as_any: bool = False,
) -> str:
"""Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump_json
Expand All @@ -324,6 +332,10 @@ def model_dump_json(
raise ValueError("round_trip is only supported in Pydantic v2")
if warnings != True:
raise ValueError("warnings is only supported in Pydantic v2")
if context is not None:
raise ValueError("context is only supported in Pydantic v2")
if serialize_as_any != False:
raise ValueError("serialize_as_any is only supported in Pydantic v2")
return super().json( # type: ignore[reportDeprecated]
indent=indent,
include=include,
Expand Down Expand Up @@ -550,7 +562,7 @@ def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any,
field_schema = field["schema"]

if field_schema["type"] == "literal":
for entry in field_schema["expected"]:
for entry in cast("LiteralSchema", field_schema)["expected"]:
if isinstance(entry, str):
mapping[entry] = variant
else:
Expand Down
8 changes: 4 additions & 4 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class NestedModel(BaseModel):

# mismatched types
m = NestedModel.construct(nested="hello!")
assert m.nested == "hello!"
assert cast(Any, m.nested) == "hello!"


def test_optional_nested_model() -> None:
Expand All @@ -48,7 +48,7 @@ class NestedModel(BaseModel):
# mismatched types
m3 = NestedModel.construct(nested={"foo"})
assert isinstance(cast(Any, m3.nested), set)
assert m3.nested == {"foo"}
assert cast(Any, m3.nested) == {"foo"}


def test_list_nested_model() -> None:
Expand Down Expand Up @@ -323,7 +323,7 @@ class Model(BaseModel):
assert len(m.items) == 2
assert isinstance(m.items[0], Submodel1)
assert m.items[0].level == -1
assert m.items[1] == 156
assert cast(Any, m.items[1]) == 156


def test_union_of_lists() -> None:
Expand Down Expand Up @@ -355,7 +355,7 @@ class Model(BaseModel):
assert len(m.items) == 2
assert isinstance(m.items[0], SubModel1)
assert m.items[0].level == -1
assert m.items[1] == 156
assert cast(Any, m.items[1]) == 156


def test_dict_of_union() -> None:
Expand Down
22 changes: 12 additions & 10 deletions tests/test_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,20 +260,22 @@ class MyModel(BaseModel):
@parametrize
@pytest.mark.asyncio
async def test_pydantic_model_to_dictionary(use_async: bool) -> None:
assert await transform(MyModel(foo="hi!"), Any, use_async) == {"foo": "hi!"}
assert await transform(MyModel.construct(foo="hi!"), Any, use_async) == {"foo": "hi!"}
assert cast(Any, await transform(MyModel(foo="hi!"), Any, use_async)) == {"foo": "hi!"}
assert cast(Any, await transform(MyModel.construct(foo="hi!"), Any, use_async)) == {"foo": "hi!"}


@parametrize
@pytest.mark.asyncio
async def test_pydantic_empty_model(use_async: bool) -> None:
assert await transform(MyModel.construct(), Any, use_async) == {}
assert cast(Any, await transform(MyModel.construct(), Any, use_async)) == {}


@parametrize
@pytest.mark.asyncio
async def test_pydantic_unknown_field(use_async: bool) -> None:
assert await transform(MyModel.construct(my_untyped_field=True), Any, use_async) == {"my_untyped_field": True}
assert cast(Any, await transform(MyModel.construct(my_untyped_field=True), Any, use_async)) == {
"my_untyped_field": True
}


@parametrize
Expand All @@ -285,7 +287,7 @@ async def test_pydantic_mismatched_types(use_async: bool) -> None:
params = await transform(model, Any, use_async)
else:
params = await transform(model, Any, use_async)
assert params == {"foo": True}
assert cast(Any, params) == {"foo": True}


@parametrize
Expand All @@ -297,7 +299,7 @@ async def test_pydantic_mismatched_object_type(use_async: bool) -> None:
params = await transform(model, Any, use_async)
else:
params = await transform(model, Any, use_async)
assert params == {"foo": {"hello": "world"}}
assert cast(Any, params) == {"foo": {"hello": "world"}}


class ModelNestedObjects(BaseModel):
Expand All @@ -309,7 +311,7 @@ class ModelNestedObjects(BaseModel):
async def test_pydantic_nested_objects(use_async: bool) -> None:
model = ModelNestedObjects.construct(nested={"foo": "stainless"})
assert isinstance(model.nested, MyModel)
assert await transform(model, Any, use_async) == {"nested": {"foo": "stainless"}}
assert cast(Any, await transform(model, Any, use_async)) == {"nested": {"foo": "stainless"}}


class ModelWithDefaultField(BaseModel):
Expand All @@ -325,19 +327,19 @@ async def test_pydantic_default_field(use_async: bool) -> None:
model = ModelWithDefaultField.construct()
assert model.with_none_default is None
assert model.with_str_default == "foo"
assert await transform(model, Any, use_async) == {}
assert cast(Any, await transform(model, Any, use_async)) == {}

# should be included when the default value is explicitly given
model = ModelWithDefaultField.construct(with_none_default=None, with_str_default="foo")
assert model.with_none_default is None
assert model.with_str_default == "foo"
assert await transform(model, Any, use_async) == {"with_none_default": None, "with_str_default": "foo"}
assert cast(Any, await transform(model, Any, use_async)) == {"with_none_default": None, "with_str_default": "foo"}

# should be included when a non-default value is explicitly given
model = ModelWithDefaultField.construct(with_none_default="bar", with_str_default="baz")
assert model.with_none_default == "bar"
assert model.with_str_default == "baz"
assert await transform(model, Any, use_async) == {"with_none_default": "bar", "with_str_default": "baz"}
assert cast(Any, await transform(model, Any, use_async)) == {"with_none_default": "bar", "with_str_default": "baz"}


class TypedDictIterableUnion(TypedDict):
Expand Down

0 comments on commit 3480e50

Please sign in to comment.