forked from dln/python-libuuid
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Daniel Lundin
committed
Jul 20, 2010
0 parents
commit 1989586
Showing
11 changed files
with
352 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Daniel Lundin <[email protected]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
AUTHORS | ||
MANIFEST | ||
MANIFEST.in | ||
README | ||
README.rst | ||
setup.py | ||
libuuid/__init__.py | ||
libuuid/_uuid.c | ||
libuuid/_uuid.pyx | ||
libuuid/uuid.pxd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
include MANIFEST.in MANIFEST | ||
include AUTHORS README.rst | ||
recursive-include libuuid *.py *.pyx *.pxd _uuid.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
README.rst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
################################################### | ||
pylibuuid - Faster UUID generation using libuuid | ||
#################################################### | ||
|
||
Python bindings for libuuid. Compatible with the standard library `uuid` module. |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from libuuid._uuid import * | ||
|
||
from uuid import UUID as _UUID | ||
from uuid import (NAMESPACE_DNS, NAMESPACE_OID, NAMESPACE_URL, NAMESPACE_X500, | ||
RESERVED_FUTURE, RESERVED_MICROSOFT, RESERVED_NCS, RFC_4122) | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# cython: embedsignature=True | ||
from binascii import hexlify | ||
import uuid as uuid_std | ||
|
||
cimport uuid | ||
from uuid cimport * | ||
|
||
cdef extern from "Python.h": | ||
object PyString_FromFormat(char *format, ...) | ||
object PyString_FromStringAndSize(char *s, int len) | ||
object PyString_FromString(char *s) | ||
object PyLong_FromVoidPtr(void *p) | ||
object PyLong_FromString(char *, char**, int) | ||
object _PyLong_FromByteArray(unsigned char *bytes, unsigned int n, | ||
int little_endian, int is_signed) | ||
int _PyLong_AsByteArray(object v, unsigned char *bytes, unsigned int n, | ||
int little_endian, int is_signed) except -1 | ||
|
||
int PyString_Size(object s) | ||
object PyString_FromStringAndSize(char *, int) | ||
char *PyString_AS_STRING(object s) | ||
|
||
|
||
class FastUUID(uuid_std.UUID): | ||
def __init__(self, version=4, *args, **kwargs): | ||
cdef object buf = PyString_FromStringAndSize(NULL, 16) | ||
cdef unsigned char *_bytes = <unsigned char*>PyString_AS_STRING(buf) | ||
if version == 1: | ||
uuid_generate_time(_bytes) | ||
elif version == 4: | ||
uuid_generate_random(_bytes) | ||
self.__dict__['bytes'] = buf | ||
self.__dict__['int'] = _PyLong_FromByteArray(_bytes, 16, 0, 0) | ||
|
||
def get_bytes(self): | ||
return self.bytes | ||
|
||
|
||
def uuid1(node=None, clock_seq=None): | ||
if node or clock_seq: | ||
raise NotImplementedError, "node and clock_seq are not supported in libuuid" | ||
return FastUUID(1) | ||
|
||
uuid3 = uuid_std.uuid3 | ||
|
||
uuid4 = FastUUID | ||
|
||
uuid5 = uuid_std.uuid5 | ||
|
||
def uuid1_bytes(): | ||
cdef object bytes = PyString_FromStringAndSize(NULL, 16) | ||
uuid_generate_time(<unsigned char*>PyString_AS_STRING(bytes)) | ||
return bytes | ||
|
||
def uuid4_bytes(): | ||
cdef object bytes = PyString_FromStringAndSize(NULL, 16) | ||
uuid_generate_random(<unsigned char*>PyString_AS_STRING(bytes)) | ||
return bytes | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Python bindings for libavro | ||
|
||
cdef extern from *: | ||
ctypedef char* const_char_ptr "const char*" | ||
|
||
cdef extern from "stdint.h" nogil: | ||
ctypedef int int32_t | ||
ctypedef int uint32_t | ||
|
||
cdef extern from 'stdio.h' nogil: | ||
int snprintf(char *str, size_t size, char *format, ...) | ||
|
||
cdef extern from "stdlib.h" nogil: | ||
void free(void * ptr) | ||
void * malloc(int size) | ||
|
||
cdef extern from "string.h" nogil: | ||
void *memset(void *, int, size_t) | ||
|
||
cdef extern from 'sys/time.h' nogil: | ||
ctypedef struct timeval: | ||
unsigned int tv_sec | ||
unsigned int tv_usec | ||
ctypedef int32_t time_t | ||
|
||
# UUID Variant definitions | ||
UUID_VARIANT_NCS = 0 | ||
UUID_VARIANT_DCE = 1 | ||
UUID_VARIANT_MICROSOFT = 2 | ||
UUID_VARIANT_OTHER = 3 | ||
|
||
# UUID Type definitions | ||
UUID_TYPE_DCE_TIME = 1 | ||
UUID_TYPE_DCE_RANDOM = 4 | ||
|
||
cdef extern from 'uuid/uuid.h' nogil: | ||
ctypedef unsigned char uuid_t[16] | ||
|
||
void uuid_clear(uuid_t uu) | ||
|
||
int uuid_compare(uuid_t uu1, uuid_t uu2) | ||
|
||
void uuid_copy(uuid_t dst, uuid_t src) | ||
|
||
void uuid_generate(uuid_t out) | ||
void uuid_generate_random(uuid_t out) | ||
void uuid_generate_time(uuid_t out) | ||
|
||
int uuid_is_null(uuid_t uu) | ||
|
||
int uuid_parse(const_char_ptr indata, uuid_t uu) | ||
|
||
void uuid_unparse(uuid_t uu, char *out) | ||
void uuid_unparse_lower(uuid_t uu, char *out) | ||
void uuid_unparse_upper(uuid_t uu, char *out) | ||
|
||
time_t uuid_time(uuid_t uu, timeval *ret_tv) | ||
int uuid_type(uuid_t uu) | ||
int uuid_variant(uuid_t uu) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
"""Python bindings to libuuid.""" | ||
|
||
__version_info__ = (0, 9, 0) | ||
__version__ = ".".join(map(str, __version_info__)) | ||
__author__ = "Daniel Lundin" | ||
__contact__ = "[email protected]" | ||
__homepage__ = "http://github.com/dln/pylibuuid/" | ||
__docformat__ = "restructuredtext" | ||
|
||
import codecs | ||
import os | ||
from glob import glob | ||
|
||
|
||
try: | ||
import setuptools | ||
except ImportError: | ||
from ez_setup import use_setuptools | ||
use_setuptools() | ||
|
||
from setuptools import setup, find_packages, Extension | ||
from distutils.command.sdist import sdist | ||
|
||
extra_setup_args = {} | ||
try: | ||
from Cython.Distutils import build_ext | ||
import Cython.Compiler.Version | ||
import Cython.Compiler.Main as cython_compiler | ||
print("building with Cython " + Cython.Compiler.Version.version) | ||
class Sdist(sdist): | ||
def __init__(self, *args, **kwargs): | ||
for src in glob('libuuid/*.pyx'): | ||
cython_compiler.compile(glob('libuuid/*.pyx'), | ||
cython_compiler.default_options) | ||
sdist.__init__(self, *args, **kwargs) | ||
extra_setup_args['cmdclass'] = {'build_ext': build_ext, 'sdist': Sdist} | ||
source_extension = ".pyx" | ||
except ImportError: | ||
print("building without Cython") | ||
source_extension = ".c" | ||
|
||
|
||
ext_modules = [ | ||
Extension('libuuid._uuid', | ||
sources=['libuuid/_uuid' + source_extension], | ||
libraries=['uuid']) | ||
] | ||
|
||
|
||
long_description = codecs.open('README.rst', "r", "utf-8").read() | ||
|
||
setup(name = 'python-libuuid', | ||
version = __version__, | ||
description = __doc__, | ||
author = __author__, | ||
author_email = __contact__, | ||
url = __homepage__, | ||
packages = ['libuuid'], | ||
ext_modules = ext_modules, | ||
zip_safe=False, | ||
test_suite="nose.collector", | ||
classifiers=[ | ||
"Development Status :: 4 - Beta", | ||
"Programming Language :: Python", | ||
"License :: OSI Approved :: Apache Software License", | ||
"Intended Audience :: Developers", | ||
"Topic :: Communications", | ||
"Topic :: System :: Distributed Computing", | ||
"Topic :: Software Development :: Libraries :: Python Modules", | ||
], | ||
long_description=long_description, | ||
**extra_setup_args | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# -*- coding: utf-8 -*- | ||
from random import choice, randrange | ||
import os | ||
import shutil | ||
import string | ||
import sys | ||
import tempfile | ||
import time | ||
import unittest | ||
import uuid | ||
|
||
import libuuid | ||
|
||
|
||
def test_properties(): | ||
_PROPERTIES = [ | ||
'bytes', 'bytes_le', 'clock_seq', 'clock_seq_hi_variant', | ||
'clock_seq_low', 'fields', 'hex', 'node', 'time', 'time_hi_version', | ||
'time_low', 'time_mid', 'urn', 'variant', 'version' | ||
] | ||
|
||
def _check_property(factory_func, prop): | ||
u = factory_func() | ||
u2 = uuid.UUID(bytes=u.bytes) | ||
a1 = getattr(u, prop) | ||
a2 = getattr(u2, prop) | ||
assert a1 == a2 | ||
|
||
for prop in _PROPERTIES: | ||
test_properties.__doc__ = "Property: " + prop | ||
yield _check_property, libuuid.uuid1, prop | ||
yield _check_property, libuuid.uuid4, prop | ||
|
||
def test_methods(): | ||
_METHODS = [ | ||
'__hash__', '__int__', '__repr__', '__str__', 'get_bytes', | ||
'get_bytes_le', 'get_clock_seq', 'get_clock_seq_hi_variant', | ||
'get_clock_seq_low', 'get_fields', 'get_hex', 'get_node', 'get_time', | ||
'get_time_hi_version', 'get_time_low', 'get_time_mid', 'get_urn', | ||
'get_variant', 'get_version' | ||
] | ||
|
||
def _check_method(factory_func, method, *args, **kwargs): | ||
u = factory_func() | ||
u2 = uuid.UUID(bytes=u.bytes) | ||
m1 = getattr(u, method)(*args, **kwargs) | ||
m2 = getattr(u2, method)(*args, **kwargs) | ||
assert m1 == m2 | ||
|
||
for method in _METHODS: | ||
test_methods.__doc__ = "Method: " + method | ||
yield _check_method, libuuid.uuid1, method | ||
yield _check_method, libuuid.uuid4, method | ||
|
||
|
||
def test_constants(): | ||
|
||
_CONSTANTS = ['NAMESPACE_DNS', 'NAMESPACE_OID', 'NAMESPACE_URL', | ||
'NAMESPACE_X500', 'RESERVED_FUTURE', 'RESERVED_MICROSOFT', | ||
'RESERVED_NCS', 'RFC_4122'] | ||
|
||
def _check_constant(const): | ||
m1 = getattr(libuuid, const) | ||
m2 = getattr(uuid, const) | ||
assert m1 == m2 | ||
|
||
for constant in _CONSTANTS: | ||
test_methods.__doc__ = "Constant: " + constant | ||
yield _check_constant, constant | ||
|
||
|
||
class TestUUID(unittest.TestCase): | ||
|
||
def test_uuid1(self): | ||
u = libuuid.uuid1() | ||
u2 = uuid.UUID(bytes=u.bytes) | ||
self.assertEqual(u.bytes, u2.bytes) | ||
|
||
def test_uuid4(self): | ||
u = libuuid.uuid4() | ||
u2 = uuid.UUID(bytes=u.bytes) | ||
self.assertEqual(u.bytes, u2.bytes) | ||
|
||
def test_is_UUID_instance(self): | ||
u = libuuid.uuid4() | ||
self.assert_(isinstance(u, uuid.UUID)) | ||
|
||
def test_uuid4_args_unsupported(self): | ||
self.assertRaises(NotImplementedError, lambda: libuuid.uuid1(42)) | ||
self.assertRaises(NotImplementedError, lambda: libuuid.uuid1(42, 42)) | ||
self.assertRaises(NotImplementedError, lambda: libuuid.uuid1(node=42)) | ||
self.assertRaises(NotImplementedError, lambda: libuuid.uuid1(clock_seq=42)) | ||
self.assertRaises(NotImplementedError, lambda: libuuid.uuid1(node=42, clock_seq=42)) | ||
|
||
def test_uuid1_bytes(self): | ||
b = libuuid.uuid1_bytes() | ||
self.assertEquals(type(b), str) | ||
self.assertEquals(uuid.UUID(bytes=b).version, 1) | ||
|
||
def test_uuid4_bytes(self): | ||
b = libuuid.uuid4_bytes() | ||
self.assertEquals(type(b), str) | ||
self.assertEquals(uuid.UUID(bytes=b).version, 4) | ||
|
||
def test_basic_sanity_uuid4(self): | ||
buf = set() | ||
for _ in xrange(10000): | ||
u = libuuid.uuid4_bytes() | ||
self.assert_(u not in buf) | ||
buf.add(u) | ||
|
||
def test_basic_sanity_uuid1(self): | ||
buf = set() | ||
clocks = [] | ||
for _ in xrange(1000): | ||
u = libuuid.uuid1() | ||
clocks.append(u.time) | ||
self.assert_(u.bytes not in buf) | ||
buf.add(u.bytes) | ||
self.assertEquals(clocks, sorted(clocks), "Timestamps increment") | ||
t = (time.time() * 1e7) + 0x01b21dd213814000L # RFC 4122 timestamp | ||
diff = abs(t - clocks[-1]) | ||
self.assert_(diff < 10000, "Timestamp reasonable") | ||
|
||
|
||
|
||
|
||
|