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