Coverage for tests/test_inherited_custom_class.py: 100%
69 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-13 13:38 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-13 13:38 +0000
1import uuid 1klmno
3import pytest 1klmno
4from fastapi import FastAPI 1klmno
5from fastapi.testclient import TestClient 1klmno
6from pydantic import BaseModel 1klmno
8from .utils import needs_pydanticv1, needs_pydanticv2 1klmno
11class MyUuid: 1klmno
12 def __init__(self, uuid_string: str): 1klmno
13 self.uuid = uuid_string 1fagbhcidje
15 def __str__(self): 1klmno
16 return self.uuid 1fagbhcidje
18 @property # type: ignore 1klmno
19 def __class__(self): 1klmno
20 return uuid.UUID 1fagbhcidje
22 @property 1klmno
23 def __dict__(self): 1klmno
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") 1fagbhcidje
29@needs_pydanticv2 1klmno
30def test_pydanticv2(): 1klmno
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) is not 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 1klmno
75def test_pydanticv1(): 1klmno
76 app = FastAPI() 1fghij
78 @app.get("/fast_uuid") 1fghij
79 def return_fast_uuid(): 1fghij
80 asyncpg_uuid = MyUuid("a10ff360-3b1e-4984-a26f-d3ab460bdb51") 1fghij
81 assert isinstance(asyncpg_uuid, uuid.UUID) 1fghij
82 assert type(asyncpg_uuid) is not uuid.UUID 1fghij
83 with pytest.raises(TypeError): 1fghij
84 vars(asyncpg_uuid) 1fghij
85 return {"fast_uuid": asyncpg_uuid} 1fghij
87 class SomeCustomClass(BaseModel): 1fghij
88 class Config: 1fghij
89 arbitrary_types_allowed = True 1fghij
90 json_encoders = {uuid.UUID: str} 1fghij
92 a_uuid: MyUuid 1fghij
94 @app.get("/get_custom_class") 1fghij
95 def return_some_user(): 1fghij
96 # Test that the fix also works for custom pydantic classes
97 return SomeCustomClass(a_uuid=MyUuid("b8799909-f914-42de-91bc-95c819218d01")) 1fghij
99 client = TestClient(app) 1fghij
101 with client: 1fghij
102 response_simple = client.get("/fast_uuid") 1fghij
103 response_pydantic = client.get("/get_custom_class") 1fghij
105 assert response_simple.json() == { 1fghij
106 "fast_uuid": "a10ff360-3b1e-4984-a26f-d3ab460bdb51"
107 }
109 assert response_pydantic.json() == { 1fghij
110 "a_uuid": "b8799909-f914-42de-91bc-95c819218d01"
111 }