From 77bc3790fa9e781ad26ec881175d22d807e16acf Mon Sep 17 00:00:00 2001 From: tamara Date: Mon, 24 Aug 2009 11:17:16 +0200 Subject: [PATCH] python extension added --- Makefile.am | 4 +- configure.in | 59 +++- python/Makefile.am | 7 + python/pyzmq.cpp | 756 +++++++++++++++++++++++++++++++++++++++++++++ python/setup.py.in | 14 + 5 files changed, 837 insertions(+), 3 deletions(-) create mode 100644 python/Makefile.am create mode 100644 python/pyzmq.cpp create mode 100644 python/setup.py.in diff --git a/Makefile.am b/Makefile.am index 156c97ef..c84eda22 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ include_HEADERS = include/zmq.h include/zmq.hpp -SUBDIRS = src examples -DIST_SUBDIRS = src examples +SUBDIRS = src examples python +DIST_SUBDIRS = src examples python diff --git a/configure.in b/configure.in index 932b4dd9..fd4ffcf0 100644 --- a/configure.in +++ b/configure.in @@ -159,6 +159,59 @@ if test "x$HAVE_INTTYPES_H" = "xyes"; then inttypes="1" fi +# Python +pyzmq="no" + +AC_ARG_WITH(python_headersdir, + AC_HELP_STRING([--with-python-headersdir], [Python.h header file location]), + [python_headersdir="$withval"], [python_headersdir="no"]) + +AC_ARG_WITH([python], [AS_HELP_STRING([--with-python], [build Python language binding [default=no]])], [with_python=yes], [with_python=no]) +if test "x$with_python" != "xno"; then + AM_PATH_PYTHON([2.4], , [:]) + if test "x$PYTHON" = "x:"; then + AC_MSG_ERROR([To run configure with --with-python option, Python has to be installed.]); + fi + + if test "x$python_headersdir" != "xno"; then + PYTHON_INCLUDES="-I${python_headersdir}" + PYTHON_SETUP_INCLUDES="${python_headersdir}" + + AC_CHECK_HEADERS($python_headersdir/Python.h, [] , + [AC_MSG_ERROR([To run configure with --with-python option, Python.h has to be usable.])]) + + else + py_prefix=`$PYTHON -c "import sys; print sys.prefix"` + py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"` + PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" + PYTHON_SETUP_INCLUDES="${py_prefix}/include/python${PYTHON_VERSION}" + + if test "$py_prefix" != "$py_exec_prefix"; then + PYTHON_INCLUDES="${PYTHON_INCLUDES} -I${py_exec_prefix}/include/python${PYTHON_VERSION}" + fi + + AC_CHECK_HEADERS($py_prefix/include/python${PYTHON_VERSION}/Python.h, [] , + [AC_MSG_ERROR([To run configure with --with-python option, Python.h has to be usable.])]) + fi + + AC_SUBST(PYTHON_INCLUDES) + AC_SUBST(PYTHON_SETUP_INCLUDES) + + pyzmq="yes" +fi + +if test "x$pyzmq" != "xyes"; then + AC_CHECK_PROG(have_python, python, yes, no) + if test "x$have_python" != "xyes"; then + AC_MSG_ERROR([Could not find python.]) + fi + fi + + # Generate version.c + AC_CONFIG_COMMANDS([version.c], + [python third-party/openpgm/libpgm-1.0.0/openpgm/pgm/version_generator.py > \ + third-party/openpgm/libpgm-1.0.0/openpgm/pgm/version.c]) + AC_SUBST(stdint) AC_SUBST(inttypes) @@ -171,7 +224,8 @@ AC_FUNC_MALLOC AC_TYPE_SIGNAL AC_CHECK_FUNCS(perror gettimeofday memset socket getifaddrs freeifaddrs) -AC_OUTPUT(Makefile src/Makefile examples/Makefile examples/chat/Makefile) +AC_OUTPUT(Makefile src/Makefile examples/Makefile examples/chat/Makefile python/Makefile \ +python/setup.py) AC_MSG_RESULT([]) AC_MSG_RESULT([ ******************************************************** ]) @@ -184,5 +238,8 @@ AC_MSG_RESULT([ license text. ]) AC_MSG_RESULT([ ******************************************************** ]) AC_MSG_RESULT([]) AC_MSG_RESULT([ 0MQ install dir: $prefix]) +AC_MSG_RESULT([ Python language binding: $pyzmq]) AC_MSG_RESULT([]) +AM_CONDITIONAL(BUILD_PYTHON, test "x$pyzmq" = "xyes") + diff --git a/python/Makefile.am b/python/Makefile.am new file mode 100644 index 00000000..effe8b9b --- /dev/null +++ b/python/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/libzmq \ +-I$(top_builddir)/libzmq $(PYTHON_INCLUDES) + +pyexec_LTLIBRARIES = libpyzmq.la +libpyzmq_la_SOURCES = pyzmq.cpp +libpyzmq_la_LIBADD = $(top_builddir)/src/libzmq.la +libpyzmq_la_LDFLAGS = -avoid-version diff --git a/python/pyzmq.cpp b/python/pyzmq.cpp new file mode 100644 index 00000000..019c73c1 --- /dev/null +++ b/python/pyzmq.cpp @@ -0,0 +1,756 @@ +/* + Copyright (c) 2007-2009 FastMQ Inc. + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the Lesser GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + Lesser GNU General Public License for more details. + + You should have received a copy of the Lesser GNU General Public License + along with this program. If not, see . +*/ + +#include + +#include + +struct pyZMQ +{ + PyObject_HEAD + +}; + +void pyZMQ_dealloc (pyZMQ *self) +{ + + self->ob_type->tp_free ((PyObject*) self); +} + +PyObject *pyZMQ_new (PyTypeObject *type, PyObject *args, PyObject *kwdict) +{ + pyZMQ *self = (pyZMQ*) type->tp_alloc (type, 0); + + return (PyObject*) self; +} + +PyObject *pyZMQ_term (PyTypeObject *type, PyObject *args, PyObject *kwdict) +{ + pyZMQ *self = (pyZMQ*) type->tp_alloc (type, 0); + + static const char *kwlist [] = {"context", NULL}; + PyObject *context; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "O", (char**) kwlist, + &context)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_term ((void *) context); + assert (rc != 0); + + return (PyObject*) self; +} + +int pyZMQ_init (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + return 0; +} + +PyObject *pyZMQ_context (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"app_threads", "io_threads", NULL}; + + int app_threads; + int io_threads; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "ii", (char**) kwlist, + &app_threads, &io_threads)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + void *context = zmq_init (app_threads, io_threads); + if (context == NULL) { + assert (errno == EINVAL); + PyErr_SetString (PyExc_ValueError, "Invalid argument"); + } + + return (PyObject*) context; +} + +PyObject *pyZMQ_msg_init (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + zmq_msg *msg; + + int rc = zmq_msg_init (msg); + + if (rc == -1) { + assert (rc == ENOMEM); + PyErr_SetString( PyExc_MemoryError, "Out of memory"); + } + + return (PyObject*) msg; +} + + +PyObject *pyZMQ_msg_init_size (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"size", NULL}; + + zmq_msg *msg; + int size; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "i", (char**) kwlist, + &size)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_msg_init_size (msg, size); + + if (rc == -1) { + assert (rc == ENOMEM); + PyErr_SetString( PyExc_ValueError, "Out of memory"); + } + + return (PyObject*) msg; +} + +PyObject *pyZMQ_msg_init_data (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"data", "size", "ffn", NULL}; + + PyObject *data = PyString_FromStringAndSize (NULL, 0); + zmq_msg *msg; + PyObject *ffn; + int size; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "SiO", (char**) kwlist, + &data, &size, &ffn)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_msg_init_data (msg, data, size, NULL); + assert (rc == 0); + + return (PyObject*) msg; +} + +PyObject *pyZMQ_msg_close (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"msg", NULL}; + + PyObject *msg; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "O", (char**) kwlist, + &msg)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_msg_close ((zmq_msg *) msg); + assert (rc == 0); + + return (PyObject*) self; +} + +PyObject *pyZMQ_msg_move (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"src", NULL}; + + zmq_msg *dest; + PyObject *src; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "O", (char**) kwlist, + &src)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_msg_move (dest, (zmq_msg*) src); + assert (rc == 0); + + return (PyObject*) dest; +} + +PyObject *pyZMQ_msg_copy (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"src", NULL}; + + PyObject *dest; + PyObject *src; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "O", (char**) kwlist, + &src)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_msg_copy ((zmq_msg*) dest, (zmq_msg*) src); + assert (rc == 0); + + return (PyObject*) dest; +} + +PyObject *pyZMQ_msg_data (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"msg", NULL}; + + PyObject *msg; + PyObject *data = PyString_FromStringAndSize (NULL, 0); + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "O", (char**) kwlist, + &msg)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + data = (PyObject *) zmq_msg_data ((zmq_msg *) msg); + + return (PyObject*) data; +} + +int pyZMQ_msg_size (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"msg", NULL}; + + PyObject *msg; + int size; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "O", (char**) kwlist, + &msg)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + size = zmq_msg_size ((zmq_msg*) msg); + + return size; +} + +int pyZMQ_msg_type (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"msg", NULL}; + + PyObject *msg; + int type; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "O", (char**) kwlist, + &msg)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + type = zmq_msg_type ((zmq_msg*) msg); + + return type; +} + +PyObject *pyZMQ_socket (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"context", "type", NULL}; + void* context; + int type; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "Oi", (char**) kwlist, + &context, &type)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + void *socket = zmq_socket ((void *) context, type); + + if (socket == NULL) { + assert (errno == EMFILE || errno == EINVAL); + if (errno == EMFILE) + PyErr_SetString (PyExc_MemoryError, "Too many threads"); + else + PyErr_SetString (PyExc_ValueError, "Invalid argument"); + } + + return (PyObject*) socket; +} + +PyObject *pyZMQ_close (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"socket", NULL}; + + PyObject* socket; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "O", (char**) kwlist, + &socket)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + + int rc = zmq_close ((void *)socket); + assert (rc == 0); + + return (PyObject *) self; +} + +PyObject *pyZMQ_setsockopt (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + static const char *kwlist [] = {"socket", "option", "optval", NULL}; + printf ("setsockopt\n"); + PyObject* socket; + int option; + PyObject* optval; + int optvallen; + int rc; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "OiO", (char**) kwlist, + &socket, &option, &optval)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + if (PyInt_Check (optval)) + rc = zmq_setsockopt ((void *) socket, option, (void *) optval, + 4); + if (PyBool_Check (optval)) + rc = zmq_setsockopt ((void *) socket, option, (void *) optval, + 1); + if (PyFloat_Check (optval)) + rc = zmq_setsockopt ((void *) socket, option, (void *) optval, + 4); + if (PyString_Check (optval)) + rc = zmq_setsockopt ((void *) socket, option, (void *) optval, + PyString_Size (optval)); + + assert (rc == 0); + + return (PyObject *) self; +} + +PyObject *pyZMQ_bind (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + char const *addr = NULL; + PyObject* socket; + + static const char *kwlist [] = {"socket", "addr", NULL}; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "Os", (char**) kwlist, + &socket, &addr)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_bind ((void*) socket, addr); + if (rc == -1) { + assert (errno == EINVAL || errno == EADDRINUSE); + if (errno == EINVAL) + PyErr_SetString (PyExc_ValueError, "Invalid argument"); + else + PyErr_SetString (PyExc_ValueError, "Address in use"); + } + + return (PyObject *) self; +} +PyObject *pyZMQ_connect (pyZMQ *self, PyObject *args, PyObject *kw) +{ + char const *addr = NULL; + PyObject* socket; + + static const char* kwlist [] = {"socket", "addr", NULL}; + + if (!PyArg_ParseTupleAndKeywords (args, kw, "Os", (char**) kwlist, + &socket, &addr)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_connect ((void *) socket, addr); + if (rc == -1) { + assert (errno == EINVAL || errno == EADDRINUSE); + if (errno == EINVAL) + PyErr_SetString (PyExc_ValueError, "Invalid argument"); + else + PyErr_SetString (PyExc_ValueError, "Address in use"); + } + + return (PyObject *) self; +} + +PyObject *pyZMQ_flush (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + + static const char *kwlist [] = {"socket", NULL}; + PyObject *socket; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "O", (char**) kwlist, + &socket)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_flush ((void*) socket); + assert (rc == 0); + + return (PyObject *) self; +} + +PyObject *pyZMQ_send (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + PyObject *msg; + PyObject *socket; + int flags = 0; + + static const char *kwlist [] = {"socket", "msg", "flags", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "OOi", (char**) kwlist, + &socket, &msg, &flags)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_send ((void*) socket, (zmq_msg*) msg, flags); + assert (rc == 0 || (rc == -1 && errno == EAGAIN)); + + return (PyObject *) self; +} + +PyObject *pyZMQ_receive (pyZMQ *self, PyObject *args, PyObject *kwdict) +{ + zmq_msg *msg; + zmq_msg_init (msg); + PyObject *socket; + + int flags = 0; + static const char *kwlist [] = {"socket", "flags", NULL}; + + if (!PyArg_ParseTupleAndKeywords (args, kwdict, "Oi", (char**) kwlist, + &socket, &flags)) + PyErr_SetString (PyExc_SystemError, + "PyArg_ParseTupleAndKeywords error"); + + int rc = zmq_recv (socket, msg, flags); + assert (rc == 0 || (rc == -1 && errno == EAGAIN)); + + PyObject *py_message = PyString_FromStringAndSize (NULL, 0); + py_message = (PyObject *) zmq_msg_data (msg); + int py_message_size = zmq_msg_size (msg); + int py_message_type = zmq_msg_type (msg); + + zmq_msg_close (msg); + + return Py_BuildValue ("isi", rc, py_message, + py_message_size, py_message_type); +} + +static PyMethodDef pyZMQ_methods [] = +{ + { + "context", + (PyCFunction) pyZMQ_context, + METH_VARARGS | METH_KEYWORDS, + "context (app_threads, io_threads) -> None\n\n" + "Creates new context\n\n" + "app_threads is the number of application threads.\n\n" + "io_threads is the number of io threads.\n\n" + + }, + { + "msg_init", + (PyCFunction) pyZMQ_msg_init, + METH_VARARGS | METH_KEYWORDS, + "msg_init () -> None\n\n" + "Creates new message\n\n" + + }, + { + "msg_init_size", + (PyCFunction) pyZMQ_msg_init_size, + METH_VARARGS | METH_KEYWORDS, + "msg_init_size (size) -> None\n\n" + "Creates new message of a specified size.\n\n" + "size if integer specifying the size of the message to be created.\n\n" + + }, + { + "msg_init_data", + (PyCFunction) pyZMQ_msg_init_data, + METH_VARARGS | METH_KEYWORDS, + "msg_init_data (data, size, ffn) -> None\n\n" + "Initialises new message with data\n\n" + "data is pointer to the data of the message\n\n" + "size is integer specifying size of data\n\n" + "ffn is function to free alocated data\n\n" + + }, + + { + "msg_close", + (PyCFunction) pyZMQ_msg_close, + METH_VARARGS | METH_KEYWORDS, + "msg_close (msg) -> None\n\n" + "Deletes the message.\n\n" + "msg is the message the be freed\n\n" + + }, + { + "msg_move", + (PyCFunction) pyZMQ_msg_move, + METH_VARARGS | METH_KEYWORDS, + "msg_move (src) -> dest\n\n" + "Move the content of the message from 'src' to 'dest'.\n\n" + "The content isn't copied, just moved. 'src' is an empty\n\n" + "message after the call. Original content of 'dest' message\n\n" + "is deallocated.\n\n" + + }, + { + "msg_copy", + (PyCFunction) pyZMQ_msg_copy, + METH_VARARGS | METH_KEYWORDS, + "msg_copy (src) -> dest\n\n" + "Copy the 'src' message to 'dest'. The content isn't copied, \n\n" + "instead reference count is increased. Don't modify the message \n\n" + "data after the call as they are shared between two messages.\n\n" + "Original content of 'dest' message is deallocated.\n\n" + + }, + { + "msg_data", + (PyCFunction) pyZMQ_msg_data, + METH_VARARGS | METH_KEYWORDS, + "msg_data (msg) -> data\n\n" + "Returns pointer to message data.\n\n" + + }, + { + "msg_size", + (PyCFunction) pyZMQ_msg_size, + METH_VARARGS | METH_KEYWORDS, + "msg_size (msg) -> size\n\n" + "Returns size of a message.\n\n" + + }, + { + "msg_type", + (PyCFunction) pyZMQ_msg_type, + METH_VARARGS | METH_KEYWORDS, + "msg_type (msg) -> type\n\n" + "Returns type of a message.\n\n" + + }, + { + "term", + (PyCFunction) pyZMQ_term, + METH_VARARGS | METH_KEYWORDS, + "term (context) -> None\n\n" + "Deinitialise 0SOCKETS context including all the open sockets.\n\n" + "Closing sockets after zmq_term has been called will result in\n\n" + "undefined behaviour.\n\n" + + }, + { + "close", + (PyCFunction) pyZMQ_close, + METH_VARARGS | METH_KEYWORDS, + "close (socket) -> None\n\n" + "Close the socket.\n\n" + + }, + + { + "socket", + (PyCFunction) pyZMQ_socket, + METH_VARARGS | METH_KEYWORDS, + "socket (context, type) -> None\n\n" + "Creates new socket.\n\n" + "'context' is a context_t object.\n" + "'type' is one of 'ZMQ_NOBLOCK', 'ZMQ_NOFLUSH', 'ZMQ_P2P', 'ZMQ_PUB', " + " 'ZMQ_SUB', 'ZMQ_REQ ZMQ_REP'\n" + }, + { + "setsockopt", + (PyCFunction) pyZMQ_setsockopt, + METH_VARARGS | METH_KEYWORDS, + "setsockopt (socket, option, value) -> None\n\n" + "Set socket options." + "Possible options are: 'ZMQ_HWM', 'ZMQ_LWM', 'ZMQ_SWAP', 'ZMQ_MASK', " + "'ZMQ_AFFINITY', 'ZMQ_IDENTITY'." + }, + { + "bind", + (PyCFunction) pyZMQ_bind, + METH_VARARGS | METH_KEYWORDS, + "bind (addr) -> None\n\n" + "Bind socket to specified address." + }, + { + "connect", + (PyCFunction) pyZMQ_connect, + METH_VARARGS | METH_KEYWORDS, + "connect (addr) -> None\n\n" + "connect socket to specified address." + }, + { + "flush", + (PyCFunction) pyZMQ_flush, + METH_VARARGS | METH_KEYWORDS, + "flush (addr) -> None\n\n" + "flush " + }, + { + "send", + (PyCFunction) pyZMQ_send, + METH_VARARGS | METH_KEYWORDS, + "send (message, flags) -> sent\n\n" + "Send a message to within the socket, " + "returns integer specifying if the message was sent.\n" + "'message' is message to be sent.\n" + "'flags' is integer specifying send options.\n" + }, + { + "receive", + (PyCFunction) pyZMQ_receive, + METH_VARARGS | METH_KEYWORDS, + "receive (flags) -> (received, message, type)\n\n" + "Receive a message." + "'flags' is integer specifying receive options.\n" + "'message' is string storing the message received.\n" + "'type' is type of the message received.\n" + + }, + { + NULL + } +}; + +static const char* pyZMQ_ZMQ_doc = + "0MQ messaging session\n\n" + "Available functions:\n" + " context\n" + " socket\n" + " setsockopt\n" + " bind\n" + " send\n" + " flush\n" + " receive\n\n"; + +static PyTypeObject pyZMQType = +{ + PyObject_HEAD_INIT (NULL) + 0, + "libpyzmq.Zmq", /* tp_name (This will appear in the default + textual representation of our objects and + in some error messages)*/ + sizeof (pyZMQ), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) pyZMQ_dealloc,/* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + (char*) pyZMQ_ZMQ_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pyZMQ_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) pyZMQ_init, /* tp_init */ + 0, /* tp_alloc */ + pyZMQ_new, /* tp_new */ +}; + +static PyMethodDef module_methods[] = +{ + { NULL, NULL, 0, NULL } +}; + +#ifndef PyMODINIT_FUNC +#define PyMODINIT_FUNC void +#endif + +static const char* pyZMQ_doc = + "0MQ Python Module\n\n" + "Constructor:\n" + " z = libpyzmq.Zmq ()\n" + "Available functions:\n" + " context\n" + " socket\n" + " setsockopt\n" + " bind\n" + " send\n" + " flush\n" + " receive\n" + "\n" + "For more information see http://www.zeromq.org.\n" + "\n" + "0MQ is distributed under GNU Lesser General Public License v3\n"; + +PyMODINIT_FUNC initlibpyzmq (void) +{ + if (PyType_Ready (&pyZMQType) < 0) + return; + + PyObject *m = Py_InitModule3 ("libpyzmq", module_methods, + (char*) pyZMQ_doc); + if (!m) + return; + + Py_INCREF (&pyZMQType); + + PyModule_AddObject (m, "Zmq", (PyObject*) &pyZMQType); + + PyObject *d = PyModule_GetDict (m); + + + PyObject *t = PyInt_FromLong (ZMQ_NOBLOCK); + PyDict_SetItemString (d, "ZMQ_NOBLOCK", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_NOFLUSH); + PyDict_SetItemString (d, "ZMQ_NOFLUSH", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_P2P); + PyDict_SetItemString (d, "ZMQ_P2P", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_PUB); + PyDict_SetItemString (d, "ZMQ_PUB", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_SUB); + PyDict_SetItemString (d, "ZMQ_SUB", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_REQ); + PyDict_SetItemString (d, "ZMQ_REQ", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_REP); + PyDict_SetItemString (d, "ZMQ_REP", t); + Py_DECREF (t); + + t = PyInt_FromLong (ZMQ_HWM); + PyDict_SetItemString (d, "ZMQ_HWM", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_LWM); + PyDict_SetItemString (d, "ZMQ_LWM", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_SWAP); + PyDict_SetItemString (d, "ZMQ_SWAP", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_MASK); + PyDict_SetItemString (d, "ZMQ_MASK", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_AFFINITY); + PyDict_SetItemString (d, "ZMQ_AFFINITY", t); + Py_DECREF (t); + t = PyInt_FromLong (ZMQ_IDENTITY); + PyDict_SetItemString (d, "ZMQ_IDENTITY", t); + Py_DECREF (t); + + +} diff --git a/python/setup.py.in b/python/setup.py.in new file mode 100644 index 00000000..f7055d53 --- /dev/null +++ b/python/setup.py.in @@ -0,0 +1,14 @@ +from distutils.core import setup, Extension + +module1 = Extension('libpyzmq', + libraries = ['zmq'], + library_dirs = ['@prefix@/lib'], + include_dirs = ['@PYTHON_SETUP_INCLUDES@','@prefix@/include'], + sources = ['pyzmq.cpp']) + +setup (name = 'libyzmq', + version = '@VERSION@', + description = '0MQ Python library', + ext_modules = [module1]) + +