diff --git a/boost_queue.cpp b/boost_queue.cpp index 079a3ea..97603bc 100644 --- a/boost_queue.cpp +++ b/boost_queue.cpp @@ -16,7 +16,7 @@ #include #include -/* get_many considarations: +/* get_many considerations: * Avoid using get_many() on the consumer side and using put() on the producer. * The get_many() thread is notified on every single put(), however immediatly * goes to sleep again because the Queue is not big enough. Hence a lot of @@ -128,7 +128,7 @@ Queue_dealloc(Queue *self) Queue_clear(self); delete self->bridge; } - self->ob_type->tp_free(reinterpret_cast(self)); + Py_TYPE(self)->tp_free(reinterpret_cast(self)); } @@ -667,8 +667,7 @@ static PyGetSetDef Queue_getsets[] = { }; static PyTypeObject QueueType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) "boost_queue.Queue", /*tp_name*/ sizeof(Queue), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -708,24 +707,49 @@ static PyTypeObject QueueType = { Queue_new, /* tp_new */ }; -PyMODINIT_FUNC -initboost_queue(void){ +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "boost_queue", /* m_name */ + "Python wrapper for C++ Queue template using boost locking", /* m_doc */ + -1, /* m_size */ + NULL, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; +#endif + +static PyObject * +moduleinit(void) +{ PyObject* module; PyObject* std_lib_queue; PyObject* std_empty; PyObject* std_full; if (PyType_Ready(&QueueType) < 0) { - return; + return NULL; } +#if PY_MAJOR_VERSION >= 3 + module = PyModule_Create(&moduledef); +#else module = Py_InitModule("boost_queue", NULL); +#endif if (module == NULL) { - return; + return NULL; } - if((std_lib_queue = PyImport_ImportModule("Queue")) == NULL) { - return; +#if PY_MAJOR_VERSION >= 3 + std_lib_queue = PyImport_ImportModule("queue"); +#else + std_lib_queue = PyImport_ImportModule("Queue"); +#endif + + if(std_lib_queue == NULL) { + return NULL; } if((std_empty = PyObject_GetAttrString(std_lib_queue, "Empty")) == NULL) { @@ -757,4 +781,19 @@ initboost_queue(void){ Py_INCREF((PyObject*) &QueueType); PyModule_AddObject(module, "Queue", (PyObject*)&QueueType); + + return module; +} + +PyMODINIT_FUNC +#if PY_MAJOR_VERSION >= 3 +PyInit_boost_queue(void) +{ + return moduleinit(); +} +#else +initboost_queue(void) +{ + moduleinit(); } +#endif diff --git a/setup.py b/setup.py index a43aedb..09ba4c8 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ mod = Extension( 'boost_queue', sources=['boost_queue.cpp'], - libraries=['boost_thread', 'boost_date_time'], + libraries=['boost_thread', 'boost_date_time', 'boost_system'], extra_compile_args=["-O2"], ) diff --git a/tests/perf_test.py b/tests/perf_test.py index e19d388..f3a8093 100644 --- a/tests/perf_test.py +++ b/tests/perf_test.py @@ -25,7 +25,7 @@ def __init__(self, q): threading.Thread.__init__(self) def run(self): - for _ in xrange(10**6): + for _ in range(10**6): self.q.get() class Prod(threading.Thread): @@ -34,7 +34,7 @@ def __init__(self, q): threading.Thread.__init__(self) def run(self): - for _ in xrange(10**6): + for _ in range(10**6): self.q.put(BigFatObject()) if __name__ == '__main__': @@ -46,4 +46,4 @@ def run(self): start = time.time() [x.start() for x in cons + prods] [x.join() for x in prods + cons] - print time.time() - start + print(time.time() - start) diff --git a/tests/test_queue.py b/tests/test_queue.py index 4301f02..7108938 100644 --- a/tests/test_queue.py +++ b/tests/test_queue.py @@ -6,7 +6,11 @@ from boost_queue import Full from boost_queue import Empty -import Queue as std_queue +import sys +if sys.version_info[0] >= 3: + import queue as std_queue +else: + import Queue as std_queue class TestQueue(TestCase): @@ -59,7 +63,7 @@ def consumer(test, q): def test_get_put_with_thread_and_late_put(self): def consumer(test, q): - to_consume = range(40) + to_consume = list(range(40)) for x in range(40): to_consume.remove(q.get(True, 4)) self.assertEqual(to_consume, []) @@ -129,8 +133,8 @@ def test_except_with_std_queue_empty(self): def test_put_many_too_many_items(self): q = Queue(1) msg = "items of size 3 is bigger then maxsize: 1" - with self.assertRaisesRegexp(ValueError, msg): - q.put_many((1, 2, 3)) + with self.assertRaises(ValueError, msg=msg): + q.put_many((1, 2, 3)) q.put(None) with self.assertRaises(Full): @@ -157,7 +161,7 @@ def test_get_many_enough_space(self): def test_get_many_not_enough_space(self): q = Queue(10) msg = "you want to get 12 but maxsize is 10" - with self.assertRaisesRegexp(ValueError, msg): + with self.assertRaises(ValueError, msg=msg): q.get_many(12) with self.assertRaises(Empty): diff --git a/tests/test_std_queue.py b/tests/test_std_queue.py index e4fc8c4..f5650cd 100644 --- a/tests/test_std_queue.py +++ b/tests/test_std_queue.py @@ -86,7 +86,7 @@ def setUp(self): def simple_queue_test(self, q): if not q.empty(): - raise RuntimeError, "Call this function with an empty queue" + raise RuntimeError("Call this function with an empty queue") # I guess we better check things actually queue correctly a little :) q.put(111) q.put(333) @@ -155,7 +155,7 @@ def queue_join_test(self, q): t.start() threads.append(t) - for i in xrange(100): + for i in range(100): q.put(i) q.join() self.assertEqual(self.cum, sum(range(100)), @@ -208,12 +208,12 @@ def __init__(self, *args): def _put(self, item): if self.fail_next_put: self.fail_next_put = False - raise FailingQueueException, "You Lose" + raise FailingQueueException("You Lose") return Queue.Queue._put(self, item) def _get(self): if self.fail_next_get: self.fail_next_get = False - raise FailingQueueException, "You Lose" + raise FailingQueueException("You Lose") return Queue.Queue._get(self) #class FailingQueueTest(unittest.TestCase, BlockingTestMixin): @@ -221,7 +221,7 @@ def doit(): def failing_queue_test(self, q): if not q.empty(): - raise RuntimeError, "Call this function with an empty queue" + raise RuntimeError("Call this function with an empty queue") for i in range(QUEUE_SIZE-1): q.put(i) # Test a failing non-blocking put.