Index: setup.py =================================================================== --- setup.py (revision 74612) +++ setup.py (working copy) @@ -438,6 +438,8 @@ # static Unicode character database exts.append( Extension('unicodedata', ['unicodedata.c']) ) + exts.append( Extension('_uuid', ['_uuid.c'], libraries=['uuid']) ) + # Modules with some UNIX dependencies -- on by default: # (If you have a really backward UNIX, select and socket may not be # supported...) Index: Lib/uuid.py =================================================================== --- Lib/uuid.py (revision 74612) +++ Lib/uuid.py (working copy) @@ -412,7 +412,16 @@ # If ctypes is available, use it to find system routines for UUID generation. # XXX This makes the module non-thread-safe! _uuid_generate_random = _uuid_generate_time = _UuidCreate = None + +_uuid_generate_random_fast = _uuid_generate_time_fast = None try: + import _uuid + _uuid_generate_random_fast = _uuid.uuid4 + _uuid_generate_time_fast = _uuid.uuid1 +except ImportError: + pass + +try: import ctypes, ctypes.util # The uuid_generate_* routines are provided by libuuid on at least @@ -446,6 +455,8 @@ def _unixdll_getnode(): """Get the hardware address on Unix using ctypes.""" + if _uuid_generate_random_fast: + return UUID(bytes=bytes_(_uuid_generate_random_fast())).node _buffer = ctypes.create_string_buffer(16) _uuid_generate_time(_buffer) return UUID(bytes=bytes_(_buffer.raw)).node @@ -500,10 +511,13 @@ # When the system provides a version-1 UUID generator, use it (but don't # use UuidCreate here because its UUIDs don't conform to RFC 4122). - if _uuid_generate_time and node is clock_seq is None: - _buffer = ctypes.create_string_buffer(16) - _uuid_generate_time(_buffer) - return UUID(bytes=bytes_(_buffer.raw)) + if node is clock_seq is None: + if _uuid_generate_time_fast: + return UUID(bytes=bytes_(_uuid_generate_time_fast())) + if _uuid_generate_time: + _buffer = ctypes.create_string_buffer(16) + _uuid_generate_time(_buffer) + return UUID(bytes=bytes_(_buffer.raw)) global _last_timestamp import time @@ -537,6 +551,8 @@ """Generate a random UUID.""" # When the system provides a version-4 UUID generator, use it. + if _uuid_generate_random_fast: + return UUID(bytes=bytes_(_uuid_generate_random_fast())) if _uuid_generate_random: _buffer = ctypes.create_string_buffer(16) _uuid_generate_random(_buffer) Index: Modules/_uuid.c =================================================================== --- Modules/_uuid.c (revision 0) +++ Modules/_uuid.c (revision 0) @@ -0,0 +1,48 @@ +/* UUID (universally unique identifiers) generator + + This is the faster version than the pure python implementation uuid.py. + It was suggested in issue 5885 by Wang Chun and implemented by Daniel Black + +This module should not be used directly. Usage should be through the uuid.py which +will load this module if available. +*/ + +#include "Python.h" + +#include + +static PyObject * +uuid_uuid1(PyObject *self, PyObject *args) +{ + uuid_t out; + uuid_generate_time(out); + return PyByteArray_FromStringAndSize((const char *) out,sizeof(out)); +} + +static PyObject * +uuid_uuid4(PyObject *self, PyObject *args) +{ + uuid_t out; + uuid_generate_random(out); + return PyByteArray_FromStringAndSize(out,sizeof(out)); +} + +static PyMethodDef uuidMethods[] = { + {"uuid1", uuid_uuid1, METH_VARARGS | METH_KEYWORDS}, + {"uuid4", uuid_uuid4, METH_VARARGS | METH_KEYWORDS}, + {NULL, NULL, 0, NULL} +}; + +static struct PyModuleDef uuidmodule = { + PyModuleDef_HEAD_INIT, + "_uuid", + NULL, /* doc */ + -1, + uuidMethods +}; + +PyMODINIT_FUNC +PyInit__uuid(void) +{ + return PyModule_Create(&uuidmodule); +}