]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
perf(c): use UUID.__new__
authorhenadzit <henadzi.tsaryk@gmail.com>
Wed, 29 Jan 2025 23:32:17 +0000 (00:32 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Thu, 20 Feb 2025 10:15:41 +0000 (11:15 +0100)
psycopg_c/psycopg_c/types/uuid.pyx
tests/types/test_uuid.py

index 0c391da6ec14ca13585284415e854c9ad2bce10e..4d643ac9c99536a2418fb98fee934e6d8ca7ec8b 100644 (file)
@@ -8,12 +8,6 @@ cdef extern from "Python.h":
     # support 3.0.x
     const char *PyUnicode_AsUTF8(object unicode) except NULL
 
-from libc.stdio cimport printf
-
-
-#cdef extern from "Python.h":
-#    Py_ssize_t PyLong_AsNativeBytes(PyObject* vv, void* buffer, Py_ssize_t n, int flags)
-
 
 @cython.final
 cdef class UUIDDumper(CDumper):
@@ -37,10 +31,6 @@ cdef class UUIDBinaryDumper(CDumper):
         cdef char *buf = CDumper.ensure_size(rv, offset, 16)
         memcpy(buf, src, 16)
         return 16
-        #cdef PyObject *pyobj = <PyObject*>obj.int
-        #cdef char *buf = CDumper.ensure_size(rv, offset, 16)
-        #PyLong_AsNativeBytes(pyobj, buf, 16, 4)
-        #return 16
 
 
 @cython.final
@@ -48,7 +38,20 @@ cdef class UUIDLoader(CLoader):
     format = PQ_TEXT
 
     cdef object cload(self, const char *data, size_t length):
-        return uuid.UUID(hex=data[:length].decode())
+        cdef char[33] hex_str
+        cdef size_t i
+        cdef int j = 0
+        for i in range(36):
+            if data[i] == b'-':
+                continue
+            hex_str[j] = data[i]
+            j += 1
+        hex_str[32] = 0
+
+        u = uuid.UUID.__new__(uuid.UUID)
+        object.__setattr__(u, 'is_safe', uuid.SafeUUID.unknown)
+        object.__setattr__(u, 'int', PyLong_FromString(hex_str, NULL, 16))
+        return u
 
 
 @cython.final
@@ -56,4 +59,7 @@ cdef class UUIDBinaryLoader(CLoader):
     format = PQ_BINARY
 
     cdef object cload(self, const char *data, size_t length):
-        return uuid.UUID(bytes=data[:length])
+        u = uuid.UUID.__new__(uuid.UUID)
+        object.__setattr__(u, 'is_safe', uuid.SafeUUID.unknown)
+        object.__setattr__(u, 'int', int.from_bytes(data[:length], 'big'))
+        return u
index 3e9987bfbeee72105dce4d4243fdb1fd6c168f70..a9c46544db732934b944e34df8c5a5d867de1888 100644 (file)
@@ -18,9 +18,11 @@ def test_uuid_dump(conn, fmt_in):
 
 @pytest.mark.crdb_skip("copy")
 @pytest.mark.parametrize("fmt_out", pq.Format)
-def test_uuid_load(conn, fmt_out):
+@pytest.mark.parametrize(
+    "val", ["12345678123456781234567812345679", "12345678-1234-5678-1234-567812345679"]
+)
+def test_uuid_load(conn, fmt_out, val):
     cur = conn.cursor(binary=fmt_out)
-    val = "12345678123456781234567812345679"
     cur.execute("select %s::uuid", (val,))
     assert cur.fetchone()[0] == UUID(val)