Commit 4b082179 authored by SVN-Git Migration's avatar SVN-Git Migration

Imported Upstream version 2.1.10

parent 1b30b35a
*.pyc
*.c
build
dist
conf
*.egg-info
*.so
*.pyd
*.dll
docs/source/api/generated
docs/gh-pages
setup.cfg
MANIFEST
include COPYING.LESSER
include README.rst
include setup.cfg.template
include setup.py
include setupegg.py
include zmqversion.py
include buildutils.py
graft docs
prune docs/build
prune docs/gh-pages
graft examples
graft zmq
graft perf
exclude setup.cfg
exclude zmq/libzmq*
# exclude docs/_static
# exclude docs/_templates
global-exclude *.so
global-exclude *.pyd
global-exclude *.pyc
global-exclude .git*
global-exclude .DS_Store
Metadata-Version: 1.0
Name: pyzmq
Version: 2.1.10
Summary: Python bindings for 0MQ.
Home-page: http://github.com/zeromq/pyzmq
Author: Brian E. Granger, Min Ragan-Kelley
Author-email: zeromq-dev@lists.zeromq.org
License: LGPL
Download-URL: http://github.com/zeromq/pyzmq/downloads
Description:
PyZMQ is a lightweight and super-fast messaging library built on top of
the ZeroMQ library (http://www.zeromq.org).
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Topic :: System :: Networking
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.5
Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.0
Classifier: Programming Language :: Python :: 3.1
Classifier: Programming Language :: Python :: 3.2
......@@ -8,7 +8,7 @@ This package contains Python bindings for `ØMQ <http://www.zeromq.org>`_.
Versioning
==========
Current release of pyzmq is 2.1.9, and targets libzmq-2.1.9. For libzmq
Current release of pyzmq is 2.1.10, and targets libzmq-2.1.10. For libzmq
2.0.x, use pyzmq release 2.0.10.1 or the 2.0.x development branch.
PyZMQ versioning follows libzmq versioning. In general, your pyzmq version should be the same
......@@ -20,10 +20,12 @@ intend to support libzmq >= 2.1.4 (the first 'stable' 2.1 release) for pyzmq 2.1
---------------
As of 2.1.7, we have experimental support for the 3.0 API of libzmq,
developed at https://github.com/zeromq/libzmq. No code to change, no flags to pass, just
build pyzmq against libzmq 3 and it should work. The pyzmq API has not changed.
developed at https://github.com/zeromq/zeromq3-0. No code to change, no flags to pass, just
build pyzmq against libzmq 3 and it should work. The pyzmq API has not changed, though
some syntax has been added to support new features, such as the LABEL routing prefix in 3.0.
2.1.9 adds support for the changes in ØMQ-4.0 dev, at time of release.
2.1.9 adds support for the changes in the experimental 4.0 development branch at
https://github.com/zeromq/libzmq.
Documentation
......@@ -51,7 +53,7 @@ Eggs and MSIs
-------------
We have binary installers for various Pythons on OSX and Windows, so you should be able to
just ``easy_install pyzmq`` in many situations. These eggs *include libzmq-2.1.9*, so they should
just ``easy_install pyzmq`` in many situations. These eggs *include matching libzmq*, so they should
be the only thing you need to start using pyzmq, but we simply don't have the experience to know
when and where these installers will not work.
......@@ -59,9 +61,14 @@ If a binary installer fails for you, please `tell us <https://github.com/zeromq/
about your system and the failure, so that we can try to fix it in later releases, and fall back
on building from source.
Eggs are on PyPI, and we have them for 'current' Pythons, which are for OSX 10.6:
Eggs are on `PyPI <http://pypi.python.org/pypi/pyzmq>`_, and we have them for 'current' Pythons,
which are for OSX 10.7:
* Python 2.6, 2.7, 3.2 (32b and 64b intel)
* Python 2.7, 3.2 (32b+64b intel)
and OSX 10.6:
* Python 2.6 (32b+64b intel)
and Windows (x86 and x64):
......@@ -76,9 +83,12 @@ Our build scripts are much improved as of 2.1.4, so if you would like to contrib
Windows installers, or have any improvements on existing releases, they would be much
appreciated. Simply ``python setup.py bdist_msi`` or ``python setupegg.py bdist_egg`` *should*
work, once you have a libzmq and Python. We simply don't have the VMs or time in which to cover
all the bases ourselves. Sometimes libzmq.so/dll/dylib doesn't get included unless ``build``
is specified *also*, e.g. ``python setupegg.py build bdist_egg``, but this doesn't always
seem to be true.
all the bases ourselves.
.. note::
Sometimes libzmq.so/dll/dylib doesn't get included unless ``build`` is
specified *also*, e.g. ``python setupegg.py build bdist_egg``, but this
doesn't always seem to be true.
General
-------
......@@ -94,11 +104,11 @@ or the zmq install directory on OSX/Linux:
$ python setup.py configure --zmq=/usr/local
The argument should be a directory containing a ``lib`` and a ``include`` directory, containing
The argument should be a directory containing ``lib`` and ``include`` directories, with
``libzmq`` and ``zmq.h`` respectively. For instance (on Windows), if you have downloaded pyzmq
and current libzmq into the same parent directory, this would be:
$ python setup.py configure --zmq=../zeromq-2.1.9
$ python setup.py configure --zmq=../zeromq-2.1.10
Second, run this command::
......@@ -229,6 +239,7 @@ The following people have contributed to the project:
* Eugene Chernyshov (chernyshov DOT eugene AT gmail DOT com)
* Douglas Creager (dcreager AT dcreager DOT net)
* Craig Austin (craig DOT austin AT gmail DOT com)
* Andrew Gwozdziewycz (git AT apgwoz DOT com)
* Baptiste Lepilleur (baptiste DOT lepilleur AT gmail DOT com)
......
......@@ -9,9 +9,32 @@ Changes in PyZMQ
This is a coarse summary of changes in pyzmq versions. For a real changelog, consult the
`git log <https://github.com/zeromq/pyzmq/commits>`_
2.1.10
======
2.1.9 (dev)
===========
* Add support for libzmq-3.0 LABEL prefixes:
* send a message with label-prefix with:
.. sourcecode:: python
send_multipart([b'msg', b'parts'], prefix=[b'label', b'prefix'])
* :meth:`recv_multipart` returns a tuple of ``(prefix,msg)`` if a label prefix is detected
* ZMQStreams and devices also respect the LABEL prefix
* add czmq-style close&term as :meth:`ctx.destroy`, so that :meth:`ctx.term`
remains threadsafe and 1:1 with libzmq.
* :meth:`Socket.close` takes optional linger option, for setting linger prior
to closing.
* add :func:`~zmq.core.version.zmq_version_info` and
:func:`~zmq.core.version.pyzmq_version_info` for getting libzmq and pyzmq versions as
tuples of numbers. This helps with the fact that version string comparison breaks down
once versions get into double-digits.
* ioloop changes merged from upstream `Tornado <http://www.tornadoweb.org>`_ 2.1
2.1.9
=====
* added zmq.ssh tools for tunneling socket connections, copied from IPython
* Expanded sockopt support to cover changes in libzmq-4.0 dev.
......
......@@ -13,8 +13,9 @@ PyZMQ Documentation
.. Note::
PyZMQ versioning follows zeromq, so your pyzmq version should match that of your
zeromq. The only changes at the pyzmq user's level are the addition of a few socket
types and socket options.
zeromq. Building the same pyzmq against various versions of zeromq should only result
in the addition/removal of a few socket types and socket options, depending on
the active zeromq's support.
PyZMQ is the Python bindings for ØMQ_, written almost entirely in Cython_. This
......@@ -27,6 +28,7 @@ an overview of what the ØMQ API looks like in Python. For information on how to
As of PyZMQ 2.1.7, PyZMQ has experimental support for the libzmq-3.0 development version,
and has dropped support for the zeromq-2.0 series.
Please don't hesitate to report pyzmq issues to our tracker_ on GitHub.
:ref:`Summary of Changes in PyZMQ <changelog>`
......
import re,time
import sys
from subprocess import Popen,PIPE
from local_lat import main as local_lat
from local_thr import main as local_thr
from remote_lat import main as remote_lat
from remote_thr import main as remote_thr
def run_thr(args):
local = Popen('python local_thr.py'.split()+args,stdout=PIPE,stdin=PIPE)
remote = Popen('python remote_thr.py'.split()+args,stdout=PIPE,stdin=PIPE)
remote.wait()
local.wait()
out,_ = local.communicate()
lines = out.splitlines()
result = lines[-1]
throughput = re.findall(r'[0-9\.]+',result)[0]
return float(throughput)
def run_lat(args):
local = Popen('python local_lat.py'.split()+args,stdout=PIPE,stdin=PIPE)
remote = Popen('python remote_lat.py'.split()+args,stdout=PIPE,stdin=PIPE)
line = ''
while 'latency' not in line:
line = remote.stdout.readline()
if 'latency' in line:
latency = re.findall(r'[0-9\.]+',line)[0]
remote.wait()
local.wait()
return float(latency)
def multi_lat(args, n=3):
lats = [ run_lat(args) for i in xrange(3) ]
avg = sum(lats) / len(lats)
return avg,min(lats),max(lats)
def multi_thr(args, n=3):
thrs = [ run_thr(args) for i in xrange(3) ]
avg = sum(thrs) / len(thrs)
return avg,min(thrs),max(thrs)
def generate_vs_msg_size(nmsgs, msg_sizes=[2**p for p in range(6,21)], samples=5):
print nmsgs
x = msg_sizes
thr = []
lat = []
for msg_size in msg_sizes:
args = ('tcp://127.0.0.1:12345 %i %i'%(msg_size, nmsgs)).split()
thr.append(multi_thr(args,samples))
print 'thr: %i %s'%(msg_size, thr[-1])
lat.append(multi_lat(args,samples))
print 'lat: %i %s'%(msg_size, lat[-1])
return x,thr,lat
def generate_vs_nmsgs(msg_size, nmsgs_s=[2**p for p in range(4,14)], samples=5):
print msg_size
x = nmsgs_s
thr = []
lat = []
for nmsgs in nmsgs_s:
args = ('tcp://127.0.0.1:12345 %i %i'%(msg_size, nmsgs)).split()
thr.append(multi_thr(args,samples))
print 'thr: %i %s'%(nmsgs, thr[-1])
lat.append(multi_lat(args,samples))
print 'lat: %i %s'%(nmsgs, lat[-1])
return x,thr,lat
def do_plot(x,thr,lat, ref=1024, vs='nmsgs'):
import pylab
pylab.figure()
if vs == 'msg_size':
title = "%i msgs"%ref
xlabel = "msg size (B)"
else:
title = "msg size = %i B"%ref
xlabel = "nmsgs"
pylab.grid(True, which='major')
# pylab.grid(True, which='minor')
pylab.title(title)
pylab.xlabel(xlabel)
t_a,t_min,t_max = zip(*thr)
pylab.loglog(x,t_a,'b',label='throughput')
pylab.loglog(x,t_min,'b:')
pylab.loglog(x,t_max,'b:')
pylab.ylabel("Mb/s")
pylab.legend(loc='upper left')
ax2 = pylab.twinx()
l_a,l_min,l_max = zip(*lat)
pylab.loglog(x,l_a,'g',label='latency')
pylab.loglog(x,l_min,'g:')
pylab.loglog(x,l_max,'g:')
pylab.ylabel("msec")
pylab.legend(loc='upper right')
......@@ -501,7 +501,7 @@ monqueue = pxd('devices', 'monitoredqueue')
submodules = dict(
core = {'constants': [libzmq],
'error':[libzmq],
'poll':[libzmq, socket],
'poll':[libzmq, socket, context],
'stopwatch':[libzmq, pxd('core','stopwatch')],
'context':[context, libzmq],
'message':[libzmq, buffers, message],
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -167,12 +167,13 @@ EADDRINUSE = ZMQ_EADDRINUSE
EADDRNOTAVAIL = ZMQ_EADDRNOTAVAIL
ECONNREFUSED = ZMQ_ECONNREFUSED
EINPROGRESS = ZMQ_EINPROGRESS
ENOTSOCK = ZMQ_ENOTSOCK
# 0MQ Native
EMTHREAD = ZMQ_EMTHREAD
EFSM = ZMQ_EFSM
ENOCOMPATPROTO = ZMQ_ENOCOMPATPROTO
ETERM = ZMQ_ETERM
EMTHREAD = ZMQ_EMTHREAD
if ZMQ_VERSION >= 400000:
ECANTROUTE = ZMQ_ECANTROUTE
_optionals.append('ECANTROUTE')
......@@ -229,10 +230,11 @@ __all__ = [
'EADDRNOTAVAIL',
'ECONNREFUSED',
'EINPROGRESS',
'EMTHREAD',
'ENOTSOCK',
'EFSM',
'ENOCOMPATPROTO',
'ETERM',
'EMTHREAD',
'EFAULT',
'ENOMEM',
'ENODEV',
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -24,7 +24,6 @@
#-----------------------------------------------------------------------------
from libc.stdlib cimport free, malloc, realloc
from errno import ENOTSOCK
from libzmq cimport *
......@@ -66,12 +65,16 @@ cdef class Context:
raise MemoryError("Could not allocate _sockets array")
def __del__(self):
"""deleting a Context should terminate it, without trying non-threadsafe destroy"""
self.term()
def __dealloc__(self):
"""don't touch members in dealloc, just cleanup allocations"""
cdef int rc
if self.handle != NULL:
self.term()
if self._sockets != NULL:
free(self._sockets)
self.term()
cdef inline void _add_socket(self, void* handle):
"""Add a socket handle to be closed when Context terminates.
......@@ -133,22 +136,15 @@ cdef class Context:
def term(self):
"""ctx.term()
Close or terminate the context and all its sockets.
Close or terminate the context.
This can be called to close the context by hand. If this is not
called, the context will automatically be closed when it is
garbage collected.
This can be called to close the context by hand. If this is not called,
the context will automatically be closed when it is garbage collected.
"""
cdef int rc
cdef int i=-1
if self.handle != NULL and not self.closed:
for i in range(self.n_sockets):
# print 'closing: ', <size_t>self._sockets[i]
with nogil:
rc = zmq_close(self._sockets[i])
if rc != 0 and zmq_errno() != ENOTSOCK:
raise ZMQError()
# print i
with nogil:
rc = zmq_term(self.handle)
if rc != 0:
......@@ -156,6 +152,37 @@ cdef class Context:
self.handle = NULL
self.closed = True
def destroy(self, linger=None):
"""ctx.destroy(linger=None)
Close all sockets associated with this context, and then terminate
the context. If linger is specified,
the LINGER sockopt of the sockets will be set prior to closing.
WARNING:
destroy involves calling zmq_close(), which is *NOT* threadsafe.
If there are active sockets in other threads, this must not be called.
"""
cdef int linger_c
cdef bint setlinger=False
if linger is not None:
linger_c = linger
setlinger=True
if self.handle != NULL and not self.closed and self.n_sockets:
while self.n_sockets:
with nogil:
if setlinger:
zmq_setsockopt(self._sockets[0], ZMQ_LINGER, &linger_c, sizeof(int))
rc = zmq_close(self._sockets[0])
if rc != 0 and zmq_errno() != ENOTSOCK:
raise ZMQError()
self.n_sockets -= 1
self._sockets[0] = self._sockets[self.n_sockets]
self.term()
def socket(self, int socket_type):
"""ctx.socket(socket_type)
......
/* Generated by Cython 0.15.1+ on Wed Oct 12 15:39:15 2011 */
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#ifndef Py_PYTHON_H
#error Python headers needed to compile C extensions, please install development version of Python.
#elif PY_VERSION_HEX < 0x02040000
#error Cython requires Python 2.4+.
#else
#include <stddef.h> /* For offsetof */
#ifndef offsetof
#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
#endif
#if !defined(WIN32) && !defined(MS_WINDOWS)
#ifndef __stdcall
#define __stdcall
#endif
#ifndef __cdecl
#define __cdecl
#endif
#ifndef __fastcall
#define __fastcall
#endif
#endif
#ifndef DL_IMPORT
#define DL_IMPORT(t) t
#endif
#ifndef DL_EXPORT
#define DL_EXPORT(t) t
#endif
#ifndef PY_LONG_LONG
#define PY_LONG_LONG LONG_LONG
#endif
#if PY_VERSION_HEX < 0x02050000
typedef int Py_ssize_t;
#define PY_SSIZE_T_MAX INT_MAX
#define PY_SSIZE_T_MIN INT_MIN
#define PY_FORMAT_SIZE_T ""
#define PyInt_FromSsize_t(z) PyInt_FromLong(z)
#define PyInt_AsSsize_t(o) __Pyx_PyInt_AsInt(o)
#define PyNumber_Index(o) PyNumber_Int(o)
#define PyIndex_Check(o) PyNumber_Check(o)
#define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
#endif
#if PY_VERSION_HEX < 0x02060000
#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
#define PyVarObject_HEAD_INIT(type, size) \
PyObject_HEAD_INIT(type) size,
#define PyType_Modified(t)
typedef struct {
void *buf;
PyObject *obj;
Py_ssize_t len;
Py_ssize_t itemsize;
int readonly;
int ndim;
char *format;
Py_ssize_t *shape;
Py_ssize_t *strides;
Py_ssize_t *suboffsets;
void *internal;
} Py_buffer;
#define PyBUF_SIMPLE 0
#define PyBUF_WRITABLE 0x0001
#define PyBUF_FORMAT 0x0004
#define PyBUF_ND 0x0008
#define PyBUF_STRIDES (0x0010 | PyBUF_ND)
#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
#endif
#if PY_MAJOR_VERSION < 3
#define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
#define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
#else
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
#define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
#endif
#if PY_MAJOR_VERSION >= 3
#define Py_TPFLAGS_CHECKTYPES 0
#define Py_TPFLAGS_HAVE_INDEX 0
#endif
#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
#define Py_TPFLAGS_HAVE_NEWBUFFER 0
#endif
/* new Py3.3 unicode representation (PEP 393) */
#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_GET_LENGTH)
#define CYTHON_PEP393_ENABLED
#define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
#define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
#else
#define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
#define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
#endif
#if PY_MAJOR_VERSION >= 3
#define PyBaseString_Type PyUnicode_Type
#define PyStringObject PyUnicodeObject
#define PyString_Type PyUnicode_Type
#define PyString_Check PyUnicode_Check
#define PyString_CheckExact PyUnicode_CheckExact
#endif
#if PY_VERSION_HEX < 0x02060000
#define PyBytesObject PyStringObject
#define PyBytes_Type PyString_Type
#define PyBytes_Check PyString_Check
#define PyBytes_CheckExact PyString_CheckExact
#define PyBytes_FromString PyString_FromString
#define PyBytes_FromStringAndSize PyString_FromStringAndSize
#define PyBytes_FromFormat PyString_FromFormat
#define PyBytes_DecodeEscape PyString_DecodeEscape
#define PyBytes_AsString PyString_AsString
#define PyBytes_AsStringAndSize PyString_AsStringAndSize
#define PyBytes_Size PyString_Size
#define PyBytes_AS_STRING PyString_AS_STRING
#define PyBytes_GET_SIZE PyString_GET_SIZE
#define PyBytes_Repr PyString_Repr
#define PyBytes_Concat PyString_Concat
#define PyBytes_ConcatAndDel PyString_ConcatAndDel
#endif
#if PY_VERSION_HEX < 0x02060000
#define PySet_Check(obj) PyObject_TypeCheck(obj, &PySet_Type)
#define PyFrozenSet_Check(obj) PyObject_TypeCheck(obj, &PyFrozenSet_Type)
#endif
#ifndef PySet_CheckExact
#define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
#endif
#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
#if PY_MAJOR_VERSION >= 3
#define PyIntObject PyLongObject
#define PyInt_Type PyLong_Type
#define PyInt_Check(op) PyLong_Check(op)
#define PyInt_CheckExact(op) PyLong_CheckExact(op)
#define PyInt_FromString PyLong_FromString
#define PyInt_FromUnicode PyLong_FromUnicode
#define PyInt_FromLong PyLong_FromLong
#define PyInt_FromSize_t PyLong_FromSize_t
#define PyInt_FromSsize_t PyLong_FromSsize_t
#define PyInt_AsLong PyLong_AsLong
#define PyInt_AS_LONG PyLong_AS_LONG
#define PyInt_AsSsize_t PyLong_AsSsize_t
#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
#endif
#if PY_MAJOR_VERSION >= 3
#define PyBoolObject PyLongObject
#endif
#if PY_VERSION_HEX < 0x03020000
typedef long Py_hash_t;
#define __Pyx_PyInt_FromHash_t PyInt_FromLong
#define __Pyx_PyInt_AsHash_t PyInt_AsLong
#else
#define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
#define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
#endif
#if PY_MAJOR_VERSION >= 3
#define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
#define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
#else
#define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
#define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
#endif
#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
#define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
#define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
#define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
#else
#define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
(PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
(likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
(PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
#define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
(PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
(likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
(PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
#define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
(PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
(likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
(PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
#endif
#if PY_MAJOR_VERSION >= 3
#define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
#endif
#if PY_VERSION_HEX < 0x02050000
#define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))
#define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
#define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))
#else
#define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))
#define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
#define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))
#endif
#if PY_VERSION_HEX < 0x02050000
#define __Pyx_NAMESTR(n) ((char *)(n))
#define __Pyx_DOCSTR(n) ((char *)(n))
#else
#define __Pyx_NAMESTR(n) (n)
#define __Pyx_DOCSTR(n) (n)
#endif
#ifndef __PYX_EXTERN_C
#ifdef __cplusplus
#define __PYX_EXTERN_C extern "C"
#else
#define __PYX_EXTERN_C extern
#endif
#endif
#if defined(WIN32) || defined(MS_WINDOWS)
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#define __PYX_HAVE__zmq__core__device
#define __PYX_HAVE_API__zmq__core__device
#include "allocate.h"
#include "errno.h"
#include "string.h"
#include "zmq_compat.h"
#include "zmq.h"
#include "zmq_utils.h"
#ifdef _OPENMP
#include <omp.h>
#endif /* _OPENMP */
#ifdef PYREX_WITHOUT_ASSERTIONS
#define CYTHON_WITHOUT_ASSERTIONS
#endif
/* inline attribute */
#ifndef CYTHON_INLINE
#if defined(__GNUC__)
#define CYTHON_INLINE __inline__
#elif defined(_MSC_VER)
#define CYTHON_INLINE __inline
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define CYTHON_INLINE inline
#else
#define CYTHON_INLINE
#endif
#endif
/* unused attribute */
#ifndef CYTHON_UNUSED
# if defined(__GNUC__)
# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
# define CYTHON_UNUSED __attribute__ ((__unused__))
# else
# define CYTHON_UNUSED
# endif
# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
# define CYTHON_UNUSED __attribute__ ((__unused__))
# else
# define CYTHON_UNUSED
# endif
#endif
typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
/* Type Conversion Predeclarations */
#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
#define __Pyx_PyBytes_AsUString(s) ((unsigned char*) PyBytes_AsString(s))
#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
<