Browse Source

🔇 Filter warnings for tests with Pydantic v1

pull/14583/head
Sebastián Ramírez 7 months ago
parent
commit
b32b4bfefb
  1. 33
      tests/test_compat_params_v1.py
  2. 6
      tests/test_pydantic_v1_v2_01.py
  3. 9
      tests/test_pydantic_v1_v2_list.py
  4. 35
      tests/test_pydantic_v1_v2_mixed.py
  5. 25
      tests/test_pydantic_v1_v2_multifile/main.py
  6. 17
      tests/test_pydantic_v1_v2_noneable.py

33
tests/test_compat_params_v1.py

@ -1,4 +1,5 @@
import sys import sys
import warnings
from typing import Optional from typing import Optional
import pytest import pytest
@ -33,6 +34,8 @@ class Item(BaseModel):
app = FastAPI() app = FastAPI()
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
@app.get("/items/{item_id}") @app.get("/items/{item_id}")
def get_item_with_path( def get_item_with_path(
@ -40,18 +43,17 @@ def get_item_with_path(
): ):
return {"item_id": item_id} return {"item_id": item_id}
@app.get("/items/") @app.get("/items/")
def get_items_with_query( def get_items_with_query(
q: Annotated[ q: Annotated[
Optional[str], Query(min_length=3, max_length=50, pattern="^[a-zA-Z0-9 ]+$") Optional[str],
Query(min_length=3, max_length=50, pattern="^[a-zA-Z0-9 ]+$"),
] = None, ] = None,
skip: Annotated[int, Query(ge=0)] = 0, skip: Annotated[int, Query(ge=0)] = 0,
limit: Annotated[int, Query(ge=1, le=100, examples=[5])] = 10, limit: Annotated[int, Query(ge=1, le=100, examples=[5])] = 10,
): ):
return {"q": q, "skip": skip, "limit": limit} return {"q": q, "skip": skip, "limit": limit}
@app.get("/users/") @app.get("/users/")
def get_user_with_header( def get_user_with_header(
x_custom: Annotated[Optional[str], Header()] = None, x_custom: Annotated[Optional[str], Header()] = None,
@ -59,7 +61,6 @@ def get_user_with_header(
): ):
return {"x_custom": x_custom, "x_token": x_token} return {"x_custom": x_custom, "x_token": x_token}
@app.get("/cookies/") @app.get("/cookies/")
def get_cookies( def get_cookies(
session_id: Annotated[Optional[str], Cookie()] = None, session_id: Annotated[Optional[str], Cookie()] = None,
@ -67,24 +68,23 @@ def get_cookies(
): ):
return {"session_id": session_id, "tracking_id": tracking_id} return {"session_id": session_id, "tracking_id": tracking_id}
@app.post("/items/") @app.post("/items/")
def create_item( def create_item(
item: Annotated[ item: Annotated[
Item, Item,
Body(examples=[{"name": "Foo", "price": 35.4, "description": "The Foo item"}]), Body(
examples=[{"name": "Foo", "price": 35.4, "description": "The Foo item"}]
),
], ],
): ):
return {"item": item} return {"item": item}
@app.post("/items-embed/") @app.post("/items-embed/")
def create_item_embed( def create_item_embed(
item: Annotated[Item, Body(embed=True)], item: Annotated[Item, Body(embed=True)],
): ):
return {"item": item} return {"item": item}
@app.put("/items/{item_id}") @app.put("/items/{item_id}")
def update_item( def update_item(
item_id: Annotated[int, Path(ge=1)], item_id: Annotated[int, Path(ge=1)],
@ -93,7 +93,6 @@ def update_item(
): ):
return {"item": item, "importance": importance} return {"item": item, "importance": importance}
@app.post("/form-data/") @app.post("/form-data/")
def submit_form( def submit_form(
username: Annotated[str, Form(min_length=3, max_length=50)], username: Annotated[str, Form(min_length=3, max_length=50)],
@ -102,7 +101,6 @@ def submit_form(
): ):
return {"username": username, "password": password, "email": email} return {"username": username, "password": password, "email": email}
@app.post("/upload/") @app.post("/upload/")
def upload_file( def upload_file(
file: Annotated[bytes, File()], file: Annotated[bytes, File()],
@ -110,7 +108,6 @@ def upload_file(
): ):
return {"file_size": len(file), "description": description} return {"file_size": len(file), "description": description}
@app.post("/upload-multiple/") @app.post("/upload-multiple/")
def upload_multiple_files( def upload_multiple_files(
files: Annotated[list[bytes], File()], files: Annotated[list[bytes], File()],
@ -211,10 +208,10 @@ def test_header_params_none():
# Cookie parameter tests # Cookie parameter tests
def test_cookie_params(): def test_cookie_params():
with TestClient(app) as client: with TestClient(app) as test_client:
client.cookies.set("session_id", "abc123") test_client.cookies.set("session_id", "abc123")
client.cookies.set("tracking_id", "1234567890abcdef") test_client.cookies.set("tracking_id", "1234567890abcdef")
response = client.get("/cookies/") response = test_client.get("/cookies/")
assert response.status_code == 200 assert response.status_code == 200
assert response.json() == { assert response.json() == {
"session_id": "abc123", "session_id": "abc123",
@ -223,9 +220,9 @@ def test_cookie_params():
def test_cookie_tracking_id_too_short(): def test_cookie_tracking_id_too_short():
with TestClient(app) as client: with TestClient(app) as test_client:
client.cookies.set("tracking_id", "short") test_client.cookies.set("tracking_id", "short")
response = client.get("/cookies/") response = test_client.get("/cookies/")
assert response.status_code == 422 assert response.status_code == 422
assert response.json() == snapshot( assert response.json() == snapshot(
{ {

6
tests/test_pydantic_v1_v2_01.py

@ -1,4 +1,5 @@
import sys import sys
import warnings
from typing import Any, Union from typing import Any, Union
from tests.utils import skip_module_if_py_gte_314 from tests.utils import skip_module_if_py_gte_314
@ -26,24 +27,23 @@ class Item(BaseModel):
app = FastAPI() app = FastAPI()
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
@app.post("/simple-model") @app.post("/simple-model")
def handle_simple_model(data: SubItem) -> SubItem: def handle_simple_model(data: SubItem) -> SubItem:
return data return data
@app.post("/simple-model-filter", response_model=SubItem) @app.post("/simple-model-filter", response_model=SubItem)
def handle_simple_model_filter(data: SubItem) -> Any: def handle_simple_model_filter(data: SubItem) -> Any:
extended_data = data.dict() extended_data = data.dict()
extended_data.update({"secret_price": 42}) extended_data.update({"secret_price": 42})
return extended_data return extended_data
@app.post("/item") @app.post("/item")
def handle_item(data: Item) -> Item: def handle_item(data: Item) -> Item:
return data return data
@app.post("/item-filter", response_model=Item) @app.post("/item-filter", response_model=Item)
def handle_item_filter(data: Item) -> Any: def handle_item_filter(data: Item) -> Any:
extended_data = data.dict() extended_data = data.dict()

9
tests/test_pydantic_v1_v2_list.py

@ -1,4 +1,5 @@
import sys import sys
import warnings
from typing import Any, Union from typing import Any, Union
from tests.utils import skip_module_if_py_gte_314 from tests.utils import skip_module_if_py_gte_314
@ -27,11 +28,13 @@ class Item(BaseModel):
app = FastAPI() app = FastAPI()
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
@app.post("/item") @app.post("/item")
def handle_item(data: Item) -> list[Item]: def handle_item(data: Item) -> list[Item]:
return [data, data] return [data, data]
@app.post("/item-filter", response_model=list[Item]) @app.post("/item-filter", response_model=list[Item])
def handle_item_filter(data: Item) -> Any: def handle_item_filter(data: Item) -> Any:
extended_data = data.dict() extended_data = data.dict()
@ -39,14 +42,12 @@ def handle_item_filter(data: Item) -> Any:
extended_data["sub"].update({"internal_id": 67890}) extended_data["sub"].update({"internal_id": 67890})
return [extended_data, extended_data] return [extended_data, extended_data]
@app.post("/item-list") @app.post("/item-list")
def handle_item_list(data: list[Item]) -> Item: def handle_item_list(data: list[Item]) -> Item:
if data: if data:
return data[0] return data[0]
return Item(title="", size=0, sub=SubItem(name="")) return Item(title="", size=0, sub=SubItem(name=""))
@app.post("/item-list-filter", response_model=Item) @app.post("/item-list-filter", response_model=Item)
def handle_item_list_filter(data: list[Item]) -> Any: def handle_item_list_filter(data: list[Item]) -> Any:
if data: if data:
@ -56,12 +57,10 @@ def handle_item_list_filter(data: list[Item]) -> Any:
return extended_data return extended_data
return Item(title="", size=0, sub=SubItem(name="")) return Item(title="", size=0, sub=SubItem(name=""))
@app.post("/item-list-to-list") @app.post("/item-list-to-list")
def handle_item_list_to_list(data: list[Item]) -> list[Item]: def handle_item_list_to_list(data: list[Item]) -> list[Item]:
return data return data
@app.post("/item-list-to-list-filter", response_model=list[Item]) @app.post("/item-list-to-list-filter", response_model=list[Item])
def handle_item_list_to_list_filter(data: list[Item]) -> Any: def handle_item_list_to_list_filter(data: list[Item]) -> Any:
if data: if data:

35
tests/test_pydantic_v1_v2_mixed.py

@ -1,4 +1,5 @@
import sys import sys
import warnings
from typing import Any, Union from typing import Any, Union
from tests.utils import skip_module_if_py_gte_314 from tests.utils import skip_module_if_py_gte_314
@ -39,6 +40,8 @@ class NewItem(NewBaseModel):
app = FastAPI() app = FastAPI()
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
@app.post("/v1-to-v2/item") @app.post("/v1-to-v2/item")
def handle_v1_item_to_v2(data: Item) -> NewItem: def handle_v1_item_to_v2(data: Item) -> NewItem:
@ -50,22 +53,24 @@ def handle_v1_item_to_v2(data: Item) -> NewItem:
new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi], new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi],
) )
@app.post("/v1-to-v2/item-filter", response_model=NewItem) @app.post("/v1-to-v2/item-filter", response_model=NewItem)
def handle_v1_item_to_v2_filter(data: Item) -> Any: def handle_v1_item_to_v2_filter(data: Item) -> Any:
result = { result = {
"new_title": data.title, "new_title": data.title,
"new_size": data.size, "new_size": data.size,
"new_description": data.description, "new_description": data.description,
"new_sub": {"new_sub_name": data.sub.name, "new_sub_secret": "sub_hidden"}, "new_sub": {
"new_sub_name": data.sub.name,
"new_sub_secret": "sub_hidden",
},
"new_multi": [ "new_multi": [
{"new_sub_name": s.name, "new_sub_secret": "sub_hidden"} for s in data.multi {"new_sub_name": s.name, "new_sub_secret": "sub_hidden"}
for s in data.multi
], ],
"secret": "hidden_v1_to_v2", "secret": "hidden_v1_to_v2",
} }
return result return result
@app.post("/v2-to-v1/item") @app.post("/v2-to-v1/item")
def handle_v2_item_to_v1(data: NewItem) -> Item: def handle_v2_item_to_v1(data: NewItem) -> Item:
return Item( return Item(
@ -76,7 +81,6 @@ def handle_v2_item_to_v1(data: NewItem) -> Item:
multi=[SubItem(name=s.new_sub_name) for s in data.new_multi], multi=[SubItem(name=s.new_sub_name) for s in data.new_multi],
) )
@app.post("/v2-to-v1/item-filter", response_model=Item) @app.post("/v2-to-v1/item-filter", response_model=Item)
def handle_v2_item_to_v1_filter(data: NewItem) -> Any: def handle_v2_item_to_v1_filter(data: NewItem) -> Any:
result = { result = {
@ -85,13 +89,13 @@ def handle_v2_item_to_v1_filter(data: NewItem) -> Any:
"description": data.new_description, "description": data.new_description,
"sub": {"name": data.new_sub.new_sub_name, "sub_secret": "sub_hidden"}, "sub": {"name": data.new_sub.new_sub_name, "sub_secret": "sub_hidden"},
"multi": [ "multi": [
{"name": s.new_sub_name, "sub_secret": "sub_hidden"} for s in data.new_multi {"name": s.new_sub_name, "sub_secret": "sub_hidden"}
for s in data.new_multi
], ],
"secret": "hidden_v2_to_v1", "secret": "hidden_v2_to_v1",
} }
return result return result
@app.post("/v1-to-v2/item-to-list") @app.post("/v1-to-v2/item-to-list")
def handle_v1_item_to_v2_list(data: Item) -> list[NewItem]: def handle_v1_item_to_v2_list(data: Item) -> list[NewItem]:
converted = NewItem( converted = NewItem(
@ -103,7 +107,6 @@ def handle_v1_item_to_v2_list(data: Item) -> list[NewItem]:
) )
return [converted, converted] return [converted, converted]
@app.post("/v1-to-v2/list-to-list") @app.post("/v1-to-v2/list-to-list")
def handle_v1_list_to_v2_list(data: list[Item]) -> list[NewItem]: def handle_v1_list_to_v2_list(data: list[Item]) -> list[NewItem]:
result = [] result = []
@ -119,7 +122,6 @@ def handle_v1_list_to_v2_list(data: list[Item]) -> list[NewItem]:
) )
return result return result
@app.post("/v1-to-v2/list-to-list-filter", response_model=list[NewItem]) @app.post("/v1-to-v2/list-to-list-filter", response_model=list[NewItem])
def handle_v1_list_to_v2_list_filter(data: list[Item]) -> Any: def handle_v1_list_to_v2_list_filter(data: list[Item]) -> Any:
result = [] result = []
@ -128,7 +130,10 @@ def handle_v1_list_to_v2_list_filter(data: list[Item]) -> Any:
"new_title": item.title, "new_title": item.title,
"new_size": item.size, "new_size": item.size,
"new_description": item.description, "new_description": item.description,
"new_sub": {"new_sub_name": item.sub.name, "new_sub_secret": "sub_hidden"}, "new_sub": {
"new_sub_name": item.sub.name,
"new_sub_secret": "sub_hidden",
},
"new_multi": [ "new_multi": [
{"new_sub_name": s.name, "new_sub_secret": "sub_hidden"} {"new_sub_name": s.name, "new_sub_secret": "sub_hidden"}
for s in item.multi for s in item.multi
@ -138,7 +143,6 @@ def handle_v1_list_to_v2_list_filter(data: list[Item]) -> Any:
result.append(converted) result.append(converted)
return result return result
@app.post("/v1-to-v2/list-to-item") @app.post("/v1-to-v2/list-to-item")
def handle_v1_list_to_v2_item(data: list[Item]) -> NewItem: def handle_v1_list_to_v2_item(data: list[Item]) -> NewItem:
if data: if data:
@ -152,7 +156,6 @@ def handle_v1_list_to_v2_item(data: list[Item]) -> NewItem:
) )
return NewItem(new_title="", new_size=0, new_sub=NewSubItem(new_sub_name="")) return NewItem(new_title="", new_size=0, new_sub=NewSubItem(new_sub_name=""))
@app.post("/v2-to-v1/item-to-list") @app.post("/v2-to-v1/item-to-list")
def handle_v2_item_to_v1_list(data: NewItem) -> list[Item]: def handle_v2_item_to_v1_list(data: NewItem) -> list[Item]:
converted = Item( converted = Item(
@ -164,7 +167,6 @@ def handle_v2_item_to_v1_list(data: NewItem) -> list[Item]:
) )
return [converted, converted] return [converted, converted]
@app.post("/v2-to-v1/list-to-list") @app.post("/v2-to-v1/list-to-list")
def handle_v2_list_to_v1_list(data: list[NewItem]) -> list[Item]: def handle_v2_list_to_v1_list(data: list[NewItem]) -> list[Item]:
result = [] result = []
@ -180,7 +182,6 @@ def handle_v2_list_to_v1_list(data: list[NewItem]) -> list[Item]:
) )
return result return result
@app.post("/v2-to-v1/list-to-list-filter", response_model=list[Item]) @app.post("/v2-to-v1/list-to-list-filter", response_model=list[Item])
def handle_v2_list_to_v1_list_filter(data: list[NewItem]) -> Any: def handle_v2_list_to_v1_list_filter(data: list[NewItem]) -> Any:
result = [] result = []
@ -189,7 +190,10 @@ def handle_v2_list_to_v1_list_filter(data: list[NewItem]) -> Any:
"title": item.new_title, "title": item.new_title,
"size": item.new_size, "size": item.new_size,
"description": item.new_description, "description": item.new_description,
"sub": {"name": item.new_sub.new_sub_name, "sub_secret": "sub_hidden"}, "sub": {
"name": item.new_sub.new_sub_name,
"sub_secret": "sub_hidden",
},
"multi": [ "multi": [
{"name": s.new_sub_name, "sub_secret": "sub_hidden"} {"name": s.new_sub_name, "sub_secret": "sub_hidden"}
for s in item.new_multi for s in item.new_multi
@ -199,7 +203,6 @@ def handle_v2_list_to_v1_list_filter(data: list[NewItem]) -> Any:
result.append(converted) result.append(converted)
return result return result
@app.post("/v2-to-v1/list-to-item") @app.post("/v2-to-v1/list-to-item")
def handle_v2_list_to_v1_item(data: list[NewItem]) -> Item: def handle_v2_list_to_v1_item(data: list[NewItem]) -> Item:
if data: if data:

25
tests/test_pydantic_v1_v2_multifile/main.py

@ -1,9 +1,13 @@
import warnings
from fastapi import FastAPI from fastapi import FastAPI
from . import modelsv1, modelsv2, modelsv2b from . import modelsv1, modelsv2, modelsv2b
app = FastAPI() app = FastAPI()
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
@app.post("/v1-to-v2/item") @app.post("/v1-to-v2/item")
def handle_v1_item_to_v2(data: modelsv1.Item) -> modelsv2.Item: def handle_v1_item_to_v2(data: modelsv1.Item) -> modelsv2.Item:
@ -15,7 +19,6 @@ def handle_v1_item_to_v2(data: modelsv1.Item) -> modelsv2.Item:
new_multi=[modelsv2.SubItem(new_sub_name=s.name) for s in data.multi], new_multi=[modelsv2.SubItem(new_sub_name=s.name) for s in data.multi],
) )
@app.post("/v2-to-v1/item") @app.post("/v2-to-v1/item")
def handle_v2_item_to_v1(data: modelsv2.Item) -> modelsv1.Item: def handle_v2_item_to_v1(data: modelsv2.Item) -> modelsv1.Item:
return modelsv1.Item( return modelsv1.Item(
@ -26,7 +29,6 @@ def handle_v2_item_to_v1(data: modelsv2.Item) -> modelsv1.Item:
multi=[modelsv1.SubItem(name=s.new_sub_name) for s in data.new_multi], multi=[modelsv1.SubItem(name=s.new_sub_name) for s in data.new_multi],
) )
@app.post("/v1-to-v2/item-to-list") @app.post("/v1-to-v2/item-to-list")
def handle_v1_item_to_v2_list(data: modelsv1.Item) -> list[modelsv2.Item]: def handle_v1_item_to_v2_list(data: modelsv1.Item) -> list[modelsv2.Item]:
converted = modelsv2.Item( converted = modelsv2.Item(
@ -38,7 +40,6 @@ def handle_v1_item_to_v2_list(data: modelsv1.Item) -> list[modelsv2.Item]:
) )
return [converted, converted] return [converted, converted]
@app.post("/v1-to-v2/list-to-list") @app.post("/v1-to-v2/list-to-list")
def handle_v1_list_to_v2_list(data: list[modelsv1.Item]) -> list[modelsv2.Item]: def handle_v1_list_to_v2_list(data: list[modelsv1.Item]) -> list[modelsv2.Item]:
result = [] result = []
@ -49,12 +50,13 @@ def handle_v1_list_to_v2_list(data: list[modelsv1.Item]) -> list[modelsv2.Item]:
new_size=item.size, new_size=item.size,
new_description=item.description, new_description=item.description,
new_sub=modelsv2.SubItem(new_sub_name=item.sub.name), new_sub=modelsv2.SubItem(new_sub_name=item.sub.name),
new_multi=[modelsv2.SubItem(new_sub_name=s.name) for s in item.multi], new_multi=[
modelsv2.SubItem(new_sub_name=s.name) for s in item.multi
],
) )
) )
return result return result
@app.post("/v1-to-v2/list-to-item") @app.post("/v1-to-v2/list-to-item")
def handle_v1_list_to_v2_item(data: list[modelsv1.Item]) -> modelsv2.Item: def handle_v1_list_to_v2_item(data: list[modelsv1.Item]) -> modelsv2.Item:
if data: if data:
@ -70,7 +72,6 @@ def handle_v1_list_to_v2_item(data: list[modelsv1.Item]) -> modelsv2.Item:
new_title="", new_size=0, new_sub=modelsv2.SubItem(new_sub_name="") new_title="", new_size=0, new_sub=modelsv2.SubItem(new_sub_name="")
) )
@app.post("/v2-to-v1/item-to-list") @app.post("/v2-to-v1/item-to-list")
def handle_v2_item_to_v1_list(data: modelsv2.Item) -> list[modelsv1.Item]: def handle_v2_item_to_v1_list(data: modelsv2.Item) -> list[modelsv1.Item]:
converted = modelsv1.Item( converted = modelsv1.Item(
@ -82,7 +83,6 @@ def handle_v2_item_to_v1_list(data: modelsv2.Item) -> list[modelsv1.Item]:
) )
return [converted, converted] return [converted, converted]
@app.post("/v2-to-v1/list-to-list") @app.post("/v2-to-v1/list-to-list")
def handle_v2_list_to_v1_list(data: list[modelsv2.Item]) -> list[modelsv1.Item]: def handle_v2_list_to_v1_list(data: list[modelsv2.Item]) -> list[modelsv1.Item]:
result = [] result = []
@ -93,12 +93,13 @@ def handle_v2_list_to_v1_list(data: list[modelsv2.Item]) -> list[modelsv1.Item]:
size=item.new_size, size=item.new_size,
description=item.new_description, description=item.new_description,
sub=modelsv1.SubItem(name=item.new_sub.new_sub_name), sub=modelsv1.SubItem(name=item.new_sub.new_sub_name),
multi=[modelsv1.SubItem(name=s.new_sub_name) for s in item.new_multi], multi=[
modelsv1.SubItem(name=s.new_sub_name) for s in item.new_multi
],
) )
) )
return result return result
@app.post("/v2-to-v1/list-to-item") @app.post("/v2-to-v1/list-to-item")
def handle_v2_list_to_v1_item(data: list[modelsv2.Item]) -> modelsv1.Item: def handle_v2_list_to_v1_item(data: list[modelsv2.Item]) -> modelsv1.Item:
if data: if data:
@ -112,7 +113,6 @@ def handle_v2_list_to_v1_item(data: list[modelsv2.Item]) -> modelsv1.Item:
) )
return modelsv1.Item(title="", size=0, sub=modelsv1.SubItem(name="")) return modelsv1.Item(title="", size=0, sub=modelsv1.SubItem(name=""))
@app.post("/v2-to-v1/same-name") @app.post("/v2-to-v1/same-name")
def handle_v2_same_name_to_v1( def handle_v2_same_name_to_v1(
item1: modelsv2.Item, item2: modelsv2b.Item item1: modelsv2.Item, item2: modelsv2b.Item
@ -125,16 +125,13 @@ def handle_v2_same_name_to_v1(
multi=[modelsv1.SubItem(name=s.dup_sub_name) for s in item2.dup_multi], multi=[modelsv1.SubItem(name=s.dup_sub_name) for s in item2.dup_multi],
) )
@app.post("/v2-to-v1/list-of-items-to-list-of-items") @app.post("/v2-to-v1/list-of-items-to-list-of-items")
def handle_v2_items_in_list_to_v1_item_in_list( def handle_v2_items_in_list_to_v1_item_in_list(
data1: list[modelsv2.ItemInList], data2: list[modelsv2b.ItemInList] data1: list[modelsv2.ItemInList], data2: list[modelsv2b.ItemInList]
) -> list[modelsv1.ItemInList]: ) -> list[modelsv1.ItemInList]:
result = []
item1 = data1[0] item1 = data1[0]
item2 = data2[0] item2 = data2[0]
result = [ return [
modelsv1.ItemInList(name1=item1.name2), modelsv1.ItemInList(name1=item1.name2),
modelsv1.ItemInList(name1=item2.dup_name2), modelsv1.ItemInList(name1=item2.dup_name2),
] ]
return result

17
tests/test_pydantic_v1_v2_noneable.py

@ -1,4 +1,5 @@
import sys import sys
import warnings
from typing import Any, Union from typing import Any, Union
from tests.utils import skip_module_if_py_gte_314 from tests.utils import skip_module_if_py_gte_314
@ -39,6 +40,8 @@ class NewItem(NewBaseModel):
app = FastAPI() app = FastAPI()
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
@app.post("/v1-to-v2/") @app.post("/v1-to-v2/")
def handle_v1_item_to_v2(data: Item) -> Union[NewItem, None]: def handle_v1_item_to_v2(data: Item) -> Union[NewItem, None]:
@ -52,7 +55,6 @@ def handle_v1_item_to_v2(data: Item) -> Union[NewItem, None]:
new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi], new_multi=[NewSubItem(new_sub_name=s.name) for s in data.multi],
) )
@app.post("/v1-to-v2/item-filter", response_model=Union[NewItem, None]) @app.post("/v1-to-v2/item-filter", response_model=Union[NewItem, None])
def handle_v1_item_to_v2_filter(data: Item) -> Any: def handle_v1_item_to_v2_filter(data: Item) -> Any:
if data.size < 0: if data.size < 0:
@ -61,15 +63,18 @@ def handle_v1_item_to_v2_filter(data: Item) -> Any:
"new_title": data.title, "new_title": data.title,
"new_size": data.size, "new_size": data.size,
"new_description": data.description, "new_description": data.description,
"new_sub": {"new_sub_name": data.sub.name, "new_sub_secret": "sub_hidden"}, "new_sub": {
"new_sub_name": data.sub.name,
"new_sub_secret": "sub_hidden",
},
"new_multi": [ "new_multi": [
{"new_sub_name": s.name, "new_sub_secret": "sub_hidden"} for s in data.multi {"new_sub_name": s.name, "new_sub_secret": "sub_hidden"}
for s in data.multi
], ],
"secret": "hidden_v1_to_v2", "secret": "hidden_v1_to_v2",
} }
return result return result
@app.post("/v2-to-v1/item") @app.post("/v2-to-v1/item")
def handle_v2_item_to_v1(data: NewItem) -> Union[Item, None]: def handle_v2_item_to_v1(data: NewItem) -> Union[Item, None]:
if data.new_size < 0: if data.new_size < 0:
@ -82,7 +87,6 @@ def handle_v2_item_to_v1(data: NewItem) -> Union[Item, None]:
multi=[SubItem(name=s.new_sub_name) for s in data.new_multi], multi=[SubItem(name=s.new_sub_name) for s in data.new_multi],
) )
@app.post("/v2-to-v1/item-filter", response_model=Union[Item, None]) @app.post("/v2-to-v1/item-filter", response_model=Union[Item, None])
def handle_v2_item_to_v1_filter(data: NewItem) -> Any: def handle_v2_item_to_v1_filter(data: NewItem) -> Any:
if data.new_size < 0: if data.new_size < 0:
@ -93,7 +97,8 @@ def handle_v2_item_to_v1_filter(data: NewItem) -> Any:
"description": data.new_description, "description": data.new_description,
"sub": {"name": data.new_sub.new_sub_name, "sub_secret": "sub_hidden"}, "sub": {"name": data.new_sub.new_sub_name, "sub_secret": "sub_hidden"},
"multi": [ "multi": [
{"name": s.new_sub_name, "sub_secret": "sub_hidden"} for s in data.new_multi {"name": s.new_sub_name, "sub_secret": "sub_hidden"}
for s in data.new_multi
], ],
"secret": "hidden_v2_to_v1", "secret": "hidden_v2_to_v1",
} }

Loading…
Cancel
Save