Coverage for tests/test_inherited_custom_class.py: 100%
69 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-08 03:53 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-08 03:53 +0000
1import uuid 1abcde
3import pytest 1abcde
4from fastapi import FastAPI 1abcde
5from fastapi.testclient import TestClient 1abcde
6from pydantic import BaseModel 1abcde
8from .utils import needs_pydanticv1, needs_pydanticv2 1abcde
11class MyUuid: 1abcde
12 def __init__(self, uuid_string: str): 1abcde
13 self.uuid = uuid_string 1abcde
15 def __str__(self): 1abcde
16 return self.uuid 1abcde
18 @property # type: ignore 1abcde
19 def __class__(self): 1abcde
20 return uuid.UUID 1abcde
22 @property 1abcde
23 def __dict__(self): 1abcde
24 """Spoof a missing __dict__ by raising TypeError, this is how
25 asyncpg.pgroto.pgproto.UUID behaves"""
26 raise TypeError("vars() argument must have __dict__ attribute") 1abcde
29@needs_pydanticv2 1abcde
30def test_pydanticv2(): 1abcde
31 from pydantic import field_serializer 1abcde
33 app = FastAPI() 1abcde
35 @app.get("/fast_uuid") 1abcde
36 def return_fast_uuid(): 1abcde
37 asyncpg_uuid = MyUuid("a10ff360-3b1e-4984-a26f-d3ab460bdb51") 1abcde
38 assert isinstance(asyncpg_uuid, uuid.UUID) 1abcde
39 assert type(asyncpg_uuid) != uuid.UUID 1abcde
40 with pytest.raises(TypeError): 1abcde
41 vars(asyncpg_uuid) 1abcde
42 return {"fast_uuid": asyncpg_uuid} 1abcde
44 class SomeCustomClass(BaseModel): 1abcde
45 model_config = {"arbitrary_types_allowed": True} 1abcde
47 a_uuid: MyUuid 1abcde
49 @field_serializer("a_uuid") 1abcde
50 def serialize_a_uuid(self, v): 1abcde
51 return str(v) 1abcde
53 @app.get("/get_custom_class") 1abcde
54 def return_some_user(): 1abcde
55 # Test that the fix also works for custom pydantic classes
56 return SomeCustomClass(a_uuid=MyUuid("b8799909-f914-42de-91bc-95c819218d01")) 1abcde
58 client = TestClient(app) 1abcde
60 with client: 1abcde
61 response_simple = client.get("/fast_uuid") 1abcde
62 response_pydantic = client.get("/get_custom_class") 1abcde
64 assert response_simple.json() == { 1abcde
65 "fast_uuid": "a10ff360-3b1e-4984-a26f-d3ab460bdb51"
66 }
68 assert response_pydantic.json() == { 1abcde
69 "a_uuid": "b8799909-f914-42de-91bc-95c819218d01"
70 }
73# TODO: remove when deprecating Pydantic v1
74@needs_pydanticv1 1abcde
75def test_pydanticv1(): 1abcde
76 app = FastAPI() 1abcde
78 @app.get("/fast_uuid") 1abcde
79 def return_fast_uuid(): 1abcde
80 asyncpg_uuid = MyUuid("a10ff360-3b1e-4984-a26f-d3ab460bdb51") 1abcde
81 assert isinstance(asyncpg_uuid, uuid.UUID) 1abcde
82 assert type(asyncpg_uuid) != uuid.UUID 1abcde
83 with pytest.raises(TypeError): 1abcde
84 vars(asyncpg_uuid) 1abcde
85 return {"fast_uuid": asyncpg_uuid} 1abcde
87 class SomeCustomClass(BaseModel): 1abcde
88 class Config: 1abcde
89 arbitrary_types_allowed = True 1abcde
90 json_encoders = {uuid.UUID: str} 1abcde
92 a_uuid: MyUuid 1abcde
94 @app.get("/get_custom_class") 1abcde
95 def return_some_user(): 1abcde
96 # Test that the fix also works for custom pydantic classes
97 return SomeCustomClass(a_uuid=MyUuid("b8799909-f914-42de-91bc-95c819218d01")) 1abcde
99 client = TestClient(app) 1abcde
101 with client: 1abcde
102 response_simple = client.get("/fast_uuid") 1abcde
103 response_pydantic = client.get("/get_custom_class") 1abcde
105 assert response_simple.json() == { 1abcde
106 "fast_uuid": "a10ff360-3b1e-4984-a26f-d3ab460bdb51"
107 }
109 assert response_pydantic.json() == { 1abcde
110 "a_uuid": "b8799909-f914-42de-91bc-95c819218d01"
111 }