Browse Source

Add a test for pydantic < 2.7.3

pull/11634/head
Alex Couper 1 year ago
parent
commit
8b802d1e1e
  1. 2
      fastapi/_compat.py
  2. 49
      tests/test_serialize_response_model.py

2
fastapi/_compat.py

@ -150,7 +150,7 @@ if PYDANTIC_V2:
# self._type_adapter.validate_python(value)
#
# context argument was introduced in pydantic 2.7.3
kwargs = {"context": context} if PYDANTIC_VERSION > "2.7.2" else {}
kwargs = {"context": context} if PYDANTIC_VERSION >= "2.7.3" else {}
return self._type_adapter.dump_python(
value,

49
tests/test_serialize_response_model.py

@ -2,10 +2,11 @@ from typing import Dict, List, Optional
import pytest
from fastapi import FastAPI
from fastapi._compat import PYDANTIC_VERSION
from fastapi._compat import PYDANTIC_V2, PYDANTIC_VERSION
from pydantic import BaseModel, Field
from starlette.testclient import TestClient
app = FastAPI()
@ -156,21 +157,20 @@ def test_validdict_exclude_unset():
}
@pytest.mark.skipif(PYDANTIC_VERSION < "2.7.2", reason="requires Pydantic 2.7.3+")
def test_validdict_with_context():
if PYDANTIC_V2:
from pydantic import SerializationInfo, model_serializer
class Item(BaseModel):
name: str = Field(alias="aliased_name")
price: Optional[float] = None
secret: Optional[str] = None
owner_ids: Optional[List[int]] = None
@model_serializer(mode="wrap")
def _serialize(self, handler, info: SerializationInfo):
data = handler(self)
if info.context and info.context.get("mode") == "FASTAPI":
if "price" in data:
data.pop("price")
if "secret" in data:
data.pop("secret")
return data
app_new = FastAPI()
@ -183,15 +183,34 @@ def test_validdict_with_context():
async def get_validdict_with_context():
return {
"k1": Item(aliased_name="foo"),
"k2": Item(aliased_name="bar", price=1.0),
"k3": Item(aliased_name="baz", price=2.0, owner_ids=[1, 2, 3]),
"k2": Item(aliased_name="bar", secret="sEcReT"),
"k3": Item(aliased_name="baz", secret="sEcReT", owner_ids=[1, 2, 3]),
}
client = TestClient(app_new)
response = client.get("/items/validdict-with-context")
response.raise_for_status()
assert response.json() == {
"k1": {"aliased_name": "foo", "owner_ids": None},
"k2": {"aliased_name": "bar", "owner_ids": None},
"k3": {"aliased_name": "baz", "owner_ids": [1, 2, 3]},
}
@pytest.mark.skipif(PYDANTIC_VERSION < "2.7.3", reason="requires Pydantic v2.7.3+")
def test_validdict_with_context__pydantic_supported():
response = client.get("/items/validdict-with-context")
response.raise_for_status()
expected_response = {
"k1": {"aliased_name": "foo", "owner_ids": None},
"k2": {"aliased_name": "bar", "owner_ids": None},
"k3": {"aliased_name": "baz", "owner_ids": [1, 2, 3]},
}
assert response.json() == expected_response
@pytest.mark.skipif(PYDANTIC_VERSION >= "2.7.3", reason="Pydantic supports the feature from this point on")
def test_validdict_with_context__pre_pydantic_support():
response = client.get("/items/validdict-with-context")
response.raise_for_status()
expected_response = {
"k1": {"aliased_name": "foo", "owner_ids": None, "secret": None},
"k2": {"aliased_name": "bar", "owner_ids": None, "secret": "sEcReT"},
"k3": {"aliased_name": "baz", "owner_ids": [1, 2, 3], "secret": "sEcReT"},
}
assert response.json() == expected_response
Loading…
Cancel
Save