# Register default adapters
from . import array, composite, date, json, numeric, singletons, text # noqa
+from . import uuid # noqa
# Register associations with array oids
array.register_all_arrays()
--- /dev/null
+"""
+Adapters for the UUID type.
+"""
+
+# Copyright (C) 2020 The Psycopg Team
+
+# TODO: importing uuid is slow. Don't import it at module level.
+# Should implement lazy dumper registration.
+from uuid import UUID
+
+import codecs
+
+from ..adapt import Dumper, Loader
+from ..proto import DecodeFunc, EncodeFunc
+from .oids import builtins
+
+_encode_ascii = codecs.lookup("ascii").encode
+_decode_ascii = codecs.lookup("ascii").decode
+
+
+@Dumper.text(UUID)
+class UUIDDumper(Dumper):
+
+ oid = builtins["uuid"].oid
+
+ def dump(self, obj: UUID, __encode: EncodeFunc = _encode_ascii) -> bytes:
+ return __encode(obj.hex)[0]
+
+
+@Dumper.binary(UUID)
+class UUIDBinaryDumper(Dumper):
+
+ oid = builtins["uuid"].oid
+
+ def dump(self, obj: UUID) -> bytes:
+ return obj.bytes
+
+
+@Loader.text(builtins["uuid"].oid)
+class UUIDLoader(Loader):
+ def load(self, data: bytes, __decode: DecodeFunc = _decode_ascii) -> UUID:
+ return UUID(__decode(data)[0])
+
+
+@Loader.binary(builtins["uuid"].oid)
+class UUIDBinaryLoader(Loader):
+ def load(self, data: bytes) -> UUID:
+ return UUID(bytes=data)
--- /dev/null
+from uuid import UUID
+
+import pytest
+
+from psycopg3.adapt import Format
+
+
+@pytest.mark.parametrize("fmt_in", [Format.TEXT, Format.BINARY])
+def test_uuid_dump(conn, fmt_in):
+ ph = "%s" if fmt_in == Format.TEXT else "%b"
+ val = "12345678123456781234567812345679"
+ cur = conn.cursor()
+ cur.execute(f"select {ph} = %s::uuid", (UUID(val), val))
+ assert cur.fetchone()[0] is True
+
+
+@pytest.mark.parametrize("fmt_out", [Format.TEXT, Format.BINARY])
+def test_uuid_load(conn, fmt_out):
+ cur = conn.cursor(format=fmt_out)
+ val = "12345678123456781234567812345679"
+ cur.execute("select %s::uuid", (val,))
+ assert cur.fetchone()[0] == UUID(val)