diff -r 3dcbf8f928ec Lib/uuid.py --- a/Lib/uuid.py Wed Feb 05 10:33:14 2014 -0500 +++ b/Lib/uuid.py Wed Feb 05 16:14:34 2014 +0000 @@ -428,32 +428,10 @@ try: import ctypes, ctypes.util - # The uuid_generate_* routines are provided by libuuid on at least - # Linux and FreeBSD, and provided by libc on Mac OS X. - for libname in ['uuid', 'c']: - try: - lib = ctypes.CDLL(ctypes.util.find_library(libname)) - except: - continue - if hasattr(lib, 'uuid_generate_random'): - _uuid_generate_random = lib.uuid_generate_random - if hasattr(lib, 'uuid_generate_time'): - _uuid_generate_time = lib.uuid_generate_time - if _uuid_generate_random is not None: - break # found everything we were looking for - - # The uuid_generate_* functions are broken on MacOS X 10.5, as noted - # in issue #8621 the function generates the same sequence of values - # in the parent process and all children created using fork (unless - # those children use exec as well). - # - # Assume that the uuid_generate functions are broken from 10.5 onward, - # the test can be adjusted when a later version is fixed. - import sys - if sys.platform == 'darwin': - import os - if int(os.uname().release.split('.')[0]) >= 9: - _uuid_generate_random = _uuid_generate_time = None + try: + import _uuid + except ImportError: + _uuid = None # On Windows prior to 2000, UuidCreate gives a UUID containing the # hardware address. On Windows 2000 and later, UuidCreate makes a @@ -463,6 +441,7 @@ # 6 bytes returned by UuidCreateSequential are fixed, they don't appear # to bear any relationship to the MAC address of any network device # on the box. + import ctypes, ctypes.util try: lib = ctypes.windll.rpcrt4 except: @@ -565,10 +544,8 @@ """Generate a random UUID.""" # When the system provides a version-4 UUID generator, use it. - if _uuid_generate_random: - _buffer = ctypes.create_string_buffer(16) - _uuid_generate_random(_buffer) - return UUID(bytes=bytes_(_buffer.raw)) + if _uuid is not None: + return UUID(bytes=_uuid.generate_random()) # Otherwise, get randomness from urandom or the 'random' module. try: diff -r 3dcbf8f928ec Modules/_uuidmodule.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Modules/_uuidmodule.c Wed Feb 05 16:14:34 2014 +0000 @@ -0,0 +1,44 @@ +#include "Python.h" +#include + +static PyObject * +_uuid_generate_random(void) +{ + uuid_t out; + uuid_generate_random(out); + return PyBytes_FromStringAndSize((const char *) out, sizeof(out)); +} + +static PyObject * +_uuid_generate_time(void) +{ + uuid_t out; + uuid_generate_time(out); + return PyBytes_FromStringAndSize((const char *) out, sizeof(out)); +} + + +static PyMethodDef uuid_methods[] = { + {"generate_random", (PyCFunction)_uuid_generate_random, METH_NOARGS, NULL}, + {"generate_time", (PyCFunction)_uuid_generate_time, METH_NOARGS, NULL}, + {NULL, NULL, 0, NULL} /* sentinel */ +}; + + +static struct PyModuleDef uuidmodule = { + PyModuleDef_HEAD_INIT, + "_uuid", + NULL, + -1, + uuid_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit__uuid(void) +{ + return PyModule_Create(&uuidmodule); +} diff -r 3dcbf8f928ec setup.py --- a/setup.py Wed Feb 05 10:33:14 2014 -0500 +++ b/setup.py Wed Feb 05 16:14:34 2014 +0000 @@ -1542,6 +1542,35 @@ define_macros=[('Py_LIMITED_API', '0x03040000')]) self.extensions.append(ext) + + # Build the _uuid module if possible + build_uuid = False + if host_platform == "darwin": + # The uuid_generate_* functions are broken on MacOS X 10.5, as noted + # in issue #8621 the function generates the same sequence of values + # in the parent process and all children created using fork (unless + # those children use exec as well). + # + # Assume that the uuid_generate functions are broken from 10.5 onward, + # the test can be adjusted when a later version is fixed. + if int(os.uname().release.split('.')[0]) < 9: + build_uuid = True + uuid_libs = [] + else: + build_uuid = False + else: + if find_file("uuid.h", inc_dirs, ["/usr/include/uuid"]): + if self.compiler.find_library_file(lib_dirs, 'uuid'): + uuid_libs = ['uuid'] + else: + uuid_libs = [] + build_uuid = True + if build_uuid: + self.extensions.append(Extension('_uuid', ['_uuidmodule.c'], + libraries=uuid_libs)) + else: + missing.append('_uuid') + return missing def detect_tkinter_explicitly(self):