summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules6
-rw-r--r--MANIFEST.in2
-rw-r--r--Makefile13
-rw-r--r--Modules/_librabbitmq/connection.c122
-rw-r--r--Modules/_librabbitmq/connection.h56
-rw-r--r--benchmark.py58
-rw-r--r--funtests/config.py2
-rw-r--r--funtests/setup.py1
-rw-r--r--librabbitmq/__init__.py7
-rw-r--r--librabbitmq/tests/test_functional.py9
m---------rabbitmq-c0
m---------rabbitmq-codegen0
-rw-r--r--requirements/README.rst13
-rw-r--r--requirements/default.txt1
-rw-r--r--requirements/test.txt2
-rw-r--r--setup.py44
16 files changed, 189 insertions, 147 deletions
diff --git a/.gitmodules b/.gitmodules
index ebc8053..53784ba 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,4 @@
-[submodule "rabbitmq-codegen"]
- path = rabbitmq-codegen
- url = https://github.com/rabbitmq/rabbitmq-codegen.git
[submodule "rabbitmq-c"]
path = rabbitmq-c
- url = https://github.com/ask/rabbitmq-c.git
+ url = https://github.com/alanxz/rabbitmq-c.git
+ branch = v0.8.0
diff --git a/MANIFEST.in b/MANIFEST.in
index 4287ace..971ccec 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -9,8 +9,6 @@ include setup.cfg
recursive-include librabbitmq *
recursive-include Modules *
recursive-include tests *
-recursive-include clib *
-recursive-include rabbitmq-codegen *
prune *.pyc
prune *.o
prune *.la
diff --git a/Makefile b/Makefile
index 8147268..537d65c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,6 @@
# Building
RABBIT_DIR=rabbitmq-c
-CODEGEN_DIR=rabbitmq-codegen
-RABBIT_TARGET=clib
-RABBIT_DIST=rabbitmq-c-0.5.3
+RABBIT_DIST=librabbitmq
# Distribuition tools
PYTHON=python
@@ -10,13 +8,11 @@ PYTHON=python
all: build
add-submodules:
- -git submodule add https://github.com/ask/rabbitmq-c.git
- -git submodule add https://github.com/rabbitmq/rabbitmq-codegen
+ -git submodule add -b v0.8.0 https://github.com/alanxz/rabbitmq-c.git
submodules:
git submodule init
git submodule update
- (cd $(RABBIT_DIR); rm -rf codegen; ln -sf ../$(CODEGEN_DIR) ./codegen)
rabbitmq-c: submodules
(cd $(RABBIT_DIR); test -f configure || autoreconf -i)
@@ -25,11 +21,9 @@ rabbitmq-c: submodules
rabbitmq-clean:
-(cd $(RABBIT_DIR) && make clean)
- -(cd $(RABBIT_TARGET) && make clean)
rabbitmq-distclean:
-(cd $(RABBIT_DIR) && make distclean)
- -(cd $(RABBIT_TARGET) && make distclean)
clean-build:
-rm -rf build
@@ -57,8 +51,7 @@ distclean: pyclean rabbitmq-distclean removepyc
$(RABBIT_TARGET):
(test -f config.h || cd $(RABBIT_DIR); ./configure --disable-tools --disable-docs)
- (cd $(RABBIT_DIR); make distdir)
- mv "$(RABBIT_DIR)/$(RABBIT_DIST)" "$(RABBIT_TARGET)"
+ (cd $(RABBIT_DIR); make)
dist: rabbitmq-c $(RABBIT_TARGET)
diff --git a/Modules/_librabbitmq/connection.c b/Modules/_librabbitmq/connection.c
index 10b0ddf..54f2427 100644
--- a/Modules/_librabbitmq/connection.c
+++ b/Modules/_librabbitmq/connection.c
@@ -15,6 +15,9 @@
#define PYRABBITMQ_CONNECTION_ERROR 0x10
#define PYRABBITMQ_CHANNEL_ERROR 0x20
+#define PYRABBITMQ_MODULE_NAME "_librabbitmq"
+#define PYRABBITMQ_MODULE_DESC "Hand-made wrapper for librabbitmq."
+
/* ------: Private Prototypes :------------------------------------------- */
PyMODINIT_FUNC init_librabbitmq(void);
@@ -248,12 +251,12 @@ PyDict_ToAMQTable(amqp_connection_state_t conn, PyObject *src, amqp_pool_t *pool
{
PyObject *dkey = NULL;
PyObject *dvalue = NULL;
- PY_SIZE_TYPE size = 0;
- PY_SIZE_TYPE pos = 0;
+ Py_ssize_t size = 0;
+ Py_ssize_t pos = 0;
uint64_t clong_value = 0;
double cdouble_value = 0.0;
int is_unicode = 0;
- amqp_table_t dst = AMQP_EMPTY_TABLE;
+ amqp_table_t dst = amqp_empty_table;
size = PyDict_Size(src);
@@ -261,7 +264,7 @@ PyDict_ToAMQTable(amqp_connection_state_t conn, PyObject *src, amqp_pool_t *pool
dst.num_entries = 0;
dst.entries = amqp_pool_alloc(pool, size * sizeof(amqp_table_entry_t));
while (PyDict_Next(src, &pos, &dkey, &dvalue)) {
-
+ dkey = Maybe_Unicode(dkey);
if (dvalue == Py_None) {
/* None */
AMQTable_SetNilValue(&dst, PyString_AS_AMQBYTES(dkey));
@@ -315,7 +318,7 @@ PyDict_ToAMQTable(amqp_connection_state_t conn, PyObject *src, amqp_pool_t *pool
else {
/* String | Unicode */
is_unicode = PyUnicode_Check(dvalue);
- if (is_unicode || PyString_Check(dvalue)) {
+ if (is_unicode || PyBytes_Check(dvalue)) {
if (is_unicode) {
if ((dvalue = PyUnicode_AsASCIIString(dvalue)) == NULL)
goto error;
@@ -329,7 +332,7 @@ PyDict_ToAMQTable(amqp_connection_state_t conn, PyObject *src, amqp_pool_t *pool
/* unsupported type */
PyErr_Format(PyExc_ValueError,
"Table member %s is of an unsupported type",
- PyString_AS_STRING(dkey));
+ PyBytes_AS_STRING(dkey));
goto error;
}
}
@@ -337,18 +340,18 @@ PyDict_ToAMQTable(amqp_connection_state_t conn, PyObject *src, amqp_pool_t *pool
return dst;
error:
assert(PyErr_Occurred());
- return AMQP_EMPTY_TABLE;
+ return amqp_empty_table;
}
static amqp_array_t
PyIter_ToAMQArray(amqp_connection_state_t conn, PyObject *src, amqp_pool_t *pool)
{
- PY_SIZE_TYPE pos = 0;
+ Py_ssize_t pos = 0;
uint64_t clong_value = 0;
int is_unicode = 0;
- amqp_array_t dst = AMQP_EMPTY_ARRAY;
+ amqp_array_t dst = amqp_empty_array;
- PY_SIZE_TYPE size = PySequence_Size(src);
+ Py_ssize_t size = PySequence_Size(src);
if (size == -1) return dst;
PyObject *iterator = PyObject_GetIter(src);
@@ -382,7 +385,7 @@ PyIter_ToAMQArray(amqp_connection_state_t conn, PyObject *src, amqp_pool_t *pool
else {
/* String | Unicode */
is_unicode = PyUnicode_Check(item);
- if (is_unicode || PyString_Check(item)) {
+ if (is_unicode || PyBytes_Check(item)) {
if (is_unicode) {
if ((item = PyUnicode_AsASCIIString(item)) == NULL)
goto item_error;
@@ -393,8 +396,8 @@ PyIter_ToAMQArray(amqp_connection_state_t conn, PyObject *src, amqp_pool_t *pool
else {
/* unsupported type */
PyErr_Format(PyExc_ValueError,
- "Array member at index %lu, %s, is of an unsupported type",
- pos, PyObject_REPR(item));
+ "Array member at index %lu, %R, is of an unsupported type",
+ pos, item);
goto item_error;
}
}
@@ -608,7 +611,7 @@ AMQArray_toPyList(amqp_array_t *array)
{
register PyObject *value = NULL;
PyObject *list = NULL;
- list = PyList_New((PY_SIZE_TYPE) array->num_entries);
+ list = PyList_New((Py_ssize_t) array->num_entries);
if (array) {
int i;
@@ -681,7 +684,7 @@ PyDict_to_basic_properties(PyObject *p,
amqp_pool_t *pool)
{
PyObject *value = NULL;
- props->headers = AMQP_EMPTY_TABLE;
+ props->headers = amqp_empty_table;
props->_flags = AMQP_BASIC_HEADERS_FLAG;
if ((value = PyDict_GetItemString(p, "content_type")) != NULL) {
@@ -951,7 +954,7 @@ PyRabbitMQ_ConnectionType_dealloc(PyRabbitMQ_Connection *self)
Py_XDECREF(self->callbacks);
Py_XDECREF(self->client_properties);
Py_XDECREF(self->server_properties);
- self->ob_type->tp_free(self);
+ Py_TYPE(self)->tp_free(self);
}
@@ -1236,7 +1239,7 @@ PyRabbitMQ_ApplyCallback(PyRabbitMQ_Connection *self,
goto error;
/* message = self.Message(channel, properties, delivery_info, body) */
- Message = PyString_FromString("Message");
+ Message = BUILD_METHOD_NAME("Message");
message = PyObject_CallMethodObjArgs((PyObject *)self, Message,
channelobj, propdict, delivery_info, view, NULL);
if (!message)
@@ -1305,8 +1308,8 @@ PyRabbitMQ_recv(PyRabbitMQ_Connection *self, PyObject *p,
amqp_channel_t cur_channel = 0;
amqp_basic_deliver_t *deliver;
amqp_basic_properties_t *props;
- PY_SIZE_TYPE body_target;
- PY_SIZE_TYPE body_received;
+ Py_ssize_t body_target;
+ Py_ssize_t body_received;
PyObject *channel = NULL;
PyObject *consumer_tag = NULL;
PyObject *delivery_info = NULL;
@@ -1393,23 +1396,21 @@ PyRabbitMQ_recv(PyRabbitMQ_Connection *self, PyObject *p,
body_received += frame.payload.body_fragment.len;
if (!i) {
if (body_received < body_target) {
- payload = PyString_FromStringAndSize(NULL,
- (PY_SIZE_TYPE)body_target);
+ payload = PyBytes_FromStringAndSize(NULL,
+ (Py_ssize_t)body_target);
if (!payload)
goto finally;
- buf = PyString_AsString(payload);
+ buf = PyBytes_AsString(payload);
if (!buf)
goto finally;
- view = PyBuffer_FromObject(payload, 0,
- (PY_SIZE_TYPE)body_target);
+ view = PyMemoryView_FromObject(payload);
}
else {
if (p) {
payload = PySTRING_FROM_AMQBYTES(
frame.payload.body_fragment);
} else {
- view = PyBuffer_FromMemory(bufp,
- (PY_SIZE_TYPE)frame.payload.body_fragment.len);
+ view = buffer_toMemoryView(bufp, (Py_ssize_t)frame.payload.body_fragment.len);
}
break;
}
@@ -1424,7 +1425,7 @@ PyRabbitMQ_recv(PyRabbitMQ_Connection *self, PyObject *p,
if (body_target) goto error;
/* did not expect content, return empty string */
- payload = PyString_FromStringAndSize(NULL, 0);
+ payload = PyBytes_FromStringAndSize(NULL, 0);
}
PyDict_SetItemString(p, "properties", propdict);
@@ -1468,7 +1469,7 @@ PyRabbitMQ_Connection_queue_bind(PyRabbitMQ_Connection *self,
PyObject *routing_key = NULL;
PyObject *arguments = NULL;
- amqp_table_t bargs = AMQP_EMPTY_TABLE;
+ amqp_table_t bargs = amqp_empty_table;
amqp_pool_t *channel_pool = NULL;
amqp_rpc_reply_t reply;
@@ -1523,7 +1524,7 @@ PyRabbitMQ_Connection_queue_unbind(PyRabbitMQ_Connection *self,
PyObject *routing_key = NULL;
PyObject *arguments = NULL;
- amqp_table_t uargs = AMQP_EMPTY_TABLE;
+ amqp_table_t uargs = amqp_empty_table;
amqp_pool_t *channel_pool = NULL;
amqp_rpc_reply_t reply;
@@ -1625,7 +1626,7 @@ PyRabbitMQ_Connection_queue_declare(PyRabbitMQ_Connection *self,
amqp_queue_declare_ok_t *ok;
amqp_rpc_reply_t reply;
amqp_pool_t *channel_pool = NULL;
- amqp_table_t qargs = AMQP_EMPTY_TABLE;
+ amqp_table_t qargs = amqp_empty_table;
PyObject *ret = NULL;
if (PyRabbitMQ_Not_Connected(self))
@@ -1661,8 +1662,7 @@ PyRabbitMQ_Connection_queue_declare(PyRabbitMQ_Connection *self,
goto bail;
if ((ret = PyTuple_New(3)) == NULL) goto bail;
- PyTuple_SET_ITEM(ret, 0, PyString_FromStringAndSize(ok->queue.bytes,
- (PY_SIZE_TYPE)ok->queue.len));
+ PyTuple_SET_ITEM(ret, 0, PySTRING_FROM_AMQBYTES(ok->queue));
PyTuple_SET_ITEM(ret, 1, PyInt_FromLong((long)ok->message_count));
PyTuple_SET_ITEM(ret, 2, PyInt_FromLong((long)ok->consumer_count));
return ret;
@@ -1725,7 +1725,7 @@ PyRabbitMQ_Connection_exchange_declare(PyRabbitMQ_Connection *self,
* as it has been decided that it's not that useful after all. */
unsigned int auto_delete = 0;
- amqp_table_t eargs = AMQP_EMPTY_TABLE;
+ amqp_table_t eargs = amqp_empty_table;
amqp_pool_t *channel_pool = NULL;
amqp_rpc_reply_t reply;
@@ -1816,7 +1816,7 @@ PyRabbitMQ_Connection_basic_publish(PyRabbitMQ_Connection *self,
unsigned int immediate = 0;
char *body_buf = NULL;
- PY_SIZE_TYPE body_size = 0;
+ Py_ssize_t body_size = 0;
int ret = 0;
amqp_basic_properties_t props;
@@ -1827,7 +1827,7 @@ PyRabbitMQ_Connection_basic_publish(PyRabbitMQ_Connection *self,
if (PyRabbitMQ_Not_Connected(self))
goto bail;
- if (!PyArg_ParseTuple(args, "It#OOO|II",
+ if (!PyArg_ParseTuple(args, "Is#OOO|II",
&channel, &body_buf, &body_size, &exchange, &routing_key,
&propdict, &mandatory, &immediate))
goto bail;
@@ -1874,7 +1874,7 @@ static PyObject*
PyRabbitMQ_Connection_basic_ack(PyRabbitMQ_Connection *self,
PyObject *args)
{
- PY_SIZE_TYPE delivery_tag = 0;
+ Py_ssize_t delivery_tag = 0;
unsigned int channel = 0;
unsigned int multiple = 0;
int ret = 0;
@@ -1907,7 +1907,7 @@ bail:
static PyObject *PyRabbitMQ_Connection_basic_reject(PyRabbitMQ_Connection *self,
PyObject *args)
{
- PY_SIZE_TYPE delivery_tag = 0;
+ Py_ssize_t delivery_tag = 0;
unsigned int channel = 0;
unsigned int multiple = 0;
@@ -1991,7 +1991,7 @@ PyRabbitMQ_Connection_basic_consume(PyRabbitMQ_Connection *self,
amqp_basic_consume_ok_t *ok;
amqp_rpc_reply_t reply;
amqp_pool_t *channel_pool = NULL;
- amqp_table_t cargs = AMQP_EMPTY_TABLE;
+ amqp_table_t cargs = amqp_empty_table;
if (PyRabbitMQ_Not_Connected(self))
goto bail;
@@ -2038,7 +2038,7 @@ PyRabbitMQ_Connection_basic_qos(PyRabbitMQ_Connection *self,
PyObject *args)
{
unsigned int channel = 0;
- PY_SIZE_TYPE prefetch_size = 0;
+ Py_ssize_t prefetch_size = 0;
unsigned int prefetch_count = 0;
unsigned int _global = 0;
@@ -2252,24 +2252,56 @@ static PyMethodDef PyRabbitMQ_functions[] = {
{NULL, NULL, 0, NULL}
};
-PyMODINIT_FUNC init_librabbitmq(void)
+#if PY_MAJOR_VERSION >= 3
+ static struct PyModuleDef PyRabbitMQ_moduledef = {
+ PyModuleDef_HEAD_INIT,
+ PYRABBITMQ_MODULE_NAME, /* m_name */
+ PYRABBITMQ_MODULE_DESC, /* m_doc */
+ -1, /* m_size */
+ PyRabbitMQ_functions, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+ };
+#endif
+
+PYRABBITMQ_MOD_INIT(_librabbitmq)
{
PyObject *module, *socket_module;
if (PyType_Ready(&PyRabbitMQ_ConnectionType) < 0) {
+ #if PY_MAJOR_VERSION >= 3
+ return NULL;
+ #else
return;
+ #endif
}
- module = Py_InitModule3("_librabbitmq", PyRabbitMQ_functions,
- "Hand-made wrapper for librabbitmq.");
+#if PY_MAJOR_VERSION >= 3
+ module = PyModule_Create(&PyRabbitMQ_moduledef);
+#else
+ module = Py_InitModule3(PYRABBITMQ_MODULE_NAME, PyRabbitMQ_functions,
+ PYRABBITMQ_MODULE_DESC);
+#endif
+
if (module == NULL) {
+ #if PY_MAJOR_VERSION >= 3
+ return NULL;
+ #else
return;
+ #endif
}
/* Get socket.error */
socket_module = PyImport_ImportModule("socket");
- if (!socket_module)
+ if (!socket_module) {
+ #if PY_MAJOR_VERSION >= 3
+ return NULL;
+ #else
return;
+ #endif
+ }
PyRabbitMQ_socket_timeout = PyObject_GetAttrString(socket_module, "timeout");
Py_XDECREF(socket_module);
@@ -2291,5 +2323,9 @@ PyMODINIT_FUNC init_librabbitmq(void)
"_librabbitmq.ChannelError", NULL, NULL);
PyModule_AddObject(module, "ChannelError",
(PyObject *)PyRabbitMQExc_ChannelError);
+#if PY_MAJOR_VERSION >= 3
+ return module;
+#else
return;
+#endif
}
diff --git a/Modules/_librabbitmq/connection.h b/Modules/_librabbitmq/connection.h
index 98de26c..273ae75 100644
--- a/Modules/_librabbitmq/connection.h
+++ b/Modules/_librabbitmq/connection.h
@@ -8,25 +8,29 @@
#include <amqp.h>
#include <amqp_framing.h>
-#if PY_VERSION_HEX < 0x02060000 && !defined(Py_SIZE)
-# define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
+#if PY_MAJOR_VERSION == 2
+# define TP_FLAGS (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS)
+#else
+# define TP_FLAGS (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE)
#endif
-#if PY_VERSION_HEX >= 0x02060000 /* 2.6 and up */
-# define PY_SIZE_TYPE Py_ssize_t
-# define PyLong_FROM_SSIZE_T PyLong_FromSsize_t
-# define PyLong_AS_SSIZE_T PyLong_AsSsize_t
-# else /* 2.5 and below */
-# define PY_SIZE_TYPE unsigned long
-# define PyLong_FROM_SSIZE_T PyLong_FromUnsignedLong
-# define PyLong_AS_SSIZE_T PyLong_AsUnsignedLong
+
+#if PY_MAJOR_VERSION >= 3
+ #define PYRABBITMQ_MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
+#else
+ #define PYRABBITMQ_MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#endif
+
#if PY_VERSION_HEX >= 0x03000000 /* 3.0 and up */
+# define BUILD_METHOD_NAME PyUnicode_FromString
# define FROM_FORMAT PyUnicode_FromFormat
# define PyInt_FromLong PyLong_FromLong
+# define PyInt_AS_LONG PyLong_AsLong
+# define PyInt_Check PyLong_Check
# define PyInt_FromSsize_t PyLong_FromSsize_t
# define PyString_INTERN_FROM_STRING PyString_FromString
#else /* 2.x */
+# define BUILD_METHOD_NAME PyBytes_FromString
# define FROM_FORMAT PyString_FromFormat
# define PyString_INTERN_FROM_STRING PyString_InternFromString
#endif
@@ -49,6 +53,21 @@
# endif
#endif
+
+_PYRMQ_INLINE PyObject*
+buffer_toMemoryView(char *buf, Py_ssize_t buf_len) {
+ PyObject *view;
+#if PY_MAJOR_VERSION == 2
+ PyObject *pybuffer;
+ pybuffer = PyBuffer_FromMemory(buf, buf_len);
+ view = PyMemoryView_FromObject(pybuffer);
+ Py_XDECREF(pybuffer);
+#else
+ view = PyMemoryView_FromMemory(buf, buf_len, PyBUF_READ);
+#endif
+ return view;
+}
+
#define PyDICT_SETNONE_DECREF(dict, key) \
do { \
PyDict_SetItem(dict, key, Py_None); \
@@ -68,8 +87,14 @@
Py_XDECREF(value); \
} while(0)
-#define PySTRING_FROM_AMQBYTES(member) \
- PyString_FromStringAndSize(member.bytes, (PY_SIZE_TYPE)member.len); \
+#if PY_MAJOR_VERSION == 2
+# define PySTRING_FROM_AMQBYTES(member) \
+ PyString_FromStringAndSize((member).bytes, (Py_ssize_t)(member).len)
+#else
+# define PySTRING_FROM_AMQBYTES(member) \
+ PyUnicode_FromStringAndSize((member).bytes, (Py_ssize_t)(member).len)
+#endif
+
#define AMQTable_TO_PYKEY(table, i) \
PySTRING_FROM_AMQBYTES(table->entries[i].key)
@@ -83,7 +108,7 @@ _PYRMQ_INLINE PyObject* Maybe_Unicode(PyObject *);
#if defined(__C99__) || defined(__GNUC__)
# define PyString_AS_AMQBYTES(s) \
- (amqp_bytes_t){Py_SIZE(s), (void *)PyString_AS_STRING(s)}
+ (amqp_bytes_t){Py_SIZE(s), (void *)PyBytes_AS_STRING(s)}
#else
_PYRMQ_INLINE amqp_bytes_t PyString_AS_AMQBYTES(PyObject *);
_PYRMQ_INLINE amqp_bytes_t
@@ -91,7 +116,7 @@ PyString_AS_AMQBYTES(PyObject *s)
{
amqp_bytes_t ret;
ret.len = Py_SIZE(s);
- ret.bytes = (void *)PyString_AS_STRING(s);
+ ret.bytes = (void *)PyBytes_AS_STRING(s);
/*{Py_SIZE(s), (void *)PyString_AS_STRING(s)};*/
return ret;
}
@@ -337,8 +362,7 @@ static PyTypeObject PyRabbitMQ_ConnectionType = {
/* tp_getattro */ 0,
/* tp_setattro */ 0,
/* tp_as_buffer */ 0,
- /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
- Py_TPFLAGS_HAVE_WEAKREFS,
+ /* tp_flags */ TP_FLAGS,
/* tp_doc */ PyRabbitMQ_ConnectionType_doc,
/* tp_traverse */ 0,
/* tp_clear */ 0,
diff --git a/benchmark.py b/benchmark.py
index 7f17813..6143682 100644
--- a/benchmark.py
+++ b/benchmark.py
@@ -1,20 +1,18 @@
import timeit
-QS = ("amqplib.benchmark", "librabbit.benchmark")
-
-
INIT_COMMON = """
connection = amqp.Connection(hostname="localhost", userid="guest",
-password="guest", virtual_host="/")
+password="guest", virtual_host="/", lazy=True)
+connection.connect()
channel = connection.channel()
channel.exchange_declare(Q, "direct")
channel.queue_declare(Q)
channel.queue_bind(Q, Q, Q)
"""
-INIT_AMQPLIB = """
-from amqplib import client_0_8 as amqp
-Q = "amqplib.benchmark"
+INIT_AMQP = """
+import amqp
+Q = "amqp.benchmark"
%s
""" % INIT_COMMON
@@ -35,7 +33,7 @@ connection._basic_publish(1, "x" * %d, Q, Q, {})
"""
CONSUME = """
-method = getattr(channel, "wait", None) or connection.drain_events
+method = connection.drain_events
def callback(m):
channel.basic_ack(m.delivery_info["delivery_tag"])
channel.basic_consume(Q, callback=callback)
@@ -45,31 +43,45 @@ for i in range(%(its)d):
def bench_basic_publish(iterations=10000, bytes=256):
- t_publish_amqplib = timeit.Timer(stmt=PUBLISH % bytes,
- setup=INIT_AMQPLIB)
+ t_publish_amqp = timeit.Timer(stmt=PUBLISH % bytes,
+ setup=INIT_AMQP)
t_publish_librabbit = timeit.Timer(stmt=PUBLISH_LIBRABBIT % bytes,
setup=INIT_LIBRABBIT)
- print("basic.publish: (%s byte messages)" % bytes)
- print(" amqplib: %.2f usec/pass" % (
- iterations * t_publish_amqplib.timeit(number=iterations)/iterations))
- print(" librabbit: %.2f usec/pass" % (
- iterations * t_publish_librabbit.timeit(number=iterations)/iterations))
+ print("basic.publish: (%s x %s bytes messages)" % (iterations, bytes))
+ print(" amqp: %.2f sec/pass" % (
+ iterations * t_publish_amqp.timeit(number=iterations)/iterations)
+ )
+ print(" librabbit: %.2f sec/pass" % (
+ iterations * t_publish_librabbit.timeit(number=iterations)/iterations)
+ )
-def bench_basic_consume(iterations=10000):
+def bench_basic_consume(iterations=10000, bytes=None):
context = {"its": (iterations/2)/10}
- t_consume_amqplib = timeit.Timer(stmt=CONSUME % context,
- setup=INIT_AMQPLIB)
+ t_consume_amqp = timeit.Timer(stmt=CONSUME % context,
+ setup=INIT_AMQP)
t_consume_librabbit = timeit.Timer(stmt=CONSUME % context,
setup=INIT_LIBRABBIT)
print("basic.consume (%s msg/pass) " % context["its"])
- print(" amqplib: %.2f usec/pass" % (
- 10 * t_consume_amqplib.timeit(number=10)/10))
- print(" librabbit: %.2f usec/pass" % (
- 10 * t_consume_librabbit.timeit(number=10)/10))
+ print(" amqp: %.2f sec/pass" % (
+ t_consume_amqp.timeit(number=10))
+ )
+ print(" librabbit: %.2f sec/pass" % (
+ t_consume_librabbit.timeit(number=10))
+ )
+
benchmarks = [bench_basic_publish, bench_basic_consume]
if __name__ == "__main__":
+ import argparse
+
+ parser = argparse.ArgumentParser(description='Runs benchmark against local RabbitMQ instance.')
+ parser.add_argument('--iters', metavar='N', type=int, default=100000,
+ help='Number of iterations')
+ parser.add_argument('--bytes', metavar='B', type=int,
+ default=256, help='Message size')
+
+ args = parser.parse_args()
for benchmark in benchmarks:
- benchmark(100000)
+ benchmark(args.iters, bytes=args.bytes)
diff --git a/funtests/config.py b/funtests/config.py
index 8e3cec4..1b95423 100644
--- a/funtests/config.py
+++ b/funtests/config.py
@@ -7,7 +7,7 @@ BROKER_USER = os.environ.get('BROKER_USER', 'guest')
BROKER_PASSWORD = os.environ.get('BROKER_PASSWORD', 'guest')
from functools import partial
-from unittest2 import TestCase
+from unittest import TestCase
from uuid import uuid4
diff --git a/funtests/setup.py b/funtests/setup.py
index fa6f625..5116dd6 100644
--- a/funtests/setup.py
+++ b/funtests/setup.py
@@ -45,7 +45,6 @@ setup(
build_requires=[
"nose",
"nose-cover3",
- "unittest2",
"coverage>=3.0",
],
classifiers=[
diff --git a/librabbitmq/__init__.py b/librabbitmq/__init__.py
index c3c831c..974f1f6 100644
--- a/librabbitmq/__init__.py
+++ b/librabbitmq/__init__.py
@@ -1,6 +1,8 @@
from __future__ import absolute_import
+import sys
import itertools
+from six.moves import xrange
import _librabbitmq
@@ -43,7 +45,10 @@ class Channel(object):
def __init__(self, connection, channel_id):
self.connection = connection
self.channel_id = channel_id
- self.next_consumer_tag = itertools.count(1).next
+ if sys.version_info.major == 2:
+ self.next_consumer_tag = itertools.count(1).next
+ else:
+ self.next_consumer_tag = itertools.count(1).__next__
self.no_ack_consumers = set()
def __enter__(self):
diff --git a/librabbitmq/tests/test_functional.py b/librabbitmq/tests/test_functional.py
index 2dc9bd6..03d6276 100644
--- a/librabbitmq/tests/test_functional.py
+++ b/librabbitmq/tests/test_functional.py
@@ -1,8 +1,9 @@
from __future__ import absolute_import
-from __future__ import with_statement
+
+from six.moves import xrange
import socket
-import unittest2 as unittest
+import unittest
from librabbitmq import Message, Connection, ConnectionError, ChannelError
TEST_QUEUE = 'pyrabbit.testq'
@@ -86,7 +87,7 @@ class test_Channel(unittest.TestCase):
for i in xrange(100):
self.connection.drain_events(timeout=0.2)
- self.assertEquals(len(messages), 100)
+ self.assertEqual(len(messages), 100)
def test_timeout(self):
"""Check that our ``drain_events`` call actually times out if
@@ -110,7 +111,7 @@ class test_Channel(unittest.TestCase):
with self.assertRaises(socket.timeout):
self.connection.drain_events(timeout=0.1)
- self.assertEquals(len(messages), 1)
+ self.assertEqual(len(messages), 1)
def tearDown(self):
if self.channel and self.connection.connected:
diff --git a/rabbitmq-c b/rabbitmq-c
-Subproject 185ce081e3efc846b476995b7da7297bb0eec82
+Subproject caad0ef1533783729c7644a226c989c79b4c497
diff --git a/rabbitmq-codegen b/rabbitmq-codegen
deleted file mode 160000
-Subproject b25efdd3f88a2b37af8e6c928432cb7378e772a
diff --git a/requirements/README.rst b/requirements/README.rst
index 1175f71..ffe49f4 100644
--- a/requirements/README.rst
+++ b/requirements/README.rst
@@ -14,10 +14,6 @@ Index
Requirements needed to run the full unittest suite.
-* :file:`requirements/test3.txt`
-
- Requirements needed to run the full unittest suite on Python 3.
-
* :file:`requirements/test-ci.txt`
Extra test requirements required by the CI suite (Tox).
@@ -41,12 +37,3 @@ Running the tests
$ pip install -U -r requirements/default.txt
$ pip install -U -r requirements/test.txt
-
-
-Running the tests on Python 3
------------------------------
-
-::
-
- $ pip install -U -r requirements/default.txt
- $ pip install -U -r requirements/test3.txt
diff --git a/requirements/default.txt b/requirements/default.txt
index 22439cb..6fa7e25 100644
--- a/requirements/default.txt
+++ b/requirements/default.txt
@@ -1 +1,2 @@
+six>=1.0.0
amqp>=1.4.6
diff --git a/requirements/test.txt b/requirements/test.txt
index 70e6505..1f4031d 100644
--- a/requirements/test.txt
+++ b/requirements/test.txt
@@ -1,3 +1,3 @@
-unittest2>=0.4.0
nose
mock
+six
diff --git a/setup.py b/setup.py
index 58118de..0b94c10 100644
--- a/setup.py
+++ b/setup.py
@@ -5,9 +5,8 @@ from setuptools import setup, find_packages
# --with-librabbitmq=<dir>: path to librabbitmq package if needed
-LRMQDIST = lambda *x: os.path.join('clib', *x)
+LRMQDIST = lambda *x: os.path.join('rabbitmq-c', *x)
LRMQSRC = lambda *x: LRMQDIST('librabbitmq', *x)
-SPECPATH = lambda *x: os.path.join('rabbitmq-codegen', *x)
PYCP = lambda *x: os.path.join('Modules', '_librabbitmq', *x)
@@ -17,25 +16,7 @@ def senv(*k__v, **kwargs):
for k, v in k__v:
prev = restore[k] = os.environ.get(k)
os.environ[k] = (prev + sep if prev else '') + str(v)
- return dict((k, v) for k, v in restore.iteritems() if v is not None)
-
-
-def codegen():
- codegen = LRMQSRC('codegen.py')
- spec = SPECPATH('amqp-rabbitmq-0.9.1.json')
- sys.path.insert(0, SPECPATH())
- commands = [
- (sys.executable, codegen, 'header', spec, LRMQSRC('amqp_framing.h')),
- (sys.executable, codegen, 'body', spec, LRMQSRC('amqp_framing.c')),
- ]
- restore = senv(('PYTHONPATH', SPECPATH()), sep=':')
- try:
- for command in commands:
- print('- generating %r' % command[-1])
- print(' '.join(command))
- os.system(' '.join(command))
- finally:
- os.environ.update(restore)
+ return dict((k, v) for k, v in restore.items() if v is not None)
def create_builder():
@@ -81,7 +62,7 @@ def create_builder():
'amqp_socket.c',
'amqp_table.c',
'amqp_tcp_socket.c',
- 'amqp_timer.c',
+ 'amqp_time.c',
'amqp_url.c',
])
@@ -92,7 +73,7 @@ def create_builder():
librabbitmq_ext = Extension(
'_librabbitmq',
- sources=PyC_files + librabbit_files,
+ sources=list(PyC_files) + list(librabbit_files),
libraries=libs, include_dirs=incdirs,
library_dirs=libdirs, define_macros=defs,
)
@@ -150,7 +131,6 @@ def create_builder():
restore = senv(
('CFLAGS', ' '.join(self.stdcflags)),
)
- codegen()
try:
_build.run(self)
finally:
@@ -179,10 +159,9 @@ packages = []
goahead = False
is_jython = sys.platform.startswith('java')
is_pypy = hasattr(sys, 'pypy_version_info')
-is_py3k = sys.version_info[0] == 3
is_win = platform.system() == 'Windows'
is_linux = platform.system() == 'Linux'
-if is_jython or is_pypy or is_py3k or is_win:
+if is_jython or is_pypy or is_win:
pass
elif find_make():
try:
@@ -216,6 +195,13 @@ if 'bdist_egg' in sys.argv and 'build' not in sys.argv:
sys.argv[:_index] + ['build', 'bdist_egg'] + sys.argv[_index + 1:]
)
+# 'test doesn't always call build for some reason
+if 'test' in sys.argv and 'build' not in sys.argv:
+ _index = sys.argv.index('test')
+ sys.argv[:] = (
+ sys.argv[:_index] + ['build', 'test'] + sys.argv[_index + 1:]
+ )
+
setup(
name='librabbitmq',
version=version,
@@ -231,6 +217,7 @@ setup(
cmdclass=cmdclass,
install_requires=[
'amqp>=1.4.6',
+ 'six>=1.0.0',
],
ext_modules=ext_modules,
classifiers=[
@@ -238,9 +225,10 @@ setup(
'Operating System :: POSIX',
'Operating System :: Microsoft :: Windows',
'Programming Language :: C',
- 'Programming Language :: Python :: 2.5',
- 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Intended Audience :: Developers',
'License :: OSI Approved :: Mozilla Public License 1.0 (MPL)',