|  | 
| 3 | 3 |  * DCE compatible Universally Unique Identifier library. | 
| 4 | 4 |  */ | 
| 5 | 5 | 
 | 
| 6 |  | -// Need limited C API version 3.13 for Py_mod_gil | 
| 7 |  | -#include "pyconfig.h"   // Py_GIL_DISABLED | 
| 8 |  | -#ifndef Py_GIL_DISABLED | 
| 9 |  | -#  define Py_LIMITED_API 0x030d0000 | 
| 10 |  | -#endif | 
| 11 |  | - | 
|  | 6 | +#define Py_BUILD_CORE_MODULE | 
| 12 | 7 | #include "Python.h" | 
|  | 8 | +#include "pycore_long.h"  // _PyLong_AsByteArray | 
| 13 | 9 | #if defined(HAVE_UUID_H) | 
| 14 | 10 |   // AIX, FreeBSD, libuuid with pkgconf | 
| 15 | 11 |   #include <uuid.h> | 
| @@ -90,6 +86,42 @@ py_windows_has_stable_node(void) | 
| 90 | 86 | } | 
| 91 | 87 | #endif /* MS_WINDOWS */ | 
| 92 | 88 | 
 | 
|  | 89 | +static PyObject * | 
|  | 90 | +py_uuid_int_to_str(PyObject *Py_UNUSED(context), PyObject *uuid_int) | 
|  | 91 | +{ | 
|  | 92 | +    if (!PyLong_Check(uuid_int)) { | 
|  | 93 | +        PyErr_SetString(PyExc_TypeError, "uuid_int must be an integer"); | 
|  | 94 | +        return NULL; | 
|  | 95 | +    } | 
|  | 96 | + | 
|  | 97 | +    unsigned char bytes[16]; | 
|  | 98 | +    if (_PyLong_AsByteArray((PyLongObject *)uuid_int, bytes, 16, 0, 0, 1) < 0) { | 
|  | 99 | +        return NULL; | 
|  | 100 | +    } | 
|  | 101 | + | 
|  | 102 | +    PyObject *result = PyUnicode_New(36, 127); | 
|  | 103 | +    if (result == NULL) { | 
|  | 104 | +        return NULL; | 
|  | 105 | +    } | 
|  | 106 | +    assert(PyUnicode_KIND(result) == PyUnicode_1BYTE_KIND); | 
|  | 107 | +    Py_UCS1 *str = PyUnicode_1BYTE_DATA(result); | 
|  | 108 | +    static const Py_UCS1 hex_digits[] = "0123456789abcdef"; | 
|  | 109 | + | 
|  | 110 | +    int pos = 0; | 
|  | 111 | +    for (int i = 0; i < 16; i++) { | 
|  | 112 | +        if (i == 4 || i == 6 || i == 8 || i == 10) { | 
|  | 113 | +            str[pos++] = '-'; | 
|  | 114 | +        } | 
|  | 115 | +        unsigned char byte = bytes[i]; | 
|  | 116 | +        str[pos++] = hex_digits[byte >> 4]; | 
|  | 117 | +        str[pos++] = hex_digits[byte & 0x0f]; | 
|  | 118 | +    } | 
|  | 119 | +#ifdef Py_DEBUG | 
|  | 120 | +    assert(pos == 36); | 
|  | 121 | +    assert(_PyUnicode_CheckConsistency(result, 1)); | 
|  | 122 | +#endif | 
|  | 123 | +    return result; | 
|  | 124 | +} | 
| 93 | 125 | 
 | 
| 94 | 126 | static int | 
| 95 | 127 | uuid_exec(PyObject *module) | 
| @@ -129,6 +161,7 @@ static PyMethodDef uuid_methods[] = { | 
| 129 | 161 | #if defined(MS_WINDOWS) | 
| 130 | 162 |     {"UuidCreate", py_UuidCreate, METH_NOARGS, NULL}, | 
| 131 | 163 | #endif | 
|  | 164 | +    {"uuid_int_to_str", py_uuid_int_to_str, METH_O, NULL}, | 
| 132 | 165 |     {NULL, NULL, 0, NULL}           /* sentinel */ | 
| 133 | 166 | }; | 
| 134 | 167 | 
 | 
|  | 
0 commit comments