diff -r 147197678bfc -r 392833053364 Lib/uuid.py --- a/Lib/uuid.py Fri Jan 21 10:18:19 2011 +0100 +++ b/Lib/uuid.py Sat Jan 22 09:56:44 2011 +0200 @@ -415,6 +415,15 @@ # 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_time_fast = _uuid.uuid1 + _uuid_generate_random_fast = _uuid.uuid4 +except ImportError: + pass + try: import ctypes, ctypes.util @@ -462,6 +471,8 @@ def _unixdll_getnode(): """Get the hardware address on Unix using ctypes.""" + if _uuid_generate_random_fast: + return UUID(int=_uuid_generate_time_fast()).node _buffer = ctypes.create_string_buffer(16) _uuid_generate_time(_buffer) return UUID(bytes=bytes_(_buffer.raw)).node @@ -516,10 +527,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(int=_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 @@ -553,6 +567,8 @@ """Generate a random UUID.""" # When the system provides a version-4 UUID generator, use it. + if _uuid_generate_random_fast: + return UUID(int=_uuid_generate_random_fast()) if _uuid_generate_random: _buffer = ctypes.create_string_buffer(16) _uuid_generate_random(_buffer) diff -r 147197678bfc -r 392833053364 Modules/_uuid.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modules/_uuid.c Sat Jan 22 09:56:44 2011 +0200 @@ -0,0 +1,68 @@ +/* UUID (universally unique identifiers) generator + + This a faster version than the pure python implementation uuid.py. + It was suggested in issue 5885 by Wang Chun and implemented by Daniel Black + and Ross Lagerwall. + + 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 * +_long_from_uuid_t(uuid_t out) +{ + int i, j; + unsigned char hex[33]; + j = 0; + for (i = 0; i < 16; i++) { + hex[j] = 48 + (out[i] >> 4); + if (hex[j] > 57) + hex[j] += 7; + j++; + hex[j] = 48 + (out[i] & 0xF); + if (hex[j] > 57) + hex[j] += 7; + j++; + } + hex[32] = '\0'; + return PyLong_FromString((char *)hex, NULL, 16); +} + +static PyObject * +uuid_uuid1(PyObject *self, PyObject *args) +{ + uuid_t out; + uuid_generate_time(out); + return _long_from_uuid_t(out); +} + +static PyObject * +uuid_uuid4(PyObject *self, PyObject *args) +{ + uuid_t out; + uuid_generate_random(out); + return _long_from_uuid_t(out); +} + +static PyMethodDef uuid_methods[] = { + {"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, + uuid_methods +}; + +PyMODINIT_FUNC +PyInit__uuid(void) +{ + return PyModule_Create(&uuidmodule); +} diff -r 147197678bfc -r 392833053364 setup.py --- a/setup.py Fri Jan 21 10:18:19 2011 +0100 +++ b/setup.py Sat Jan 22 09:56:44 2011 +0200 @@ -509,6 +509,11 @@ # static Unicode character database exts.append( Extension('unicodedata', ['unicodedata.c']) ) + if find_file('uuid/uuid.h', inc_dirs, []) is not None: + exts.append( Extension('_uuid', ['_uuid.c'], libraries=['uuid']) ) + else: + missing.append('_uuid') + # Modules with some UNIX dependencies -- on by default: # (If you have a really backward UNIX, select and socket may not be # supported...)