spoof a missing dict by raising typeerror this is how asyncpg pgroto pgproto uuid behaves raise typeerrorvars argument must have dict attribute needspydanticv2 def testpydanticv2 from pydantic import fieldserializer app fastapi app getfastuuid def returnfastuuid asyncpguuid myuuida10ff3603b1e4984a26fd3ab460bdb51 assert isinstanceasyncpguuid uuid uuid assert typeasyncpguuid uuid uuid with pytest raisestypeerror varsasyncpguuid return fastuuid asyncpguuid class somecustomclassbasemodel modelconfig arbitrarytypesallowed true auuid myuuid fieldserializerauuid def serializeauuidself v return strv app getgetcustomclass def returnsomeuser test that the fix also works for custom pydantic classes return somecustomclassauuidmyuuidb8799909f91442de91bc95c819218d01 client testclientapp with client responsesimple client getfastuuid responsepydantic client getgetcustomclass assert responsesimple json fastuuid a10ff3603b1e4984a26fd3ab460bdb51 assert responsepydantic json auuid b8799909f91442de91bc95c819218d01 todo remove when deprecating pydantic v1 needspydanticv1 def testpydanticv1 app fastapi app getfastuuid def returnfastuuid asyncpguuid myuuida10ff3603b1e4984a26fd3ab460bdb51 assert isinstanceasyncpguuid uuid uuid assert typeasyncpguuid uuid uuid with pytest raisestypeerror varsasyncpguuid return fastuuid asyncpguuid class somecustomclassbasemodel class config arbitrarytypesallowed true jsonencoders uuid uuid str auuid myuuid app getgetcustomclass def returnsomeuser test that the fix also works for custom pydantic classes return somecustomclassauuidmyuuidb8799909f91442de91bc95c819218d01 client testclientapp with client responsesimple client getfastuuid responsepydantic client getgetcustomclass assert responsesimple json fastuuid a10ff3603b1e4984a26fd3ab460bdb51 assert responsepydantic json auuid b8799909f91442de91bc95c819218d01 type ignore spoof a missing __dict__ by raising typeerror this is how asyncpg pgroto pgproto uuid behaves test that the fix also works for custom pydantic classes todo remove when deprecating pydantic v1 test that the fix also works for custom pydantic classes
import uuid

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel

from .utils import needs_pydanticv1, needs_pydanticv2


class MyUuid:
    def __init__(self, uuid_string: str):
        self.uuid = uuid_string

    def __str__(self):
        return self.uuid

    @property  
    def __class__(self):
        return uuid.UUID

    @property
    def __dict__(self):
        
        raise TypeError("vars() argument must have __dict__ attribute")


@needs_pydanticv2
def test_pydanticv2():
    from pydantic import field_serializer

    app = FastAPI()

    @app.get("/fast_uuid")
    def return_fast_uuid():
        asyncpg_uuid = MyUuid("a10ff360-3b1e-4984-a26f-d3ab460bdb51")
        assert isinstance(asyncpg_uuid, uuid.UUID)
        assert type(asyncpg_uuid) != uuid.UUID
        with pytest.raises(TypeError):
            vars(asyncpg_uuid)
        return {"fast_uuid": asyncpg_uuid}

    class SomeCustomClass(BaseModel):
        model_config = {"arbitrary_types_allowed": True}

        a_uuid: MyUuid

        @field_serializer("a_uuid")
        def serialize_a_uuid(self, v):
            return str(v)

    @app.get("/get_custom_class")
    def return_some_user():
        
        return SomeCustomClass(a_uuid=MyUuid("b8799909-f914-42de-91bc-95c819218d01"))

    client = TestClient(app)

    with client:
        response_simple = client.get("/fast_uuid")
        response_pydantic = client.get("/get_custom_class")

    assert response_simple.json() == {
        "fast_uuid": "a10ff360-3b1e-4984-a26f-d3ab460bdb51"
    }

    assert response_pydantic.json() == {
        "a_uuid": "b8799909-f914-42de-91bc-95c819218d01"
    }



@needs_pydanticv1
def test_pydanticv1():
    app = FastAPI()

    @app.get("/fast_uuid")
    def return_fast_uuid():
        asyncpg_uuid = MyUuid("a10ff360-3b1e-4984-a26f-d3ab460bdb51")
        assert isinstance(asyncpg_uuid, uuid.UUID)
        assert type(asyncpg_uuid) != uuid.UUID
        with pytest.raises(TypeError):
            vars(asyncpg_uuid)
        return {"fast_uuid": asyncpg_uuid}

    class SomeCustomClass(BaseModel):
        class Config:
            arbitrary_types_allowed = True
            json_encoders = {uuid.UUID: str}

        a_uuid: MyUuid

    @app.get("/get_custom_class")
    def return_some_user():
        
        return SomeCustomClass(a_uuid=MyUuid("b8799909-f914-42de-91bc-95c819218d01"))

    client = TestClient(app)

    with client:
        response_simple = client.get("/fast_uuid")
        response_pydantic = client.get("/get_custom_class")

    assert response_simple.json() == {
        "fast_uuid": "a10ff360-3b1e-4984-a26f-d3ab460bdb51"
    }

    assert response_pydantic.json() == {
        "a_uuid": "b8799909-f914-42de-91bc-95c819218d01"
    }