diff options
260 files changed, 0 insertions, 27781 deletions
diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 006c23c..0000000 --- a/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -*.pyc -zmq/*/*.c -zmq/*/*/*.c -zmq/utils/*.json -__pycache__ -build -dist -conf -bundled -*.egg-info -*.so -*.pyd -*.dll -*.dylib -docs/source/api/generated -docs/gh-pages -setup.cfg -MANIFEST -.tox -examples/security/public_keys -examples/security/private_keys diff --git a/.mailmap b/.mailmap deleted file mode 100644 index 2ad5e4f..0000000 --- a/.mailmap +++ /dev/null @@ -1,8 +0,0 @@ -Brian E. Granger <ellisonbg@gmail.com> Brian Granger <ellisonbg@gmail.com> -Daniel Lundin <dln@eintr.org> Daniel Lundin <dln@spotify.com> -Min Ragan-Kelley <benjaminrk@gmail.com> Min RK <benjaminrk@gmail.com> -Min Ragan-Kelley <benjaminrk@gmail.com> MinRK <benjaminrk@gmail.com> -Michel Pelletier <pelletier.michel@gmail.com> Michel Pelletier <pelletier.michel@yahoo.com> -Nicholas Piël <nicholas@nichol.as> nicholas <nicholas@bastet.ss.sitesupport.com> -Felipe Cruz <felipecruz@loogica.net> felipecruz <felipecruz@loogica.net> -Felipe Cruz <felipecruz@loogica.net> Felipe cruz <felipecruz@loogica.net> diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches deleted file mode 100644 index 6857a8d..0000000 --- a/.pc/.quilt_patches +++ /dev/null @@ -1 +0,0 @@ -debian/patches diff --git a/.pc/.quilt_series b/.pc/.quilt_series deleted file mode 100644 index c206706..0000000 --- a/.pc/.quilt_series +++ /dev/null @@ -1 +0,0 @@ -series diff --git a/.pc/.version b/.pc/.version deleted file mode 100644 index 0cfbf08..0000000 --- a/.pc/.version +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/.pc/applied-patches b/.pc/applied-patches deleted file mode 100644 index 0d2af1f..0000000 --- a/.pc/applied-patches +++ /dev/null @@ -1,3 +0,0 @@ -noncopysend-test.patch -cffi-fix.patch -monitor-test.patch diff --git a/.pc/cffi-fix.patch/zmq/backend/cffi/__init__.py b/.pc/cffi-fix.patch/zmq/backend/cffi/__init__.py deleted file mode 100644 index ca3164d..0000000 --- a/.pc/cffi-fix.patch/zmq/backend/cffi/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -"""CFFI backend (for PyPY)""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from zmq.backend.cffi import (constants, error, message, context, socket, -                           _poll, devices, utils) - -__all__ = [] -for submod in (constants, error, message, context, socket, -               _poll, devices, utils): -    __all__.extend(submod.__all__) - -from .constants import * -from .error import * -from .message import * -from .context import * -from .socket import * -from .devices import * -from ._poll import * -from ._cffi import zmq_version_info, ffi -from .utils import * diff --git a/.pc/cffi-fix.patch/zmq/backend/cffi/_cffi.py b/.pc/cffi-fix.patch/zmq/backend/cffi/_cffi.py deleted file mode 100644 index 67f4b6b..0000000 --- a/.pc/cffi-fix.patch/zmq/backend/cffi/_cffi.py +++ /dev/null @@ -1,238 +0,0 @@ -# coding: utf-8 -"""The main CFFI wrapping of libzmq""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import json -import os -from os.path import dirname, join -from cffi import FFI - -from zmq.utils.constant_names import all_names, no_prefix - - -ffi = FFI() - -base_zmq_version = (3,2,2) - -core_functions = \ -''' -void* zmq_socket(void *context, int type); -int zmq_close(void *socket); - -int zmq_bind(void *socket, const char *endpoint); -int zmq_connect(void *socket, const char *endpoint); - -int zmq_errno(void); -const char * zmq_strerror(int errnum); - -void* zmq_stopwatch_start(void); -unsigned long zmq_stopwatch_stop(void *watch); -void zmq_sleep(int seconds_); -int zmq_device(int device, void *frontend, void *backend); -''' - -core32_functions = \ -''' -int zmq_unbind(void *socket, const char *endpoint); -int zmq_disconnect(void *socket, const char *endpoint); -void* zmq_ctx_new(); -int zmq_ctx_destroy(void *context); -int zmq_ctx_get(void *context, int opt); -int zmq_ctx_set(void *context, int opt, int optval); -int zmq_proxy(void *frontend, void *backend, void *capture); -int zmq_socket_monitor(void *socket, const char *addr, int events); -''' - -core40_functions = \ -''' -int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key); -''' - -message32_functions = \ -''' -typedef struct { ...; } zmq_msg_t; -typedef ... zmq_free_fn; - -int zmq_msg_init(zmq_msg_t *msg); -int zmq_msg_init_size(zmq_msg_t *msg, size_t size); -int zmq_msg_init_data(zmq_msg_t *msg, -                      void *data, -                      size_t size, -                      zmq_free_fn *ffn, -                      void *hint); - -size_t zmq_msg_size(zmq_msg_t *msg); -void *zmq_msg_data(zmq_msg_t *msg); -int zmq_msg_close(zmq_msg_t *msg); - -int zmq_msg_send(zmq_msg_t *msg, void *socket, int flags); -int zmq_msg_recv(zmq_msg_t *msg, void *socket, int flags); -''' - -sockopt_functions = \ -''' -int zmq_getsockopt(void *socket, -                   int option_name, -                   void *option_value, -                   size_t *option_len); - -int zmq_setsockopt(void *socket, -                   int option_name, -                   const void *option_value, -                   size_t option_len); -''' - -polling_functions = \ -''' -typedef struct -{ -    void *socket; -    int fd; -    short events; -    short revents; -} zmq_pollitem_t; - -int zmq_poll(zmq_pollitem_t *items, int nitems, long timeout); -''' - -extra_functions = \ -''' -void * memcpy(void *restrict s1, const void *restrict s2, size_t n); -int get_ipc_path_max_len(void); -''' - -def load_compiler_config(): -    import zmq -    zmq_dir = dirname(zmq.__file__) -    zmq_parent = dirname(zmq_dir) -     -    fname = join(zmq_dir, 'utils', 'compiler.json') -    if os.path.exists(fname): -        with open(fname) as f: -            cfg = json.load(f) -    else: -        cfg = {} -     -    cfg.setdefault("include_dirs", []) -    cfg.setdefault("library_dirs", []) -    cfg.setdefault("runtime_library_dirs", []) -    cfg.setdefault("libraries", ["zmq"]) -     -    # cast to str, because cffi can't handle unicode paths (?!) -    cfg['libraries'] = [str(lib) for lib in cfg['libraries']] -    for key in ("include_dirs", "library_dirs", "runtime_library_dirs"): -        # interpret paths relative to parent of zmq (like source tree) -        abs_paths = [] -        for p in cfg[key]: -            if p.startswith('zmq'): -                p = join(zmq_parent, p) -            abs_paths.append(str(p)) -        cfg[key] = abs_paths -    return cfg - -cfg = load_compiler_config() - -def zmq_version_info(): -    ffi_check = FFI() -    ffi_check.cdef('void zmq_version(int *major, int *minor, int *patch);') -    cfg = load_compiler_config() -    C_check_version = ffi_check.verify('#include <zmq.h>', -        libraries=cfg['libraries'], -        include_dirs=cfg['include_dirs'], -        library_dirs=cfg['library_dirs'], -        runtime_library_dirs=cfg['runtime_library_dirs'], -    ) -    major = ffi.new('int*') -    minor = ffi.new('int*') -    patch = ffi.new('int*') - -    C_check_version.zmq_version(major, minor, patch) - -    return (int(major[0]), int(minor[0]), int(patch[0])) - -def _make_defines(names): -    _names = [] -    for name in names: -        define_line = "#define %s ..." % (name) -        _names.append(define_line) - -    return "\n".join(_names) - -c_constant_names = [] -for name in all_names: -    if no_prefix(name): -        c_constant_names.append(name) -    else: -        c_constant_names.append("ZMQ_" + name) - -constants = _make_defines(c_constant_names) - -try: -    _version_info = zmq_version_info() -except Exception as e: -    raise ImportError("PyZMQ CFFI backend couldn't find zeromq: %s\n" -    "Please check that you have zeromq headers and libraries." % e) - -if _version_info >= (3,2,2): -    functions = '\n'.join([constants, -                         core_functions, -                         core32_functions, -                         core40_functions, -                         message32_functions, -                         sockopt_functions, -                         polling_functions, -                         extra_functions, -    ]) -else: -    raise ImportError("PyZMQ CFFI backend requires zeromq >= 3.2.2," -        " but found %i.%i.%i" % _version_info -    ) - - -ffi.cdef(functions) - -C = ffi.verify(''' -    #include <stdio.h> -    #include <sys/un.h> -    #include <string.h> -     -    #include <zmq.h> -    #include <zmq_utils.h> -    #include "zmq_compat.h" - -int get_ipc_path_max_len(void) { -    struct sockaddr_un *dummy; -    return sizeof(dummy->sun_path) - 1; -} - -''', -    libraries=cfg['libraries'], -    include_dirs=cfg['include_dirs'], -    library_dirs=cfg['library_dirs'], -    runtime_library_dirs=cfg['runtime_library_dirs'], -) - -nsp = new_sizet_pointer = lambda length: ffi.new('size_t*', length) - -new_uint64_pointer = lambda: (ffi.new('uint64_t*'), -                              nsp(ffi.sizeof('uint64_t'))) -new_int64_pointer = lambda: (ffi.new('int64_t*'), -                             nsp(ffi.sizeof('int64_t'))) -new_int_pointer = lambda: (ffi.new('int*'), -                           nsp(ffi.sizeof('int'))) -new_binary_data = lambda length: (ffi.new('char[%d]' % (length)), -                                  nsp(ffi.sizeof('char') * length)) - -value_uint64_pointer = lambda val : (ffi.new('uint64_t*', val), -                                     ffi.sizeof('uint64_t')) -value_int64_pointer = lambda val: (ffi.new('int64_t*', val), -                                   ffi.sizeof('int64_t')) -value_int_pointer = lambda val: (ffi.new('int*', val), -                                 ffi.sizeof('int')) -value_binary_data = lambda val, length: (ffi.new('char[%d]' % (length + 1), val), -                                         ffi.sizeof('char') * length) - -IPC_PATH_MAX_LEN = C.get_ipc_path_max_len() diff --git a/.pc/monitor-test.patch/zmq/tests/test_monitor.py b/.pc/monitor-test.patch/zmq/tests/test_monitor.py deleted file mode 100644 index d47e23f..0000000 --- a/.pc/monitor-test.patch/zmq/tests/test_monitor.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import sys -import time -import struct - -from unittest import TestCase - -import zmq -from zmq.tests import BaseZMQTestCase, skip_if, skip_pypy -from zmq.utils.monitor import recv_monitor_message - -skip_lt_4 = skip_if(zmq.zmq_version_info() < (4,), "requires zmq >= 4") - -class TestSocketMonitor(BaseZMQTestCase): - -    @skip_lt_4 -    def test_monitor(self): -        """Test monitoring interface for sockets.""" -        s_rep = self.context.socket(zmq.REP) -        s_req = self.context.socket(zmq.REQ) -        self.sockets.extend([s_rep, s_req]) -        s_req.bind("tcp://127.0.0.1:6666") -        # try monitoring the REP socket -         -        s_rep.monitor("inproc://monitor.rep", zmq.EVENT_ALL) -        # create listening socket for monitor -        s_event = self.context.socket(zmq.PAIR) -        self.sockets.append(s_event) -        s_event.connect("inproc://monitor.rep") -        s_event.linger = 0 -        # test receive event for connect event -        s_rep.connect("tcp://127.0.0.1:6666") -        m = recv_monitor_message(s_event) -        self.assertEqual(m['event'], zmq.EVENT_CONNECT_DELAYED) -        self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6666") -        # test receive event for connected event -        m = recv_monitor_message(s_event) -        self.assertEqual(m['event'], zmq.EVENT_CONNECTED) - -    @skip_lt_4 -    def test_monitor_connected(self): -        """Test connected monitoring socket.""" -        s_rep = self.context.socket(zmq.REP) -        s_req = self.context.socket(zmq.REQ) -        self.sockets.extend([s_rep, s_req]) -        s_req.bind("tcp://127.0.0.1:6667") -        # try monitoring the REP socket -        # create listening socket for monitor -        s_event = s_rep.get_monitor_socket() -        s_event.linger = 0 -        self.sockets.append(s_event) -        # test receive event for connect event -        s_rep.connect("tcp://127.0.0.1:6667") -        m = recv_monitor_message(s_event) -        self.assertEqual(m['event'], zmq.EVENT_CONNECT_DELAYED) -        self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6667") -        # test receive event for connected event -        m = recv_monitor_message(s_event) -        self.assertEqual(m['event'], zmq.EVENT_CONNECTED) diff --git a/.pc/noncopysend-test.patch/zmq/tests/test_message.py b/.pc/noncopysend-test.patch/zmq/tests/test_message.py deleted file mode 100644 index d8770bd..0000000 --- a/.pc/noncopysend-test.patch/zmq/tests/test_message.py +++ /dev/null @@ -1,362 +0,0 @@ -# -*- coding: utf8 -*- -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import copy -import sys -try: -    from sys import getrefcount as grc -except ImportError: -    grc = None - -import time -from pprint import pprint -from unittest import TestCase - -import zmq -from zmq.tests import BaseZMQTestCase, SkipTest, skip_pypy, PYPY -from zmq.utils.strtypes import unicode, bytes, b, u - - -# some useful constants: - -x = b'x' - -try: -    view = memoryview -except NameError: -    view = buffer - -if grc: -    rc0 = grc(x) -    v = view(x) -    view_rc = grc(x) - rc0 - -def await_gc(obj, rc): -    """wait for refcount on an object to drop to an expected value -     -    Necessary because of the zero-copy gc thread, -    which can take some time to receive its DECREF message. -    """ -    for i in range(50): -        # rc + 2 because of the refs in this function -        if grc(obj) <= rc + 2: -            return -        time.sleep(0.05) -     -class TestFrame(BaseZMQTestCase): - -    @skip_pypy -    def test_above_30(self): -        """Message above 30 bytes are never copied by 0MQ.""" -        for i in range(5, 16):  # 32, 64,..., 65536 -            s = (2**i)*x -            self.assertEqual(grc(s), 2) -            m = zmq.Frame(s) -            self.assertEqual(grc(s), 4) -            del m -            await_gc(s, 2) -            self.assertEqual(grc(s), 2) -            del s - -    def test_str(self): -        """Test the str representations of the Frames.""" -        for i in range(16): -            s = (2**i)*x -            m = zmq.Frame(s) -            m_str = str(m) -            m_str_b = b(m_str) # py3compat -            self.assertEqual(s, m_str_b) - -    def test_bytes(self): -        """Test the Frame.bytes property.""" -        for i in range(1,16): -            s = (2**i)*x -            m = zmq.Frame(s) -            b = m.bytes -            self.assertEqual(s, m.bytes) -            if not PYPY: -                # check that it copies -                self.assert_(b is not s) -            # check that it copies only once -            self.assert_(b is m.bytes) - -    def test_unicode(self): -        """Test the unicode representations of the Frames.""" -        s = u('asdf') -        self.assertRaises(TypeError, zmq.Frame, s) -        for i in range(16): -            s = (2**i)*u('§') -            m = zmq.Frame(s.encode('utf8')) -            self.assertEqual(s, unicode(m.bytes,'utf8')) - -    def test_len(self): -        """Test the len of the Frames.""" -        for i in range(16): -            s = (2**i)*x -            m = zmq.Frame(s) -            self.assertEqual(len(s), len(m)) - -    @skip_pypy -    def test_lifecycle1(self): -        """Run through a ref counting cycle with a copy.""" -        for i in range(5, 16):  # 32, 64,..., 65536 -            s = (2**i)*x -            rc = 2 -            self.assertEqual(grc(s), rc) -            m = zmq.Frame(s) -            rc += 2 -            self.assertEqual(grc(s), rc) -            m2 = copy.copy(m) -            rc += 1 -            self.assertEqual(grc(s), rc) -            buf = m2.buffer - -            rc += view_rc -            self.assertEqual(grc(s), rc) - -            self.assertEqual(s, b(str(m))) -            self.assertEqual(s, bytes(m2)) -            self.assertEqual(s, m.bytes) -            # self.assert_(s is str(m)) -            # self.assert_(s is str(m2)) -            del m2 -            rc -= 1 -            self.assertEqual(grc(s), rc) -            rc -= view_rc -            del buf -            self.assertEqual(grc(s), rc) -            del m -            rc -= 2 -            await_gc(s, rc) -            self.assertEqual(grc(s), rc) -            self.assertEqual(rc, 2) -            del s - -    @skip_pypy -    def test_lifecycle2(self): -        """Run through a different ref counting cycle with a copy.""" -        for i in range(5, 16):  # 32, 64,..., 65536 -            s = (2**i)*x -            rc = 2 -            self.assertEqual(grc(s), rc) -            m = zmq.Frame(s) -            rc += 2 -            self.assertEqual(grc(s), rc) -            m2 = copy.copy(m) -            rc += 1 -            self.assertEqual(grc(s), rc) -            buf = m.buffer -            rc += view_rc -            self.assertEqual(grc(s), rc) -            self.assertEqual(s, b(str(m))) -            self.assertEqual(s, bytes(m2)) -            self.assertEqual(s, m2.bytes) -            self.assertEqual(s, m.bytes) -            # self.assert_(s is str(m)) -            # self.assert_(s is str(m2)) -            del buf -            self.assertEqual(grc(s), rc) -            del m -            # m.buffer is kept until m is del'd -            rc -= view_rc -            rc -= 1 -            self.assertEqual(grc(s), rc) -            del m2 -            rc -= 2 -            await_gc(s, rc) -            self.assertEqual(grc(s), rc) -            self.assertEqual(rc, 2) -            del s -     -    @skip_pypy -    def test_tracker(self): -        m = zmq.Frame(b'asdf', track=True) -        self.assertFalse(m.tracker.done) -        pm = zmq.MessageTracker(m) -        self.assertFalse(pm.done) -        del m -        for i in range(10): -            if pm.done: -                break -            time.sleep(0.1) -        self.assertTrue(pm.done) -     -    def test_no_tracker(self): -        m = zmq.Frame(b'asdf', track=False) -        self.assertEqual(m.tracker, None) -        m2 = copy.copy(m) -        self.assertEqual(m2.tracker, None) -        self.assertRaises(ValueError, zmq.MessageTracker, m) -     -    @skip_pypy -    def test_multi_tracker(self): -        m = zmq.Frame(b'asdf', track=True) -        m2 = zmq.Frame(b'whoda', track=True) -        mt = zmq.MessageTracker(m,m2) -        self.assertFalse(m.tracker.done) -        self.assertFalse(mt.done) -        self.assertRaises(zmq.NotDone, mt.wait, 0.1) -        del m -        time.sleep(0.1) -        self.assertRaises(zmq.NotDone, mt.wait, 0.1) -        self.assertFalse(mt.done) -        del m2 -        self.assertTrue(mt.wait() is None) -        self.assertTrue(mt.done) -         -     -    def test_buffer_in(self): -        """test using a buffer as input""" -        ins = b("§§¶•ªº˜µ¬˚…∆˙åß∂©œ∑´†≈ç√") -        m = zmq.Frame(view(ins)) -     -    def test_bad_buffer_in(self): -        """test using a bad object""" -        self.assertRaises(TypeError, zmq.Frame, 5) -        self.assertRaises(TypeError, zmq.Frame, object()) -         -    def test_buffer_out(self): -        """receiving buffered output""" -        ins = b("§§¶•ªº˜µ¬˚…∆˙åß∂©œ∑´†≈ç√") -        m = zmq.Frame(ins) -        outb = m.buffer -        self.assertTrue(isinstance(outb, view)) -        self.assert_(outb is m.buffer) -        self.assert_(m.buffer is m.buffer) -     -    def test_multisend(self): -        """ensure that a message remains intact after multiple sends""" -        a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        s = b"message" -        m = zmq.Frame(s) -        self.assertEqual(s, m.bytes) -         -        a.send(m, copy=False) -        time.sleep(0.1) -        self.assertEqual(s, m.bytes) -        a.send(m, copy=False) -        time.sleep(0.1) -        self.assertEqual(s, m.bytes) -        a.send(m, copy=True) -        time.sleep(0.1) -        self.assertEqual(s, m.bytes) -        a.send(m, copy=True) -        time.sleep(0.1) -        self.assertEqual(s, m.bytes) -        for i in range(4): -            r = b.recv() -            self.assertEqual(s,r) -        self.assertEqual(s, m.bytes) -     -    def test_buffer_numpy(self): -        """test non-copying numpy array messages""" -        try: -            import numpy -        except ImportError: -            raise SkipTest("numpy required") -        rand = numpy.random.randint -        shapes = [ rand(2,16) for i in range(5) ] -        for i in range(1,len(shapes)+1): -            shape = shapes[:i] -            A = numpy.random.random(shape) -            m = zmq.Frame(A) -            if view.__name__ == 'buffer': -                self.assertEqual(A.data, m.buffer) -                B = numpy.frombuffer(m.buffer,dtype=A.dtype).reshape(A.shape) -            else: -                self.assertEqual(memoryview(A), m.buffer) -                B = numpy.array(m.buffer,dtype=A.dtype).reshape(A.shape) -            self.assertEqual((A==B).all(), True) -     -    def test_memoryview(self): -        """test messages from memoryview""" -        major,minor = sys.version_info[:2] -        if not (major >= 3 or (major == 2 and minor >= 7)): -            raise SkipTest("memoryviews only in python >= 2.7") - -        s = b'carrotjuice' -        v = memoryview(s) -        m = zmq.Frame(s) -        buf = m.buffer -        s2 = buf.tobytes() -        self.assertEqual(s2,s) -        self.assertEqual(m.bytes,s) -     -    def test_noncopying_recv(self): -        """check for clobbering message buffers""" -        null = b'\0'*64 -        sa,sb = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        for i in range(32): -            # try a few times -            sb.send(null, copy=False) -            m = sa.recv(copy=False) -            mb = m.bytes -            # buf = view(m) -            buf = m.buffer -            del m -            for i in range(5): -                ff=b'\xff'*(40 + i*10) -                sb.send(ff, copy=False) -                m2 = sa.recv(copy=False) -                if view.__name__ == 'buffer': -                    b = bytes(buf) -                else: -                    b = buf.tobytes() -                self.assertEqual(b, null) -                self.assertEqual(mb, null) -                self.assertEqual(m2.bytes, ff) - -    @skip_pypy -    def test_buffer_numpy(self): -        """test non-copying numpy array messages""" -        try: -            import numpy -        except ImportError: -            raise SkipTest("requires numpy") -        if sys.version_info < (2,7): -            raise SkipTest("requires new-style buffer interface (py >= 2.7)") -        rand = numpy.random.randint -        shapes = [ rand(2,5) for i in range(5) ] -        a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        dtypes = [int, float, '>i4', 'B'] -        for i in range(1,len(shapes)+1): -            shape = shapes[:i] -            for dt in dtypes: -                A = numpy.empty(shape, dtype=dt) -                while numpy.isnan(A).any(): -                    # don't let nan sneak in -                    A = numpy.ndarray(shape, dtype=dt) -                a.send(A, copy=False) -                msg = b.recv(copy=False) -                 -                B = numpy.frombuffer(msg, A.dtype).reshape(A.shape) -                self.assertEqual(A.shape, B.shape) -                self.assertTrue((A==B).all()) -            A = numpy.empty(shape, dtype=[('a', int), ('b', float), ('c', 'a32')]) -            A['a'] = 1024 -            A['b'] = 1e9 -            A['c'] = 'hello there' -            a.send(A, copy=False) -            msg = b.recv(copy=False) -             -            B = numpy.frombuffer(msg, A.dtype).reshape(A.shape) -            self.assertEqual(A.shape, B.shape) -            self.assertTrue((A==B).all()) -     -    def test_frame_more(self): -        """test Frame.more attribute""" -        frame = zmq.Frame(b"hello") -        self.assertFalse(frame.more) -        sa,sb = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        sa.send_multipart([b'hi', b'there']) -        frame = self.recv(sb, copy=False) -        self.assertTrue(frame.more) -        if zmq.zmq_version_info()[0] >= 3 and not PYPY: -            self.assertTrue(frame.get(zmq.MORE)) -        frame = self.recv(sb, copy=False) -        self.assertFalse(frame.more) -        if zmq.zmq_version_info()[0] >= 3 and not PYPY: -            self.assertFalse(frame.get(zmq.MORE)) - diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d16b810..0000000 --- a/.travis.yml +++ /dev/null @@ -1,48 +0,0 @@ -language: python - -cache: -    apt -    pip -python: -  - 2.6 -  - 2.7 -  - 3.2 -  - 3.3 -  - 3.4 -  - pypy -env: -    - ZMQ= -    - ZMQ=bundled -    - ZMQ=master -before_install: -  - sudo add-apt-repository -y ppa:shnatsel/dnscrypt -  - sudo apt-get update -  - if [[ $ZMQ != 'bundled' ]]; then sudo apt-get install -qq libzmq3-dev libsodium-dev; fi -  - if [[ $TRAVIS_PYTHON_VERSION != 'pypy' ]]; then pip install -q cython --install-option='--no-cython-compile'; fi - -  - if [[ $ZMQ == 'master' ]]; then git clone --depth 1 https://github.com/zeromq/libzmq; fi -  - if [[ $ZMQ == 'master' ]]; then sh -c 'cd libzmq; sh autogen.sh; ./configure; make -j; sudo make install; sudo ldconfig'; fi -  - pip install -q --use-mirrors nose - -install: -  - if [[ $ZMQ == 'master' ]]; then export ZMQ=/usr/local; fi -  - python setup.py build_ext --inplace --zmq=$ZMQ - -matrix: -  exclude: -    - python: 2.6 -      env: ZMQ=bundled -    - python: 2.6 -      env: ZMQ=master -    - python: 3.2 -      env: ZMQ=bundled -    - python: 3.2 -      env: ZMQ=master -    - python: 3.3 -      env: ZMQ=bundled -    - python: 3.3 -      env: ZMQ=master -  allow_failures: -    - env: ZMQ=master - -script: python setup.py test diff --git a/AUTHORS.md b/AUTHORS.md deleted file mode 100644 index bbee345..0000000 --- a/AUTHORS.md +++ /dev/null @@ -1,103 +0,0 @@ -## Authors - -This project was started and continues to be led by Brian E. Granger -(ellisonbg AT gmail DOT com). Min Ragan-Kelley (benjaminrk AT gmail DOT -com) is the primary developer of pyzmq at this time. - -The following people have contributed to the project: - -- Alexander Else (alexander DOT else AT team DOT telstra DOT com) -- Alexander Pyhalov (apyhalov AT gmail DOT com) -- Alexandr Emelin (frvzmb AT gmail DOT com) -- Andre Caron (andre DOT l DOT caron AT gmail DOT com) -- Andrea Crotti (andrea DOT crotti DOT 0 AT gmail DOT com) -- Andrew Gwozdziewycz (git AT apgwoz DOT com) -- Baptiste Lepilleur (baptiste DOT lepilleur AT gmail DOT com) -- Brandyn A. White (bwhite AT dappervision DOT com) -- Brian E. Granger (ellisonbg AT gmail DOT com) -- Carlos A. Rocha (carlos DOT rocha AT gmail DOT com) -- Chris Laws (clawsicus AT gmail DOT com) -- Christian Wyglendowski (christian AT bu DOT mp) -- Christoph Gohlke (cgohlke AT uci DOT edu) -- Curtis (curtis AT tinbrain DOT net) -- Cyril Holweck (cyril DOT holweck AT free DOT fr) -- Dan Colish (dcolish AT gmail DOT com) -- Daniel Lundin (dln AT eintr DOT org) -- Daniel Truemper (truemped AT googlemail DOT com) -- Douglas Creager (douglas DOT creager AT redjack DOT com) -- Eduardo Stalinho (eduardooc DOT 86 AT gmail DOT com) -- Eren Güven (erenguven0 AT gmail DOT com) -- Erick Tryzelaar (erick DOT tryzelaar AT gmail DOT com) -- Erik Tollerud (erik DOT tollerud AT gmail DOT com) -- FELD Boris (lothiraldan AT gmail DOT com) -- Fantix King (fantix DOT king AT gmail DOT com) -- Felipe Cruz (felipecruz AT loogica DOT net) -- Fernando Perez (Fernando DOT Perez AT berkeley DOT edu) -- Frank Wiles (frank AT revsys DOT com) -- Gavrie Philipson (gavriep AT il DOT ibm DOT com) -- Godefroid Chapelle (gotcha AT bubblenet DOT be) -- Greg Banks (gbanks AT mybasis DOT com) -- Greg Ward (greg AT gerg DOT ca) -- Guido Goldstein (github AT a-nugget DOT de) -- Ivo Danihelka (ivo AT danihelka DOT net) -- Iyed (iyed DOT bennour AT gmail DOT com) -- Jim Garrison (jim AT garrison DOT cc) -- John Gallagher (johnkgallagher AT gmail DOT com) -- Julian Taylor (jtaylor DOT debian AT googlemail DOT com) -- Justin Bronder (jsbronder AT gmail DOT com) -- Justin Riley (justin DOT t DOT riley AT gmail DOT com) -- Marc Abramowitz (marc AT marc-abramowitz DOT com) -- Matthew Aburn (mattja6 AT gmail DOT com) -- Michel Pelletier (pelletier DOT michel AT gmail DOT com) -- Michel Zou (xantares09 AT hotmail DOT com) -- Min Ragan-Kelley (benjaminrk AT gmail DOT com) -- Nell Hardcastle (nell AT dev-nell DOT com) -- Nicholas Pilkington (nicholas DOT pilkington AT gmail DOT com) -- Nicholas Piël (nicholas AT nichol DOT as) -- Nick Pellegrino (npellegrino AT mozilla DOT com) -- Nicolas Delaby (nicolas DOT delaby AT ezeep DOT com) -- Ondrej Certik (ondrej AT certik DOT cz) -- Paul Colomiets (paul AT colomiets DOT name) -- Pawel Jasinski (pawel DOT jasinski AT gmail DOT com) -- Phus Lu (phus DOT lu AT gmail DOT com) -- Robert Buchholz (rbu AT goodpoint DOT de) -- Robert Jordens (jordens AT gmail DOT com) -- Ryan Cox (ryan DOT a DOT cox AT gmail DOT com) -- Ryan Kelly (ryan AT rfk DOT id DOT au) -- Scott Maxwell (scott AT codecobblers DOT com) -- Scott Sadler (github AT mashi DOT org) -- Simon Knight (simon DOT knight AT gmail DOT com) -- Stefan Friesel (sf AT cloudcontrol DOT de) -- Stefan van der Walt (stefan AT sun DOT ac DOT za) -- Stephen Diehl (stephen DOT m DOT diehl AT gmail DOT com) -- Thomas Kluyver (takowl AT gmail DOT com) -- Thomas Spura (tomspur AT fedoraproject DOT org) -- Tigger Bear (Tigger AT Tiggers-Mac-mini DOT local) -- Torsten Landschoff (torsten DOT landschoff AT dynamore DOT de) -- Vadim Markovtsev (v DOT markovtsev AT samsung DOT com) -- Zbigniew Jędrzejewski-Szmek (zbyszek AT in DOT waw DOT pl) -- hugo  shi (hugoshi AT bleb2 DOT (none)) -- jdgleeson (jdgleeson AT mac DOT com) -- kyledj (kyle AT bucebuce DOT com) -- spez (steve AT hipmunk DOT com) -- stu (stuart DOT axon AT jpcreative DOT co DOT uk) -- xantares (xantares AT fujitsu-l64 DOT (none)) - -as reported by: - -    git log --all --format='- %aN (%aE)' | sort -u | sed 's/@/ AT /1' | sed -e 's/\.\([^ ]\)/ DOT \1/g' - -with some adjustments. - -### Not in git log - -- Brandon Craig-Rhodes (brandon AT rhodesmill DOT org) -- Eugene Chernyshov (chernyshov DOT eugene AT gmail DOT com) -- Craig Austin (craig DOT austin AT gmail DOT com) - -### gevent\_zeromq, now zmq.green - -- Travis Cline (travis DOT cline AT gmail DOT com) -- Ryan Kelly (ryan AT rfk DOT id DOT au) -- Zachary Voase (z AT zacharyvoase DOT com) - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 688a6c3..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,86 +0,0 @@ -# Opening an Issue - -For a good bug report: - -1. [Search][] for existing Issues, both on GitHub and in general with Google/Stack Overflow before posting a duplicate question. -2. Update to pyzmq master, if possible, especially if you are already using git. It's -   possible that the bug you are about to report has already been fixed. - -Many things reported as pyzmq Issues are often just libzmq-related, -and don't have anything to do with pyzmq itself. -These are better directed to [zeromq-dev][]. - -When making a bug report, it is helpful to tell us as much as you can about your system -(such as pyzmq version, libzmq version, Python version, OS Version, how you built/installed pyzmq and libzmq, etc.) - -The basics: - -```python -import sys -import zmq - -print "libzmq-%s" % zmq.zmq_version() -print "pyzmq-%s" % zmq.pyzmq_version() -print "Python-%s" % sys.version -``` - -Which will give something like: - -    libzmq-3.3.0 -    pyzmq-2.2dev -    Python-2.7.2 (default, Jun 20 2012, 16:23:33)  -    [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] - -[search]: https://github.com/zeromq/pyzmq/issues -[zeromq-dev]: mailto:zeromq-dev@zeromq.org - - -# Licensing and contributing to PyZMQ - -PyZMQ uses different licenses for different parts of the code. - -The 'core' of PyZMQ (located in zmq/core) is licensed under LGPLv3. -This just  means that if you make any changes to how that code works, -you must release  those changes under the LGPL. -If you just *use* pyzmq, then you can use any license you want for your own code. - -We don't feel that the restrictions imposed by the LGPL make sense for the  -'non-core' functionality in pyzmq (derivative code must *also* be LGPL or GPL),  -especially for examples and utility code, so we have relicensed all 'non-core'  -code under the more permissive BSD (specifically Modified BSD aka New BSD aka  -3-clause BSD), where possible. This means that you can copy this code and build  -your own apps without needing to license your own code with the LGPL or GPL. - -## Your contributions - -**Pull Requests are welcome!** - -When you contribute to PyZMQ, your contributions are made under the same  -license as the file you are working on. Any new, original code should be BSD  -licensed. - -We don't enforce strict style, but when in doubt [PEP8][] is a good guideline. -The only thing we really don't like is mixing up 'cleanup' in real work. - -Examples are copyright their respective authors, and BSD unless otherwise  -specified by the author. You can LGPL (or GPL or MIT or Apache, etc.) your own new  -examples if you like, but we strongly encourage using the default BSD license. - -[PEP8]: http://www.python.org/dev/peps/pep-0008 - -## Inherited licenses in pyzmq - -Some code outside the core is taken from other open-source projects, and  -inherits that project's license. - -* zmq/eventloop contains files inherited and adapted from [tornado][], and inherits the Apache license - -* zmq/ssh/forward.py is from [paramiko][], and inherits LGPL - -* zmq/devices/monitoredqueue.pxd is derived from the zmq_device function in  -libzmq, and inherits LGPL - -* perf examples are (c) iMatix, and LGPL - -[tornado]: http://www.tornadoweb.org -[paramiko]: http://www.lag.net/paramiko
\ No newline at end of file diff --git a/COPYING.BSD b/COPYING.BSD deleted file mode 100644 index a0a3790..0000000 --- a/COPYING.BSD +++ /dev/null @@ -1,32 +0,0 @@ -PyZMQ is licensed under the terms of the Modified BSD License (also known as -New or Revised BSD), as follows: - -Copyright (c) 2009-2012, Brian Granger, Min Ragan-Kelley - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. - -Neither the name of PyZMQ nor the names of its contributors may be used to -endorse or promote products derived from this software without specific prior -written permission. - - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/COPYING.LESSER b/COPYING.LESSER deleted file mode 100644 index 3462706..0000000 --- a/COPYING.LESSER +++ /dev/null @@ -1,165 +0,0 @@ -		   GNU LESSER GENERAL PUBLIC LICENSE -                       Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - -  This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - -  0. Additional Definitions. - -  As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - -  "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - -  An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - -  A "Combined Work" is a work produced by combining or linking an -Application with the Library.  The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - -  The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - -  The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - -  1. Exception to Section 3 of the GNU GPL. - -  You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - -  2. Conveying Modified Versions. - -  If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - -   a) under this License, provided that you make a good faith effort to -   ensure that, in the event an Application does not supply the -   function or data, the facility still operates, and performs -   whatever part of its purpose remains meaningful, or - -   b) under the GNU GPL, with none of the additional permissions of -   this License applicable to that copy. - -  3. Object Code Incorporating Material from Library Header Files. - -  The object code form of an Application may incorporate material from -a header file that is part of the Library.  You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - -   a) Give prominent notice with each copy of the object code that the -   Library is used in it and that the Library and its use are -   covered by this License. - -   b) Accompany the object code with a copy of the GNU GPL and this license -   document. - -  4. Combined Works. - -  You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - -   a) Give prominent notice with each copy of the Combined Work that -   the Library is used in it and that the Library and its use are -   covered by this License. - -   b) Accompany the Combined Work with a copy of the GNU GPL and this license -   document. - -   c) For a Combined Work that displays copyright notices during -   execution, include the copyright notice for the Library among -   these notices, as well as a reference directing the user to the -   copies of the GNU GPL and this license document. - -   d) Do one of the following: - -       0) Convey the Minimal Corresponding Source under the terms of this -       License, and the Corresponding Application Code in a form -       suitable for, and under terms that permit, the user to -       recombine or relink the Application with a modified version of -       the Linked Version to produce a modified Combined Work, in the -       manner specified by section 6 of the GNU GPL for conveying -       Corresponding Source. - -       1) Use a suitable shared library mechanism for linking with the -       Library.  A suitable mechanism is one that (a) uses at run time -       a copy of the Library already present on the user's computer -       system, and (b) will operate properly with a modified version -       of the Library that is interface-compatible with the Linked -       Version. - -   e) Provide Installation Information, but only if you would otherwise -   be required to provide such information under section 6 of the -   GNU GPL, and only to the extent that such information is -   necessary to install and execute a modified version of the -   Combined Work produced by recombining or relinking the -   Application with a modified version of the Linked Version. (If -   you use option 4d0, the Installation Information must accompany -   the Minimal Corresponding Source and Corresponding Application -   Code. If you use option 4d1, you must provide the Installation -   Information in the manner specified by section 6 of the GNU GPL -   for conveying Corresponding Source.) - -  5. Combined Libraries. - -  You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - -   a) Accompany the combined library with a copy of the same work based -   on the Library, uncombined with any other library facilities, -   conveyed under the terms of this License. - -   b) Give prominent notice with the combined library that part of it -   is a work based on the Library, and explaining where to find the -   accompanying uncombined form of the same work. - -  6. Revised Versions of the GNU Lesser General Public License. - -  The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - -  Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - -  If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library.
\ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 501c320..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,49 +0,0 @@ -include COPYING.BSD -include COPYING.LESSER -include CONTRIBUTING.md -include MANIFEST.in -include README.md -include AUTHORS.md -include setup.cfg.template -include setup.cfg.android -include setup.py -include setupegg.py -include zmqversion.py -include tox.ini -include .travis.yml - -graft docs -prune docs/build -prune docs/gh-pages - -include bundled/zeromq/COPYING -graft bundled/zeromq/include -graft bundled/zeromq/src -include bundled/zeromq/builds/msvc/platform.hpp -exclude bundled/zeromq/src/Makefile* -exclude bundled/zeromq/src/platform.hpp - -include bundled/libsodium/LICENSE -graft bundled/libsodium/src - -graft buildutils -graft examples -graft zmq -graft perf - -exclude setup.cfg -exclude zmq/libzmq* -# exclude docs/_static -# exclude docs/_templates - -global-exclude __pycache__/* -global-exclude .deps/* -global-exclude *.so -global-exclude *.pyd -global-exclude *.pyc -global-exclude .git* -global-exclude .DS_Store -global-exclude .mailmap -global-exclude Makefile.am -global-exclude Makefile.in - diff --git a/README.md b/README.md deleted file mode 100644 index 8f46e5d..0000000 --- a/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# PyZMQ: Python bindings for ØMQ - -[](https://travis-ci.org/zeromq/pyzmq) - -This package contains Python bindings for [ØMQ](http://www.zeromq.org). -ØMQ is a lightweight and fast messaging implementation. - -PyZMQ should work with any Python ≥ 2.6 (including Python 3), as well as PyPy. -The Cython backend used by CPython supports libzmq ≥ 2.1.4 (including 3.2.x and 4.x), -but the CFFI backend used by PyPy only supports libzmq ≥ 3.2.2 (including 4.x). - -For a summary of changes to pyzmq, see our -[changelog](http://zeromq.github.io/pyzmq/changelog.html). - -### ØMQ 3.x, 4.x - -PyZMQ ≥ 2.2.0 fully supports the 3.x and 4.x APIs of libzmq, -developed at [zeromq/libzmq](https://github.com/zeromq/libzmq). -No code to change, no flags to pass, -just build pyzmq against the latest and it should work. - -PyZMQ does not support the old libzmq 2 API on PyPy. - -## Documentation - -See PyZMQ's Sphinx-generated -[documentation](http://zeromq.github.com/pyzmq) on GitHub for API -details, and some notes on Python and Cython development. If you want to -learn about using ØMQ in general, the excellent [ØMQ -Guide](http://zguide.zeromq.org/py:all) is the place to start, which has a -Python version of every example. We also have some information on our -[wiki](https://github.com/zeromq/pyzmq/wiki). - -## Downloading - -Unless you specifically want to develop PyZMQ, we recommend downloading -the PyZMQ source code, eggs, or wheels from -[PyPI](http://pypi.python.org/pypi/pyzmq). On Windows, you can get `.exe` installers -from [Christoph Gohlke](http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyzmq). - -You can also get the latest source code from our GitHub repository, but -building from the repository will require that you install Cython -version 0.16 or later. - -## Building and installation - -For more detail on building pyzmq, see [our Wiki](https://github.com/zeromq/pyzmq/wiki/Building-and-Installing-PyZMQ). - -We build eggs and wheels for OS X and Windows, so you can get a binary on those platforms with either: - -    pip install pyzmq - -or - -    easy_install pyzmq - -but compiling from source with `pip install pyzmq` should work in most environments. - -When compiling pyzmq (e.g. installing with pip on Linux), -it is generally recommended that zeromq be installed separately, via homebrew, apt, yum, etc. -If this is not available, pyzmq will *try* to build libzmq as a Python Extension, -though this is not guaranteed to work. - -To build pyzmq from the git repo (including release tags) requires Cython. - -## Old versions - -For libzmq 2.0.x, use pyzmq release 2.0.10.1. - -pyzmq-2.1.11 was the last version of pyzmq to support Python 2.5, -and pyzmq ≥ 2.2.0 requires Python ≥ 2.6. -pyzmq-13.0.0 introduces PyPy support via CFFI, which only supports libzmq-3.2.2 and newer. - -PyZMQ releases ≤ 2.2.0 matched libzmq versioning, but this is no longer the case, -starting with PyZMQ 13.0.0 (it was the thirteenth release, so why not?). -PyZMQ ≥ 13.0 follows semantic versioning conventions accounting only for PyZMQ itself. - diff --git a/buildutils/__init__.py b/buildutils/__init__.py deleted file mode 100644 index 91097f7..0000000 --- a/buildutils/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -"""utilities for building pyzmq. - -Largely adapted from h5py -""" - -from .msg import * -from .config import * -from .detect import * -from .bundle import * -from .misc import * diff --git a/buildutils/bundle.py b/buildutils/bundle.py deleted file mode 100644 index eb61160..0000000 --- a/buildutils/bundle.py +++ /dev/null @@ -1,197 +0,0 @@ -"""utilities for fetching build dependencies.""" - -#----------------------------------------------------------------------------- -#  Copyright (C) PyZMQ Developers -#  Distributed under the terms of the Modified BSD License. -# -#  This bundling code is largely adapted from pyzmq-static's get.sh by -#  Brandon Craig-Rhodes, which is itself BSD licensed. -#----------------------------------------------------------------------------- - - -import os -import shutil -import stat -import sys -import tarfile -from glob import glob -from subprocess import Popen, PIPE - -try: -    # py2 -    from urllib2 import urlopen -except ImportError: -    # py3 -    from urllib.request import urlopen - -from .msg import fatal, debug, info, warn - -pjoin = os.path.join - -#----------------------------------------------------------------------------- -# Constants -#----------------------------------------------------------------------------- - -bundled_version = (4,0,4) -libzmq = "zeromq-%i.%i.%i.tar.gz" % (bundled_version) -libzmq_url = "http://download.zeromq.org/" + libzmq - -libsodium_version = (0,4,5) -libsodium = "libsodium-%i.%i.%i.tar.gz" % (libsodium_version) -libsodium_url = "https://github.com/jedisct1/libsodium/releases/download/%i.%i.%i/" % libsodium_version + libsodium - -HERE = os.path.dirname(__file__) -ROOT = os.path.dirname(HERE) - -#----------------------------------------------------------------------------- -# Utilities -#----------------------------------------------------------------------------- - - -def untgz(archive): -    return archive.replace('.tar.gz', '') - -def localpath(*args): -    """construct an absolute path from a list relative to the root pyzmq directory""" -    plist = [ROOT] + list(args) -    return os.path.abspath(pjoin(*plist)) - -def fetch_archive(savedir, url, fname, force=False): -    """download an archive to a specific location""" -    dest = pjoin(savedir, fname) -    if os.path.exists(dest) and not force: -        info("already have %s" % fname) -        return dest -    info("fetching %s into %s" % (url, savedir)) -    if not os.path.exists(savedir): -        os.makedirs(savedir) -    req = urlopen(url) -    with open(dest, 'wb') as f: -        f.write(req.read()) -    return dest - -#----------------------------------------------------------------------------- -# libsodium -#----------------------------------------------------------------------------- - -def fetch_libsodium(savedir): -    """download and extract libsodium""" -    dest = pjoin(savedir, 'libsodium') -    if os.path.exists(dest): -        info("already have %s" % dest) -        return -    fname = fetch_archive(savedir, libsodium_url, libsodium) -    tf = tarfile.open(fname) -    with_version = pjoin(savedir, tf.firstmember.path) -    tf.extractall(savedir) -    tf.close() -    # remove version suffix: -    shutil.move(with_version, dest) - -def stage_libsodium_headers(libsodium_root): -    """stage configure headers for libsodium""" -    src_dir = pjoin(HERE, 'include_sodium') -    dest_dir = pjoin(libsodium_root, 'src', 'libsodium', 'include', 'sodium') -    for src in glob(pjoin(src_dir, '*.h')): -        base = os.path.basename(src) -        dest = pjoin(dest_dir, base) -        if os.path.exists(dest): -            info("already have %s" % base) -            continue -        info("staging %s to %s" % (src, dest)) -        shutil.copy(src, dest) - -#----------------------------------------------------------------------------- -# libzmq -#----------------------------------------------------------------------------- - -def fetch_libzmq(savedir): -    """download and extract libzmq""" -    dest = pjoin(savedir, 'zeromq') -    if os.path.exists(dest): -        info("already have %s" % dest) -        return -    fname = fetch_archive(savedir, libzmq_url, libzmq) -    tf = tarfile.open(fname) -    with_version = pjoin(savedir, tf.firstmember.path) -    tf.extractall(savedir) -    tf.close() -    # remove version suffix: -    shutil.move(with_version, dest) - -def stage_platform_hpp(zmqroot): -    """stage platform.hpp into libzmq sources -     -    Tries ./configure first (except on Windows), -    then falls back on included platform.hpp previously generated. -    """ -     -    platform_hpp = pjoin(zmqroot, 'src', 'platform.hpp') -    if os.path.exists(platform_hpp): -        info("already have platform.hpp") -        return -    if os.name == 'nt': -        # stage msvc platform header -        platform_dir = pjoin(zmqroot, 'builds', 'msvc') -    else: -        info("attempting ./configure to generate platform.hpp") -         -        p = Popen('./configure', cwd=zmqroot, shell=True, -            stdout=PIPE, stderr=PIPE, -        ) -        o,e = p.communicate() -        if p.returncode: -            warn("failed to configure libzmq:\n%s" % e) -            if sys.platform == 'darwin': -                platform_dir = pjoin(HERE, 'include_darwin') -            elif sys.platform.startswith('freebsd'): -                platform_dir = pjoin(HERE, 'include_freebsd') -            elif sys.platform.startswith('linux-armv'): -                platform_dir = pjoin(HERE, 'include_linux-armv') -            else: -                platform_dir = pjoin(HERE, 'include_linux') -        else: -            return -     -    info("staging platform.hpp from: %s" % platform_dir) -    shutil.copy(pjoin(platform_dir, 'platform.hpp'), platform_hpp) - - -def copy_and_patch_libzmq(ZMQ, libzmq): -    """copy libzmq into source dir, and patch it if necessary. -     -    This command is necessary prior to running a bdist on Linux or OS X. -    """ -    if sys.platform.startswith('win'): -        return -    # copy libzmq into zmq for bdist -    local = localpath('zmq',libzmq) -    if not ZMQ and not os.path.exists(local): -        fatal("Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` " -        "or copy libzmq into zmq/ manually prior to running bdist.") -    try: -        # resolve real file through symlinks -        lib = os.path.realpath(pjoin(ZMQ, 'lib', libzmq)) -        print ("copying %s -> %s"%(lib, local)) -        shutil.copy(lib, local) -    except Exception: -        if not os.path.exists(local): -            fatal("Could not copy libzmq into zmq/, which is necessary for bdist. " -            "Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` " -            "or copy libzmq into zmq/ manually.") -     -    if sys.platform == 'darwin': -        # chmod u+w on the lib, -        # which can be user-read-only for some reason -        mode = os.stat(local).st_mode -        os.chmod(local, mode | stat.S_IWUSR) -        # patch install_name on darwin, instead of using rpath -        cmd = ['install_name_tool', '-id', '@loader_path/../%s'%libzmq, local] -        try: -            p = Popen(cmd, stdout=PIPE,stderr=PIPE) -        except OSError: -            fatal("install_name_tool not found, cannot patch libzmq for bundling.") -        out,err = p.communicate() -        if p.returncode: -            fatal("Could not patch bundled libzmq install_name: %s"%err, p.returncode) -         diff --git a/buildutils/check_sys_un.c b/buildutils/check_sys_un.c deleted file mode 100644 index 8c013c4..0000000 --- a/buildutils/check_sys_un.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <stdio.h> -#include "sys/un.h" - -int main(int argc, char **argv) { -    struct sockaddr_un *dummy; -    printf("%lu\n", sizeof(dummy->sun_path) - 1); -    return 0; -} diff --git a/buildutils/config.py b/buildutils/config.py deleted file mode 100644 index c674655..0000000 --- a/buildutils/config.py +++ /dev/null @@ -1,157 +0,0 @@ -"""Config functions""" -#----------------------------------------------------------------------------- -#  Copyright (C) PyZMQ Developers -# -#  This file is part of pyzmq, copied and adapted from h5py. -#  h5py source used under the New BSD license -# -#  h5py: <http://code.google.com/p/h5py/> -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import sys -import os -import json - -try: -    from configparser import ConfigParser -except: -    from ConfigParser import ConfigParser - -pjoin = os.path.join -from .msg import debug, fatal, warn - -#----------------------------------------------------------------------------- -# Utility functions (adapted from h5py: http://h5py.googlecode.com) -#----------------------------------------------------------------------------- - - -def load_config(name, base='conf'): -    """Load config dict from JSON""" -    fname = pjoin(base, name + '.json') -    if not os.path.exists(fname): -        return {} -    try: -        with open(fname) as f: -            cfg = json.load(f) -    except Exception as e: -        warn("Couldn't load %s: %s" % (fname, e)) -        cfg = {} -    return cfg - - -def save_config(name, data, base='conf'): -    """Save config dict to JSON""" -    if not os.path.exists(base): -        os.mkdir(base) -    fname = pjoin(base, name+'.json') -    with open(fname, 'w') as f: -        json.dump(data, f, indent=2) - - -def v_str(v_tuple): -    """turn (2,0,1) into '2.0.1'.""" -    return ".".join(str(x) for x in v_tuple) - -def get_eargs(): -    """ Look for options in environment vars """ - -    settings = {} - -    zmq = os.environ.get("ZMQ_PREFIX", None) -    if zmq is not None: -        debug("Found environ var ZMQ_PREFIX=%s" % zmq) -        settings['zmq_prefix'] = zmq - -    return settings - -def cfg2dict(cfg): -    """turn a ConfigParser into a nested dict -     -    because ConfigParser objects are dumb. -    """ -    d = {} -    for section in cfg.sections(): -        d[section] = dict(cfg.items(section)) -    return d - -def get_cfg_args(): -    """ Look for options in setup.cfg """ - -    if not os.path.exists('setup.cfg'): -        return {} -    cfg = ConfigParser() -    cfg.read('setup.cfg') -    cfg = cfg2dict(cfg) - -    g = cfg.setdefault('global', {}) -    # boolean keys: -    for key in ['libzmq_extension', -                'bundle_libzmq_dylib', -                'no_libzmq_extension', -                'have_sys_un_h', -                'skip_check_zmq', -                ]: -        if key in g: -            g[key] = eval(g[key]) - -    # globals go to top level -    cfg.update(cfg.pop('global')) -    return cfg - -def config_from_prefix(prefix): -    """Get config from zmq prefix""" -    settings = {} -    if prefix.lower() in ('default', 'auto', ''): -        settings['zmq_prefix'] = '' -        settings['libzmq_extension'] = False -        settings['no_libzmq_extension'] = False -    elif prefix.lower() in ('bundled', 'extension'): -        settings['zmq_prefix'] = '' -        settings['libzmq_extension'] = True -        settings['no_libzmq_extension'] = False -    else: -        settings['zmq_prefix'] = prefix -        settings['libzmq_extension'] = False -        settings['no_libzmq_extension'] = True -    return settings - -def merge(into, d): -    """merge two containers -     -    into is updated, d has priority -    """ -    if isinstance(into, dict): -        for key in d.keys(): -            if key not in into: -                into[key] = d[key] -            else: -                into[key] = merge(into[key], d[key]) -        return into -    elif isinstance(into, list): -        return into + d -    else: -        return d - -def discover_settings(conf_base=None): -    """ Discover custom settings for ZMQ path""" -    settings = { -        'zmq_prefix': '', -        'libzmq_extension': False, -        'no_libzmq_extension': False, -        'skip_check_zmq': False, -        'build_ext': {}, -        'bdist_egg': {}, -    } -    if sys.platform.startswith('win'): -        settings['have_sys_un_h'] = False -     -    if conf_base: -        # lowest priority -        merge(settings, load_config('config', conf_base)) -    merge(settings, get_cfg_args()) -    merge(settings, get_eargs()) -     -    return settings diff --git a/buildutils/constants.py b/buildutils/constants.py deleted file mode 100644 index ad8a499..0000000 --- a/buildutils/constants.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -script for generating files that involve repetitive updates for zmq constants. - -Run this after updating utils/constant_names - -Currently generates the following files from templates: - -- constant_enums.pxi -- constants.pxi -- zmq_constants.h - -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import os -import sys - -from . import info -pjoin = os.path.join - -root = os.path.abspath(pjoin(os.path.dirname(__file__), os.path.pardir)) - -sys.path.insert(0, pjoin(root, 'zmq', 'utils')) -from constant_names import all_names, no_prefix - -ifndef_t = """#ifndef {0} -    #define {0} (-1) -#endif -""" - -def cython_enums(): -    """generate `enum: ZMQ_CONST` block for constant_enums.pxi""" -    lines = [] -    for name in all_names: -        if no_prefix(name): -            lines.append('enum: ZMQ_{0} "{0}"'.format(name)) -        else: -            lines.append('enum: ZMQ_{0}'.format(name)) -             -    return dict(ZMQ_ENUMS='\n    '.join(lines)) - -def ifndefs(): -    """generate `#ifndef ZMQ_CONST` block for zmq_constants.h""" -    lines = [] -    for name in all_names: -        if not no_prefix(name): -            name = 'ZMQ_%s' % name -        lines.append(ifndef_t.format(name)) -    return dict(ZMQ_IFNDEFS='\n'.join(lines)) - -def constants_pyx(): -    """generate CONST = ZMQ_CONST and __all__ for constants.pxi""" -    all_lines = [] -    assign_lines = [] -    for name in all_names: -        if name == "NULL": -            # avoid conflict with NULL in Cython -            assign_lines.append("globals()['NULL'] = ZMQ_NULL") -        else: -            assign_lines.append('{0} = ZMQ_{0}'.format(name)) -        all_lines.append('  "{0}",'.format(name)) -    return dict(ASSIGNMENTS='\n'.join(assign_lines), ALL='\n'.join(all_lines)) - -def generate_file(fname, ns_func, dest_dir="."): -    """generate a constants file from its template""" -    with open(pjoin(root, 'buildutils', 'templates', '%s' % fname), 'r') as f: -        tpl = f.read() -    out = tpl.format(**ns_func()) -    dest = pjoin(dest_dir, fname) -    info("generating %s from template" % dest) -    with open(dest, 'w') as f: -        f.write(out) - -def render_constants(): -    """render generated constant files from templates""" -    generate_file("constant_enums.pxi", cython_enums, pjoin(root, 'zmq', 'backend', 'cython')) -    generate_file("constants.pxi", constants_pyx, pjoin(root, 'zmq', 'backend', 'cython')) -    generate_file("zmq_constants.h", ifndefs, pjoin(root, 'zmq', 'utils')) - -if __name__ == '__main__': -    render_constants() diff --git a/buildutils/detect.py b/buildutils/detect.py deleted file mode 100644 index 04dd17a..0000000 --- a/buildutils/detect.py +++ /dev/null @@ -1,145 +0,0 @@ -"""Detect zmq version""" -#----------------------------------------------------------------------------- -#  Copyright (C) PyZMQ Developers -# -#  This file is part of pyzmq, copied and adapted from h5py. -#  h5py source used under the New BSD license -# -#  h5py: <http://code.google.com/p/h5py/> -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import shutil -import sys -import os -import logging -import platform -from distutils import ccompiler -from distutils.sysconfig import customize_compiler -from subprocess import Popen, PIPE - -from .misc import customize_mingw - -pjoin = os.path.join - -#----------------------------------------------------------------------------- -# Utility functions (adapted from h5py: http://h5py.googlecode.com) -#----------------------------------------------------------------------------- - -def test_compilation(cfile, compiler=None, **compiler_attrs): -    """Test simple compilation with given settings""" -    if compiler is None or isinstance(compiler, str): -        cc = ccompiler.new_compiler(compiler=compiler) -        customize_compiler(cc) -        if cc.compiler_type == 'mingw32': -            customize_mingw(cc) -    else: -        cc = compiler -     -    for name, val in compiler_attrs.items(): -        setattr(cc, name, val) -     -    efile, ext = os.path.splitext(cfile) - -    cpreargs = lpreargs = None -    if sys.platform == 'darwin': -        # use appropriate arch for compiler -        if platform.architecture()[0]=='32bit': -            if platform.processor() == 'powerpc': -                cpu = 'ppc' -            else: -                cpu = 'i386' -            cpreargs = ['-arch', cpu] -            lpreargs = ['-arch', cpu, '-undefined', 'dynamic_lookup'] -        else: -            # allow for missing UB arch, since it will still work: -            lpreargs = ['-undefined', 'dynamic_lookup'] -    if sys.platform == 'sunos5': -        if platform.architecture()[0]=='32bit': -            lpreargs = ['-m32'] -        else:  -            lpreargs = ['-m64'] -    extra = compiler_attrs.get('extra_compile_args', None) - -    objs = cc.compile([cfile],extra_preargs=cpreargs, extra_postargs=extra) -    cc.link_executable(objs, efile, extra_preargs=lpreargs) -    return efile - -def compile_and_run(basedir, src, compiler=None, **compiler_attrs): -    if not os.path.exists(basedir): -        os.makedirs(basedir) -    cfile = pjoin(basedir, os.path.basename(src)) -    shutil.copy(src, cfile) -    try: -        efile = test_compilation(cfile, compiler=compiler, **compiler_attrs) -        result = Popen(efile, stdout=PIPE, stderr=PIPE) -        so, se = result.communicate() -        # for py3k: -        so = so.decode() -        se = se.decode() -    finally: -        shutil.rmtree(basedir) -     -    return result.returncode, so, se -     -     -def detect_zmq(basedir, compiler=None, **compiler_attrs): -    """Compile, link & execute a test program, in empty directory `basedir`. -     -    The C compiler will be updated with any keywords given via setattr. -     -    Parameters -    ---------- -     -    basedir : path -        The location where the test program will be compiled and run -    compiler : str -        The distutils compiler key (e.g. 'unix', 'msvc', or 'mingw32') -    **compiler_attrs : dict -        Any extra compiler attributes, which will be set via ``setattr(cc)``. -     -    Returns -    ------- -     -    A dict of properties for zmq compilation, with the following two keys: -     -    vers : tuple -        The ZMQ version as a tuple of ints, e.g. (2,2,0) -    settings : dict -        The compiler options used to compile the test function, e.g. `include_dirs`, -        `library_dirs`, `libs`, etc. -    """ -     -    cfile = pjoin(basedir, 'vers.c') -    shutil.copy(pjoin(os.path.dirname(__file__), 'vers.c'), cfile) -     -    # check if we need to link against Realtime Extensions library -    if sys.platform.startswith('linux'): -        cc = ccompiler.new_compiler(compiler=compiler) -        cc.output_dir = basedir -        if not cc.has_function('timer_create'): -            compiler_attrs['libraries'].append('rt') -             -    efile = test_compilation(cfile, compiler=compiler, **compiler_attrs) -     -    result = Popen(efile, stdout=PIPE, stderr=PIPE) -    so, se = result.communicate() -    # for py3k: -    so = so.decode() -    se = se.decode() -    if result.returncode: -        msg = "Error running version detection script:\n%s\n%s" % (so,se) -        logging.error(msg) -        raise IOError(msg) - -    handlers = {'vers':  lambda val: tuple(int(v) for v in val.split('.'))} - -    props = {} -    for line in (x for x in so.split('\n') if x): -        key, val = line.split(':') -        props[key] = handlers[key](val) - -    return props - diff --git a/buildutils/dummy.c b/buildutils/dummy.c deleted file mode 100644 index 4dbdc60..0000000 --- a/buildutils/dummy.c +++ /dev/null @@ -1,5 +0,0 @@ -// empty file, just to test compilation - -int main(int argc, char **argv){ -    return 0; -} diff --git a/buildutils/include_darwin/platform.hpp b/buildutils/include_darwin/platform.hpp deleted file mode 100644 index 0a18e82..0000000 --- a/buildutils/include_darwin/platform.hpp +++ /dev/null @@ -1,271 +0,0 @@ -/* src/platform.hpp.  Generated from platform.hpp.in by configure.  */ -/* src/platform.hpp.in.  Generated from configure.ac by autoheader.  */ - -/* Define to 1 if you have the <alloca.h> header file. */ -#define HAVE_ALLOCA_H 1 - -/* Define to 1 if you have the <arpa/inet.h> header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -/* #undef HAVE_CLOCK_GETTIME */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the `fork' function. */ -#define HAVE_FORK 1 - -/* Define to 1 if you have the `freeifaddrs' function. */ -#define HAVE_FREEIFADDRS 1 - -/* Define to 1 if you have the `gethrtime' function. */ -/* #undef HAVE_GETHRTIME */ - -/* Define to 1 if you have the `getifaddrs' function. */ -#define HAVE_GETIFADDRS 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the <ifaddrs.h> header file. */ -#define HAVE_IFADDRS_H 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */ -/* #undef HAVE_LIBIPHLPAPI */ - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -/* #undef HAVE_LIBNSL */ - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#define HAVE_LIBPTHREAD 1 - -/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */ -/* #undef HAVE_LIBRPCRT4 */ - -/* Define to 1 if you have the `rt' library (-lrt). */ -/* #undef HAVE_LIBRT */ - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the `sodium' library (-lsodium). */ -/* #undef HAVE_LIBSODIUM */ - -/* Define to 1 if you have the `ws2_32' library (-lws2_32). */ -/* #undef HAVE_LIBWS2_32 */ - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if you have the <netinet/in.h> header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the <netinet/tcp.h> header file. */ -#define HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the `perror' function. */ -#define HAVE_PERROR 1 - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if stdbool.h conforms to C99. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the <stddef.h> header file. */ -#define HAVE_STDDEF_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/eventfd.h> header file. */ -/* #undef HAVE_SYS_EVENTFD_H */ - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/uio.h> header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the <time.h> header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the <windows.h> header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to 1 if the system has the type `_Bool'. */ -/* #undef HAVE__BOOL */ - -/* Define to the sub-directory in which libtool stores uninstalled libraries. -   */ -#define LT_OBJDIR ".libs/" - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -#define PACKAGE "zeromq" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "zeromq-dev@lists.zeromq.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "zeromq" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "zeromq 4.0.4" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "zeromq" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "4.0.4" - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#define TIME_WITH_SYS_TIME 1 - -/* Version number of package */ -#define VERSION "4.0.4" - -/* Force to use mutexes */ -/* #undef ZMQ_FORCE_MUTEXES */ - -/* Have AIX OS */ -/* #undef ZMQ_HAVE_AIX */ - -/* Have Android OS */ -/* #undef ZMQ_HAVE_ANDROID */ - -/* Have Cygwin */ -/* #undef ZMQ_HAVE_CYGWIN */ - -/* Have eventfd extension. */ -/* #undef ZMQ_HAVE_EVENTFD */ - -/* Have FreeBSD OS */ -/* #undef ZMQ_HAVE_FREEBSD */ - -/* Have HPUX OS */ -/* #undef ZMQ_HAVE_HPUX */ - -/* Have ifaddrs.h header. */ -#define ZMQ_HAVE_IFADDRS 1 - -/* Have Linux OS */ -/* #undef ZMQ_HAVE_LINUX */ - -/* Have MinGW32 */ -/* #undef ZMQ_HAVE_MINGW32 */ - -/* Have NetBSD OS */ -/* #undef ZMQ_HAVE_NETBSD */ - -/* Have OpenBSD OS */ -/* #undef ZMQ_HAVE_OPENBSD */ - -/* Have OpenPGM extension */ -/* #undef ZMQ_HAVE_OPENPGM */ - -/* Have DarwinOSX OS */ -#define ZMQ_HAVE_OSX 1 - -/* Have QNX Neutrino OS */ -/* #undef ZMQ_HAVE_QNXNTO */ - -/* Whether SOCK_CLOEXEC is defined and functioning. */ -/* #undef ZMQ_HAVE_SOCK_CLOEXEC */ - -/* Have Solaris OS */ -/* #undef ZMQ_HAVE_SOLARIS */ - -/* Whether SO_KEEPALIVE is supported. */ -#define ZMQ_HAVE_SO_KEEPALIVE 1 - -/* Whether TCP_KEEPALIVE is supported. */ -#define ZMQ_HAVE_TCP_KEEPALIVE 1 - -/* Whether TCP_KEEPCNT is supported. */ -/* #undef ZMQ_HAVE_TCP_KEEPCNT */ - -/* Whether TCP_KEEPIDLE is supported. */ -/* #undef ZMQ_HAVE_TCP_KEEPIDLE */ - -/* Whether TCP_KEEPINTVL is supported. */ -/* #undef ZMQ_HAVE_TCP_KEEPINTVL */ - -/* Have uio.h header. */ -#define ZMQ_HAVE_UIO 1 - -/* Have Windows OS */ -/* #undef ZMQ_HAVE_WINDOWS */ - -/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, -   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the -   #define below would cause a syntax error. */ -/* #undef _UINT32_T */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler -   calls it, or to nothing if 'inline' is not supported under any name.  */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ - -/* Define to `int' if <sys/types.h> does not define. */ -/* #undef ssize_t */ - -/* Define to the type of an unsigned integer type of width exactly 32 bits if -   such a type exists and the standard includes do not define it. */ -/* #undef uint32_t */ - -/* Define to empty if the keyword `volatile' does not work. Warning: valid -   code using `volatile' can become incorrect without. Disable with care. */ -/* #undef volatile */ diff --git a/buildutils/include_freebsd/platform.hpp b/buildutils/include_freebsd/platform.hpp deleted file mode 100644 index 6fce15b..0000000 --- a/buildutils/include_freebsd/platform.hpp +++ /dev/null @@ -1,271 +0,0 @@ -/* src/platform.hpp.  Generated from platform.hpp.in by configure.  */ -/* src/platform.hpp.in.  Generated from configure.ac by autoheader.  */ - -/* Define to 1 if you have the <alloca.h> header file. */ -/* #undef HAVE_ALLOCA_H */ - -/* Define to 1 if you have the <arpa/inet.h> header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -#define HAVE_CLOCK_GETTIME 1 - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the `fork' function. */ -#define HAVE_FORK 1 - -/* Define to 1 if you have the `freeifaddrs' function. */ -#define HAVE_FREEIFADDRS 1 - -/* Define to 1 if you have the `gethrtime' function. */ -/* #undef HAVE_GETHRTIME */ - -/* Define to 1 if you have the `getifaddrs' function. */ -#define HAVE_GETIFADDRS 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the <ifaddrs.h> header file. */ -#define HAVE_IFADDRS_H 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */ -/* #undef HAVE_LIBIPHLPAPI */ - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -/* #undef HAVE_LIBNSL */ - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#define HAVE_LIBPTHREAD 1 - -/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */ -/* #undef HAVE_LIBRPCRT4 */ - -/* Define to 1 if you have the `rt' library (-lrt). */ -#define HAVE_LIBRT 1 - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the `sodium' library (-lsodium). */ -/* #undef HAVE_LIBSODIUM */ - -/* Define to 1 if you have the `ws2_32' library (-lws2_32). */ -/* #undef HAVE_LIBWS2_32 */ - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if you have the <netinet/in.h> header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the <netinet/tcp.h> header file. */ -#define HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the `perror' function. */ -#define HAVE_PERROR 1 - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if stdbool.h conforms to C99. */ -/* #undef HAVE_STDBOOL_H */ - -/* Define to 1 if you have the <stddef.h> header file. */ -#define HAVE_STDDEF_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/eventfd.h> header file. */ -/* #undef HAVE_SYS_EVENTFD_H */ - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/uio.h> header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the <time.h> header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the <windows.h> header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to 1 if the system has the type `_Bool'. */ -/* #undef HAVE__BOOL */ - -/* Define to the sub-directory in which libtool stores uninstalled libraries. -   */ -#define LT_OBJDIR ".libs/" - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -#define PACKAGE "zeromq" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "zeromq-dev@lists.zeromq.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "zeromq" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "zeromq 4.0.4" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "zeromq" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "4.0.4" - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#define TIME_WITH_SYS_TIME 1 - -/* Version number of package */ -#define VERSION "4.0.4" - -/* Force to use mutexes */ -/* #undef ZMQ_FORCE_MUTEXES */ - -/* Have AIX OS */ -/* #undef ZMQ_HAVE_AIX */ - -/* Have Android OS */ -/* #undef ZMQ_HAVE_ANDROID */ - -/* Have Cygwin */ -/* #undef ZMQ_HAVE_CYGWIN */ - -/* Have eventfd extension. */ -/* #undef ZMQ_HAVE_EVENTFD */ - -/* Have FreeBSD OS */ -#define ZMQ_HAVE_FREEBSD 1 - -/* Have HPUX OS */ -/* #undef ZMQ_HAVE_HPUX */ - -/* Have ifaddrs.h header. */ -#define ZMQ_HAVE_IFADDRS 1 - -/* Have Linux OS */ -/* #undef ZMQ_HAVE_LINUX */ - -/* Have MinGW32 */ -/* #undef ZMQ_HAVE_MINGW32 */ - -/* Have NetBSD OS */ -/* #undef ZMQ_HAVE_NETBSD */ - -/* Have OpenBSD OS */ -/* #undef ZMQ_HAVE_OPENBSD */ - -/* Have OpenPGM extension */ -/* #undef ZMQ_HAVE_OPENPGM */ - -/* Have DarwinOSX OS */ -/* #undef ZMQ_HAVE_OSX */ - -/* Have QNX Neutrino OS */ -/* #undef ZMQ_HAVE_QNXNTO */ - -/* Whether SOCK_CLOEXEC is defined and functioning. */ -#define ZMQ_HAVE_SOCK_CLOEXEC 1 - -/* Have Solaris OS */ -/* #undef ZMQ_HAVE_SOLARIS */ - -/* Whether SO_KEEPALIVE is supported. */ -#define ZMQ_HAVE_SO_KEEPALIVE 1 - -/* Whether TCP_KEEPALIVE is supported. */ -/* #undef ZMQ_HAVE_TCP_KEEPALIVE */ - -/* Whether TCP_KEEPCNT is supported. */ -#define ZMQ_HAVE_TCP_KEEPCNT 1 - -/* Whether TCP_KEEPIDLE is supported. */ -#define ZMQ_HAVE_TCP_KEEPIDLE 1 - -/* Whether TCP_KEEPINTVL is supported. */ -#define ZMQ_HAVE_TCP_KEEPINTVL 1 - -/* Have uio.h header. */ -#define ZMQ_HAVE_UIO 1 - -/* Have Windows OS */ -/* #undef ZMQ_HAVE_WINDOWS */ - -/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, -   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the -   #define below would cause a syntax error. */ -/* #undef _UINT32_T */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler -   calls it, or to nothing if 'inline' is not supported under any name.  */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ - -/* Define to `int' if <sys/types.h> does not define. */ -/* #undef ssize_t */ - -/* Define to the type of an unsigned integer type of width exactly 32 bits if -   such a type exists and the standard includes do not define it. */ -/* #undef uint32_t */ - -/* Define to empty if the keyword `volatile' does not work. Warning: valid -   code using `volatile' can become incorrect without. Disable with care. */ -/* #undef volatile */ diff --git a/buildutils/include_linux-armv/platform.hpp b/buildutils/include_linux-armv/platform.hpp deleted file mode 100644 index 39c7368..0000000 --- a/buildutils/include_linux-armv/platform.hpp +++ /dev/null @@ -1,265 +0,0 @@ -/* src/platform.hpp.  Generated from platform.hpp.in by configure.  */ -/* src/platform.hpp.in.  Generated from configure.in by autoheader.  */ - -/* Define to 1 if you have the <alloca.h> header file. */ -#define HAVE_ALLOCA_H 1 - -/* Define to 1 if you have the <arpa/inet.h> header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -#define HAVE_CLOCK_GETTIME 1 - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the `freeifaddrs' function. */ -/* #undef HAVE_FREEIFADDRS */ - -/* Define to 1 if you have the `gethrtime' function. */ -/* #undef HAVE_GETHRTIME */ - -/* Define to 1 if you have the `getifaddrs' function. */ -/* #undef HAVE_GETIFADDRS */ - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the <ifaddrs.h> header file. */ -/* #undef HAVE_IFADDRS_H */ - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */ -/* #undef HAVE_LIBIPHLPAPI */ - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -/* #undef HAVE_LIBNSL */ - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -/* #undef HAVE_LIBPTHREAD */ - -/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */ -/* #undef HAVE_LIBRPCRT4 */ - -/* Define to 1 if you have the `rt' library (-lrt). */ -/* #undef HAVE_LIBRT */ - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the `ws2_32' library (-lws2_32). */ -/* #undef HAVE_LIBWS2_32 */ - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if you have the <netinet/in.h> header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the <netinet/tcp.h> header file. */ -#define HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the `perror' function. */ -#define HAVE_PERROR 1 - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if stdbool.h conforms to C99. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the <stddef.h> header file. */ -#define HAVE_STDDEF_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/eventfd.h> header file. */ -/* #undef HAVE_SYS_EVENTFD_H */ - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/uio.h> header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the <time.h> header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the <windows.h> header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to 1 if the system has the type `_Bool'. */ -/* #undef HAVE__BOOL */ - -/* Define to the sub-directory in which libtool stores uninstalled libraries. -   */ -#define LT_OBJDIR ".libs/" - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -#define PACKAGE "zeromq" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "zeromq-dev@lists.zeromq.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "zeromq" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "zeromq 3.2.1" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "zeromq" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "3.2.1" - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#define TIME_WITH_SYS_TIME 1 - -/* Version number of package */ -#define VERSION "3.2.1" - -/* Force to use mutexes */ -/* #undef ZMQ_FORCE_MUTEXES */ - -/* Have AIX OS */ -/* #undef ZMQ_HAVE_AIX */ - -/* Have Android OS */ -#define ZMQ_HAVE_ANDROID 1 - -/* Have Cygwin */ -/* #undef ZMQ_HAVE_CYGWIN */ - -/* Have eventfd extension. */ -/* #undef ZMQ_HAVE_EVENTFD */ - -/* Have FreeBSD OS */ -/* #undef ZMQ_HAVE_FREEBSD */ - -/* Have HPUX OS */ -/* #undef ZMQ_HAVE_HPUX */ - -/* Have ifaddrs.h header. */ -/* #undef ZMQ_HAVE_IFADDRS */ - -/* Have Linux OS */ -#define ZMQ_HAVE_LINUX 1 - -/* Have MinGW32 */ -/* #undef ZMQ_HAVE_MINGW32 */ - -/* Have NetBSD OS */ -/* #undef ZMQ_HAVE_NETBSD */ - -/* Have OpenBSD OS */ -/* #undef ZMQ_HAVE_OPENBSD */ - -/* Have OpenPGM extension */ -/* #undef ZMQ_HAVE_OPENPGM */ - -/* Have DarwinOSX OS */ -/* #undef ZMQ_HAVE_OSX */ - -/* Have QNX Neutrino OS */ -/* #undef ZMQ_HAVE_QNXNTO */ - -/* Whether SOCK_CLOEXEC is defined and functioning. */ -/* #undef ZMQ_HAVE_SOCK_CLOEXEC */ - -/* Have Solaris OS */ -/* #undef ZMQ_HAVE_SOLARIS */ - -/* Whether SO_KEEPALIVE is supported. */ -/* #undef ZMQ_HAVE_SO_KEEPALIVE */ - -/* Whether TCP_KEEPALIVE is supported. */ -/* #undef ZMQ_HAVE_TCP_KEEPALIVE */ - -/* Whether TCP_KEEPCNT is supported. */ -/* #undef ZMQ_HAVE_TCP_KEEPCNT */ - -/* Whether TCP_KEEPIDLE is supported. */ -/* #undef ZMQ_HAVE_TCP_KEEPIDLE */ - -/* Whether TCP_KEEPINTVL is supported. */ -/* #undef ZMQ_HAVE_TCP_KEEPINTVL */ - -/* Have uio.h header. */ -#define ZMQ_HAVE_UIO 1 - -/* Have Windows OS */ -/* #undef ZMQ_HAVE_WINDOWS */ - -/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, -   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the -   #define below would cause a syntax error. */ -/* #undef _UINT32_T */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler -   calls it, or to nothing if 'inline' is not supported under any name.  */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ - -/* Define to `int' if <sys/types.h> does not define. */ -/* #undef ssize_t */ - -/* Define to the type of an unsigned integer type of width exactly 32 bits if -   such a type exists and the standard includes do not define it. */ -/* #undef uint32_t */ - -/* Define to empty if the keyword `volatile' does not work. Warning: valid -   code using `volatile' can become incorrect without. Disable with care. */ -/* #undef volatile */ diff --git a/buildutils/include_linux/platform.hpp b/buildutils/include_linux/platform.hpp deleted file mode 100644 index da4c816..0000000 --- a/buildutils/include_linux/platform.hpp +++ /dev/null @@ -1,271 +0,0 @@ -/* src/platform.hpp.  Generated from platform.hpp.in by configure.  */ -/* src/platform.hpp.in.  Generated from configure.ac by autoheader.  */ - -/* Define to 1 if you have the <alloca.h> header file. */ -#define HAVE_ALLOCA_H 1 - -/* Define to 1 if you have the <arpa/inet.h> header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -#define HAVE_CLOCK_GETTIME 1 - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the <errno.h> header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the `fork' function. */ -#define HAVE_FORK 1 - -/* Define to 1 if you have the `freeifaddrs' function. */ -#define HAVE_FREEIFADDRS 1 - -/* Define to 1 if you have the `gethrtime' function. */ -/* #undef HAVE_GETHRTIME */ - -/* Define to 1 if you have the `getifaddrs' function. */ -#define HAVE_GETIFADDRS 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the <ifaddrs.h> header file. */ -#define HAVE_IFADDRS_H 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */ -/* #undef HAVE_LIBIPHLPAPI */ - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -/* #undef HAVE_LIBNSL */ - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#define HAVE_LIBPTHREAD 1 - -/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */ -/* #undef HAVE_LIBRPCRT4 */ - -/* Define to 1 if you have the `rt' library (-lrt). */ -#define HAVE_LIBRT 1 - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the `sodium' library (-lsodium). */ -/* #undef HAVE_LIBSODIUM */ - -/* Define to 1 if you have the `ws2_32' library (-lws2_32). */ -/* #undef HAVE_LIBWS2_32 */ - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if you have the <netinet/in.h> header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the <netinet/tcp.h> header file. */ -#define HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the `perror' function. */ -#define HAVE_PERROR 1 - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if stdbool.h conforms to C99. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the <stddef.h> header file. */ -#define HAVE_STDDEF_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the <sys/eventfd.h> header file. */ -#define HAVE_SYS_EVENTFD_H 1 - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/uio.h> header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the <time.h> header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the <windows.h> header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to 1 if the system has the type `_Bool'. */ -/* #undef HAVE__BOOL */ - -/* Define to the sub-directory in which libtool stores uninstalled libraries. -   */ -#define LT_OBJDIR ".libs/" - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -#define PACKAGE "zeromq" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "zeromq-dev@lists.zeromq.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "zeromq" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "zeromq 4.0.4" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "zeromq" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "4.0.4" - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#define TIME_WITH_SYS_TIME 1 - -/* Version number of package */ -#define VERSION "4.0.4" - -/* Force to use mutexes */ -/* #undef ZMQ_FORCE_MUTEXES */ - -/* Have AIX OS */ -/* #undef ZMQ_HAVE_AIX */ - -/* Have Android OS */ -/* #undef ZMQ_HAVE_ANDROID */ - -/* Have Cygwin */ -/* #undef ZMQ_HAVE_CYGWIN */ - -/* Have eventfd extension. */ -#define ZMQ_HAVE_EVENTFD 1 - -/* Have FreeBSD OS */ -/* #undef ZMQ_HAVE_FREEBSD */ - -/* Have HPUX OS */ -/* #undef ZMQ_HAVE_HPUX */ - -/* Have ifaddrs.h header. */ -#define ZMQ_HAVE_IFADDRS 1 - -/* Have Linux OS */ -#define ZMQ_HAVE_LINUX 1 - -/* Have MinGW32 */ -/* #undef ZMQ_HAVE_MINGW32 */ - -/* Have NetBSD OS */ -/* #undef ZMQ_HAVE_NETBSD */ - -/* Have OpenBSD OS */ -/* #undef ZMQ_HAVE_OPENBSD */ - -/* Have OpenPGM extension */ -/* #undef ZMQ_HAVE_OPENPGM */ - -/* Have DarwinOSX OS */ -/* #undef ZMQ_HAVE_OSX */ - -/* Have QNX Neutrino OS */ -/* #undef ZMQ_HAVE_QNXNTO */ - -/* Whether SOCK_CLOEXEC is defined and functioning. */ -#define ZMQ_HAVE_SOCK_CLOEXEC 1 - -/* Have Solaris OS */ -/* #undef ZMQ_HAVE_SOLARIS */ - -/* Whether SO_KEEPALIVE is supported. */ -#define ZMQ_HAVE_SO_KEEPALIVE 1 - -/* Whether TCP_KEEPALIVE is supported. */ -/* #undef ZMQ_HAVE_TCP_KEEPALIVE */ - -/* Whether TCP_KEEPCNT is supported. */ -#define ZMQ_HAVE_TCP_KEEPCNT 1 - -/* Whether TCP_KEEPIDLE is supported. */ -#define ZMQ_HAVE_TCP_KEEPIDLE 1 - -/* Whether TCP_KEEPINTVL is supported. */ -#define ZMQ_HAVE_TCP_KEEPINTVL 1 - -/* Have uio.h header. */ -#define ZMQ_HAVE_UIO 1 - -/* Have Windows OS */ -/* #undef ZMQ_HAVE_WINDOWS */ - -/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, -   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the -   #define below would cause a syntax error. */ -/* #undef _UINT32_T */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler -   calls it, or to nothing if 'inline' is not supported under any name.  */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -/* #undef size_t */ - -/* Define to `int' if <sys/types.h> does not define. */ -/* #undef ssize_t */ - -/* Define to the type of an unsigned integer type of width exactly 32 bits if -   such a type exists and the standard includes do not define it. */ -/* #undef uint32_t */ - -/* Define to empty if the keyword `volatile' does not work. Warning: valid -   code using `volatile' can become incorrect without. Disable with care. */ -/* #undef volatile */ diff --git a/buildutils/include_sodium/crypto_scalarmult_curve25519.h b/buildutils/include_sodium/crypto_scalarmult_curve25519.h deleted file mode 100644 index a4b4dd1..0000000 --- a/buildutils/include_sodium/crypto_scalarmult_curve25519.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef crypto_scalarmult_curve25519_H -#define crypto_scalarmult_curve25519_H - -#if 0 -# ifndef SODIUM_HAVE_TI_MODE -#  define SODIUM_HAVE_TI_MODE -# endif -#endif - -#include <stddef.h> - -#include "export.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define crypto_scalarmult_curve25519_BYTES 32 -SODIUM_EXPORT -size_t crypto_scalarmult_curve25519_bytes(void); - -#define crypto_scalarmult_curve25519_SCALARBYTES 32 -SODIUM_EXPORT -size_t crypto_scalarmult_curve25519_scalarbytes(void); - -SODIUM_EXPORT -int crypto_scalarmult_curve25519(unsigned char *,const unsigned char *,const unsigned char *); - -SODIUM_EXPORT -int crypto_scalarmult_curve25519_base(unsigned char *,const unsigned char *); - -#ifdef SODIUM_HAVE_TI_MODE -# define crypto_scalarmult_curve25519_donna_c64 crypto_scalarmult_curve25519 -# define crypto_scalarmult_curve25519_donna_c64_base crypto_scalarmult_curve25519_base -#else -# define crypto_scalarmult_curve25519_ref crypto_scalarmult_curve25519 -# define crypto_scalarmult_curve25519_ref_base crypto_scalarmult_curve25519_base -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/buildutils/include_sodium/crypto_stream_salsa20.h b/buildutils/include_sodium/crypto_stream_salsa20.h deleted file mode 100644 index 8ce595e..0000000 --- a/buildutils/include_sodium/crypto_stream_salsa20.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef crypto_stream_salsa20_H -#define crypto_stream_salsa20_H - -/* - *  WARNING: This is just a stream cipher. It is NOT authenticated encryption. - *  While it provides some protection against eavesdropping, it does NOT - *  provide any security against active attacks. - *  Unless you know what you're doing, what you are looking for is probably - *  the crypto_box functions. - */ - -#if 0 -# ifndef SODIUM_HAVE_AMD64_ASM -#  define SODIUM_HAVE_AMD64_ASM -# endif -#endif - -#include <stddef.h> -#include "export.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define crypto_stream_salsa20_KEYBYTES 32U -SODIUM_EXPORT -size_t crypto_stream_salsa20_keybytes(void); - -#define crypto_stream_salsa20_NONCEBYTES 8U -SODIUM_EXPORT -size_t crypto_stream_salsa20_noncebytes(void); - -SODIUM_EXPORT -const char * crypto_stream_salsa20_primitive(void); - -SODIUM_EXPORT -int crypto_stream_salsa20(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); - -SODIUM_EXPORT -int crypto_stream_salsa20_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *); - -#ifdef SODIUM_HAVE_AMD64_ASM -# define crypto_stream_salsa20_amd64_xmm6 crypto_stream_salsa20 -# define crypto_stream_salsa20_amd64_xmm6_xor crypto_stream_salsa20_xor -#else -# define crypto_stream_salsa20_ref crypto_stream_salsa20 -# define crypto_stream_salsa20_ref_xor crypto_stream_salsa20_xor -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/buildutils/include_sodium/version.h b/buildutils/include_sodium/version.h deleted file mode 100644 index 56b03e2..0000000 --- a/buildutils/include_sodium/version.h +++ /dev/null @@ -1,29 +0,0 @@ - -#ifndef __SODIUM_VERSION_H__ -#define __SODIUM_VERSION_H__ - -#include "export.h" - -#define SODIUM_VERSION_STRING "0.4.5" - -#define SODIUM_LIBRARY_VERSION_MAJOR 4 -#define SODIUM_LIBRARY_VERSION_MINOR 4 - -#ifdef __cplusplus -extern "C" { -#endif - -SODIUM_EXPORT -const char *sodium_version_string(void); - -SODIUM_EXPORT -int         sodium_library_version_major(void); - -SODIUM_EXPORT -int         sodium_library_version_minor(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/buildutils/initlibsodium.c b/buildutils/initlibsodium.c deleted file mode 100644 index f0de774..0000000 --- a/buildutils/initlibsodium.c +++ /dev/null @@ -1,45 +0,0 @@ -/* -This file is from pyzmq-static by Brandon Craig-Rhodes, -and used under the BSD license - -py3compat from http://wiki.python.org/moin/PortingExtensionModulesToPy3k - -Provide the init function that Python expects -when we compile libzmq by pretending it is a Python extension. -*/ -#include "Python.h" - -static PyMethodDef Methods[] = { -    {NULL, NULL, 0, NULL} -}; - -#if PY_MAJOR_VERSION >= 3 - -static struct PyModuleDef moduledef = { -        PyModuleDef_HEAD_INIT, -        "libsodium", -        NULL, -        -1, -        Methods, -        NULL, -        NULL, -        NULL, -        NULL -}; - -PyMODINIT_FUNC -PyInit_libzmq(void) -{ -    PyObject *module = PyModule_Create(&moduledef); -    return module; -} - -#else // py2 - -PyMODINIT_FUNC -initlibzmq(void) -{ -    (void) Py_InitModule("libsodium", Methods); -} - -#endif diff --git a/buildutils/initlibzmq.c b/buildutils/initlibzmq.c deleted file mode 100644 index ec299f0..0000000 --- a/buildutils/initlibzmq.c +++ /dev/null @@ -1,45 +0,0 @@ -/* -This file is from pyzmq-static by Brandon Craig-Rhodes, -and used under the BSD license - -py3compat from http://wiki.python.org/moin/PortingExtensionModulesToPy3k - -Provide the init function that Python expects -when we compile libzmq by pretending it is a Python extension. -*/ -#include "Python.h" - -static PyMethodDef Methods[] = { -    {NULL, NULL, 0, NULL} -}; - -#if PY_MAJOR_VERSION >= 3 - -static struct PyModuleDef moduledef = { -        PyModuleDef_HEAD_INIT, -        "libzmq", -        NULL, -        -1, -        Methods, -        NULL, -        NULL, -        NULL, -        NULL -}; - -PyMODINIT_FUNC -PyInit_libzmq(void) -{ -    PyObject *module = PyModule_Create(&moduledef); -    return module; -} - -#else // py2 - -PyMODINIT_FUNC -initlibzmq(void) -{ -    (void) Py_InitModule("libzmq", Methods); -} - -#endif diff --git a/buildutils/misc.py b/buildutils/misc.py deleted file mode 100644 index 77f843b..0000000 --- a/buildutils/misc.py +++ /dev/null @@ -1,15 +0,0 @@ -"""misc build utility functions""" -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -def customize_mingw(cc): -    # strip -mno-cygwin from mingw32 (Python Issue #12641) -    for cmd in [cc.compiler, cc.compiler_cxx, cc.compiler_so, cc.linker_exe, cc.linker_so]: -        if '-mno-cygwin' in cmd: -            cmd.remove('-mno-cygwin') -     -    # remove problematic msvcr90 -    if 'msvcr90' in cc.dll_libraries: -        cc.dll_libraries.remove('msvcr90') - -__all__ = ['customize_mingw'] diff --git a/buildutils/msg.py b/buildutils/msg.py deleted file mode 100644 index 3b4a337..0000000 --- a/buildutils/msg.py +++ /dev/null @@ -1,43 +0,0 @@ -"""logging""" -#----------------------------------------------------------------------------- -#  Copyright (C) PyZMQ Developers -# -#  This file is part of pyzmq, copied and adapted from h5py. -#  h5py source used under the New BSD license -# -#  h5py: <http://code.google.com/p/h5py/> -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -from __future__ import division - -import sys -import logging - -#----------------------------------------------------------------------------- -# Logging (adapted from h5py: http://h5py.googlecode.com) -#----------------------------------------------------------------------------- - - -logger = logging.getLogger() -logger.setLevel(logging.INFO) -logger.addHandler(logging.StreamHandler(sys.stderr)) - -def debug(msg): -    logger.debug(msg) - -def info(msg): -    logger.info(msg) - -def fatal(msg, code=1): -    logger.error("Fatal: " + msg) -    exit(code) - -def warn(msg): -    logger.error("Warning: " + msg) - -def line(c='*', width=48): -    print(c * (width // len(c))) - diff --git a/buildutils/templates/constant_enums.pxi b/buildutils/templates/constant_enums.pxi deleted file mode 100644 index 6039548..0000000 --- a/buildutils/templates/constant_enums.pxi +++ /dev/null @@ -1,3 +0,0 @@ -cdef extern from "zmq.h" nogil: - -    {ZMQ_ENUMS} diff --git a/buildutils/templates/constants.pxi b/buildutils/templates/constants.pxi deleted file mode 100644 index 042a6e8..0000000 --- a/buildutils/templates/constants.pxi +++ /dev/null @@ -1,12 +0,0 @@ -#----------------------------------------------------------------------------- -# Python module level constants -#----------------------------------------------------------------------------- - -{ASSIGNMENTS} - -#----------------------------------------------------------------------------- -# Symbols to export -#----------------------------------------------------------------------------- -__all__ = [ -{ALL} -] diff --git a/buildutils/templates/zmq_constants.h b/buildutils/templates/zmq_constants.h deleted file mode 100644 index 6855331..0000000 --- a/buildutils/templates/zmq_constants.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PYZMQ_CONSTANT_DEFS -#define _PYZMQ_CONSTANT_DEFS - -{ZMQ_IFNDEFS} - -#endif // ifndef _PYZMQ_CONSTANT_DEFS diff --git a/buildutils/vers.c b/buildutils/vers.c deleted file mode 100644 index 362564f..0000000 --- a/buildutils/vers.c +++ /dev/null @@ -1,11 +0,0 @@ -// check libzmq version - -#include <stdio.h> -#include "zmq.h" - -int main(int argc, char **argv){ -    int major, minor, patch; -    zmq_version(&major, &minor, &patch); -    fprintf(stdout, "vers: %d.%d.%d\n", major, minor, patch); -    return 0; -} diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index 062fbcb..0000000 --- a/debian/changelog +++ /dev/null @@ -1,194 +0,0 @@ -pyzmq (14.3.1-2+leap) unstable; urgency=medium - -  * Non-maintainer upload. -  * Link against libsodium-enabled libzmq3 -  * Disable dh_autotest due to random failures - - -- Ben Carrillo <ben@futeisha.org>  Fri, 08 Aug 2014 19:31:53 -0500 - -pyzmq (14.3.1-1) unstable; urgency=medium - -  * New upstream release -  * monitor-test.patch: fix test logic for synchronous connects on freebsd -  * ignore test results on mips, hard to debug race condition, no reason to -    delay testing migration (Closes: #750813) - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Tue, 17 Jun 2014 23:23:35 +0200 - -pyzmq (14.3.0-1) unstable; urgency=medium - -  * New upstream release - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Wed, 14 May 2014 21:27:23 +0200 - -pyzmq (14.2.0-1) unstable; urgency=medium - -  * New upstream release - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Sat, 03 May 2014 17:45:57 +0200 - -pyzmq (14.1.1-1) unstable; urgency=medium - -  * New upstream release -    - drop upstream applied cython-error.patch -  * fix minitornado copyright information -    thanks to Thorsten Alteholz for the report -  * bump pypy build dependency to 2.2, required for cffi patch to work. - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Fri, 04 Apr 2014 16:33:57 +0200 - -pyzmq (14.0.1-1) unstable; urgency=low - -  * New upstream release -    drop upstream applied workaround-gevent.patch -  * cython-error.patch: fix use-after-free due to wrong cython use -  * provide pypy-zmq package -  * build package with pybuild -  * bump cython build depend version to required >= 0.16 (Closes: #721711) -  * run nose with zmq.tests to avoid autopkgtest issues if optional -    dependencies are missing -  * bump X-Python-Version to >= 2.6 as required by 0.13.x -  * bump debhelper to >= 8.1~ for build-arch support -  * remove Miguel Landaeta from Uploaders. (Closes: #728413) -    Thank you for your work. -  * bump standard to 3.9.5, no changes required - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Sat, 04 Jan 2014 22:24:19 +0100 - -pyzmq (13.1.0-1) unstable; urgency=low - -  * New upstream release built with zeromq3 (Closes: #698830) -    - drop all patches -  * workaround-gevent.patch: workaround issue with gevent < 1.0 -  * noncopysend-test.patch: avoid uninitialized values in tests -  * update copyright - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Sun, 12 May 2013 13:59:20 +0200 - -pyzmq (2.2.0.1-2) unstable; urgency=low - -  [ Julian Taylor ] -  * upload to unstable -  * python-gevent-dbg is fixed, enable python2 dbg autopkgtests -  * cython0.19-compat.patch: fix build with cython 0.19 - -  [ Jakub Wilk ] -  * Use canonical URIs for Vcs-* fields. - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Thu, 09 May 2013 15:07:29 +0200 - -pyzmq (2.2.0.1-1) experimental; urgency=low - -  * New upstream release -  * relicense debian packaging to LGPL-3 -  * update watch file to use github directly -    thanks to Bart Martens for the file -  * add autopkgtests -  * drop obsolete DM-Upload-Allowed -  * bump standard to 3.9.4, no changes required - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Sun, 24 Feb 2013 19:23:15 +0100 - -pyzmq (2.2.0-1) unstable; urgency=low - -  [ Julian Taylor ] -  * New upstream release -  * update debian/copyright for relicensing of non core files to BSD-3-clause -  * bump standard to 3.9.3, no changes required -  * build with hardening flags - -  [ Bernd Zeimetz ] -  * Set DM-Upload-Allowed: yes - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Sun, 20 May 2012 17:41:34 +0200 - -pyzmq (2.1.11-1) unstable; urgency=low - -  [ Julian Taylor ] -  * New upstream release (Closes: #655793) -  * added myself to Uploaders -  * properly clean to allow building twice in a row -  * ignore testsuite result due to random failures on armel and mips -    probably caused by libzmq or toolchain -  * add Python3 to short description of py3 packages -  * wrap-and-sort debian/ -  * add python-nose to build depends to get better test result output -  * add python-numpy to build depends to get more tests -  * use githubredir.debian.net in debian/watch - - -- Julian Taylor <jtaylor.debian@googlemail.com>  Sun, 19 Feb 2012 14:53:20 +0100 - -pyzmq (2.1.10-2) unstable; urgency=low - -  [ Julian Taylor ] -  * remove python:Provides, python:Breaks and XB-Python-Version -    not needed with dh_python2 -  * bump python dependency to >= 2.6.6-3~ for dh_python2 -  * do not delete *_d.so files from lib/debug in python-zmq-dbg -    - needed for gdb when using debug interpreter -  * fix dep5 copyright syntax error -  * add python3 packages (Closes: #636484) -  * add a directory existance check to clean target to allow build with -    git-buildpackage --git-overlay - - -- Debian Python Modules Team <python-modules-team@lists.alioth.debian.org>  Mon, 05 Dec 2011 21:42:24 +0100 - -pyzmq (2.1.10-1) unstable; urgency=low - -  * New upstream version -  * Build-depend on zeromq 2.1.10 - - -- Debian Python Modules Team <python-modules-team@lists.alioth.debian.org>  Tue, 22 Nov 2011 14:54:20 +0100 - -pyzmq (2.1.9-1) unstable; urgency=low - -  * New upstream version -    - should build on kFreeBSD without patches (Closes: #637777). -  * Build-depend on zeromq 2.1.9 - - -- Debian Python Modules Team <python-modules-team@lists.alioth.debian.org>  Fri, 23 Sep 2011 00:16:39 +0200 - -pyzmq (2.1.7-1) unstable; urgency=low - -  [ Bernd Zeimetz ] -  * New upstream version. -  * Build-depend on zeromq 2.1.7. -  * Bump Standards-Version to 3.9.2, no changes needed. -  * Remove all .pyc and .so files during clean.  - -  [ Miguel Landaeta ] -  * Update copyright dates and make it DEP-5 compliant. -  * Refresh patches. -  * Enable build-time tests. - - -- Miguel Landaeta <miguel@miguel.cc>  Mon, 23 May 2011 08:57:59 +0200 - -pyzmq (2.0.10.1-2) unstable; urgency=low - -  * Team upload. -  * Upload to unstable -  * Add Breaks: ${python:Breaks} - - -- Piotr Ożarowski <piotr@debian.org>  Tue, 15 Feb 2011 09:08:36 +0100 - -pyzmq (2.0.10.1-1) experimental; urgency=low - -  * New upstream release. -  * Migrate to dh_python2 and drop Build-Depends on python-support. -  * Fix typo in package descriptions. - - -- Miguel Landaeta <miguel@miguel.cc>  Thu, 03 Feb 2011 13:50:00 -0430 - -pyzmq (2.0.10-1) experimental; urgency=low - -  * New upstream release. -    - cpython minimum build version bumped to 0.13 -  * Add watch file. - - -- Miguel Landaeta <miguel@miguel.cc>  Wed, 17 Nov 2010 16:14:17 -0430 - -pyzmq (0.1.20100703+git18f5d06155-1) unstable; urgency=low - -  * Initial release. (Closes: #590633) - - -- Miguel Landaeta <miguel@miguel.cc>  Wed, 08 Sep 2010 13:50:41 -0430 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index 7f8f011..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/debian/control b/debian/control deleted file mode 100644 index f052973..0000000 --- a/debian/control +++ /dev/null @@ -1,131 +0,0 @@ -Source: pyzmq -Section: python -Priority: optional -Maintainer: Debian Python Modules Team <python-modules-team@lists.alioth.debian.org> -Uploaders: Julian Taylor <jtaylor.debian@googlemail.com> -Build-Depends: cython (>= 0.16), -               cython-dbg (>= 0.16), -               debhelper (>= 8.1~), -               dh-python (>= 1.20131021-1~), -               dpkg-dev (>= 1.16.1~), -               libzmq3-dev, -               pypy (>= 2.2), -               python-all-dbg (>= 2.6.6-3~), -               python-all-dev (>= 2.6.6-3~), -               python-nose, -               python-numpy, -               python-setuptools, -               python3 (>= 3.3.0-2), -               python3-all-dbg (>= 3.2), -               python3-all-dev (>= 3.2) -Standards-Version: 3.9.5 -X-Python-Version: >= 2.6 -X-Python3-Version: >= 3.2 -Homepage: http://www.zeromq.org/bindings:python -Vcs-Svn: svn://anonscm.debian.org/python-modules/packages/pyzmq/trunk/ -Vcs-Browser: http://anonscm.debian.org/viewvc/python-modules/packages/pyzmq/trunk/ - -Package: python-zmq -Architecture: any -Depends: ${misc:Depends}, ${python:Depends}, ${shlibs:Depends} -Description: Python bindings for 0MQ library - Python bindings for 0MQ. 0MQ is a small, fast, and free - software library that gives you message-passing concurrency - for applications in most common languages. - . - The 0MQ lightweight messaging kernel is a library which - extends the standard socket interfaces with features - traditionally provided by specialised messaging middleware - products. 0MQ sockets provide an abstraction of asynchronous - message queues, multiple messaging patterns, message - filtering (subscriptions), seamless access to multiple - transport protocols and more. - -Package: python-zmq-dbg -Section: debug -Priority: extra -Architecture: any -Depends: python-zmq (= ${binary:Version}), -         ${misc:Depends}, -         ${python:Depends}, -         ${shlibs:Depends} -Recommends: python-dbg -Description: Python bindings for 0MQ library - debugging files - Python bindings for 0MQ. 0MQ is a small, fast, and free - software library that gives you message-passing concurrency - for applications in most common languages. - . - The 0MQ lightweight messaging kernel is a library which - extends the standard socket interfaces with features - traditionally provided by specialised messaging middleware - products. 0MQ sockets provide an abstraction of asynchronous - message queues, multiple messaging patterns, message - filtering (subscriptions), seamless access to multiple - transport protocols and more. - . - This package contains the extension built for the Python debug interpreter. - -Package: python3-zmq -Architecture: any -Depends: ${misc:Depends}, ${python3:Depends}, ${shlibs:Depends} -Description: Python3 bindings for 0MQ library - Python bindings for 0MQ. 0MQ is a small, fast, and free - software library that gives you message-passing concurrency - for applications in most common languages. - . - The 0MQ lightweight messaging kernel is a library which - extends the standard socket interfaces with features - traditionally provided by specialised messaging middleware - products. 0MQ sockets provide an abstraction of asynchronous - message queues, multiple messaging patterns, message - filtering (subscriptions), seamless access to multiple - transport protocols and more. - . - This package contains the extension built for the Python3 interpreter. - -Package: python3-zmq-dbg -Section: debug -Priority: extra -Architecture: any -Depends: python3-zmq (= ${binary:Version}), -         ${misc:Depends}, -         ${python3:Depends}, -         ${shlibs:Depends} -Recommends: python-dbg -Description: Python3 bindings for 0MQ library - debugging files - Python bindings for 0MQ. 0MQ is a small, fast, and free - software library that gives you message-passing concurrency - for applications in most common languages. - . - The 0MQ lightweight messaging kernel is a library which - extends the standard socket interfaces with features - traditionally provided by specialised messaging middleware - products. 0MQ sockets provide an abstraction of asynchronous - message queues, multiple messaging patterns, message - filtering (subscriptions), seamless access to multiple - transport protocols and more. - . - This package contains the extension built for the Python3 debug interpreter. - -Package: pypy-zmq -Architecture: any -Depends: gcc, -         libzmq3-dev, -         pypy (>= 2.2), -         ${misc:Depends}, -         ${pypy:Depends}, -         ${shlibs:Depends} -Description: PyPy bindings for 0MQ library - Python bindings for 0MQ. 0MQ is a small, fast, and free - software library that gives you message-passing concurrency - for applications in most common languages. - . - The 0MQ lightweight messaging kernel is a library which - extends the standard socket interfaces with features - traditionally provided by specialised messaging middleware - products. 0MQ sockets provide an abstraction of asynchronous - message queues, multiple messaging patterns, message - filtering (subscriptions), seamless access to multiple - transport protocols and more. - . - This package contains the extension built for the PyPy interpreter. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 7bed693..0000000 --- a/debian/copyright +++ /dev/null @@ -1,139 +0,0 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: pyzmq -Upstream-Contact: Min Ragan-Kelley <benjaminrk@gmail.com> -Source: https://github.com/zeromq/pyzmq/downloads - -Files: * -Copyright:  2010-2012, Brian Granger - 2010-2013, Min Ragan-Kelley - 2013 Felipe Cruz - 2014 PyZMQ Developers -License: BSD-3-clause - -Files: examples/mongodb/* -Copyright: 2010, Justin Riley -License: BSD-3-clause - -Files: examples/chat/* -Copyright: 2010, Andrew Gwozdziewycz -License: LGPL-3 - -Files: examples/device/client.py examples/device/server.py -Copyright: 2010, Brian E. Granger - 2010, Eugene Chernyshov -License: LGPL-3 - -Files: zmq/backends/cython -Copyright: 2010-2011, Brian E. Granger - 2010, Andrew Gwozdziewycz - 2010, Fernando Perez - 2011, 2013, Min Ragan-Kelley -License: LGPL-3 - -Files: zmq/devices/monitoredqueue.pxd -Copyright: 2010, Brian E. Granger - 2010, Min Ragan-Kelley -License: LGPL-3 - -Files: perf/* -Copyright: 2007-2010, iMatix Corporation - 2013 Brian Granger, Min Ragan-Kelley -License: LGPL-3 - -Files: docs/sphinxext/sphinx_cython.py -Copyright: 2010, Nikolaus Rath <Nikolaus@rath.org> -License: LGPL-3 - -Files: zmq/ssh/forward.py -Copyright: 2003-2007, Robey Pointer <robeypointer@gmail.com>, - 2010-2011, IPython Development Team -License: LGPL-2.1 - -Files: zmq/eventloop/zmqstream.py zmq/eventloop/minitornado/* -Copyright: 2009, Facebook. -License: Apache-2.0 - -Files: debian/* -Copyright: 2010-2011, Miguel Landaeta <miguel@miguel.cc> - 2011-2014, Julian Taylor -License: LGPL-3 - -License: BSD-3-clause - All rights reserved. - . - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - . - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - . - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - . - Neither the name of PyZMQ nor the names of its contributors may be used to - endorse or promote products derived from this software without specific prior - written permission. - . - . - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -License: LGPL-3 - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - . - This library 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 GNU - Library General Public License for more details. - . - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. - . - The full text of the GNU Lesser General Public License version 3 - is distributed in /usr/share/common-licenses/LGPL-3 on Debian systems. - -License: LGPL-2.1 - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - . - This library 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 GNU - Lesser General Public License for more details. - . - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - . - The full text of the GNU Lesser General Public License version 2.1 - is distributed in /usr/share/common-licenses/LGPL-2.1 on Debian systems. - -License: Apache-2.0 - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - . -     http://www.apache.org/licenses/LICENSE-2.0 -     /usr/share/common-licenses/Apache-2.0 (on Debian systems) - . - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/debian/gbp.conf b/debian/gbp.conf deleted file mode 100644 index ae1dc36..0000000 --- a/debian/gbp.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -upstream-branch = upstream -debian-branch = master -upstream-tag = upstream/%(version)s -debian-tag = debian/%(version)s -pristine-tar = True -sign-tags = True diff --git a/debian/patches/cffi-fix.patch b/debian/patches/cffi-fix.patch deleted file mode 100644 index fccf587..0000000 --- a/debian/patches/cffi-fix.patch +++ /dev/null @@ -1,69 +0,0 @@ -Description: check package root for cffi binaries - cffi checks __pycache__ for binaries which is cleaned by pypy installation so - packages can't ship in there. - Instead ship in package root and patch module finding to look in there. - Also use fixed path in a place passed to cffi to get the same checksum - in build and install. After it is installed no build is needed so it doesn't - matter if its wrong. - This patch assumes pypy 2.2 api, won't work with 2.1 as so_suffices is no - list. -Bug: https://bitbucket.org/cffi/cffi/issue/109/enable-sane-packaging-for-cffi - ---- a/zmq/backend/cffi/__init__.py -+++ b/zmq/backend/cffi/__init__.py -@@ -3,6 +3,40 @@ - # Copyright (C) PyZMQ Developers - # Distributed under the terms of the Modified BSD License. -  -+import imp -+import os.path -+import sys -+ -+import cffi.vengine_cpy -+import cffi.vengine_gen -+_ma_triplet = None -+ -+def vengine_gen_find_module(self, module_name, path, so_suffixes): -+    global _ma_triplet -+    if _ma_triplet is None: -+        try: -+            import subprocess as sp -+            p = sp.Popen(["gcc", "-print-multiarch"], stdout=sp.PIPE) -+            _ma_triplet = str(p.communicate()[0].decode().strip()) -+        except: -+            import warnings -+            warnings.warn('failed to detect multiarch paths, please install gcc') -+ -+    for so_suffix in so_suffixes + ['.%s-%s.so' % (imp.get_tag(), _ma_triplet)]: -+        basename = module_name + so_suffix -+        if path is None: -+            path = sys.path -+            # import from non root package would try __pycache__ which is -+            # cleaned by pypy installation -+            path.insert(0, "/usr/lib/pypy/dist-packages/zmq/backend/cffi") -+        for dirname in path: -+            filename = os.path.join(dirname, basename) -+            if os.path.isfile(filename): -+                return filename -+ -+ -+cffi.vengine_gen.VGenericEngine.find_module = vengine_gen_find_module -+ - from zmq.backend.cffi import (constants, error, message, context, socket, -                            _poll, devices, utils) -  ---- a/zmq/backend/cffi/_cffi.py -+++ b/zmq/backend/cffi/_cffi.py -@@ -106,10 +106,10 @@ int get_ipc_path_max_len(void); -  - def load_compiler_config(): -     import zmq --    zmq_dir = dirname(zmq.__file__) -+    zmq_dir = "zmq" -     zmq_parent = dirname(zmq_dir) -      --    fname = join(zmq_dir, 'utils', 'compiler.json') -+    fname = join(dirname(zmq.__file__), 'utils', 'compiler.json') -     if os.path.exists(fname): -         with open(fname) as f: -             cfg = json.load(f) diff --git a/debian/patches/monitor-test.patch b/debian/patches/monitor-test.patch deleted file mode 100644 index 578484e..0000000 --- a/debian/patches/monitor-test.patch +++ /dev/null @@ -1,36 +0,0 @@ -Description: handle freebsd connecting without delay -Bug: https://github.com/zeromq/pyzmq/pull/558 ---- a/zmq/tests/test_monitor.py -+++ b/zmq/tests/test_monitor.py -@@ -35,11 +35,13 @@ class TestSocketMonitor(BaseZMQTestCase) -         # test receive event for connect event -         s_rep.connect("tcp://127.0.0.1:6666") -         m = recv_monitor_message(s_event) --        self.assertEqual(m['event'], zmq.EVENT_CONNECT_DELAYED) --        self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6666") --        # test receive event for connected event --        m = recv_monitor_message(s_event) -+        if m['event'] == zmq.EVENT_CONNECT_DELAYED: -+            self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6666") -+            # test receive event for connected event -+            m = recv_monitor_message(s_event) -         self.assertEqual(m['event'], zmq.EVENT_CONNECTED) -+        self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6666") -+ -  -     @skip_lt_4 -     def test_monitor_connected(self): -@@ -56,8 +58,9 @@ class TestSocketMonitor(BaseZMQTestCase) -         # test receive event for connect event -         s_rep.connect("tcp://127.0.0.1:6667") -         m = recv_monitor_message(s_event) --        self.assertEqual(m['event'], zmq.EVENT_CONNECT_DELAYED) --        self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6667") --        # test receive event for connected event --        m = recv_monitor_message(s_event) -+        if m['event'] == zmq.EVENT_CONNECT_DELAYED: -+            self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6667") -+            # test receive event for connected event -+            m = recv_monitor_message(s_event) -         self.assertEqual(m['event'], zmq.EVENT_CONNECTED) -+        self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6667") diff --git a/debian/patches/noncopysend-test.patch b/debian/patches/noncopysend-test.patch deleted file mode 100644 index 4880ae1..0000000 --- a/debian/patches/noncopysend-test.patch +++ /dev/null @@ -1,20 +0,0 @@ -Description: don't use uninitialized memory for test - the memory could contain signalling NaN which crashes sparc python -Author: Julian Taylor <jtaylor.debian@googlemail.com> -Forwarded: not-needed - ---- a/zmq/tests/test_message.py -+++ b/zmq/tests/test_message.py -@@ -324,10 +324,8 @@ class TestFrame(BaseZMQTestCase): -         for i in range(1,len(shapes)+1): -             shape = shapes[:i] -             for dt in dtypes: --                A = numpy.empty(shape, dtype=dt) --                while numpy.isnan(A).any(): --                    # don't let nan sneak in --                    A = numpy.ndarray(shape, dtype=dt) -+                A = numpy.random.uniform(-10000000, -+                                         1000000, size=shape).astype(dt) -                 a.send(A, copy=False) -                 msg = b.recv(copy=False) -                  diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index 0d2af1f..0000000 --- a/debian/patches/series +++ /dev/null @@ -1,3 +0,0 @@ -noncopysend-test.patch -cffi-fix.patch -monitor-test.patch diff --git a/debian/rules b/debian/rules deleted file mode 100755 index 9ebe3a9..0000000 --- a/debian/rules +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/make -f - -DPKG_EXPORT_BUILDFLAGS = 1 -include /usr/share/dpkg/buildflags.mk - -ARCHITECTURE := $(shell dpkg-architecture -qDEB_HOST_ARCH) -export PYBUILD_DESTDIR_python2=debian/python-zmq/ -export PYBUILD_DESTDIR_python2-dbg=debian/python-zmq-dbg/ -export PYBUILD_DESTDIR_python3=debian/python3-zmq/ -export PYBUILD_DESTDIR_python3-dbg=debian/python3-zmq-dbg/ -export PYBUILD_DESTDIR_pypy=debian/pypy-zmq/ -export PYBUILD_DEBUG=1 -export DH_VERBOSE=1 - -%: -	dh $@ --with python2,python3,pypy --buildsystem=pybuild - -override_dh_install: -	dh_install -	# remove a couple of header files already in python3-zmq -	find debian/python3-zmq-dbg/usr/lib/ ! -type d ! -name '*.so' -delete -	find debian/python-zmq-dbg/usr/lib/ ! -type d ! -name '*.so' -delete -	# cffi is only used for pypy -	rm -rf debian/python-zmq/usr/lib/python*/dist-packages/zmq/backend/cffi/ -	rm -rf debian/python-dbg-zmq/usr/lib/python*/dist-packages/zmq/backend/cffi/ -	rm -rf debian/python3-zmq/usr/lib/python*/dist-packages/zmq/backend/cffi/ -	rm -rf debian/python3-dbg-zmq/usr/lib/python*/dist-packages/zmq/backend/cffi/ -	find debian/python*-zmq/ -name compiler.json -delete -	find debian/python*-zmq/ -name config.json -delete -	# cython core is only used for cpython -	rm -rf debian/pypy-zmq/usr/lib/pypy/dist-packages/zmq/backend/cython - -	# build shared libraries for pypy and install them -	pypy -c 'import zmq' -	mv -v zmq/backend/cffi/__pycache__/*so \ -	  $(CURDIR)/debian/pypy-zmq/usr/lib/pypy/dist-packages/zmq/backend/cffi -	# put there by install, not needed -	rm -f $(CURDIR)/debian/pypy-zmq/usr/lib/pypy/dist-packages/_cffi*.so - -	find debian/python-zmq -depth -type d -empty -exec rmdir {} \; -	find debian/python-zmq-dbg -type d -depth -empty -exec rmdir {} \; -	find debian/python3-zmq -depth -type d -empty -exec rmdir {} \; -	find debian/python3-zmq-dbg -type d -depth -empty -exec rmdir {} \; -	find debian/pypy-zmq -type d -depth -empty -exec rmdir {} \; - -override_dh_auto_test: -	echo "skipping test" -# hard to debug race condition in monitor sockets -#ifneq (,$(filter $(ARCHITECTURE), mipsel mips)) -	#-dh_auto_test -#else -#	dh_auto_test -#endif diff --git a/debian/source/format b/debian/source/format deleted file mode 100644 index 163aaf8..0000000 --- a/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/debian/watch b/debian/watch deleted file mode 100644 index bcf07d5..0000000 --- a/debian/watch +++ /dev/null @@ -1,2 +0,0 @@ -version=3 -https://github.com/zeromq/pyzmq/tags .*/.*v(\d.*)\.(?:tgz|tar\.(?:gz|bz2|xz)) diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 87988f8..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,117 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS    = -SPHINXBUILD   = sphinx-build -PAPER         = -BUILDDIR      = build -SRCDIR        = source - -# Internal variables. -PAPEROPT_a4     = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SRCDIR) - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -default: html - -help: -	@echo "Please use \`make <target>' where <target> is one of" -	@echo "  html      to make standalone HTML files" -	@echo "  dirhtml   to make HTML files named index.html in directories" -	@echo "  pickle    to make pickle files" -	@echo "  json      to make JSON files" -	@echo "  htmlhelp  to make HTML files and a HTML help project" -	@echo "  qthelp    to make HTML files and a qthelp project" -	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter" -	@echo "  changes   to make an overview of all changed/added/deprecated items" -	@echo "  linkcheck to check all external links for integrity" -	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)" - -clean: -	-rm -rf $(BUILDDIR)/* -	-rm -rf $(SRCDIR)/api/generated/* -	-rm -rf dist -	-rm -rf gh-pages - -api: $(SRCDIR)/api/generated/gen.rst - -$(SRCDIR)/api/generated/gen.rst: -	python autogen_api.py -	@echo "Build API docs finished." - -dist: all -	mkdir -p dist -	rm -rf dist/* -	ln $(BUILDDIR)/latex/PyZMQ.pdf dist/ -	cp -a $(BUILDDIR)/html dist/ -	@echo "Build finished.  Final docs are in dist/" - -pdf: latex -	cd $(BUILDDIR)/latex && make all-pdf - -all: html pdf - -html: api -	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html -	@echo -	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: -	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml -	@echo -	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -pickle: -	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle -	@echo -	@echo "Build finished; now you can process the pickle files." - -json: -	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json -	@echo -	@echo "Build finished; now you can process the JSON files." - -htmlhelp: -	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp -	@echo -	@echo "Build finished; now you can run HTML Help Workshop with the" \ -	      ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: -	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp -	@echo -	@echo "Build finished; now you can run "qcollectiongenerator" with the" \ -	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:" -	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PyZMQ.qhcp" -	@echo "To view the help file:" -	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PyZMQ.qhc" - -latex: api -	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex -	@echo -	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." -	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ -	      "run these through (pdf)latex." - -changes: -	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes -	@echo -	@echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: -	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck -	@echo -	@echo "Link check complete; look for any errors in the above output " \ -	      "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: -	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest -	@echo "Testing of doctests in the sources finished, look at the " \ -	      "results in $(BUILDDIR)/doctest/output.txt." - -gh-pages: html -	sh update_ghpages.sh - diff --git a/docs/autogen_api.py b/docs/autogen_api.py deleted file mode 100755 index 004c461..0000000 --- a/docs/autogen_api.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python -"""Script to auto-generate our API docs. -""" -# stdlib imports -import os -import sys - -# local imports -sys.path.append(os.path.abspath('sphinxext')) -# import sphinx_cython -from apigen import ApiDocWriter - -#***************************************************************************** -if __name__ == '__main__': -    pjoin = os.path.join -    package = 'zmq' -    outdir = pjoin('source','api','generated') -    docwriter = ApiDocWriter(package,rst_extension='.rst') -    # You have to escape the . here because . is a special char for regexps. -    # You must do make clean if you change this! -    docwriter.package_skip_patterns += [ -        r'\.tests$', -        r'\.backend$', -        r'\.auth$', -        r'\.eventloop\.minitornado$', -        r'\.green\.eventloop$', -        r'\.sugar$', -        r'\.devices$', -    ] - -    docwriter.module_skip_patterns += [ -        r'\.eventloop\.stack_context$', -        r'\.error$', -        r'\.green\..+$', -        r'\.utils\.initthreads$', -        r'\.utils\.constant_names$', -        r'\.utils\.garbage$', -        r'\.utils\.rebuffer$', -        r'\.utils\.strtypes$', -        ] -     -    # Now, generate the outputs -    docwriter.write_api_docs(outdir) -    docwriter.write_index(outdir, 'gen', -                          relative_to = pjoin('source','api') -                          ) -     -    print('%d files written' % len(docwriter.written_modules)) diff --git a/docs/source/_static/default.css b/docs/source/_static/default.css deleted file mode 100644 index 71c9d5e..0000000 --- a/docs/source/_static/default.css +++ /dev/null @@ -1,553 +0,0 @@ -/** - * Alternate Sphinx design - * Originally created by Armin Ronacher for Werkzeug, adapted by Georg Brandl. - */ - -body { -    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', 'Verdana', sans-serif; -    font-size: 14px; -    letter-spacing: -0.01em; -    line-height: 150%; -    text-align: center; -    /*background-color: #AFC1C4; */ -    background-color: #BFD1D4; -    color: black; -    padding: 0; -    border: 1px solid #aaa; - -    margin: 0px 80px 0px 80px; -    min-width: 740px; -} - -a { -    color: #CA7900; -    text-decoration: none; -} - -a:hover { -    color: #2491CF; -} - -pre { -    font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; -    font-size: 0.95em; -    letter-spacing: 0.015em; -    padding: 0.5em; -    border: 1px solid #ccc; -    background-color: #f8f8f8; -} - -td.linenos pre { -    padding: 0.5em 0; -    border: 0; -    background-color: transparent; -    color: #aaa; -} - -table.highlighttable { -    margin-left: 0.5em; -} - -table.highlighttable td { -    padding: 0 0.5em 0 0.5em; -} - -cite, code, tt { -    font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; -    font-size: 0.95em; -    letter-spacing: 0.01em; -} - -hr { -    border: 1px solid #abc; -    margin: 2em; -} - -tt { -    background-color: #f2f2f2; -    border-bottom: 1px solid #ddd; -    color: #333; -} - -tt.descname { -    background-color: transparent; -    font-weight: bold; -    font-size: 1.2em; -    border: 0; -} - -tt.descclassname { -    background-color: transparent; -    border: 0; -} - -tt.xref { -    background-color: transparent; -    font-weight: bold; -    border: 0; -} - -a tt { -    background-color: transparent; -    font-weight: bold; -    border: 0; -    color: #CA7900; -} - -a tt:hover { -    color: #2491CF; -} - -dl { -    margin-bottom: 15px; -} - -dd p { -    margin-top: 0px; -} - -dd ul, dd table { -    margin-bottom: 10px; -} - -dd { -    margin-top: 3px; -    margin-bottom: 10px; -    margin-left: 30px; -} - -.refcount { -    color: #060; -} - -dt:target, -.highlight { -    background-color: #fbe54e; -} - -dl.class, dl.function { -    border-top: 2px solid #888; -} - -dl.method, dl.attribute { -    border-top: 1px solid #aaa; -} - -dl.glossary dt { -    font-weight: bold; -    font-size: 1.1em; -} - -pre { -    line-height: 120%; -} - -pre a { -    color: inherit; -    text-decoration: underline; -} - -.first { -    margin-top: 0 !important; -} - -div.document { -    background-color: white; -    text-align: left; -    background-image: url(contents.png); -    background-repeat: repeat-x; -} - -/* -div.documentwrapper { -    width: 100%; -} -*/ - -div.clearer { -    clear: both; -} - -div.related h3 { -    display: none; -} - -div.related ul { -    background-image: url(navigation.png); -    height: 2em; -    list-style: none; -    border-top: 1px solid #ddd; -    border-bottom: 1px solid #ddd; -    margin: 0; -    padding-left: 10px; -} - -div.related ul li { -    margin: 0; -    padding: 0; -    height: 2em; -    float: left; -} - -div.related ul li.right { -    float: right; -    margin-right: 5px; -} - -div.related ul li a { -    margin: 0; -    padding: 0 5px 0 5px; -    line-height: 1.75em; -    color: #EE9816; -} - -div.related ul li a:hover { -    color: #3CA8E7; -} - -div.body { -    margin: 0; -    padding: 0.5em 20px 20px 20px; -} - -div.bodywrapper { -    margin: 0 240px 0 0; -    border-right: 1px solid #ccc; -} - -div.body a { -    text-decoration: underline; -} - -div.sphinxsidebar { -    margin: 0; -    padding: 0.5em 15px 15px 0; -    width: 210px; -    float: right; -    text-align: left; -/*    margin-left: -100%; */ -} - -div.sphinxsidebar h4, div.sphinxsidebar h3 { -    margin: 1em 0 0.5em 0; -    font-size: 0.9em; -    padding: 0.1em 0 0.1em 0.5em; -    color: white; -    border: 1px solid #86989B; -    background-color: #AFC1C4; -} - -div.sphinxsidebar ul { -    padding-left: 1.5em; -    margin-top: 7px; -    list-style: none; -    padding: 0; -    line-height: 130%; -} - -div.sphinxsidebar ul ul { -    list-style: square; -    margin-left: 20px; -} - -p { -    margin: 0.8em 0 0.5em 0; -} - -p.rubric { -    font-weight: bold; -} - -h1 { -    margin: 0; -    padding: 0.7em 0 0.3em 0; -    font-size: 1.5em; -    color: #11557C; -} - -h2 { -    margin: 1.3em 0 0.2em 0; -    font-size: 1.35em; -    padding: 0; -} - -h3 { -    margin: 1em 0 -0.3em 0; -    font-size: 1.2em; -} - -h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { -    color: black!important; -} - -h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { -    display: none; -    margin: 0 0 0 0.3em; -    padding: 0 0.2em 0 0.2em; -    color: #aaa!important; -} - -h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, -h5:hover a.anchor, h6:hover a.anchor { -    display: inline; -} - -h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, -h5 a.anchor:hover, h6 a.anchor:hover { -    color: #777; -    background-color: #eee; -} - -table { -    border-collapse: collapse; -    margin: 0 -0.5em 0 -0.5em; -} - -table td, table th { -    padding: 0.2em 0.5em 0.2em 0.5em; -} - -div.footer { -    background-color: #E3EFF1; -    color: #86989B; -    padding: 3px 8px 3px 0; -    clear: both; -    font-size: 0.8em; -    text-align: right; -} - -div.footer a { -    color: #86989B; -    text-decoration: underline; -} - -div.pagination { -    margin-top: 2em; -    padding-top: 0.5em; -    border-top: 1px solid black; -    text-align: center; -} - -div.sphinxsidebar ul.toc { -    margin: 1em 0 1em 0; -    padding: 0 0 0 0.5em; -    list-style: none; -} - -div.sphinxsidebar ul.toc li { -    margin: 0.5em 0 0.5em 0; -    font-size: 0.9em; -    line-height: 130%; -} - -div.sphinxsidebar ul.toc li p { -    margin: 0; -    padding: 0; -} - -div.sphinxsidebar ul.toc ul { -    margin: 0.2em 0 0.2em 0; -    padding: 0 0 0 1.8em; -} - -div.sphinxsidebar ul.toc ul li { -    padding: 0; -} - -div.admonition, div.warning { -    font-size: 0.9em; -    margin: 1em 0 0 0; -    border: 1px solid #86989B; -    background-color: #f7f7f7; -} - -div.admonition p, div.warning p { -    margin: 0.5em 1em 0.5em 1em; -    padding: 0; -} - -div.admonition pre, div.warning pre { -    margin: 0.4em 1em 0.4em 1em; -} - -div.admonition p.admonition-title, -div.warning p.admonition-title { -    margin: 0; -    padding: 0.1em 0 0.1em 0.5em; -    color: white; -    border-bottom: 1px solid #86989B; -    font-weight: bold; -    background-color: #AFC1C4; -} - -div.warning { -    border: 1px solid #940000; -} - -div.warning p.admonition-title { -    background-color: #CF0000; -    border-bottom-color: #940000; -} - -div.admonition ul, div.admonition ol, -div.warning ul, div.warning ol { -    margin: 0.1em 0.5em 0.5em 3em; -    padding: 0; -} - -div.versioninfo { -    margin: 1em 0 0 0; -    border: 1px solid #ccc; -    background-color: #DDEAF0; -    padding: 8px; -    line-height: 1.3em; -    font-size: 0.9em; -} - - -a.headerlink { -    color: #c60f0f!important; -    font-size: 1em; -    margin-left: 6px; -    padding: 0 4px 0 4px; -    text-decoration: none!important; -    visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { -    visibility: visible; -} - -a.headerlink:hover { -    background-color: #ccc; -    color: white!important; -} - -table.indextable td { -    text-align: left; -    vertical-align: top; -} - -table.indextable dl, table.indextable dd { -    margin-top: 0; -    margin-bottom: 0; -} - -table.indextable tr.pcap { -    height: 10px; -} - -table.indextable tr.cap { -    margin-top: 10px; -    background-color: #f2f2f2; -} - -img.toggler { -    margin-right: 3px; -    margin-top: 3px; -    cursor: pointer; -} - -img.inheritance { -    border: 0px -} - -form.pfform { -    margin: 10px 0 20px 0; -} - -table.contentstable { -    width: 90%; -} - -table.contentstable p.biglink { -    line-height: 150%; -} - -a.biglink { -    font-size: 1.3em; -} - -span.linkdescr { -    font-style: italic; -    padding-top: 5px; -    font-size: 90%; -} - -ul.search { -    margin: 10px 0 0 20px; -    padding: 0; -} - -ul.search li { -    padding: 5px 0 5px 20px; -    background-image: url(file.png); -    background-repeat: no-repeat; -    background-position: 0 7px; -} - -ul.search li a { -    font-weight: bold; -} - -ul.search li div.context { -    color: #888; -    margin: 2px 0 0 30px; -    text-align: left; -} - -ul.keywordmatches li.goodmatch a { -    font-weight: bold; -} -/* from numpy:*/ -td.field-body > blockquote { -    margin-top: 0.1em; -    margin-bottom: 0.5em; -} -/* spacing in see also definition lists */ -dl.last > dd { -    margin-top: 1px; -    margin-bottom: 5px; -    margin-left: 30px; -} - -.field-list th { -  color: rgb(0,102,204); -  background: #eee; -} - -table.field-list th { -/*  border-left: 1px solid #aaa !important;*/ -  padding-left: 5px; -  white-space: nowrap; -} - -table.field-list {  -  border-collapse: separate; -  border-spacing: 10px; -} - -th.field-name { -/*  border-left: 1px solid #aaa !important;*/ -padding-left: .5em; -padding-right: .5em; -text-align: right; -   -} - -.rubric { -  color: rgb(0,50,150); -  background-color: ; -  font-style: italic; -} - -.versionadded { -  font-style: italic; -  background: #ffe; -}
\ No newline at end of file diff --git a/docs/source/_static/logo.png b/docs/source/_static/logo.png Binary files differdeleted file mode 100644 index c3e8dab..0000000 --- a/docs/source/_static/logo.png +++ /dev/null diff --git a/docs/source/_static/zeromq.ico b/docs/source/_static/zeromq.ico Binary files differdeleted file mode 100644 index 3f810a1..0000000 --- a/docs/source/_static/zeromq.ico +++ /dev/null diff --git a/docs/source/_templates/layout.html b/docs/source/_templates/layout.html deleted file mode 100644 index a3eebdb..0000000 --- a/docs/source/_templates/layout.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends "!layout.html" %} - - -{% block rootrellink %} -        <li><a href="{{ pathto('index') }}">home</a>| </li> -        <li><a href="{{ pathto('search') }}">search</a>| </li> -       <li><a href="{{ pathto('api/index') }}">API</a> »</li> -{% endblock %} - - -{% block relbar1 %} - -<div style="background-color: white; text-align: left; padding: 10px 10px 15px 15px"> -<a href="{{ pathto('index') }}"><img src="{{ -pathto("_static/logo.png", 1) }}" border="0" alt="PyZMQ Documentation"/></a> -</div> -{{ super() }} -{% endblock %} - -{# put the sidebar before the body #} -{% block sidebar1 %}{{ sidebar() }}{% endblock %} -{% block sidebar2 %}{% endblock %} - diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst deleted file mode 100644 index 6b51f0c..0000000 --- a/docs/source/api/index.rst +++ /dev/null @@ -1,25 +0,0 @@ -.. _api-index: - -################### -  The PyZMQ API -################### - -:Release: |release| -:Date: |today| - -.. toctree:: - -    zmq -    zmq.devices -    zmq.green -    generated/zmq.eventloop.ioloop -    generated/zmq.eventloop.zmqstream -    zmq.auth -    zmq.auth.thread -    zmq.auth.ioloop -    generated/zmq.log.handlers -    generated/zmq.ssh.tunnel -    generated/zmq.utils.jsonapi -    generated/zmq.utils.monitor -    generated/zmq.utils.z85 - diff --git a/docs/source/api/zmq.auth.ioloop.rst b/docs/source/api/zmq.auth.ioloop.rst deleted file mode 100644 index efcb026..0000000 --- a/docs/source/api/zmq.auth.ioloop.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. AUTO-GENERATED FILE -- DO NOT EDIT! - -auth.ioloop -=========== - -Module: :mod:`auth.ioloop` --------------------------- -.. automodule:: zmq.auth.ioloop - -.. currentmodule:: zmq.auth.ioloop - -:class:`IOLoopAuthenticator` ----------------------------- - - -.. autoclass:: IOLoopAuthenticator -  :members: -  :undoc-members: -  :inherited-members: - diff --git a/docs/source/api/zmq.auth.rst b/docs/source/api/zmq.auth.rst deleted file mode 100644 index 6ca29d7..0000000 --- a/docs/source/api/zmq.auth.rst +++ /dev/null @@ -1,30 +0,0 @@ -auth -==== - -Module: :mod:`auth` -------------------- -.. automodule:: zmq.auth - -.. currentmodule:: zmq.auth - - -:class:`Authenticator` ----------------------- - - -.. autoclass:: Authenticator -  :members: -  :undoc-members: -  :inherited-members: - - -Functions ---------- - - -.. autofunction:: create_certificates - -.. autofunction:: load_certificate - -.. autofunction:: load_certificates - diff --git a/docs/source/api/zmq.auth.thread.rst b/docs/source/api/zmq.auth.thread.rst deleted file mode 100644 index e2c0b1b..0000000 --- a/docs/source/api/zmq.auth.thread.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. AUTO-GENERATED FILE -- DO NOT EDIT! - -auth.thread -=========== - -Module: :mod:`auth.thread` --------------------------- -.. automodule:: zmq.auth.thread - -.. currentmodule:: zmq.auth.thread - -Classes -------- - - -:class:`ThreadAuthenticator` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - -.. autoclass:: ThreadAuthenticator -  :members: -  :undoc-members: -  :inherited-members: - diff --git a/docs/source/api/zmq.devices.rst b/docs/source/api/zmq.devices.rst deleted file mode 100644 index 690b0b5..0000000 --- a/docs/source/api/zmq.devices.rst +++ /dev/null @@ -1,86 +0,0 @@ -devices -======= - -Functions ---------- - -.. autofunction:: zmq.device - -.. autofunction:: zmq.proxy - -Module: :mod:`zmq.devices` --------------------------- -.. automodule:: zmq.devices - -.. currentmodule:: zmq.devices - - -Base Devices ------------- - -:class:`Device` -*************** - -.. autoclass:: Device -  :members: -  :exclude-members: context_factory, run, run_device - -:class:`ThreadDevice` -********************* - -.. autoclass:: ThreadDevice -  :members: - -:class:`ProcessDevice` -********************** - -.. autoclass:: ProcessDevice -  :members: - - -Proxy Devices -------------- - -:class:`Proxy` -******************** - -.. autoclass:: Proxy -  :members: bind_mon, connect_mon, setsockopt_mon - -:class:`ThreadProxy` -******************** - -.. autoclass:: ThreadProxy -  :members: - -:class:`ProcessProxy` -********************* - -.. autoclass:: ProcessProxy -  :members: - - -MonitoredQueue Devices ----------------------- - -.. autofunction:: zmq.devices.monitored_queue - -:class:`MonitoredQueue` -***************************** - -.. autoclass:: MonitoredQueue -  :members: - -:class:`ThreadMonitoredQueue` -***************************** - -.. autoclass:: ThreadMonitoredQueue -  :members: - -:class:`ProcessMonitoredQueue` -****************************** - -.. autoclass:: ProcessMonitoredQueue -  :members: - - diff --git a/docs/source/api/zmq.green.rst b/docs/source/api/zmq.green.rst deleted file mode 100644 index 6d0667a..0000000 --- a/docs/source/api/zmq.green.rst +++ /dev/null @@ -1,7 +0,0 @@ -green -===== - -Module: :mod:`green` --------------------- - -.. automodule:: zmq.green diff --git a/docs/source/api/zmq.rst b/docs/source/api/zmq.rst deleted file mode 100644 index 0a0f7fe..0000000 --- a/docs/source/api/zmq.rst +++ /dev/null @@ -1,140 +0,0 @@ -zmq -=== - -.. automodule:: zmq - -.. currentmodule:: zmq - -Basic Classes -------------- - -:class:`Context` -**************** - - -.. autoclass:: Context -  :members: -  :undoc-members: -  :inherited-members: -  :exclude-members: sockopts, closed -   -  .. attribute:: closed -   -      boolean - whether the context has been terminated. -      If True, you can no longer use this Context. - - -:class:`Socket` -*************** - - -.. autoclass:: Socket -  :members: -  :undoc-members: -  :inherited-members: -  :exclude-members: closed, context, getsockopt_unicode, recv_unicode, setsockopt_unicode, send_unicode - -  .. attribute:: closed - -      boolean - whether the socket has been closed. -      If True, you can no longer use this Socket. -   - - -:class:`Frame` -************** - - -.. autoclass:: Frame -  :members: -  :inherited-members: - - -:class:`MessageTracker` -*********************** - - -.. autoclass:: MessageTracker -  :members: -  :inherited-members: - - -Polling -------- - -:class:`Poller` -*************** - -.. autoclass:: Poller -  :members: -  :inherited-members: - - -.. autofunction:: zmq.select - - -Exceptions ----------- - -:class:`ZMQError` -***************** - -.. autoclass:: ZMQError -  :members: -  :inherited-members: - - -:class:`ZMQVersionError` -***************** - -.. autoclass:: ZMQVersionError -  :members: -  :inherited-members: - -:class:`Again` -************** - - -.. autoclass:: Again - - -:class:`ContextTerminated` -************************** - - -.. autoclass:: ContextTerminated - - -:class:`NotDone` -**************** - - -.. autoclass:: NotDone - - -:class:`ZMQBindError` -********************* - - -.. autoclass:: ZMQBindError - - - -Functions ---------- - -.. autofunction:: zmq.zmq_version - -.. autofunction:: zmq.pyzmq_version - -.. autofunction:: zmq.zmq_version_info - -.. autofunction:: zmq.pyzmq_version_info - -.. autofunction:: zmq.device - -.. autofunction:: zmq.proxy - -.. autofunction:: zmq.curve_keypair - -.. autofunction:: zmq.get_includes
\ No newline at end of file diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst deleted file mode 100644 index 8af0652..0000000 --- a/docs/source/changelog.rst +++ /dev/null @@ -1,446 +0,0 @@ -.. PyZMQ changelog summary, started by Min Ragan-Kelley, 2011 - -.. _changelog: - -================ -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>`_ - -14.3.1 -====== - -Minor bugfixes to pyzmq 14.3: - -- Fixes to building bundled libzmq on OS X < 10.9 -- Fixes to import-failure warnings on Python 3.4 -- Fixes to tests -- Pull upstream fixes to zmq.ssh for ssh multiplexing - -14.3.0 -====== - -- PyZMQ no longer calls :meth:`.Socket.close` or :meth:`.Context.term` during process cleanup. -  Changes to garbage collection in Python 3.4 make this impossible to do sensibly. -- :meth:`ZMQStream.close` closes its socket immediately, rather than scheduling a timeout. -- Raise the original ImportError when importing zmq fails. -  Should be more informative than `no module cffi...`. - -.. warning:: - -    Users of Python 3.4 should not use pyzmq < 14.3, due to changes in garbage collection. - - -14.2.0 -====== - -New Stuff ---------- - -- Raise new ZMQVersionError when a requested method is not supported by the linked libzmq. -  For backward compatibility, this subclasses NotImplementedError. - - -Bugs Fixed ----------- - -- Memory leak introduced in pyzmq-14.0 in zero copy. -- OverflowError on 32 bit systems in zero copy. - - -14.1.0 -====== - -Security --------- - -The headline features for 14.1 are adding better support for libzmq's -security features. - -- When libzmq is bundled as a Python extension (e.g. wheels, eggs), -  libsodium is also bundled (excluding Windows), -  ensuring that libzmq security is available to users who install from wheels -- New :mod:`zmq.auth`, implementing zeromq's ZAP authentication, -  modeled on czmq zauth. -  For more information, see the `examples <https://github.com/zeromq/pyzmq/tree/master/examples/>`_. - - -Other New Stuff ---------------- - -- Add PYZMQ_BACKEND for enabling use of backends outside the pyzmq codebase. -- Add :attr:`~.Context.underlying` property and :meth:`~.Context.shadow` -  method to Context and Socket, for handing off sockets and contexts. -  between pyzmq and other bindings (mainly pyczmq_). -- Add TOS, ROUTER_HANDOVER, and IPC_FILTER constants from libzmq-4.1-dev. -- Add Context option support in the CFFI backend. -- Various small unicode and build fixes, as always. -- :meth:`~.Socket.send_json` and :meth:`~.Socket.recv_json` pass any extra kwargs to ``json.dumps/loads``. - - -.. _pyczmq: https://github.com/zeromq/pyczmq - - -Deprecations ------------- - -- ``Socket.socket_type`` is deprecated, in favor of ``Socket.type``, -  which has been available since 2.1. - - -14.0.1 -====== - -Bugfix release - -- Update bundled libzmq to current (4.0.3). -- Fix bug in :meth:`.Context.destroy` with no open sockets. -- Threadsafety fixes in the garbage collector. -- Python 3 fixes in :mod:`zmq.ssh`. - - -14.0.0 -====== - -* Update bundled libzmq to current (4.0.1). -* Backends are now implemented in ``zmq.backend`` instead of ``zmq.core``. -  This has no effect on public APIs. -* Various build improvements for Cython and CFFI backends (PyPy compiles at build time). -* Various GIL-related performance improvements - the GIL is no longer touched from a zmq IO thread. -* Adding a constant should now be a bit easier - only zmq/sugar/constant_names should need updating, -  all other constant-related files should be automatically updated by ``setup.py constants``. -* add support for latest libzmq-4.0.1 -  (includes ZMQ_CURVE security and socket event monitoring). - -New stuff ---------- - -- :meth:`.Socket.monitor` -- :meth:`.Socket.get_monitor_socket` -- :func:`zmq.curve_keypair` -- :mod:`zmq.utils.monitor` -- :mod:`zmq.utils.z85` - - -13.1.0 -====== - -The main new feature is improved tornado 3 compatibility. -PyZMQ ships a 'minitornado' submodule, which contains a small subset of tornado 3.0.1, -in order to get the IOLoop base class.  zmq.eventloop.ioloop.IOLoop is now a simple subclass, -and if the system tornado is ≥ 3.0, then the zmq IOLoop is a proper registered subclass -of the tornado one itself, and minitornado is entirely unused. - -13.0.2 -====== - -Bugfix release! - -A few things were broken in 13.0.0, so this is a quick bugfix release. - -* **FIXED** EAGAIN was unconditionally turned into KeyboardInterrupt -* **FIXED** we used totally deprecated ctypes_configure to generate constants in CFFI backend -* **FIXED** memory leak in CFFI backend for PyPy -* **FIXED** typo prevented IPC_PATH_MAX_LEN from ever being defined -* **FIXED** various build fixes - linking with librt, Cython compatibility, etc. - -13.0.1 -====== - -defunct bugfix. We do not speak of this... - -13.0.0 -====== - -PyZMQ now officially targets libzmq-3 (3.2.2), -0MQ ≥ 2.1.4 is still supported for the indefinite future, but 3.x is recommended. -PyZMQ has detached from libzmq versioning, -and will just follow its own regular versioning scheme from now on. -PyZMQ bdists will include whatever is the latest stable libzmq release (3.2.2 for pyzmq-13.0). - -.. note:: - -    set/get methods are exposed via get/setattr on all Context, Socket, and Frame classes. -    This means that subclasses of these classes that require extra attributes -    **must declare these attributes at the class level**. - -Experiments Removed -------------------- - -* The Threadsafe ZMQStream experiment in 2.2.0.1 was deemed inappropriate and not useful, -  and has been removed. -* The :mod:`zmq.web` experiment has been removed, -  to be developed as a `standalone project <https://github.com/ellisonbg/zmqweb>`_. - -New Stuff ---------- - -* Support for PyPy via CFFI backend (requires py, ctypes-configure, and cffi). -* Add support for new APIs in libzmq-3 - -  - :meth:`.Socket.disconnect` -  - :meth:`.Socket.unbind` -  - :meth:`.Context.set` -  - :meth:`.Context.get` -  - :meth:`.Frame.set` -  - :meth:`.Frame.get` -  - :func:`zmq.proxy` -  - :class:`zmq.devices.Proxy` -  - Exceptions for common zmq errnos: :class:`zmq.Again`, :class:`zmq.ContextTerminated` -    (subclass :class:`ZMQError`, so fully backward-compatible). -   - -* Setting and getting :attr:`.Socket.hwm` sets or gets *both* SNDHWM/RCVHWM for libzmq-3. -* Implementation splits core Cython bindings from pure-Python subclasses -  with sugar methods (send/recv_multipart). This should facilitate -  non-Cython backends and PyPy support [spoiler: it did!]. - - -Bugs Fixed ----------- - -* Unicode fixes in log and monitored queue -* MinGW, ppc, cross-compilation, and HP-UX build fixes -* :mod:`zmq.green` should be complete - devices and tornado eventloop both work -  in gevent contexts. - - -2.2.0.1 -======= - -This is a tech-preview release, to try out some new features. -It is expected to be short-lived, as there are likely to be issues to iron out, -particularly with the new pip-install support. - -Experimental New Stuff ----------------------- - -These features are marked 'experimental', which means that their APIs are not set in stone, -and may be removed or changed in incompatible ways in later releases. - - -Threadsafe ZMQStream -******************** - -With the IOLoop inherited from tornado, there is exactly one method that is threadsafe: -:meth:`.IOLoop.add_callback`.  With this release, we are trying an experimental option -to pass all IOLoop calls via this method, so that ZMQStreams can be used from one thread -while the IOLoop runs in another.  To try out a threadsafe stream: - -.. sourcecode:: python - -    stream = ZMQStream(socket, threadsafe=True) - - -pip install pyzmq -***************** - -PyZMQ should now be pip installable, even on systems without libzmq. -In these cases, when pyzmq fails to find an appropriate libzmq to link against, -it will try to build libzmq as a Python extension. -This work is derived from `pyzmq_static <https://github.com/brandon-rhodes/pyzmq-static>`_. - -To this end, PyZMQ source distributions include the sources for libzmq (2.2.0) and libuuid (2.21), -both used under the LGPL. - - -zmq.green -********* - -The excellent `gevent_zeromq <https://github.com/traviscline/gevent_zeromq>`_ socket -subclass which provides `gevent <http://www.gevent.org/>`_ compatibility has been merged as -:mod:`zmq.green`. - -.. seealso:: - -    :ref:`zmq_green` - - -Bugs Fixed ----------- - -* TIMEO sockopts are properly included for libzmq-2.2.0 -* avoid garbage collection of sockets after fork (would cause ``assert (mailbox.cpp:79)``). - - -2.2.0 -===== - -Some effort has gone into refining the pyzmq API in this release to make it a model for  -other language bindings.  This is principally made in a few renames of objects and methods, -all of which leave the old name for backwards compatibility. - -.. note:: - -    As of this release, all code outside ``zmq.core`` is BSD licensed (where -    possible), to allow more permissive use of less-critical code and utilities. - -Name Changes ------------- - -* The :class:`~.Message` class has been renamed to :class:`~.Frame`, to better match other -  zmq bindings. The old Message name remains for backwards-compatibility.  Wherever pyzmq -  docs say "Message", they should refer to a complete zmq atom of communication (one or -  more Frames, connected by ZMQ_SNDMORE). Please report any remaining instances of -  Message==MessagePart with an Issue (or better yet a Pull Request). - -* All ``foo_unicode`` methods are now called ``foo_string`` (``_unicode`` remains for -  backwards compatibility).  This is not only for cross-language consistency, but it makes -  more sense in Python 3, where native strings are unicode, and the ``_unicode`` suffix -  was wedded too much to Python 2. - -Other Changes and Removals --------------------------- - -* ``prefix`` removed as an unused keyword argument from :meth:`~.Socket.send_multipart`. - -* ZMQStream :meth:`~.ZMQStream.send` default has been changed to `copy=True`, so it matches -  Socket :meth:`~.Socket.send`. - -* ZMQStream :meth:`~.ZMQStream.on_err` is deprecated, because it never did anything. - -* Python 2.5 compatibility has been dropped, and some code has been cleaned up to reflect -  no-longer-needed hacks. - -* Some Cython files in :mod:`zmq.core` have been split, to reduce the amount of  -  Cython-compiled code.  Much of the body of these files were pure Python, and thus did -  not benefit from the increased compile time.  This change also aims to ease maintaining -  feature parity in other projects, such as  -  `pyzmq-ctypes <https://github.com/svpcom/pyzmq-ctypes>`_. - - -New Stuff ---------- - -* :class:`~.Context` objects can now set default options when they create a socket. These -  are set and accessed as attributes to the context.  Socket options that do not apply to a -  socket (e.g. SUBSCRIBE on non-SUB sockets) will simply be ignored. - -* :meth:`~.ZMQStream.on_recv_stream` has been added, which adds the stream itself as a -  second argument to the callback, making it easier to use a single callback on multiple -  streams. - -* A :attr:`~Frame.more` boolean attribute has been added to the :class:`~.Frame` (née -  Message) class, so that frames can be identified as terminal without extra queires of -  :attr:`~.Socket.rcvmore`. - - -Experimental New Stuff ----------------------- - -These features are marked 'experimental', which means that their APIs are not -set in stone, and may be removed or changed in incompatible ways in later releases. - -* :mod:`zmq.web` added for load-balancing requests in a tornado webapp with zeromq. - - -2.1.11 -====== - -* remove support for LABEL prefixes.  A major feature of libzmq-3.0, the LABEL -  prefix, has been removed from libzmq, prior to the first stable libzmq 3.x release. -   -  * The prefix argument to :meth:`~.Socket.send_multipart` remains, but it continue to behave in -    exactly the same way as it always has on 2.1.x, simply prepending message parts. -   -  * :meth:`~.Socket.recv_multipart` will always return a list, because prefixes are once -    again indistinguishable from regular message parts. - -* add :meth:`.Socket.poll` method, for simple polling of events on a single socket. - -* no longer require monkeypatching tornado IOLoop.  The :class:`.ioloop.ZMQPoller` class -  is a poller implementation that matches tornado's expectations, and pyzmq sockets can -  be used with any tornado application just by specifying the use of this poller.  The -  pyzmq IOLoop implementation now only trivially differs from tornado's. - -  It is still recommended to use :func:`.ioloop.install`, which sets *both* the zmq and -  tornado global IOLoop instances to the same object, but it is no longer necessary. - -  .. warning:: - -    The most important part of this change is that the ``IOLoop.READ/WRITE/ERROR`` -    constants now match tornado's, rather than being mapped directly to the zmq -    ``POLLIN/OUT/ERR``. So applications that used the low-level :meth:`IOLoop.add_handler` -    code with ``POLLIN/OUT/ERR`` directly (used to work, but was incorrect), rather than -    using the IOLoop class constants will no longer work. Fixing these to use the IOLoop -    constants should be insensitive to the actual value of the constants. - -2.1.10 -====== - -* Add support for libzmq-3.0 LABEL prefixes: - -  .. warning:: - -    This feature has been removed from libzmq, and thus removed from future pyzmq -    as well. - -  * 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. -* Fixed an issue that prevented :exc:`KeyboardInterrupts` from being catchable. -* Added attribute-access for set/getsockopt.  Setting/Getting attributes of :class:`Sockets` -  with the names of socket options is mapped to calls of set/getsockopt. - -.. sourcecode:: python - -    s.hwm = 10 -    s.identity = b'whoda' -    s.linger -    # -1 -     -* Terminating a :class:`~Context` closes the sockets it created, matching the behavior in -  `czmq <http://czmq.zeromq.org/>`_. -* :class:`ThreadDevices` use :meth:`Context.instance` to create sockets, so they can use -  inproc connections to sockets in other threads. -* fixed units error on :func:`zmq.select`, where the poll timeout was 1000 times longer -  than expected. -* Add missing ``DEALER/ROUTER`` socket type names (currently aliases, to be replacements for ``XREP/XREQ``). -* base libzmq dependency raised to 2.1.4 (first stable release) from 2.1.0. - - -2.1.7.1 -======= - -* bdist for 64b Windows only.  This fixed a type mismatch on the ``ZMQ_FD`` sockopt -  that only affected that platform. - - -2.1.7 -===== - -* Added experimental support for libzmq-3.0 API -* Add :func:`zmq.eventloop.ioloop.install` for using pyzmq's IOLoop in a tornado -  application. - - -2.1.4 -===== - -* First version with binary distribution support -* Added :meth:`~Context.instance()` method for using a single Context throughout an application -  without passing references around. - diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index 0761991..0000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,209 +0,0 @@ -# -*- coding: utf-8 -*- -# -# PyZMQ documentation build configuration file, created by -# sphinx-quickstart on Sat Feb 20 23:31:19 2010. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os -import string - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0,os.path.abspath('../sphinxext')) - -# patch autodoc to work with Cython Sources -import sphinx_cython - -# -- General configuration ----------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ -              'sphinx.ext.autodoc', -              'sphinx.ext.doctest', -              'sphinx.ext.intersphinx', -              'ipython_console_highlighting', -              'numpydoc', -              ] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -source_encoding = 'utf-8' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'PyZMQ' -copyright = u"""2013, Brian E. Granger & Min Ragan-Kelley.   -ØMQ logo © iMatix Corportation, used under the Creative Commons Attribution-Share Alike 3.0 License.   -Python logo ™ of the Python Software Foundation, used by Min RK with permission from the Foundation""" - -intersphinx_mapping = {'python': ('http://docs.python.org/', None)} -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. - -import zmq - -# The short X.Y version. -version = zmq.__version__.split('-')[0] -# The full version, including alpha/beta/rc tags. -release = zmq.__version__ - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of documents that shouldn't be included in the build. -#unused_docs = [] - -# List of directories, relative to source directory, that shouldn't be searched -# for source files. -exclude_trees = ['build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages.  Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -html_theme = 'default' - -# Theme options are theme-specific and customize the look and feel of a theme -# further.  For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents.  If None, it defaults to -# "<project> v<release> documentation". -#html_title = None - -# A shorter title for the navigation bar.  Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -html_favicon = 'zeromq.ico' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_use_modindex = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a <link> tag referring to it.  The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'PyZMQdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ -  ('index', 'PyZMQ.tex', u'PyZMQ Documentation', -   u'Brian E. Granger \\and Min Ragan-Kelley', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_use_modindex = True diff --git a/docs/source/devices.rst b/docs/source/devices.rst deleted file mode 100644 index 4ef70ce..0000000 --- a/docs/source/devices.rst +++ /dev/null @@ -1,82 +0,0 @@ -.. PyZMQ devices doc, by Min Ragan-Kelley, 2011 - -.. _devices: - -Devices in PyZMQ -================ - -.. seealso:: - -    ØMQ Guide `Device coverage <http://zguide.zeromq.org/chapter:all#toc32>`_. - -ØMQ has a notion of Devices - simple programs that manage a send-recv pattern for -connecting two or more sockets. Being full programs, devices include a ``while(True)`` -loop and thus block execution permanently once invoked. We have provided in the -:mod:`devices` subpackage some facilities for running these devices in the background, as -well as a custom three-socket MonitoredQueue_ device. - - -BackgroundDevices ------------------ - -It seems fairly rare that in a Python program one would actually want to create a zmq -device via :func:`.device` in the main thread, since such a call would block execution -forever. The most likely model for launching devices is in background threads or -processes. We have provided classes for launching devices in a background thread with -:class:`.ThreadDevice` and via multiprocessing with :class:`.ProcessDevice`. For -threadsafety and running across processes, these methods do not take Socket objects as -arguments, but rather socket types, and then the socket creation and configuration happens -via the BackgroundDevice's :meth:`foo_in` proxy methods. For each configuration method -(bind/connect/setsockopt), there are proxy methods for calling those methods on the Socket -objects created in the background thread or process, prefixed with 'in\_' or 'out\_', -corresponding to the `in_socket` and `out_socket`:: - -    from zmq.devices import ProcessDevice -     -    pd = ProcessDevice(zmq.QUEUE, zmq.ROUTER, zmq.DEALER) -    pd.bind_in('tcp://*:12345') -    pd.connect_out('tcp://127.0.0.1:12543') -    pd.setsockopt_in(zmq.IDENTITY, 'ROUTER') -    pd.setsockopt_out(zmq.IDENTITY, 'DEALER') -    pd.start() -    # it will now be running in a background process - -MonitoredQueue --------------- - -One of ØMQ's builtin devices is the ``QUEUE``. This is a symmetric two-socket device that -fully supports passing messages in either direction via any pattern. We saw a logical -extension of the ``QUEUE`` as one that behaves in the same way with respect to the in/out -sockets, but also sends every message in either direction *also* on a third `monitor` -socket. For performance reasons, this :func:`.monitored_queue` function is written in -Cython, so the loop does not involve Python, and should have the same performance as the -basic ``QUEUE`` device. - -One shortcoming of the ``QUEUE`` device is that it does not support having ``ROUTER`` -sockets as both input and output. This is because ``ROUTER`` sockets, when they receive a -message, prepend the ``IDENTITY`` of the socket that sent the message (for use in routing -the reply). The result is that the output socket will always try to route the incoming -message back to the original sender, which is presumably not the intended pattern. In -order for the queue to support a ROUTER-ROUTER connection, it must swap the first two parts -of the message in order to get the right message out the other side. - -To invoke a monitored queue is similar to invoking a regular ØMQ device:: - -    from zmq.devices import monitored_queue -    ins = ctx.socket(zmq.ROUTER) -    outs = ctx.socket(zmq.DEALER) -    mons = ctx.socket(zmq.PUB) -    configure_sockets(ins,outs,mons) -    monitored_queue(ins, outs, mons, in_prefix='in', out_prefix='out') - -The `in_prefix` and `out_prefix` default to 'in' and 'out' respectively, and a PUB socket -is most logical for the monitor socket, since it will never receive messages, and the -in/out prefix is well suited to the PUB/SUB topic subscription model. All messages sent on -`mons` will be multipart, the first part being the prefix corresponding to the socket that -received the message. - -Or for launching an MQ in the background, there are :class:`.ThreadMonitoredQueue` and -:class:`.ProcessMonitoredQueue`, which function just like the base -BackgroundDevice objects, but add :meth:`foo_mon` methods for configuring the monitor socket. - - diff --git a/docs/source/eventloop.rst b/docs/source/eventloop.rst deleted file mode 100644 index 3126b8b..0000000 --- a/docs/source/eventloop.rst +++ /dev/null @@ -1,197 +0,0 @@ -.. PyZMQ eventloop doc, by Min Ragan-Kelley, 2011 - -.. _eventloop: - -==================== -Eventloops and PyZMQ -==================== - -Tornado IOLoop -============== - -Facebook's `Tornado`_ includes an eventloop for handing poll events on filedescriptors and -native sockets. We have included a small part of Tornado (specifically its -:mod:`.ioloop`), and adapted its :class:`IOStream` class into :class:`.ZMQStream` for -handling poll events on ØMQ sockets. A ZMQStream object works much like a Socket object, -but instead of calling :meth:`~.Socket.recv` directly, you register a callback with -:meth:`~.ZMQStream.on_recv`. Callbacks can also be registered for send events -with :meth:`~.ZMQStream.on_send`. - - -:func:`install()` ------------------ - -With PyZMQ's ioloop, you can use zmq sockets in any tornado application.  You must first -install PyZMQ's :class:`.IOLoop`, with the :func:`.ioloop.install` function: - -.. sourcecode:: python - -    from zmq.eventloop import ioloop -    ioloop.install() - -This sets the global instance of :class:`tornado.ioloop.IOLoop` with the global instance of -our IOLoop class. The reason this must happen is that tornado objects avoid having to pass -the active IOLoop instance around by having a staticmethod :meth:`.IOLoop.instance`, which -always returns the active instance. If PyZMQ's IOLoop is installed after the first call to -:meth:`.IOLoop.instance()` (called in almost every tornado object constructor), then it will -raise an :exc:`AssertionError`, because the global IOLoop instance has already been -created, and proceeding would result in not all objects being associated with the right -IOLoop. - -It is possible to use PyZMQ sockets with tornado *without* calling :func:`.ioloop.install`, -but it is less convenient. First, you must instruct the tornado IOLoop to use the zmq poller: - -.. sourcecode:: python - -    from zmq.eventloop.ioloop import ZMQIOLoop -     -    loop = ZMQIOLoop() - -Then, when you instantiate tornado and ZMQStream objects, you must pass the `io_loop` -argument to ensure that they use this loop, instead of the global instance. - -This is especially useful for writing tests, such as this: - -.. sourcecode:: python - -    from tornado.testing import AsyncTestCase -    from zmq.eventloop.ioloop import ZMQIOLoop -    from zmq.eventloop.zmqstream import ZMQStream - -    class TestZMQBridge(AsyncTestCase): - -         # Use a ZMQ-compatible I/O loop so that we can use `ZMQStream`. -         def get_new_ioloop(self): -             return ZMQIOLoop() - -You can also manually install this IOLoop as the global tornado instance, with: - -.. sourcecode:: python - -    from zmq.eventloop.ioloop import ZMQIOLoop -    loop = ZMQIOLoop() -    loop.install() - -but it will **NOT** be the global *pyzmq* IOLoop instance, so it must still be -passed to your ZMQStream constructors. - - -:meth:`send` ------------- - -ZMQStream objects do have :meth:`~.ZMQStream.send` and :meth:`~.ZMQStream.send_multipart` -methods, which behaves the same way as :meth:`.Socket.send`, but instead of sending right -away, the :class:`.IOLoop` will wait until socket is able to send (for instance if ``HWM`` -is met, or a ``REQ/REP`` pattern prohibits sending at a certain point). Messages sent via -send will also be passed to the callback registered with :meth:`~.ZMQStream.on_send` after -sending. - -:meth:`on_recv` ---------------- - -:meth:`.ZMQStream.on_recv` is the primary method for using a ZMQStream. It registers a -callback to fire with messages as they are received, which will *always* be multipart, -even if its length is 1. You can easily use this to build things like an echo socket: - -.. sourcecode:: python - -    s = ctx.socket(zmq.REP) -    s.bind('tcp://localhost:12345') -    stream = ZMQStream(s) -    def echo(msg): -        stream.send_multipart(msg) -    stream.on_recv(echo) -    ioloop.IOLoop.instance().start() - -on_recv can also take a `copy` flag, just like :meth:`.Socket.recv`. If `copy=False`, then -callbacks registered with on_recv will receive tracked :class:`.Frame` objects instead of -bytes. - -.. note:: - -    A callback must be registered using either :meth:`.ZMQStream.on_recv` or -    :meth:`.ZMQStream.on_recv_stream` before any data will be received on the -    underlying socket.  This allows you to temporarily pause processing on a -    socket by setting both callbacks to None.  Processing can later be resumed -    by restoring either callback. - - -:meth:`on_recv_stream` ----------------------- - -:meth:`.ZMQStream.on_recv_stream` is just like on_recv above, but the callback will be  -passed both the message and the stream, rather than just the message.  This is meant to make -it easier to use a single callback with multiple streams. - -.. sourcecode:: python - -    s1 = ctx.socket(zmq.REP) -    s1.bind('tcp://localhost:12345') -    stream1 = ZMQStream(s1) -     -    s2 = ctx.socket(zmq.REP) -    s2.bind('tcp://localhost:54321') -    stream2 = ZMQStream(s2) -     -    def echo(stream, msg): -        stream.send_multipart(msg) -     -    stream1.on_recv_stream(echo) -    stream2.on_recv_stream(echo) -     -    ioloop.IOLoop.instance().start() - - -:meth:`flush` -------------- - -Sometimes with an eventloop, there can be multiple events ready on a single iteration of -the loop. The :meth:`~.ZMQStream.flush` method allows developers to pull messages off of -the queue to enforce some priority over the event loop ordering. flush pulls any pending -events off of the queue. You can specify to flush only recv events, only send events, or -any events, and you can specify a limit for how many events to flush in order to prevent -starvation. - -.. _Tornado: https://github.com/facebook/tornado - -.. _zmq_green: - -PyZMQ and gevent -================ - -PyZMQ ≥ 2.2.0.1 ships with a `gevent <http://www.gevent.org/>`_ compatible API as :mod:`zmq.green`. -To use it, simply: - -.. sourcecode:: python - -    import zmq.green as zmq - -Then write your code as normal. - -Socket.send/recv and zmq.Poller are gevent-aware. - -In PyZMQ ≥ 2.2.0.2, green.device and green.eventloop should be gevent-friendly as well. - -.. note:: - -    The green device does *not* release the GIL, unlike the true device in zmq.core. - -zmq.green.eventloop includes minimally patched IOLoop/ZMQStream in order to use the gevent-enabled Poller, -so you should be able to use the ZMQStream interface in gevent apps as well, -though using two eventloops simultaneously (tornado + gevent) is not recommended. - -.. warning:: - -    There is a `known issue <https://github.com/zeromq/pyzmq/issues/229>`_ in gevent ≤ 1.0 or libevent, -    which can cause zeromq socket events to be missed. -    PyZMQ works around this by adding a timeout so it will not wait forever for gevent to notice events. -    The only known solution for this is to use gevent ≥ 1.0, which is currently at 1.0b3, -    and does not exhibit this behavior. - -.. seealso:: - -    zmq.green examples `on GitHub <https://github.com/zeromq/pyzmq/tree/master/examples/gevent>`_. - -:mod:`zmq.green` is simply `gevent_zeromq <https://github.com/traviscline/gevent_zeromq>`_, -merged into the pyzmq project. - diff --git a/docs/source/index.rst b/docs/source/index.rst deleted file mode 100644 index f32c90d..0000000 --- a/docs/source/index.rst +++ /dev/null @@ -1,95 +0,0 @@ -.. PyZMQ documentation master file, created by -   sphinx-quickstart on Sat Feb 20 23:31:19 2010. -   You can adapt this file completely to your liking, but it should at least -   contain the root `toctree` directive. - -PyZMQ Documentation -=================== - -:Release: |release| -:Date: |today| - - -PyZMQ is the Python bindings for ØMQ_. This -documentation currently contains notes on some important aspects of developing PyZMQ and -an overview of what the ØMQ API looks like in Python. For information on how to use -ØMQ in general, see the many examples in the excellent `ØMQ Guide`_, all of which -have a version in Python. - -PyZMQ works with Python 3 (≥ 3.2), and Python 2 (≥ 2.6), with no transformations or 2to3, -as well as PyPy (at least 2.0 beta), thanks to a new CFFI backend. - -Please don't hesitate to report pyzmq-specific issues to our tracker_ on GitHub. -General questions about ØMQ are better sent to the ØMQ `mailing list`_ or `IRC Channel`_. - -:ref:`Summary of Changes in PyZMQ <changelog>` - - -Supported LibZMQ -================ - -PyZMQ aims to support all stable ( ≥2.1.4, ≥ 3.2.2, ≥ 4.0.1 ) and active development ( ≥ 4.1.0 ) -versions of libzmq.  Building the same pyzmq against various versions of libzmq is supported, -but only the functionality of the linked libzmq will be available. - -.. note:: - -    libzmq 3.0-3.1 are not, and will never be supported. -    There never was a stable release of either. - - -Binary distributions (eggs, MSIs, and wheels on `PyPI <http://pypi.python.org/pypi/pyzmq>`__ -or `GitHub <https://www.github.com/zeromq/pyzmq/downloads>`__) of PyZMQ ship with -the stable version of libzmq at the time of release, built with default configuration. -For pyzmq-|release|, this is 4.0.3. - -Using PyZMQ -=========== - -.. toctree:: -    :maxdepth: 2 -     -    api/index.rst -    morethanbindings.rst -    serialization.rst -    devices.rst -    eventloop.rst -    logging.rst -    ssh.rst -     - -Notes from developing PyZMQ -=========================== - -.. toctree:: -    :maxdepth: 2 -     -    pyversions.rst -    unicode.rst - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -Links -===== - -* ØMQ_ Home -* The `ØMQ Guide`_ -* `PyZMQ Installation`_ notes on the ZeroMQ website -* PyZMQ on GitHub_ -* Issue Tracker_ - -.. _ØMQ: http://www.zeromq.org -.. _ØMQ Guide: http://zguide.zeromq.org -.. _mailing list: http://www.zeromq.org/docs:mailing-lists -.. _IRC Channel: http://www.zeromq.org/chatroom -.. _Cython: http://cython.org/ -.. _GitHub: https://www.github.com/zeromq/pyzmq -.. _ØMQ Manual: http://www.zeromq.org/intro:read-the-manual -.. _PyZMQ Installation: http://www.zeromq.org/bindings:python -.. _tracker: https://www.github.com/zeromq/pyzmq/issues - diff --git a/docs/source/logging.rst b/docs/source/logging.rst deleted file mode 100644 index ea16da3..0000000 --- a/docs/source/logging.rst +++ /dev/null @@ -1,84 +0,0 @@ -.. PyZMQ logging doc, by Min Ragan-Kelley, 2011 - -.. _logging: - -Asynchronous Logging via PyZMQ -============================== - -.. seealso:: - -    * The ØMQ guide `coverage <http://zguide.zeromq.org/chapter:all#toc7>`_ of PUB/SUB -      messaging -    * Python logging module `documentation <http://docs.python.org/library/logging.html>`_ - -Python provides extensible logging facilities through its :py:mod:`logging` module. This -module allows for easily extensible logging functionality through the use of -:py:class:`~logging.Handler` objects. The most obvious case for hooking up pyzmq to -logging would be to broadcast log messages over a PUB socket, so we have provides a -:class:`.PUBHandler` class for doing just that. - -PUB/SUB and Topics ------------------- - -The ØMQ PUB/SUB pattern consists of a PUB socket broadcasting messages, and a collection -of SUB sockets that receive those messages. Each PUB message is a multipart-message, where -the first part is interpreted as a topic. SUB sockets can subscribe to topics by setting -their ``SUBSCRIBE`` sockopt, e.g.:: - -    sub = ctx.socket(zmq.SUB) -    sub.setsockopt(zmq.SUBSCRIBE, 'topic1') -    sub.setsockopt(zmq.SUBSCRIBE, 'topic2') - -When subscribed, the SUB socket will only receive messages where the first part *starts -with* one of the topics set via ``SUBSCRIBE``. The default behavior is to exclude all -messages, and subscribing to the empty string '' will receive all messages. - -PUBHandler ----------- - -The :class:`.PUBHandler` object is created for allowing the python logging to be emitted -on a PUB socket. The main difference between a PUBHandler and a regular logging Handler is -the inclusion of topics. For the most basic logging, you can simply create a PUBHandler -with an interface or a configured PUB socket, and just let it go:: - -    pub = context.socket(zmq.PUB) -    pub.bind('tcp://*:12345') -    handler = PUBHandler(pub) -    logger = logging.getLogger() -    logger.addHandler(handler) - -At this point, all messages logged with the default logger will be broadcast on the pub -socket. - -the PUBHandler does work with topics, and the handler has an attribute ``root_topic``:: - -    handler.root_topic = 'myprogram' - -Python loggers also have loglevels. The base topic of messages emitted by the PUBHandler -will be of the form: ``<handler.root_topic>.<loglevel>``, e.g. 'myprogram.INFO' or -'whatever.ERROR'. This way, subscribers can easily subscribe to subsets of the logging -messages. Log messages are always two-part, where the first part is the topic tree, and -the second part is the actual log message. - -    >>> logger.info('hello there') -    >>> print sub.recv_multipart() -    ['myprogram.INFO', 'hello there'] - -Subtopics -********* - -You can also add to the topic tree below the loglevel on an individual message basis. -Assuming your logger is connected to a PUBHandler, you can add as many additional topics -on the front of the message, which will be added always after the loglevel. A special -delimiter defined at ``zmq.log.handlers.TOPIC_DELIM`` is scanned by the PUBHandler, so if -you pass your own subtopics prior to that symbol, they will be stripped from the message -and added to the topic tree:: - -    >>> log_msg  = "hello there" -    >>> subtopic = "sub.topic" -    >>> msg = zmq.log.handlers.TOPIC_DELIM.join([subtopic, log_msg]) -    >>> logger.warn(msg) -    >>> print sub.recv_multipart() -    ['myprogram.WARN.sub.topic', 'hello there'] - - diff --git a/docs/source/morethanbindings.rst b/docs/source/morethanbindings.rst deleted file mode 100644 index 1bff8f0..0000000 --- a/docs/source/morethanbindings.rst +++ /dev/null @@ -1,166 +0,0 @@ -.. PyZMQ Bindings doc, by Min Ragan-Kelley, 2011 - -.. _bindings: - -More Than Just Bindings -======================= - -PyZMQ is ostensibly the Python bindings for `ØMQ`_, but the project, following -Python's 'batteries included' philosophy, provides more than just Python methods and -objects for calling into the ØMQ C++ library. - - - -The Core as Bindings --------------------- - -PyZMQ is currently broken up into four subpackages. First, is the Core. :mod:`zmq.core` -contains the actual bindings for ZeroMQ, and no extended functionality beyond the very -basic. The core modules are split, such that each basic ZeroMQ object (or function, if no -object is associated) is a separate module, e.g. :mod:`zmq.core.context` contains the -:class:`.Context` object, :mod:`zmq.core.poll` contains a :class:`.Poller` object, as well -as the :func:`.select` function, etc. ZMQ constants are, for convenience, all kept -together in :mod:`zmq.core.constants`. - -There are two reasons for breaking the core into submodules: *recompilation* and -*derivative projects*. The monolithic PyZMQ became quite tedious to have to recompile -everything for a small change to a single object. With separate files, that's no longer -necessary. The second reason has to do with Cython. PyZMQ is written in Cython, a tool for -efficiently writing C-extensions for Python. By separating out our objects into individual -`pyx` files, each with their declarations in a `pxd` header, other projects can write -extensions in Cython and call directly to ZeroMQ at the C-level without the penalty of -going through our Python objects. - -Thread Safety -------------- - -In ØMQ, Contexts are threadsafe objects, but Sockets are **not**. It is safe to use a -single Context (e.g. via :meth:`zmq.Context.instance`) in your entire multithreaded -application, but you should create sockets on a per-thread basis. If you share sockets -across threads, you are likely to encounter uncatchable c-level crashes of your -application unless you use judicious application of :py:class:`threading.Lock`, but this -approach is not recommended. - -.. seealso:: - -    ZeroMQ API note on threadsafety on `2.2 <http://api.zeromq.org/2-2:zmq>`_ -    or `3.2 <http://api.zeromq.org/3-2:zmq>`_ - - -Socket Options as Attributes ----------------------------- - -.. versionadded:: 2.1.9 - -In 0MQ, socket options are set/retrieved with the :meth:`set/getsockopt` methods. With the -class-based approach in pyzmq, it would be logical to perform these operations with -simple attribute access, and this has been added in pyzmq 2.1.9. Simply assign to or -request a Socket attribute with the (case-insensitive) name of a sockopt, and it should -behave just as you would expect: - -.. sourcecode:: python - -    s = ctx.socket(zmq.DEALER) -    s.identity = b'dealer' -    s.hwm = 10 -    s.events -    # 0 -    s.fd -    # 16 - - -Default Options on the Context -****************************** - -.. versionadded:: 2.1.11 - -Just like setting socket options as attributes on Sockets, you can do the same on Contexts. -This affects the default options of any *new* sockets created after the assignment. - -.. sourcecode:: python - -    ctx = zmq.Context() -    ctx.linger = 0 -    rep = ctx.socket(zmq.REP) -    req = ctx.socket(zmq.REQ) - -Socket options that do not apply to a socket (e.g. SUBSCRIBE on non-SUB sockets) will -simply be ignored. - - -Core Extensions ---------------- - -We have extended the core functionality in two ways that appear inside the :mod:`core` -bindings, and are not general ØMQ features. - -Builtin Serialization -********************* - -First, we added common serialization with the builtin :py:mod:`json` and :py:mod:`pickle` -as first-class methods to the :class:`Socket` class. A socket has the methods -:meth:`~.Socket.send_json` and :meth:`~.Socket.send_pyobj`, which correspond to sending an -object over the wire after serializing with :mod:`json` and :mod:`pickle` respectively, -and any object sent via those methods can be reconstructed with the -:meth:`~.Socket.recv_json` and :meth:`~.Socket.recv_pyobj` methods. Unicode strings are -other objects that are not unambiguously sendable over the wire, so we include -:meth:`~.Socket.send_string` and :meth:`~.Socket.recv_string` that simply send bytes -after encoding the message ('utf-8' is the default).  - -.. seealso:: - -    * :ref:`Further information <serialization>` on serialization in pyzmq. -     -    * :ref:`Our Unicode discussion <unicode>` for more information on the trials and -      tribulations of working with Unicode in a C extension while supporting Python 2 and 3. - - -MessageTracker -************** - -The second extension of basic ØMQ functionality is the :class:`MessageTracker`. The -MessageTracker is an object used to track when the underlying ZeroMQ is done with a -message buffer. One of the main use cases for ØMQ in Python is the ability to perform -non-copying sends. Thanks to Python's buffer interface, many objects (including NumPy -arrays) provide the buffer interface, and are thus directly sendable. However, as with any -asynchronous non-copying messaging system like ØMQ or MPI, it can be important to know -when the message has actually been sent, so it is safe again to edit the buffer without -worry of corrupting the message. This is what the MessageTracker is for. - -The MessageTracker is a simple object, but there is a penalty to its use. Since by its -very nature, the MessageTracker must involve threadsafe communication (specifically a -builtin :py:class:`~Queue.Queue` object), instantiating a MessageTracker takes a modest -amount of time (10s of µs), so in situations instantiating many small messages, this can -actually dominate performance. As a result, tracking is optional, via the ``track`` flag, -which is optionally passed, always defaulting to ``False``, in each of the three places -where a Frame object (the pyzmq object for wrapping a segment of a message) is  -instantiated: The :class:`.Frame` constructor, and non-copying sends and receives. - -A MessageTracker is very simple, and has just one method and one attribute. The property -:attr:`MessageTracker.done` will be ``True`` when the Frame(s) being tracked are no -longer in use by ØMQ, and :meth:`.MessageTracker.wait` will block, waiting for the -Frame(s) to be released. - -.. Note:: - -    A Frame cannot be tracked after it has been instantiated without tracking. If a -    Frame is to even have the *option* of tracking, it must be constructed with -    ``track=True``. - - -Extensions ----------- - -So far, PyZMQ includes four extensions to core ØMQ that we found basic enough to be -included in PyZMQ itself: - -* :ref:`zmq.log <logging>` : Logging handlers for hooking Python logging up to the -  network -* :ref:`zmq.devices <devices>` : Custom devices and objects for running devices in the  -  background -* :ref:`zmq.eventloop <eventloop>` : The `Tornado`_ event loop, adapted for use  -  with ØMQ sockets. -* :ref:`zmq.ssh <ssh>` : Simple tools for tunneling zeromq connections via ssh. - -.. _ØMQ: http://www.zeromq.org -.. _Tornado: https://github.com/facebook/tornado diff --git a/docs/source/pyversions.rst b/docs/source/pyversions.rst deleted file mode 100644 index 8a509dc..0000000 --- a/docs/source/pyversions.rst +++ /dev/null @@ -1,195 +0,0 @@ -.. PyZMQ Version compatibility doc, by Min Ragan-Kelley, 2010 - -.. _pyversions: - -PyZMQ, Python2.5, and Python3 -============================= - -PyZMQ is a fairly light, low-level library, so supporting as many versions -as is reasonable is our goal.  Currently, we support at least Python 2.5-3.1. -Making the changes to the codebase required a few tricks, which are documented here -for future reference, either by us or by other developers looking to support several -versions of Python. - -.. Note:: - -    It is far simpler to support 2.6-3.x than to include 2.5. Many of the significant -    syntax changes have been backported to 2.6, so just writing new-style code would work -    in many cases. I will try to note these points as they come up. - - -pyversion_compat.h ------------------- - -Many functions we use, primarily involved in converting between C-buffers and Python -objects, are not available on all supported versions of Python. In order to resolve -missing symbols, we added a header :file:`utils/pyversion_compat.h` that defines missing -symbols with macros. Some of these macros alias new names to old functions (e.g. -``PyBytes_AsString``), so that we can call new-style functions on older versions, and some -simply define the function as an empty exception raiser. The important thing is that the -symbols are defined to prevent compiler warnings and linking errors. Everywhere we use -C-API functions that may not be available in a supported version, at the top of the file -is the code: - -.. sourcecode:: guess - -    cdef extern from "pyversion_compat.h": -        pass - -This ensures that the symbols are defined in the Cython generated C-code. Higher level -switching logic exists in the code itself, to prevent actually calling unavailable -functions, but the symbols must still be defined. - -Bytes and Strings ------------------ - -.. Note:: - -    If you are using Python >= 2.6, to prepare your PyZMQ code for Python3 you should use -    the ``b'message'`` syntax to ensure all your string literal messages will still be -    :class:`bytes` after you make the upgrade. - -The most cumbersome part of PyZMQ compatibility from a user's perspective is the fact -that, since ØMQ uses C-strings, and would like to do so without copying, we must use the -Py3k :class:`bytes` object, which is backported to 2.6. In order to do this in a -Python-version independent way, we added a small utility that unambiguously defines the -string types: :class:`bytes`, :class:`unicode`, :obj:`basestring`. This is important, -because :class:`str` means different things on 2.x and 3.x, and :class:`bytes` is -undefined on 2.5, and both :class:`unicode` and :obj:`basestring` are undefined on 3.x. -All typechecking in PyZMQ is done against these types: - -=================  =================   ==================== -Explicit Type           2.x                      3.x -=================  =================   ==================== -:obj:`bytes`       :obj:`str`          :obj:`bytes` -:obj:`unicode`     :obj:`unicode`      :obj:`str` -:obj:`basestring`  :obj:`basestring`   :obj:`(str, bytes)` -=================  =================   ==================== - -.. Note:: -     -    2.5 specific - -    Where we really noticed the issue of :class:`bytes` vs :obj:`strings` coming up for -    users was in updating the tests to run on every version. Since the ``b'bytes -    literal'`` syntax was not backported to 2.5, we must call ``"message".encode()`` for -    *every* string in the test suite. - -.. seealso:: :ref:`Unicode discussion <unicode>` for more information on strings/bytes. - -``PyBytes_*`` -************* - -The standard C-API function for turning a C-string into a Python string was a set of -functions with the prefix ``PyString_*``. However, with the Unicode changes made in -Python3, this was broken into ``PyBytes_*`` for bytes objects and ``PyUnicode_*`` for -unicode objects. We changed all our ``PyString_*`` code to ``PyBytes_*``, which was -backported to 2.6. - - -.. Note:: - -    2.5 Specific: - -    Since Python 2.5 doesn't support the ``PyBytes_*`` functions, we had to alias them to -    the ``PyString_*`` methods in utils/pyversion_compat.h. - -    .. sourcecode:: c++ - -        #define PyBytes_FromStringAndSize PyString_FromStringAndSize -        #define PyBytes_FromString PyString_FromString -        #define PyBytes_AsString PyString_AsString -        #define PyBytes_Size PyString_Size - -Buffers -------- - -The layer that is most complicated for developers, but shouldn't trouble users, is the -Python C-Buffer APIs. These are the methods for converting between Python objects and C -buffers. The reason it is complicated is that it keeps changing. - -There are two buffer interfaces for converting an object to a C-buffer, known as new-style -and old-style. Old-style buffers were introduced long ago, but the new-style is only -backported to 2.6. The old-style buffer interface is not available in 3.x. There is also -an old- and new-style interface for creating Python objects that view C-memory. The -old-style object is called a :class:`buffer`, and the new-style object is -:class:`memoryview`. Unlike the new-style buffer interface for objects, -:class:`memoryview` has only been backported to *2.7*. This means that the available -buffer-related functions are not the same in any two versions of Python 2.5, 2.6, 2.7, or -3.1. - -We have a :file:`utils/buffers.pxd` file that defines our :func:`asbuffer` and -:func:`frombuffer` functions. :file:`utils/buffers.pxd` was adapted from mpi4py_'s -:file:`asbuffer.pxi`. The :func:`frombuffer` functionality was added. These functions -internally switch based on Python version to call the appropriate C-API functions. - -.. seealso:: `Python Buffer API <bufferapi>`_ - -.. _bufferapi: http://docs.python.org/c-api/buffer.html - - -``__str__`` ------------ - -As discussed, :class:`str` is not a platform independent type. The two places where we are -required to return native str objects are :func:`error.strerror`, and -:func:`Message.__str__`. In both of these cases, the natural return is actually a -:class:`bytes` object. In the methods, the native :class:`str` type is checked, and if the -native str is actually unicode, then we decode the bytes into unicode: - -.. sourcecode:: py - -    # ... -    b = natural_result() -    if str is unicode: -        return b.decode() -    else: -        return b - -Exceptions ----------- - -.. Note:: - -    This section is only relevant for supporting Python 2.5 and 3.x, not for 2.6-3.x. - -The syntax for handling exceptions has `changed <PEP-3110>`_ in Python 3.  The old syntax: - -.. sourcecode:: py - -    try: -        s.send(msg) -    except zmq.ZMQError, e: -        handle(e) - -is no longer valid in Python 3. Instead, the new syntax for this is: - -.. sourcecode:: py - -    try: -        s.send(msg) -    except zmq.ZMQError as e: -        handle(e) - -This new syntax is backported to Python 2.6, but is invalid on 2.5. For 2.6-3.x compatible -code, we could just use the new syntax. However, the only method we found to catch an -exception for handling on both 2.5 and 3.1 is to get the exception object inside the -exception block: - -.. sourcecode:: py - -    try: -        s.send(msg) -    except zmq.ZMQError: -        e = sys.exc_info()[1] -        handle(e) - -This is certainly not as elegant as either the old or new syntax, but it's the only way we -have found to work everywhere. - -.. seealso:: PEP-3110_ - -.. _PEP-3110: http://www.python.org/dev/peps/pep-3110/ - - -.. _mpi4py: http://mpi4py.googlecode.com
\ No newline at end of file diff --git a/docs/source/serialization.rst b/docs/source/serialization.rst deleted file mode 100644 index 8f9095a..0000000 --- a/docs/source/serialization.rst +++ /dev/null @@ -1,90 +0,0 @@ -.. PyZMQ serialization doc, by Min Ragan-Kelley, 2011 - -.. _serialization: - -Serializing messages with PyZMQ -=============================== - -When sending messages over a network, you often need to marshall your data into bytes. - - -Builtin serialization ---------------------- - -PyZMQ is primarily bindings for libzmq, but we do provide three builtin serialization -methods for convenience, to help Python developers learn libzmq. Python has two primary -packages for serializing objects: :py:mod:`json` and :py:mod:`pickle`, so we provide -simple convenience methods for sending and receiving objects serialized with these -modules. A socket has the methods :meth:`~.Socket.send_json` and -:meth:`~.Socket.send_pyobj`, which correspond to sending an object over the wire after -serializing with json and pickle respectively, and any object sent via those -methods can be reconstructed with the :meth:`~.Socket.recv_json` and -:meth:`~.Socket.recv_pyobj` methods. - - -These methods designed for convenience, not for performance, so developers who do want  -to emphasize performance should use their own serialized send/recv methods. - -Using your own serialization ----------------------------- - -In general, you will want to provide your own serialization that is optimized for your -application or library availability.  This may include using your own preferred -serialization ([msgpack]_, [protobuf]_), or adding compression via [zlib]_ in the standard -library, or the super fast [blosc]_ library. - -There are two simple models for implementing your own serialization: write a function -that takes the socket as an argument, or subclass Socket for use in your own apps. - -For instance, pickles can often be reduced substantially in size by compressing the data. -The following will send *compressed* pickles over the wire: - -.. sourcecode:: python - -    import zlib, cPickle as pickle - -    def send_zipped_pickle(socket, obj, flags=0, protocol=-1): -        """pickle an object, and zip the pickle before sending it""" -        p = pickle.dumps(obj, protocol) -        z = zlib.compress(p) -        return socket.send(z, flags=flags) - -    def recv_zipped_pickle(socket, flags=0, protocol=-1): -        """inverse of send_zipped_pickle""" -        z = socket.recv(flags) -        p = zlib.uncompress(z) -        return pickle.loads(p) - -A common data structure in Python is the numpy array.  PyZMQ supports sending -numpy arrays without copying any data, since they provide the Python buffer interface. -However just the buffer is not enough information to reconstruct the array on the -receiving side.  Here is an example of a send/recv that allow non-copying -sends/recvs of numpy arrays including the dtype/shape data necessary for reconstructing -the array. - -.. sourcecode:: python - -    import numpy - -    def send_array(socket, A, flags=0, copy=True, track=False): -        """send a numpy array with metadata""" -        md = dict( -            dtype = str(A.dtype), -            shape = A.shape, -        ) -        socket.send_json(md, flags|zmq.SNDMORE) -        return socket.send(A, flags, copy=copy, track=track) - -    def recv_array(socket, flags=0, copy=True, track=False): -        """recv a numpy array""" -        md = socket.recv_json(flags=flags) -        msg = socket.recv(flags=flags, copy=copy, track=track) -        buf = buffer(msg) -        A = numpy.frombuffer(buf, dtype=md['dtype']) -        return A.reshape(md['shape']) - - -.. [msgpack] Message Pack serialization library http://msgpack.org -.. [protobuf] Google Protocol Buffers http://code.google.com/p/protobuf -.. [zlib] Python stdlib module for zip compression: :py:mod:`zlib` -.. [blosc] Blosc: A blocking, shuffling and loss-less (and crazy-fast) compression library http://blosc.pytables.org/trac diff --git a/docs/source/ssh.rst b/docs/source/ssh.rst deleted file mode 100644 index ca2a607..0000000 --- a/docs/source/ssh.rst +++ /dev/null @@ -1,80 +0,0 @@ -.. PyZMQ ssh doc, by Min Ragan-Kelley, 2011 - -.. _ssh: - -Tunneling PyZMQ Connections with SSH -==================================== - -.. versionadded:: 2.1.9 - -You may want to connect ØMQ sockets across machines, or untrusted networks. One common way -to do this is to tunnel the connection via SSH. IPython_ introduced some tools for -tunneling ØMQ connections over ssh in simple cases. These functions have been brought into -pyzmq as :mod:`zmq.ssh` under IPython's BSD license. - -PyZMQ will use the shell ssh command via pexpect_ by default, but it also supports -using paramiko_ for tunnels, so it should work on Windows. - -.. note:: - -    pexpect has no Python3 support at this time, so Python 3 users should get Thomas -    Kluyver's `pexpect-u`_ fork. - -An SSH tunnel has five basic components: - -* server : the SSH server through which the tunnel will be created -* remote ip : the IP of the remote machine *as seen from the server*  -  (remote ip may be, but is not not generally the same machine as server). -* remote port : the port on the remote machine that you want to connect to. -* local ip : the interface on your local machine you want to use (default: 127.0.0.1) -* local port : the local port you want to forward to the remote port (default: high random) - -So once you have established the tunnel, connections to ``localip:localport`` will actually -be connections to ``remoteip:remoteport``. - -In most cases, you have a zeromq url for a remote machine, but you need to tunnel the -connection through an ssh server.  This is - -So if you would use this command from the same LAN as the remote machine: - -.. sourcecode:: python - -    sock.connect("tcp://10.0.1.2:5555") - -to make the same connection from another machine that is outside the network, but you have -ssh access to a machine ``server`` on the same LAN, you would simply do: - -.. sourcecode:: python - -    from zmq import ssh -    ssh.tunnel_connection(sock, "tcp://10.0.1.2:5555", "server") - -Note that ``"server"`` can actually be a fully specified ``"user@server:port"`` ssh url. -Since this really just launches a shell command, all your ssh configuration of usernames, -aliases, keys, etc. will be respected. If necessary, :func:`tunnel_connection` does take -arguments for specific passwords, private keys (the ssh ``-i`` option), and non-default -choice of whether to use paramiko. - -If you are on the same network as the machine, but it is only listening on localhost, you -can still connect by making the machine itself the server, and using loopback as the -remote ip: - -.. sourcecode:: python - -    from zmq import ssh -    ssh.tunnel_connection(sock, "tcp://127.0.0.1:5555", "10.0.1.2") - -The :func:`tunnel_connection` function is a simple utility that forwards a random -localhost port to the real destination, and connects a socket to the new local url, -rather than the remote one that wouldn't actually work. - -.. seealso:: - -    A short discussion of ssh tunnels: http://www.revsys.com/writings/quicktips/ssh-tunnel.html - - -.. _IPython: http://ipython.org -.. _pexpect: http://www.noah.org/wiki/pexpect -.. _pexpect-u: http://pypi.python.org/pypi/pexpect-u -.. _paramiko: http://www.lag.net/paramiko/ - diff --git a/docs/source/unicode.rst b/docs/source/unicode.rst deleted file mode 100644 index a0c7878..0000000 --- a/docs/source/unicode.rst +++ /dev/null @@ -1,188 +0,0 @@ -.. PyZMQ Unicode doc, by Min Ragan-Kelley, 2010 - -.. _unicode: - -PyZMQ and Unicode -================= - -PyZMQ is built with an eye towards an easy transition to Python 3, and part of -that is dealing with unicode strings. This is an overview of some of what we -found, and what it means for PyZMQ. - -First, Unicode in Python 2 and 3 -******************************** - -In Python < 3, a ``str`` object is really a C string with some sugar - a -specific series of bytes with some fun methods like ``endswith()`` and -``split()``. In 2.0, the ``unicode`` object was added, which handles different -methods of encoding. In Python 3, however, the meaning of ``str`` changes. A -``str`` in Python 3 is a full unicode object, with encoding and everything. If -you want a C string with some sugar, there is a new object called ``bytes``, -that behaves much like the 2.x ``str``. The idea is that for a user, a string is -a series of *characters*, not a series of bytes. For simple ascii, the two are -interchangeable, but if you consider accents and non-Latin characters, then the -character meaning of byte sequences can be ambiguous, since it depends on the -encoding scheme. They decided to avoid the ambiguity by forcing users who want -the actual bytes to specify the encoding every time they want to convert a -string to bytes. That way, users are aware of the difference between a series of -bytes and a collection of characters, and don't confuse the two, as happens in -Python 2.x. - -The problems (on both sides) come from the fact that regardless of the language -design, users are mostly going to use ``str`` objects to represent collections -of characters, and the behavior of that object is dramatically different in -certain aspects between the 2.x ``bytes`` approach and the 3.x ``unicode`` -approach. The ``unicode`` approach has the advantage of removing byte ambiguity -- it's a list of characters, not bytes. However, if you really do want the -bytes, it's very inefficient to get them. The ``bytes`` approach has the -advantage of efficiency. A ``bytes`` object really is just a char* pointer with -some methods to be used on it, so when interacting with, so interacting with C -code, etc is highly efficient and straightforward. However, understanding a -bytes object as a string with extended characters introduces ambiguity and -possibly confusion. - -To avoid ambiguity, hereafter we will refer to encoded C arrays as 'bytes' and -abstract unicode objects as 'strings'. - -Unicode Buffers ---------------- - -Since unicode objects have a wide range of representations, they are not stored -as the bytes according to their encoding, but rather in a format called UCS (an -older fixed-width Unicode format). On some platforms (OS X, Windows), the storage -is UCS-2, which is 2 bytes per character. On most \*ix systems, it is UCS-4, or -4 bytes per character. The contents of the *buffer* of a ``unicode`` object are -not encoding dependent (always UCS-2 or UCS-4), but they are *platform* -dependent. As a result of this, and the further insistence on not interpreting -``unicode`` objects as bytes without specifying encoding, ``str`` objects in -Python 3 don't even provide the buffer interface. You simply cannot get the raw -bytes of a ``unicode`` object without specifying the encoding for the bytes. In -Python 2.x, you can get to the raw buffer, but the platform dependence and the -fact that the encoding of the buffer is not the encoding of the object makes it -very confusing, so this is probably a good move. - -The efficiency problem here comes from the fact that simple ascii strings are 4x -as big in memory as they need to be (on most Linux, 2x on other platforms). -Also, to translate to/from C code that works with char*, you always have to copy -data and encode/decode the bytes. This really is horribly inefficient from a -memory standpoint. Essentially, Where memory efficiency matters to you, you -should never ever use strings; use bytes. The problem is that users will almost -always use ``str``, and in 2.x they are efficient, but in 3.x they are not. We -want to make sure that we don't help the user make this mistake, so we ensure -that zmq methods don't try to hide what strings really are. - -What This Means for PyZMQ -************************* - -PyZMQ is a wrapper for a C library, so it really should use bytes, since a -string is not a simple wrapper for ``char *`` like it used to be, but an -abstract sequence of characters. The representations of bytes in Python are -either the ``bytes`` object itself, or any object that provides the buffer -interface (aka memoryview). In Python 2.x, unicode objects do provide the buffer -interface, but as they do not in Python 3, where pyzmq requires bytes, we -specifically reject unicode objects. - -The relevant methods here are ``socket.send/recv``, ``socket.get/setsockopt``, -``socket.bind/connect``. The important consideration for send/recv and -set/getsockopt is that when you put in something, you really should get the same -object back with its partner method. We can easily coerce unicode objects to -bytes with send/setsockopt, but the problem is that the pair method of -recv/getsockopt will always be bytes, and there should be symmetry. We certainly -shouldn't try to always decode on the retrieval side, because if users just want -bytes, then we are potentially using up enormous amounts of excess memory -unnecessarily, due to copying and larger memory footprint of unicode strings. - -Still, we recognize the fact that users will quite frequently have unicode -strings that they want to send, so we have added ``socket.<method>_string()`` -wrappers. These methods simply wrap their bytes counterpart by encoding -to/decoding from bytes around them, and they all take an `encoding` keyword -argument that defaults to utf-8. Since encoding and decoding are necessary to -translate between unicode and bytes, it is impossible to perform non-copying -actions with these wrappers. - -``socket.bind/connect`` methods are different from these, in that they are -strictly setters and there is not corresponding getter method. As a result, we -feel that we can safely coerce unicode objects to bytes (always to utf-8) in -these methods. - -.. note:: - -    For cross-language symmetry (including Python 3), the ``_unicode`` methods  -    are now ``_string``. Many languages have a notion of native strings, and  -    the use of ``_unicode`` was wedded too closely to the name of such objects  -    in Python 2.  For the time being, anywhere you see ``_string``, ``_unicode`` -    also works, and is the only option in pyzmq ≤ 2.1.11. - - -The Methods ------------ - -Overview of the relevant methods: - -.. py:function::    socket.bind(self, addr) -     -        `addr` is ``bytes`` or ``unicode``. If ``unicode``,  -        encoded to utf-8 ``bytes`` - -.. py:function::    socket.connect(self, addr) - -        `addr` is ``bytes`` or ``unicode``. If ``unicode``,  -        encoded to utf-8 ``bytes`` - -.. py:function::    socket.send(self, object obj, flags=0, copy=True) - -        `obj` is ``bytes`` or provides buffer interface.  -         -        if `obj` is ``unicode``, raise ``TypeError`` - -.. py:function::    socket.recv(self, flags=0, copy=True) - -        returns ``bytes`` if `copy=True` -         -        returns ``zmq.Message`` if `copy=False`: -         -            `message.buffer` is a buffer view of the ``bytes`` -             -            `str(message)` provides the ``bytes`` -             -            `unicode(message)` decodes `message.buffer` with utf-8 -     -.. py:function::    socket.send_string(self, unicode s, flags=0, encoding='utf-8') - -        takes a ``unicode`` string `s`, and sends the ``bytes``  -        after encoding without an extra copy, via: -         -        `socket.send(s.encode(encoding), flags, copy=False)` -     -.. py:function::    socket.recv_string(self, flags=0, encoding='utf-8') - -        always returns ``unicode`` string -         -        there will be a ``UnicodeError`` if it cannot decode the buffer -         -        performs non-copying `recv`, and decodes the buffer with `encoding` -     -.. py:function::    socket.setsockopt(self, opt, optval) - -        only accepts ``bytes``  for `optval` (or ``int``, depending on `opt`) -         -        ``TypeError`` if ``unicode`` or anything else -     -.. py:function::    socket.getsockopt(self, opt) - -        returns ``bytes`` (or ``int``), never ``unicode`` -     -.. py:function::    socket.setsockopt_string(self, opt, unicode optval, encoding='utf-8') - -        accepts ``unicode`` string for `optval` -         -        encodes `optval` with `encoding` before passing the ``bytes`` to  -        `setsockopt` -     -.. py:function::    socket.getsockopt_string(self, opt, encoding='utf-8') - -        always returns ``unicode`` string, after decoding with `encoding` -         -        note that `zmq.IDENTITY` is the only `sockopt` with a string value  -        that can be queried with `getsockopt` - diff --git a/docs/sphinxext/apigen.py b/docs/sphinxext/apigen.py deleted file mode 100644 index b06e3d4..0000000 --- a/docs/sphinxext/apigen.py +++ /dev/null @@ -1,441 +0,0 @@ -"""Attempt to generate templates for module reference with Sphinx - -XXX - we exclude extension modules - -To include extension modules, first identify them as valid in the -``_uri2path`` method, then handle them in the ``_parse_module`` script. - -We get functions and classes by parsing the text of .py files. -Alternatively we could import the modules for discovery, and we'd have -to do that for extension modules.  This would involve changing the -``_parse_module`` method to work via import and introspection, and -might involve changing ``discover_modules`` (which determines which -files are modules, and therefore which module URIs will be passed to -``_parse_module``). - -NOTE: this is a modified version of a script originally shipped with the -PyMVPA project, which we've adapted for NIPY use.  PyMVPA is an MIT-licensed -project.""" - -# Stdlib imports -import os -import re - -# Functions and classes -class ApiDocWriter(object): -    ''' Class for automatic detection and parsing of API docs -    to Sphinx-parsable reST format''' - -    # only separating first two levels -    rst_section_levels = ['*', '=', '-', '~', '^'] - -    def __init__(self, -                 package_name, -                 rst_extension='.rst', -                 package_skip_patterns=None, -                 module_skip_patterns=None, -                 ): -        ''' Initialize package for parsing - -        Parameters -        ---------- -        package_name : string -            Name of the top-level package.  *package_name* must be the -            name of an importable package -        rst_extension : string, optional -            Extension for reST files, default '.rst' -        package_skip_patterns : None or sequence of {strings, regexps} -            Sequence of strings giving URIs of packages to be excluded -            Operates on the package path, starting at (including) the -            first dot in the package path, after *package_name* - so, -            if *package_name* is ``sphinx``, then ``sphinx.util`` will -            result in ``.util`` being passed for earching by these -            regexps.  If is None, gives default. Default is: -            ['\.tests$'] -        module_skip_patterns : None or sequence -            Sequence of strings giving URIs of modules to be excluded -            Operates on the module name including preceding URI path, -            back to the first dot after *package_name*.  For example -            ``sphinx.util.console`` results in the string to search of -            ``.util.console`` -            If is None, gives default. Default is: -            ['\.setup$', '\._'] -        ''' -        if package_skip_patterns is None: -            package_skip_patterns = ['\\.tests$'] -        if module_skip_patterns is None: -            module_skip_patterns = ['\\.setup$', '\\._'] -        self.package_name = package_name -        self.rst_extension = rst_extension -        self.package_skip_patterns = package_skip_patterns -        self.module_skip_patterns = module_skip_patterns - -    def get_package_name(self): -        return self._package_name - -    def set_package_name(self, package_name): -        ''' Set package_name - -        >>> docwriter = ApiDocWriter('sphinx') -        >>> import sphinx -        >>> docwriter.root_path == sphinx.__path__[0] -        True -        >>> docwriter.package_name = 'docutils' -        >>> import docutils -        >>> docwriter.root_path == docutils.__path__[0] -        True -        ''' -        # It's also possible to imagine caching the module parsing here -        self._package_name = package_name -        self.root_module = __import__(package_name) -        self.root_path = self.root_module.__path__[0] -        self.written_modules = None - -    package_name = property(get_package_name, set_package_name, None, -                            'get/set package_name') - -    def _get_object_name(self, line): -        ''' Get second token in line -        >>> docwriter = ApiDocWriter('sphinx') -        >>> docwriter._get_object_name("  def func():  ") -        'func' -        >>> docwriter._get_object_name("  class Klass(object):  ") -        'Klass' -        >>> docwriter._get_object_name("  class Klass:  ") -        'Klass' -        ''' -        if line.startswith('cdef'): -            line = line.split(None,1)[1] -        name = line.split()[1].split('(')[0].strip() -        # in case we have classes which are not derived from object -        # ie. old style classes -        return name.rstrip(':') - -    def _uri2path(self, uri): -        ''' Convert uri to absolute filepath - -        Parameters -        ---------- -        uri : string -            URI of python module to return path for - -        Returns -        ------- -        path : None or string -            Returns None if there is no valid path for this URI -            Otherwise returns absolute file system path for URI - -        Examples -        -------- -        >>> docwriter = ApiDocWriter('sphinx') -        >>> import sphinx -        >>> modpath = sphinx.__path__[0] -        >>> res = docwriter._uri2path('sphinx.builder') -        >>> res == os.path.join(modpath, 'builder.py') -        True -        >>> res = docwriter._uri2path('sphinx') -        >>> res == os.path.join(modpath, '__init__.py') -        True -        >>> docwriter._uri2path('sphinx.does_not_exist') - -        ''' -        if uri == self.package_name: -            return os.path.join(self.root_path, '__init__.py') -        path = uri.replace('.', os.path.sep) -        path = path.replace(self.package_name + os.path.sep, '') -        path = os.path.join(self.root_path, path) -        # XXX maybe check for extensions as well? -        if os.path.exists(path + '.py'): # file -            path += '.py' -        elif os.path.exists(path + '.pyx'): # file -            path += '.pyx' -        elif os.path.exists(os.path.join(path, '__init__.py')): -            path = os.path.join(path, '__init__.py') -        else: -            return None -        return path - -    def _path2uri(self, dirpath): -        ''' Convert directory path to uri ''' -        relpath = dirpath.replace(self.root_path, self.package_name) -        if relpath.startswith(os.path.sep): -            relpath = relpath[1:] -        return relpath.replace(os.path.sep, '.') - -    def _parse_module(self, uri): -        ''' Parse module defined in *uri* ''' -        filename = self._uri2path(uri) -        if filename is None: -            # nothing that we could handle here. -            return ([],[]) -        f = open(filename, 'rt') -        functions, classes = self._parse_lines(f) -        f.close() -        return functions, classes -     -    def _parse_lines(self, linesource): -        ''' Parse lines of text for functions and classes ''' -        functions = [] -        classes = [] -        for line in linesource: -            if line.startswith('def ') and line.count('('): -                # exclude private stuff -                name = self._get_object_name(line) -                if not name.startswith('_'): -                    functions.append(name) -            elif line.startswith('class '): -                # exclude private stuff -                name = self._get_object_name(line) -                if not name.startswith('_'): -                    classes.append(name) -            elif line.startswith('cpdef ') and line.count('('): -                # exclude private stuff -                name = self._get_object_name(line) -                if not name.startswith('_'): -                    functions.append(name) -            elif line.startswith('cdef class '): -                # exclude private stuff -                name = self._get_object_name(line) -                if not name.startswith('_'): -                    classes.append(name) -            else: -                pass -        functions.sort() -        classes.sort() -        return functions, classes - -    def generate_api_doc(self, uri): -        '''Make autodoc documentation template string for a module - -        Parameters -        ---------- -        uri : string -            python location of module - e.g 'sphinx.builder' - -        Returns -        ------- -        S : string -            Contents of API doc -        ''' -        # get the names of all classes and functions -        functions, classes = self._parse_module(uri) -        if not len(functions) and not len(classes): -            print 'WARNING: Empty -',uri  # dbg -            return '' - -        # Make a shorter version of the uri that omits the package name for -        # titles  -        uri_short = re.sub(r'^%s\.' % self.package_name,'',uri) -         -        ad = '.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n' - -        chap_title = uri_short -        ad += (chap_title+'\n'+ self.rst_section_levels[1] * len(chap_title) -               + '\n\n') - -        # Set the chapter title to read 'module' for all modules except for the -        # main packages -        if '.' in uri: -            title = 'Module: :mod:`' + uri_short + '`' -        else: -            title = ':mod:`' + uri_short + '`' -        ad += title + '\n' + self.rst_section_levels[2] * len(title) - -        # if len(classes): -        #     ad += '\nInheritance diagram for ``%s``:\n\n' % uri -        #     ad += '.. inheritance-diagram:: %s \n' % uri -        #     ad += '   :parts: 3\n' - -        ad += '\n.. automodule:: ' + uri + '\n' -        ad += '\n.. currentmodule:: ' + uri + '\n' -        multi_class = len(classes) > 1 -        multi_fx = len(functions) > 1 -        if multi_class: -            ad += '\n' + 'Classes' + '\n' + \ -                  self.rst_section_levels[2] * 7 + '\n' -        elif len(classes) and multi_fx: -            ad += '\n' + 'Class' + '\n' + \ -                  self.rst_section_levels[2] * 5 + '\n' -        for c in classes: -            ad += '\n:class:`' + c + '`\n' \ -                  + self.rst_section_levels[multi_class + 2 ] * \ -                  (len(c)+9) + '\n\n' -            ad += '\n.. autoclass:: ' + c + '\n' -            # must NOT exclude from index to keep cross-refs working -            ad += '  :members:\n' \ -                  '  :undoc-members:\n' \ -                  '  :inherited-members:\n' \ -                  '\n'  -                  # skip class.__init__() -                  # '  .. automethod:: __init__\n' -        if multi_fx: -            ad += '\n' + 'Functions' + '\n' + \ -                  self.rst_section_levels[2] * 9 + '\n\n' -        elif len(functions) and multi_class: -            ad += '\n' + 'Function' + '\n' + \ -                  self.rst_section_levels[2] * 8 + '\n\n' -        for f in functions: -            # must NOT exclude from index to keep cross-refs working -            ad += '\n.. autofunction:: ' + uri + '.' + f + '\n\n' -        return ad - -    def _survives_exclude(self, matchstr, match_type): -        ''' Returns True if *matchstr* does not match patterns - -        ``self.package_name`` removed from front of string if present - -        Examples -        -------- -        >>> dw = ApiDocWriter('sphinx') -        >>> dw._survives_exclude('sphinx.okpkg', 'package') -        True -        >>> dw.package_skip_patterns.append('^\\.badpkg$') -        >>> dw._survives_exclude('sphinx.badpkg', 'package') -        False -        >>> dw._survives_exclude('sphinx.badpkg', 'module') -        True -        >>> dw._survives_exclude('sphinx.badmod', 'module') -        True -        >>> dw.module_skip_patterns.append('^\\.badmod$') -        >>> dw._survives_exclude('sphinx.badmod', 'module') -        False -        ''' -        if match_type == 'module': -            patterns = self.module_skip_patterns -        elif match_type == 'package': -            patterns = self.package_skip_patterns -        else: -            raise ValueError('Cannot interpret match type "%s"'  -                             % match_type) -        # Match to URI without package name -        L = len(self.package_name) -        if matchstr[:L] == self.package_name: -            matchstr = matchstr[L:] -        for pat in patterns: -            try: -                pat.search -            except AttributeError: -                pat = re.compile(pat) -            if pat.search(matchstr): -                return False -        return True - -    def discover_modules(self): -        ''' Return module sequence discovered from ``self.package_name``  - - -        Parameters -        ---------- -        None - -        Returns -        ------- -        mods : sequence -            Sequence of module names within ``self.package_name`` - -        Examples -        -------- -        >>> dw = ApiDocWriter('sphinx') -        >>> mods = dw.discover_modules() -        >>> 'sphinx.util' in mods -        True -        >>> dw.package_skip_patterns.append('\.util$') -        >>> 'sphinx.util' in dw.discover_modules() -        False -        >>>  -        ''' -        modules = [self.package_name] -        # raw directory parsing -        for dirpath, dirnames, filenames in os.walk(self.root_path): -            # Check directory names for packages -            root_uri = self._path2uri(os.path.join(self.root_path, -                                                   dirpath)) -            for dirname in dirnames[:]: # copy list - we modify inplace -                package_uri = '.'.join((root_uri, dirname)) -                if (self._uri2path(package_uri) and -                    self._survives_exclude(package_uri, 'package')): -                    modules.append(package_uri) -                else: -                    dirnames.remove(dirname) -            # Check filenames for modules -            for filename in filenames: -                module_name = filename[:-3] -                module_uri = '.'.join((root_uri, module_name)) -                if (self._uri2path(module_uri) and -                    self._survives_exclude(module_uri, 'module')): -                    modules.append(module_uri) -        return sorted(modules) -     -    def write_modules_api(self, modules,outdir): -        # write the list -        written_modules = [] -        for m in modules: -            api_str = self.generate_api_doc(m) -            if not api_str: -                continue -            # write out to file -            outfile = os.path.join(outdir, -                                   m + self.rst_extension) -            fileobj = open(outfile, 'wt') -            fileobj.write(api_str) -            fileobj.close() -            written_modules.append(m) -        self.written_modules = written_modules - -    def write_api_docs(self, outdir): -        """Generate API reST files. - -        Parameters -        ---------- -        outdir : string -            Directory name in which to store files -            We create automatic filenames for each module -             -        Returns -        ------- -        None - -        Notes -        ----- -        Sets self.written_modules to list of written modules -        """ -        if not os.path.exists(outdir): -            os.mkdir(outdir) -        # compose list of modules -        modules = self.discover_modules() -        self.write_modules_api(modules,outdir) -         -    def write_index(self, outdir, froot='gen', relative_to=None): -        """Make a reST API index file from written files - -        Parameters -        ---------- -        path : string -            Filename to write index to -        outdir : string -            Directory to which to write generated index file -        froot : string, optional -            root (filename without extension) of filename to write to -            Defaults to 'gen'.  We add ``self.rst_extension``. -        relative_to : string -            path to which written filenames are relative.  This -            component of the written file path will be removed from -            outdir, in the generated index.  Default is None, meaning, -            leave path as it is. -        """ -        if self.written_modules is None: -            raise ValueError('No modules written') -        # Get full filename path -        path = os.path.join(outdir, froot+self.rst_extension) -        # Path written into index is relative to rootpath -        if relative_to is not None: -            relpath = outdir.replace(relative_to + os.path.sep, '') -        else: -            relpath = outdir -        idx = open(path,'wt') -        w = idx.write -        w('.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n') -        w('.. toctree::\n\n') -        for f in self.written_modules: -            w('   %s\n' % os.path.join(relpath,f)) -        idx.close() diff --git a/docs/sphinxext/docscrape.py b/docs/sphinxext/docscrape.py deleted file mode 100644 index f374b3d..0000000 --- a/docs/sphinxext/docscrape.py +++ /dev/null @@ -1,497 +0,0 @@ -"""Extract reference documentation from the NumPy source tree. - -""" - -import inspect -import textwrap -import re -import pydoc -from StringIO import StringIO -from warnings import warn -4 -class Reader(object): -    """A line-based string reader. - -    """ -    def __init__(self, data): -        """ -        Parameters -        ---------- -        data : str -           String with lines separated by '\n'. - -        """ -        if isinstance(data,list): -            self._str = data -        else: -            self._str = data.split('\n') # store string as list of lines - -        self.reset() - -    def __getitem__(self, n): -        return self._str[n] - -    def reset(self): -        self._l = 0 # current line nr - -    def read(self): -        if not self.eof(): -            out = self[self._l] -            self._l += 1 -            return out -        else: -            return '' - -    def seek_next_non_empty_line(self): -        for l in self[self._l:]: -            if l.strip(): -                break -            else: -                self._l += 1 - -    def eof(self): -        return self._l >= len(self._str) - -    def read_to_condition(self, condition_func): -        start = self._l -        for line in self[start:]: -            if condition_func(line): -                return self[start:self._l] -            self._l += 1 -            if self.eof(): -                return self[start:self._l+1] -        return [] - -    def read_to_next_empty_line(self): -        self.seek_next_non_empty_line() -        def is_empty(line): -            return not line.strip() -        return self.read_to_condition(is_empty) - -    def read_to_next_unindented_line(self): -        def is_unindented(line): -            return (line.strip() and (len(line.lstrip()) == len(line))) -        return self.read_to_condition(is_unindented) - -    def peek(self,n=0): -        if self._l + n < len(self._str): -            return self[self._l + n] -        else: -            return '' - -    def is_empty(self): -        return not ''.join(self._str).strip() - - -class NumpyDocString(object): -    def __init__(self,docstring): -        docstring = textwrap.dedent(docstring).split('\n') - -        self._doc = Reader(docstring) -        self._parsed_data = { -            'Signature': '', -            'Summary': [''], -            'Extended Summary': [], -            'Parameters': [], -            'Returns': [], -            'Raises': [], -            'Warns': [], -            'Other Parameters': [], -            'Attributes': [], -            'Methods': [], -            'See Also': [], -            'Notes': [], -            'Warnings': [], -            'References': '', -            'Examples': '', -            'index': {} -            } - -        self._parse() - -    def __getitem__(self,key): -        return self._parsed_data[key] - -    def __setitem__(self,key,val): -        if not self._parsed_data.has_key(key): -            warn("Unknown section %s" % key) -        else: -            self._parsed_data[key] = val - -    def _is_at_section(self): -        self._doc.seek_next_non_empty_line() - -        if self._doc.eof(): -            return False - -        l1 = self._doc.peek().strip()  # e.g. Parameters - -        if l1.startswith('.. index::'): -            return True - -        l2 = self._doc.peek(1).strip() #    ---------- or ========== -        return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1)) - -    def _strip(self,doc): -        i = 0 -        j = 0 -        for i,line in enumerate(doc): -            if line.strip(): break - -        for j,line in enumerate(doc[::-1]): -            if line.strip(): break - -        return doc[i:len(doc)-j] - -    def _read_to_next_section(self): -        section = self._doc.read_to_next_empty_line() - -        while not self._is_at_section() and not self._doc.eof(): -            if not self._doc.peek(-1).strip(): # previous line was empty -                section += [''] - -            section += self._doc.read_to_next_empty_line() - -        return section - -    def _read_sections(self): -        while not self._doc.eof(): -            data = self._read_to_next_section() -            name = data[0].strip() - -            if name.startswith('..'): # index section -                yield name, data[1:] -            elif len(data) < 2: -                yield StopIteration -            else: -                yield name, self._strip(data[2:]) - -    def _parse_param_list(self,content): -        r = Reader(content) -        params = [] -        while not r.eof(): -            header = r.read().strip() -            if ' : ' in header: -                arg_name, arg_type = header.split(' : ')[:2] -            else: -                arg_name, arg_type = header, '' - -            desc = r.read_to_next_unindented_line() -            desc = dedent_lines(desc) - -            params.append((arg_name,arg_type,desc)) - -        return params - -     -    _name_rgx = re.compile(r"^\s*(:(?P<role>\w+):`(?P<name>[a-zA-Z0-9_.-]+)`|" -                           r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X) -    def _parse_see_also(self, content): -        """ -        func_name : Descriptive text -            continued text -        another_func_name : Descriptive text -        func_name1, func_name2, :meth:`func_name`, func_name3 - -        """ -        items = [] - -        def parse_item_name(text): -            """Match ':role:`name`' or 'name'""" -            m = self._name_rgx.match(text) -            if m: -                g = m.groups() -                if g[1] is None: -                    return g[3], None -                else: -                    return g[2], g[1] -            raise ValueError("%s is not a item name" % text) - -        def push_item(name, rest): -            if not name: -                return -            name, role = parse_item_name(name) -            items.append((name, list(rest), role)) -            del rest[:] - -        current_func = None -        rest = [] -         -        for line in content: -            if not line.strip(): continue - -            m = self._name_rgx.match(line) -            if m and line[m.end():].strip().startswith(':'): -                push_item(current_func, rest) -                current_func, line = line[:m.end()], line[m.end():] -                rest = [line.split(':', 1)[1].strip()] -                if not rest[0]: -                    rest = [] -            elif not line.startswith(' '): -                push_item(current_func, rest) -                current_func = None -                if ',' in line: -                    for func in line.split(','): -                        push_item(func, []) -                elif line.strip(): -                    current_func = line -            elif current_func is not None: -                rest.append(line.strip()) -        push_item(current_func, rest) -        return items - -    def _parse_index(self, section, content): -        """ -        .. index: default -           :refguide: something, else, and more - -        """ -        def strip_each_in(lst): -            return [s.strip() for s in lst] - -        out = {} -        section = section.split('::') -        if len(section) > 1: -            out['default'] = strip_each_in(section[1].split(','))[0] -        for line in content: -            line = line.split(':') -            if len(line) > 2: -                out[line[1]] = strip_each_in(line[2].split(',')) -        return out -     -    def _parse_summary(self): -        """Grab signature (if given) and summary""" -        if self._is_at_section(): -            return - -        summary = self._doc.read_to_next_empty_line() -        summary_str = " ".join([s.strip() for s in summary]).strip() -        if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str): -            self['Signature'] = summary_str -            if not self._is_at_section(): -                self['Summary'] = self._doc.read_to_next_empty_line() -        else: -            self['Summary'] = summary - -        if not self._is_at_section(): -            self['Extended Summary'] = self._read_to_next_section() -     -    def _parse(self): -        self._doc.reset() -        self._parse_summary() - -        for (section,content) in self._read_sections(): -            if not section.startswith('..'): -                section = ' '.join([s.capitalize() for s in section.split(' ')]) -            if section in ('Parameters', 'Attributes', 'Methods', -                           'Returns', 'Raises', 'Warns'): -                self[section] = self._parse_param_list(content) -            elif section.startswith('.. index::'): -                self['index'] = self._parse_index(section, content) -            elif section == 'See Also': -                self['See Also'] = self._parse_see_also(content) -            else: -                self[section] = content - -    # string conversion routines - -    def _str_header(self, name, symbol='-'): -        return [name, len(name)*symbol] - -    def _str_indent(self, doc, indent=4): -        out = [] -        for line in doc: -            out += [' '*indent + line] -        return out - -    def _str_signature(self): -        if self['Signature']: -            return [self['Signature'].replace('*','\*')] + [''] -        else: -            return [''] - -    def _str_summary(self): -        if self['Summary']: -            return self['Summary'] + [''] -        else: -            return [] - -    def _str_extended_summary(self): -        if self['Extended Summary']: -            return self['Extended Summary'] + [''] -        else: -            return [] - -    def _str_param_list(self, name): -        out = [] -        if self[name]: -            out += self._str_header(name) -            for param,param_type,desc in self[name]: -                out += ['%s : %s' % (param, param_type)] -                out += self._str_indent(desc) -            out += [''] -        return out - -    def _str_section(self, name): -        out = [] -        if self[name]: -            out += self._str_header(name) -            out += self[name] -            out += [''] -        return out - -    def _str_see_also(self, func_role): -        if not self['See Also']: return [] -        out = [] -        out += self._str_header("See Also") -        last_had_desc = True -        for func, desc, role in self['See Also']: -            if role: -                link = ':%s:`%s`' % (role, func) -            elif func_role: -                link = ':%s:`%s`' % (func_role, func) -            else: -                link = "`%s`_" % func -            if desc or last_had_desc: -                out += [''] -                out += [link] -            else: -                out[-1] += ", %s" % link -            if desc: -                out += self._str_indent([' '.join(desc)]) -                last_had_desc = True -            else: -                last_had_desc = False -        out += [''] -        return out - -    def _str_index(self): -        idx = self['index'] -        out = [] -        out += ['.. index:: %s' % idx.get('default','')] -        for section, references in idx.iteritems(): -            if section == 'default': -                continue -            out += ['   :%s: %s' % (section, ', '.join(references))] -        return out - -    def __str__(self, func_role=''): -        out = [] -        out += self._str_signature() -        out += self._str_summary() -        out += self._str_extended_summary() -        for param_list in ('Parameters','Returns','Raises'): -            out += self._str_param_list(param_list) -        out += self._str_section('Warnings') -        out += self._str_see_also(func_role) -        for s in ('Notes','References','Examples'): -            out += self._str_section(s) -        out += self._str_index() -        return '\n'.join(out) - - -def indent(str,indent=4): -    indent_str = ' '*indent -    if str is None: -        return indent_str -    lines = str.split('\n') -    return '\n'.join(indent_str + l for l in lines) - -def dedent_lines(lines): -    """Deindent a list of lines maximally""" -    return textwrap.dedent("\n".join(lines)).split("\n") - -def header(text, style='-'): -    return text + '\n' + style*len(text) + '\n' - - -class FunctionDoc(NumpyDocString): -    def __init__(self, func, role='func', doc=None): -        self._f = func -        self._role = role # e.g. "func" or "meth" -        if doc is None: -            doc = inspect.getdoc(func) or '' -        try: -            NumpyDocString.__init__(self, doc) -        except ValueError, e: -            print '*'*78 -            print "ERROR: '%s' while parsing `%s`" % (e, self._f) -            print '*'*78 -            #print "Docstring follows:" -            #print doclines -            #print '='*78 - -        if not self['Signature']: -            func, func_name = self.get_func() -            try: -                # try to read signature -                argspec = inspect.getargspec(func) -                argspec = inspect.formatargspec(*argspec) -                argspec = argspec.replace('*','\*') -                signature = '%s%s' % (func_name, argspec) -            except TypeError, e: -                signature = '%s()' % func_name -            self['Signature'] = signature - -    def get_func(self): -        func_name = getattr(self._f, '__name__', self.__class__.__name__) -        if inspect.isclass(self._f): -            func = getattr(self._f, '__call__', self._f.__init__) -        else: -            func = self._f -        return func, func_name -             -    def __str__(self): -        out = '' - -        func, func_name = self.get_func() -        signature = self['Signature'].replace('*', '\*') - -        roles = {'func': 'function', -                 'meth': 'method'} - -        if self._role: -            if not roles.has_key(self._role): -                print "Warning: invalid role %s" % self._role -            out += '.. %s:: %s\n    \n\n' % (roles.get(self._role,''), -                                             func_name) - -        out += super(FunctionDoc, self).__str__(func_role=self._role) -        return out - - -class ClassDoc(NumpyDocString): -    def __init__(self,cls,modulename='',func_doc=FunctionDoc,doc=None): -        if not inspect.isclass(cls): -            raise ValueError("Initialise using a class. Got %r" % cls) -        self._cls = cls - -        if modulename and not modulename.endswith('.'): -            modulename += '.' -        self._mod = modulename -        self._name = cls.__name__ -        self._func_doc = func_doc - -        if doc is None: -            doc = pydoc.getdoc(cls) - -        NumpyDocString.__init__(self, doc) - -    @property -    def methods(self): -        return [name for name,func in inspect.getmembers(self._cls) -                if not name.startswith('_') and callable(func)] - -    def __str__(self): -        out = '' -        out += super(ClassDoc, self).__str__() -        out += "\n\n" - -        #for m in self.methods: -        #    print "Parsing `%s`" % m -        #    out += str(self._func_doc(getattr(self._cls,m), 'meth')) + '\n\n' -        #    out += '.. index::\n   single: %s; %s\n\n' % (self._name, m) - -        return out - - diff --git a/docs/sphinxext/docscrape_sphinx.py b/docs/sphinxext/docscrape_sphinx.py deleted file mode 100644 index 77ed271..0000000 --- a/docs/sphinxext/docscrape_sphinx.py +++ /dev/null @@ -1,136 +0,0 @@ -import re, inspect, textwrap, pydoc -from docscrape import NumpyDocString, FunctionDoc, ClassDoc - -class SphinxDocString(NumpyDocString): -    # string conversion routines -    def _str_header(self, name, symbol='`'): -        return ['.. rubric:: ' + name, ''] - -    def _str_field_list(self, name): -        return [':' + name + ':'] - -    def _str_indent(self, doc, indent=4): -        out = [] -        for line in doc: -            out += [' '*indent + line] -        return out - -    def _str_signature(self): -        return [''] -        if self['Signature']: -            return ['``%s``' % self['Signature']] + [''] -        else: -            return [''] - -    def _str_summary(self): -        return self['Summary'] + [''] - -    def _str_extended_summary(self): -        return self['Extended Summary'] + [''] - -    def _str_param_list(self, name): -        out = [] -        if self[name]: -            out += self._str_field_list(name) -            out += [''] -            for param,param_type,desc in self[name]: -                out += self._str_indent(['**%s** : %s' % (param.strip(), -                                                          param_type)]) -                out += [''] -                out += self._str_indent(desc,8) -                out += [''] -        return out - -    def _str_section(self, name): -        out = [] -        if self[name]: -            out += self._str_header(name) -            out += [''] -            content = textwrap.dedent("\n".join(self[name])).split("\n") -            out += content -            out += [''] -        return out - -    def _str_see_also(self, func_role): -        out = [] -        if self['See Also']: -            see_also = super(SphinxDocString, self)._str_see_also(func_role) -            out = ['.. seealso::', ''] -            out += self._str_indent(see_also[2:]) -        return out - -    def _str_warnings(self): -        out = [] -        if self['Warnings']: -            out = ['.. warning::', ''] -            out += self._str_indent(self['Warnings']) -        return out - -    def _str_index(self): -        idx = self['index'] -        out = [] -        if len(idx) == 0: -            return out - -        out += ['.. index:: %s' % idx.get('default','')] -        for section, references in idx.iteritems(): -            if section == 'default': -                continue -            elif section == 'refguide': -                out += ['   single: %s' % (', '.join(references))] -            else: -                out += ['   %s: %s' % (section, ','.join(references))] -        return out - -    def _str_references(self): -        out = [] -        if self['References']: -            out += self._str_header('References') -            if isinstance(self['References'], str): -                self['References'] = [self['References']] -            out.extend(self['References']) -            out += [''] -        return out - -    def __str__(self, indent=0, func_role="obj"): -        out = [] -        out += self._str_signature() -        out += self._str_index() + [''] -        out += self._str_summary() -        out += self._str_extended_summary() -        for param_list in ('Parameters', 'Attributes', 'Methods', -                           'Returns','Raises'): -            out += self._str_param_list(param_list) -        out += self._str_warnings() -        out += self._str_see_also(func_role) -        out += self._str_section('Notes') -        out += self._str_references() -        out += self._str_section('Examples') -        out = self._str_indent(out,indent) -        return '\n'.join(out) - -class SphinxFunctionDoc(SphinxDocString, FunctionDoc): -    pass - -class SphinxClassDoc(SphinxDocString, ClassDoc): -    pass - -def get_doc_object(obj, what=None, doc=None): -    if what is None: -        if inspect.isclass(obj): -            what = 'class' -        elif inspect.ismodule(obj): -            what = 'module' -        elif callable(obj): -            what = 'function' -        else: -            what = 'object' -    if what == 'class': -        return SphinxClassDoc(obj, '', func_doc=SphinxFunctionDoc, doc=doc) -    elif what in ('function', 'method'): -        return SphinxFunctionDoc(obj, '', doc=doc) -    else: -        if doc is None: -            doc = pydoc.getdoc(obj) -        return SphinxDocString(doc) - diff --git a/docs/sphinxext/inheritance_diagram.py b/docs/sphinxext/inheritance_diagram.py deleted file mode 100644 index 407fc13..0000000 --- a/docs/sphinxext/inheritance_diagram.py +++ /dev/null @@ -1,407 +0,0 @@ -""" -Defines a docutils directive for inserting inheritance diagrams. - -Provide the directive with one or more classes or modules (separated -by whitespace).  For modules, all of the classes in that module will -be used. - -Example:: - -   Given the following classes: - -   class A: pass -   class B(A): pass -   class C(A): pass -   class D(B, C): pass -   class E(B): pass - -   .. inheritance-diagram: D E - -   Produces a graph like the following: - -               A -              / \ -             B   C -            / \ / -           E   D - -The graph is inserted as a PNG+image map into HTML and a PDF in -LaTeX. -""" - -import inspect -import os -import re -import subprocess -try: -    from hashlib import md5 -except ImportError: -    from md5 import md5 - -from docutils.nodes import Body, Element -from docutils.parsers.rst import directives -from sphinx.roles import xfileref_role - -def my_import(name): -    """Module importer - taken from the python documentation. - -    This function allows importing names with dots in them.""" -     -    mod = __import__(name) -    components = name.split('.') -    for comp in components[1:]: -        mod = getattr(mod, comp) -    return mod - -class DotException(Exception): -    pass - -class InheritanceGraph(object): -    """ -    Given a list of classes, determines the set of classes that -    they inherit from all the way to the root "object", and then -    is able to generate a graphviz dot graph from them. -    """ -    def __init__(self, class_names, show_builtins=False): -        """ -        *class_names* is a list of child classes to show bases from. - -        If *show_builtins* is True, then Python builtins will be shown -        in the graph. -        """ -        self.class_names = class_names -        self.classes = self._import_classes(class_names) -        self.all_classes = self._all_classes(self.classes) -        if len(self.all_classes) == 0: -            raise ValueError("No classes found for inheritance diagram") -        self.show_builtins = show_builtins - -    py_sig_re = re.compile(r'''^([\w.]*\.)?    # class names -                           (\w+)  \s* $        # optionally arguments -                           ''', re.VERBOSE) - -    def _import_class_or_module(self, name): -        """ -        Import a class using its fully-qualified *name*. -        """ -        try: -            path, base = self.py_sig_re.match(name).groups() -        except: -            raise ValueError( -                "Invalid class or module '%s' specified for inheritance diagram" % name) -        fullname = (path or '') + base -        path = (path and path.rstrip('.')) -        if not path: -            path = base -        try: -            module = __import__(path, None, None, []) -            # We must do an import of the fully qualified name.  Otherwise if a -            # subpackage 'a.b' is requested where 'import a' does NOT provide -            # 'a.b' automatically, then 'a.b' will not be found below.  This -            # second call will force the equivalent of 'import a.b' to happen -            # after the top-level import above. -            my_import(fullname) -             -        except ImportError: -            raise ValueError( -                "Could not import class or module '%s' specified for inheritance diagram" % name) - -        try: -            todoc = module -            for comp in fullname.split('.')[1:]: -                todoc = getattr(todoc, comp) -        except AttributeError: -            raise ValueError( -                "Could not find class or module '%s' specified for inheritance diagram" % name) - -        # If a class, just return it -        if inspect.isclass(todoc): -            return [todoc] -        elif inspect.ismodule(todoc): -            classes = [] -            for cls in todoc.__dict__.values(): -                if inspect.isclass(cls) and cls.__module__ == todoc.__name__: -                    classes.append(cls) -            return classes -        raise ValueError( -            "'%s' does not resolve to a class or module" % name) - -    def _import_classes(self, class_names): -        """ -        Import a list of classes. -        """ -        classes = [] -        for name in class_names: -            classes.extend(self._import_class_or_module(name)) -        return classes - -    def _all_classes(self, classes): -        """ -        Return a list of all classes that are ancestors of *classes*. -        """ -        all_classes = {} - -        def recurse(cls): -            all_classes[cls] = None -            for c in cls.__bases__: -                if c not in all_classes: -                    recurse(c) - -        for cls in classes: -            recurse(cls) - -        return all_classes.keys() - -    def class_name(self, cls, parts=0): -        """ -        Given a class object, return a fully-qualified name.  This -        works for things I've tested in matplotlib so far, but may not -        be completely general. -        """ -        module = cls.__module__ -        if module == '__builtin__': -            fullname = cls.__name__ -        else: -            fullname = "%s.%s" % (module, cls.__name__) -        if parts == 0: -            return fullname -        name_parts = fullname.split('.') -        return '.'.join(name_parts[-parts:]) - -    def get_all_class_names(self): -        """ -        Get all of the class names involved in the graph. -        """ -        return [self.class_name(x) for x in self.all_classes] - -    # These are the default options for graphviz -    default_graph_options = { -        "rankdir": "LR", -        "size": '"8.0, 12.0"' -        } -    default_node_options = { -        "shape": "box", -        "fontsize": 10, -        "height": 0.25, -        "fontname": "Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans", -        "style": '"setlinewidth(0.5)"' -        } -    default_edge_options = { -        "arrowsize": 0.5, -        "style": '"setlinewidth(0.5)"' -        } - -    def _format_node_options(self, options): -        return ','.join(["%s=%s" % x for x in options.items()]) -    def _format_graph_options(self, options): -        return ''.join(["%s=%s;\n" % x for x in options.items()]) - -    def generate_dot(self, fd, name, parts=0, urls={}, -                     graph_options={}, node_options={}, -                     edge_options={}): -        """ -        Generate a graphviz dot graph from the classes that -        were passed in to __init__. - -        *fd* is a Python file-like object to write to. - -        *name* is the name of the graph - -        *urls* is a dictionary mapping class names to http urls - -        *graph_options*, *node_options*, *edge_options* are -        dictionaries containing key/value pairs to pass on as graphviz -        properties. -        """ -        g_options = self.default_graph_options.copy() -        g_options.update(graph_options) -        n_options = self.default_node_options.copy() -        n_options.update(node_options) -        e_options = self.default_edge_options.copy() -        e_options.update(edge_options) - -        fd.write('digraph %s {\n' % name) -        fd.write(self._format_graph_options(g_options)) - -        for cls in self.all_classes: -            if not self.show_builtins and cls in __builtins__.values(): -                continue - -            name = self.class_name(cls, parts) - -            # Write the node -            this_node_options = n_options.copy() -            url = urls.get(self.class_name(cls)) -            if url is not None: -                this_node_options['URL'] = '"%s"' % url -            fd.write('  "%s" [%s];\n' % -                     (name, self._format_node_options(this_node_options))) - -            # Write the edges -            for base in cls.__bases__: -                if not self.show_builtins and base in __builtins__.values(): -                    continue - -                base_name = self.class_name(base, parts) -                fd.write('  "%s" -> "%s" [%s];\n' % -                         (base_name, name, -                          self._format_node_options(e_options))) -        fd.write('}\n') - -    def run_dot(self, args, name, parts=0, urls={}, -                graph_options={}, node_options={}, edge_options={}): -        """ -        Run graphviz 'dot' over this graph, returning whatever 'dot' -        writes to stdout. - -        *args* will be passed along as commandline arguments. - -        *name* is the name of the graph - -        *urls* is a dictionary mapping class names to http urls - -        Raises DotException for any of the many os and -        installation-related errors that may occur. -        """ -        try: -            dot = subprocess.Popen(['dot'] + list(args), -                                   stdin=subprocess.PIPE, stdout=subprocess.PIPE, -                                   close_fds=True) -        except OSError: -            raise DotException("Could not execute 'dot'.  Are you sure you have 'graphviz' installed?") -        except ValueError: -            raise DotException("'dot' called with invalid arguments") -        except: -            raise DotException("Unexpected error calling 'dot'") - -        self.generate_dot(dot.stdin, name, parts, urls, graph_options, -                          node_options, edge_options) -        dot.stdin.close() -        result = dot.stdout.read() -        returncode = dot.wait() -        if returncode != 0: -            raise DotException("'dot' returned the errorcode %d" % returncode) -        return result - -class inheritance_diagram(Body, Element): -    """ -    A docutils node to use as a placeholder for the inheritance -    diagram. -    """ -    pass - -def inheritance_diagram_directive(name, arguments, options, content, lineno, -                                  content_offset, block_text, state, -                                  state_machine): -    """ -    Run when the inheritance_diagram directive is first encountered. -    """ -    node = inheritance_diagram() - -    class_names = arguments - -    # Create a graph starting with the list of classes -    graph = InheritanceGraph(class_names) - -    # Create xref nodes for each target of the graph's image map and -    # add them to the doc tree so that Sphinx can resolve the -    # references to real URLs later.  These nodes will eventually be -    # removed from the doctree after we're done with them. -    for name in graph.get_all_class_names(): -        refnodes, x = xfileref_role( -            'class', ':class:`%s`' % name, name, 0, state) -        node.extend(refnodes) -    # Store the graph object so we can use it to generate the -    # dot file later -    node['graph'] = graph -    # Store the original content for use as a hash -    node['parts'] = options.get('parts', 0) -    node['content'] = " ".join(class_names) -    return [node] - -def get_graph_hash(node): -    return md5(node['content'] + str(node['parts'])).hexdigest()[-10:] - -def html_output_graph(self, node): -    """ -    Output the graph for HTML.  This will insert a PNG with clickable -    image map. -    """ -    graph = node['graph'] -    parts = node['parts'] - -    graph_hash = get_graph_hash(node) -    name = "inheritance%s" % graph_hash -    path = '_images' -    dest_path = os.path.join(setup.app.builder.outdir, path) -    if not os.path.exists(dest_path): -        os.makedirs(dest_path) -    png_path = os.path.join(dest_path, name + ".png") -    path = setup.app.builder.imgpath - -    # Create a mapping from fully-qualified class names to URLs. -    urls = {} -    for child in node: -        if child.get('refuri') is not None: -            urls[child['reftitle']] = child.get('refuri') -        elif child.get('refid') is not None: -            urls[child['reftitle']] = '#' + child.get('refid') - -    # These arguments to dot will save a PNG file to disk and write -    # an HTML image map to stdout. -    image_map = graph.run_dot(['-Tpng', '-o%s' % png_path, '-Tcmapx'], -                              name, parts, urls) -    return ('<img src="%s/%s.png" usemap="#%s" class="inheritance"/>%s' % -            (path, name, name, image_map)) - -def latex_output_graph(self, node): -    """ -    Output the graph for LaTeX.  This will insert a PDF. -    """ -    graph = node['graph'] -    parts = node['parts'] - -    graph_hash = get_graph_hash(node) -    name = "inheritance%s" % graph_hash -    dest_path = os.path.abspath(os.path.join(setup.app.builder.outdir, '_images')) -    if not os.path.exists(dest_path): -        os.makedirs(dest_path) -    pdf_path = os.path.abspath(os.path.join(dest_path, name + ".pdf")) - -    graph.run_dot(['-Tpdf', '-o%s' % pdf_path], -                  name, parts, graph_options={'size': '"6.0,6.0"'}) -    return '\n\\includegraphics{%s}\n\n' % pdf_path - -def visit_inheritance_diagram(inner_func): -    """ -    This is just a wrapper around html/latex_output_graph to make it -    easier to handle errors and insert warnings. -    """ -    def visitor(self, node): -        try: -            content = inner_func(self, node) -        except DotException, e: -            # Insert the exception as a warning in the document -            warning = self.document.reporter.warning(str(e), line=node.line) -            warning.parent = node -            node.children = [warning] -        else: -            source = self.document.attributes['source'] -            self.body.append(content) -            node.children = [] -    return visitor - -def do_nothing(self, node): -    pass - -def setup(app): -    setup.app = app -    setup.confdir = app.confdir - -    app.add_node( -        inheritance_diagram, -        latex=(visit_inheritance_diagram(latex_output_graph), do_nothing), -        html=(visit_inheritance_diagram(html_output_graph), do_nothing)) -    app.add_directive( -        'inheritance-diagram', inheritance_diagram_directive, -        False, (1, 100, 0), parts = directives.nonnegative_int) diff --git a/docs/sphinxext/ipython_console_highlighting.py b/docs/sphinxext/ipython_console_highlighting.py deleted file mode 100644 index 217b779..0000000 --- a/docs/sphinxext/ipython_console_highlighting.py +++ /dev/null @@ -1,114 +0,0 @@ -"""reST directive for syntax-highlighting ipython interactive sessions. - -XXX - See what improvements can be made based on the new (as of Sept 2009) -'pycon' lexer for the python console.  At the very least it will give better -highlighted tracebacks. -""" - -#----------------------------------------------------------------------------- -# Needed modules - -# Standard library -import re - -# Third party -from pygments.lexer import Lexer, do_insertions -from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer,  -                                   PythonTracebackLexer) -from pygments.token import Comment, Generic - -from sphinx import highlighting - -#----------------------------------------------------------------------------- -# Global constants -line_re = re.compile('.*?\n') - -#----------------------------------------------------------------------------- -# Code begins - classes and functions - -class IPythonConsoleLexer(Lexer): -    """ -    For IPython console output or doctests, such as: - -    .. sourcecode:: ipython - -      In [1]: a = 'foo' - -      In [2]: a -      Out[2]: 'foo' - -      In [3]: print a -      foo - -      In [4]: 1 / 0 - -    Notes: - -      - Tracebacks are not currently supported. - -      - It assumes the default IPython prompts, not customized ones. -    """ -     -    name = 'IPython console session' -    aliases = ['ipython'] -    mimetypes = ['text/x-ipython-console'] -    input_prompt = re.compile("(In \[[0-9]+\]: )|(   \.\.\.+:)") -    output_prompt = re.compile("(Out\[[0-9]+\]: )|(   \.\.\.+:)") -    continue_prompt = re.compile("   \.\.\.+:") -    tb_start = re.compile("\-+") - -    def get_tokens_unprocessed(self, text): -        pylexer = PythonLexer(**self.options) -        tblexer = PythonTracebackLexer(**self.options) - -        curcode = '' -        insertions = [] -        for match in line_re.finditer(text): -            line = match.group() -            input_prompt = self.input_prompt.match(line) -            continue_prompt = self.continue_prompt.match(line.rstrip()) -            output_prompt = self.output_prompt.match(line) -            if line.startswith("#"): -                insertions.append((len(curcode), -                                   [(0, Comment, line)])) -            elif input_prompt is not None: -                insertions.append((len(curcode), -                                   [(0, Generic.Prompt, input_prompt.group())])) -                curcode += line[input_prompt.end():] -            elif continue_prompt is not None: -                insertions.append((len(curcode), -                                   [(0, Generic.Prompt, continue_prompt.group())])) -                curcode += line[continue_prompt.end():] -            elif output_prompt is not None: -                # Use the 'error' token for output.  We should probably make -                # our own token, but error is typicaly in a bright color like -                # red, so it works fine for our output prompts. -                insertions.append((len(curcode), -                                   [(0, Generic.Error, output_prompt.group())])) -                curcode += line[output_prompt.end():] -            else: -                if curcode: -                    for item in do_insertions(insertions, -                                              pylexer.get_tokens_unprocessed(curcode)): -                        yield item -                        curcode = '' -                        insertions = [] -                yield match.start(), Generic.Output, line -        if curcode: -            for item in do_insertions(insertions, -                                      pylexer.get_tokens_unprocessed(curcode)): -                yield item - - -def setup(app): -    """Setup as a sphinx extension.""" - -    # This is only a lexer, so adding it below to pygments appears sufficient. -    # But if somebody knows that the right API usage should be to do that via -    # sphinx, by all means fix it here.  At least having this setup.py -    # suppresses the sphinx warning we'd get without it. -    pass - -#----------------------------------------------------------------------------- -# Register the extension as a valid pygments lexer -highlighting.lexers['ipython'] = IPythonConsoleLexer() diff --git a/docs/sphinxext/numpydoc.py b/docs/sphinxext/numpydoc.py deleted file mode 100644 index 7b4821b..0000000 --- a/docs/sphinxext/numpydoc.py +++ /dev/null @@ -1,116 +0,0 @@ -""" -======== -numpydoc -======== - -Sphinx extension that handles docstrings in the Numpy standard format. [1] - -It will: - -- Convert Parameters etc. sections to field lists. -- Convert See Also section to a See also entry. -- Renumber references. -- Extract the signature from the docstring, if it can't be determined otherwise. - -.. [1] http://projects.scipy.org/scipy/numpy/wiki/CodingStyleGuidelines#docstring-standard - -""" - -import os, re, pydoc -from docscrape_sphinx import get_doc_object, SphinxDocString -import inspect - -def mangle_docstrings(app, what, name, obj, options, lines, -                      reference_offset=[0]): -    if what == 'module': -        # Strip top title -        title_re = re.compile(r'^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s*', -                              re.I|re.S) -        lines[:] = title_re.sub('', "\n".join(lines)).split("\n") -    else: -        doc = get_doc_object(obj, what, "\n".join(lines)) -        lines[:] = unicode(doc).split("\n") - -    if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \ -           obj.__name__: -        if hasattr(obj, '__module__'): -            v = dict(full_name="%s.%s" % (obj.__module__, obj.__name__)) -        else: -            v = dict(full_name=obj.__name__) -        lines += ['', '.. htmlonly::', ''] -        lines += ['    %s' % x for x in -                  (app.config.numpydoc_edit_link % v).split("\n")] - -    # replace reference numbers so that there are no duplicates -    references = [] -    for l in lines: -        l = l.strip() -        if l.startswith('.. ['): -            try: -                references.append(int(l[len('.. ['):l.index(']')])) -            except ValueError: -                print "WARNING: invalid reference in %s docstring" % name - -    # Start renaming from the biggest number, otherwise we may -    # overwrite references. -    references.sort() -    if references: -        for i, line in enumerate(lines): -            for r in references: -                new_r = reference_offset[0] + r -                lines[i] = lines[i].replace('[%d]_' % r, -                                            '[%d]_' % new_r) -                lines[i] = lines[i].replace('.. [%d]' % r, -                                            '.. [%d]' % new_r) - -    reference_offset[0] += len(references) - -def mangle_signature(app, what, name, obj, options, sig, retann): -    # Do not try to inspect classes that don't define `__init__` -    if (inspect.isclass(obj) and -        'initializes x; see ' in pydoc.getdoc(obj.__init__)): -        return '', '' - -    if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return -    if not hasattr(obj, '__doc__'): return - -    doc = SphinxDocString(pydoc.getdoc(obj)) -    if doc['Signature']: -        sig = re.sub("^[^(]*", "", doc['Signature']) -        return sig, '' - -def initialize(app): -    try: -        app.connect('autodoc-process-signature', mangle_signature) -    except: -        monkeypatch_sphinx_ext_autodoc() - -def setup(app, get_doc_object_=get_doc_object): -    global get_doc_object -    get_doc_object = get_doc_object_ -     -    app.connect('autodoc-process-docstring', mangle_docstrings) -    app.connect('builder-inited', initialize) -    app.add_config_value('numpydoc_edit_link', None, True) - -#------------------------------------------------------------------------------ -# Monkeypatch sphinx.ext.autodoc to accept argspecless autodocs (Sphinx < 0.5) -#------------------------------------------------------------------------------ - -def monkeypatch_sphinx_ext_autodoc(): -    global _original_format_signature -    import sphinx.ext.autodoc - -    if sphinx.ext.autodoc.format_signature is our_format_signature: -        return - -    print "[numpydoc] Monkeypatching sphinx.ext.autodoc ..." -    _original_format_signature = sphinx.ext.autodoc.format_signature -    sphinx.ext.autodoc.format_signature = our_format_signature - -def our_format_signature(what, obj): -    r = mangle_signature(None, what, None, obj, None, None, None) -    if r is not None: -        return r[0] -    else: -        return _original_format_signature(what, obj) diff --git a/docs/sphinxext/sphinx_cython.py b/docs/sphinxext/sphinx_cython.py deleted file mode 100644 index 38c6322..0000000 --- a/docs/sphinxext/sphinx_cython.py +++ /dev/null @@ -1,115 +0,0 @@ -''' - -sphinx_cython.py - -This module monkeypatches sphinx autodoc to support Cython generated -function signatures in the first line of the docstring of functions -implemented as C extensions.  - -Copyright (C) Nikolaus Rath <Nikolaus@rath.org> - -This file is part of LLFUSE (http://python-llfuse.googlecode.com). -LLFUSE can be distributed under the terms of the GNU LGPL. - -It has been slightly modified by MinRK. -''' - -import sphinx.ext.autodoc as SphinxAutodoc -from sphinx.util.docstrings import prepare_docstring -import inspect -import re -from sphinx.util import force_decode - -TYPE_RE = re.compile(r'(?:int|char)(?:\s+\*?\s*|\s*\*?\s+)([a-zA-Z_].*)') - -ClassDocumenter  = SphinxAutodoc.ClassDocumenter -MethodDocumenter = SphinxAutodoc.MethodDocumenter -FunctionDocumenter = SphinxAutodoc.FunctionDocumenter - -class MyDocumenter(SphinxAutodoc.Documenter): -    ''' -    Overwrites `get_doc()` to remove function and -    method signatures and `format_args` to parse and give -    precedence to function signatures in the first line -    of the docstring.  -    '''  - -    def get_doc(self, encoding=None): -        docstr = self.get_attr(self.object, '__doc__', None) -        if docstr: -            docstr = force_decode(docstr, encoding) -         -        myname = self.fullname[len(self.modname)+1:] -        if myname.endswith('()'): -            myname = myname[:-2] -         -        if (docstr -            and (myname + '(') in docstr -            and '\n' in docstr -            and docstr[docstr.index('\n')-1] == ')'): -            docstr = docstr[docstr.index('\n')+1:] -                     -        if docstr: -            # make sure we have Unicode docstrings, then sanitize and split -            # into lines -            return [prepare_docstring(force_decode(docstr, encoding))] -        return [] -         -         -    def format_args(self): -        myname = self.fullname[len(self.modname)+1:] -        if myname.endswith('()'): -            myname = myname[:-2] -        # Try to parse docstring -        docstr = self.get_attr(self.object, '__doc__', None) -        if docstr: -            docstr = force_decode(docstr, 'utf-8') -        if (docstr  -            and (myname + '(') in docstr -            and '\n' in docstr -            and docstr[docstr.index('\n')-1] == ')'): -            args = docstr[len(myname)+1:docstr.index('\n')-1] -             -            # Get rid of Cython style types declarations -            argl = [] -            for arg in [ x.strip() for x in args.split(',') ]: -                if (arg in ('cls', 'self')  -                    and isinstance(self, SphinxAutodoc.MethodDocumenter)): -                    continue  -                hit = TYPE_RE.match(arg) -                if hit: -                    argl.append(hit.group(1)) -                else: -                    argl.append(arg) -            args = '(%s)' % ', '.join(argl) -        else: -            # super seems to get this wrong: -            for cls in (MethodDocumenter, -                        FunctionDocumenter, -                        ClassDocumenter): -                if isinstance(self, cls): -                    return cls.format_args(self) -            # return super(self.__class__, self).format_args()   - -        # escape backslashes for reST -        args = args.replace('\\', '\\\\') -        return args - - -class MyFunctionDocumenter(MyDocumenter, SphinxAutodoc.FunctionDocumenter): -    pass -         -class MyMethodDocumenter(MyDocumenter, SphinxAutodoc.MethodDocumenter):     -    pass - -class MyClassDocumenter(MyDocumenter, SphinxAutodoc.ClassDocumenter):     -    def format_signature(self): -        return self.format_args() or "()" - -SphinxAutodoc.ClassDocumenter = MyClassDocumenter  -SphinxAutodoc.MethodDocumenter = MyMethodDocumenter  -SphinxAutodoc.FunctionDocumenter = MyFunctionDocumenter - -# don't use AttributeDocumenter on 'method_descriptor' members: -AD = SphinxAutodoc.AttributeDocumenter -AD.method_types = tuple(list(AD.method_types) + [type(str.count)]) diff --git a/docs/update_ghpages.sh b/docs/update_ghpages.sh deleted file mode 100755 index a097691..0000000 --- a/docs/update_ghpages.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env sh -# pick repo for gh-pages branch -repo=origin - -if [ ! -d gh-pages ]; then -    echo "setting up gh-pages subdir" -    mkdir gh-pages || exit -1 -    cp -r ../.git gh-pages/ || exit -1 -    cd gh-pages || exit -1 -    init=0 -    git checkout $repo/gh-pages || init=1 -    if [ "$init" != "0" ]; then -        echo "initializing gh-pages repo" -        git symbolic-ref HEAD refs/heads/gh-pages || exit -1 -        rm .git/index || exit -1 -        git clean -fdx || exit -1 -        touch index.html -        git add . -        git commit -a -m 'init gh-pages' || exit -1 -        git push origin HEAD:gh-pages -    fi -    cd .. -fi -echo "updating local gh-pages with html build" -rsync -va build/html/ gh-pages/ --delete --exclude .git --exclude .nojekyll || exit -1 -cd gh-pages -touch .nojekyll -git add .nojekyll -git add . -git commit -a || exit -1 -echo "pushing to remote gh-pages" -# pwd -git push $repo HEAD:gh-pages diff --git a/examples/LICENSE b/examples/LICENSE deleted file mode 100644 index d4d3950..0000000 --- a/examples/LICENSE +++ /dev/null @@ -1,3 +0,0 @@ -PyZMQ examples are copyright their respective authors, and licensed -under the New BSD License as described in COPYING.BSD unless otherwise -specified in the file.
\ No newline at end of file diff --git a/examples/README_PY3K b/examples/README_PY3K deleted file mode 100644 index d5272d0..0000000 --- a/examples/README_PY3K +++ /dev/null @@ -1,10 +0,0 @@ -These examples use Python2 syntax.  Due to the change in Python from bytestring str objects -to unicode str objects, 2to3 does not perform an adequate transform of the code.  Examples -can be valid on both Python2.5 and Python3, but such code is less readable than it should be. - -As a result, the Python3 examples are kept in a separate repo: - -https://github.com/minrk/pyzmq-py3k-examples - - -The differences are very small, but important.
\ No newline at end of file diff --git a/examples/bench/benchmark.py b/examples/bench/benchmark.py deleted file mode 100644 index c379af9..0000000 --- a/examples/bench/benchmark.py +++ /dev/null @@ -1,25 +0,0 @@ -from timeit import default_timer as timer - -def benchmark(f, size, reps): -    msg = size*'0' -    t1 = timer() -    for i in range(reps): -        msg2 = f(msg) -        assert msg == msg2 -    t2 = timer() -    diff = (t2-t1) -    latency = diff/reps -    return latency*1000000 - -kB = [1000*2**n for n in range(10)] -MB = [1000000*2**n for n in range(8)] -sizes = [1] + kB + MB - -def benchmark_set(f, sizes, reps): -    latencies = [] -    for size, rep in zip(sizes, reps): -        print "Running benchmark with %r reps of %r bytes" % (rep, size) -        lat = benchmark(f, size, rep) -        latencies.append(lat) -    return sizes, latencies - diff --git a/examples/bench/jsonrpc_client.py b/examples/bench/jsonrpc_client.py deleted file mode 100644 index 7fb6ef4..0000000 --- a/examples/bench/jsonrpc_client.py +++ /dev/null @@ -1,4 +0,0 @@ -from timeit import default_timer as timer -from jsonrpclib import Server - -client = Server('http://localhost:10000') diff --git a/examples/bench/jsonrpc_server.py b/examples/bench/jsonrpc_server.py deleted file mode 100644 index 4500a02..0000000 --- a/examples/bench/jsonrpc_server.py +++ /dev/null @@ -1,8 +0,0 @@ -from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer - -def echo(x): -    return x - -server = SimpleJSONRPCServer(('localhost',10000)) -server.register_function(echo) -server.serve_forever()
\ No newline at end of file diff --git a/examples/bench/latency.png b/examples/bench/latency.png Binary files differdeleted file mode 100644 index bb414b5..0000000 --- a/examples/bench/latency.png +++ /dev/null diff --git a/examples/bench/msgs_sec.png b/examples/bench/msgs_sec.png Binary files differdeleted file mode 100644 index a7b294b..0000000 --- a/examples/bench/msgs_sec.png +++ /dev/null diff --git a/examples/bench/msgs_sec_log.png b/examples/bench/msgs_sec_log.png Binary files differdeleted file mode 100644 index c3a361e..0000000 --- a/examples/bench/msgs_sec_log.png +++ /dev/null diff --git a/examples/bench/msgs_sec_ratio.png b/examples/bench/msgs_sec_ratio.png Binary files differdeleted file mode 100644 index 0a87331..0000000 --- a/examples/bench/msgs_sec_ratio.png +++ /dev/null diff --git a/examples/bench/plot_latency.py b/examples/bench/plot_latency.py deleted file mode 100644 index f50ef29..0000000 --- a/examples/bench/plot_latency.py +++ /dev/null @@ -1,84 +0,0 @@ -"""Plot latency data from messaging benchmarks. - -To generate the data for each library, I started the server and then did -the following for each client:: - -    from xmlrpc_client import client -    for i in range(9): -        s = '0'*10**i -        print s -        %timeit client.echo(s) -""" - -from matplotlib.pylab import * - -rawdata = """# Data in milliseconds -Bytes	JSONRPC	PYRO	XMLRPC	pyzmq_copy	pyzmq_nocopy -1	2.15	0.186	2.07	0.111	0.136 -10	2.49	0.187	1.87	0.115	0.137 -100	2.5	0.189	1.9	0.126	0.138 -1000	2.54	0.196	1.91	0.129	0.141 -10000	2.91	0.271	2.77	0.204	0.197 -100000	6.65	1.44	9.17	0.961	0.546 -1000000	50.2	15.8	81.5	8.39	2.25 -10000000	491	159	816	91.7	25.2 -100000000	5010	1560	8300	893	248 - -""" -with open('latency.csv','w') as f: -    f.writelines(rawdata) - -data = csv2rec('latency.csv',delimiter='\t') - -loglog(data.bytes, data.xmlrpc*1000, label='XMLRPC') -loglog(data.bytes, data.jsonrpc*1000, label='JSONRPC') -loglog(data.bytes, data.pyro*1000, label='Pyro') -loglog(data.bytes, data.pyzmq_nocopy*1000, label='PyZMQ') -loglog(data.bytes, len(data.bytes)*[60], label='Ping') -legend(loc=2) -title('Latency') -xlabel('Number of bytes') -ylabel('Round trip latency ($\mu s$)') -grid(True) -show() -savefig('latency.png') - -clf() - -semilogx(data.bytes, 1000/data.xmlrpc, label='XMLRPC') -semilogx(data.bytes, 1000/data.jsonrpc, label='JSONRPC') -semilogx(data.bytes, 1000/data.pyro, label='Pyro') -semilogx(data.bytes, 1000/data.pyzmq_nocopy, label='PyZMQ') -legend(loc=1) -xlabel('Number of bytes') -ylabel('Message/s') -title('Message Throughput') -grid(True) -show() -savefig('msgs_sec.png') - -clf() - -loglog(data.bytes, 1000/data.xmlrpc, label='XMLRPC') -loglog(data.bytes, 1000/data.jsonrpc, label='JSONRPC') -loglog(data.bytes, 1000/data.pyro, label='Pyro') -loglog(data.bytes, 1000/data.pyzmq_nocopy, label='PyZMQ') -legend(loc=3) -xlabel('Number of bytes') -ylabel('Message/s') -title('Message Throughput') -grid(True) -show() -savefig('msgs_sec_log.png') - -clf() - -semilogx(data.bytes, data.pyro/data.pyzmq_nocopy, label="No-copy") -semilogx(data.bytes, data.pyro/data.pyzmq_copy, label="Copy") -xlabel('Number of bytes') -ylabel('Ratio throughputs') -title('PyZMQ Throughput/Pyro Throughput') -grid(True) -legend(loc=2) -show() -savefig('msgs_sec_ratio.png') diff --git a/examples/bench/pyro_client.py b/examples/bench/pyro_client.py deleted file mode 100644 index 5e25feb..0000000 --- a/examples/bench/pyro_client.py +++ /dev/null @@ -1,3 +0,0 @@ -import Pyro.core - -client = Pyro.core.getProxyForURI("PYROLOC://localhost:7766/echo")
\ No newline at end of file diff --git a/examples/bench/pyro_server.py b/examples/bench/pyro_server.py deleted file mode 100644 index a2a2446..0000000 --- a/examples/bench/pyro_server.py +++ /dev/null @@ -1,14 +0,0 @@ -import Pyro.core - -class Echo(Pyro.core.ObjBase): -        def __init__(self): -                Pyro.core.ObjBase.__init__(self) -        def echo(self, x): -                return x - -Pyro.core.initServer() -daemon=Pyro.core.Daemon() -uri=daemon.connect(Echo(),"echo") - -daemon.requestLoop() -    
\ No newline at end of file diff --git a/examples/bench/pyzmq_client.py b/examples/bench/pyzmq_client.py deleted file mode 100644 index 9afccec..0000000 --- a/examples/bench/pyzmq_client.py +++ /dev/null @@ -1,16 +0,0 @@ -import zmq - -c = zmq.Context() -s = c.socket(zmq.REQ) -s.connect('tcp://127.0.0.1:10001') - -def echo(msg): -    s.send(msg, copy=False) -    msg2 = s.recv(copy=False) -    return msg2 - -class Client(object): -    pass - -client = Client() -client.echo = echo diff --git a/examples/bench/pyzmq_server.py b/examples/bench/pyzmq_server.py deleted file mode 100644 index cab0082..0000000 --- a/examples/bench/pyzmq_server.py +++ /dev/null @@ -1,10 +0,0 @@ -import zmq - -c = zmq.Context() -s = c.socket(zmq.REP) -s.bind('tcp://127.0.0.1:10001') - -while True: -    msg = s.recv(copy=False) -    s.send(msg) - diff --git a/examples/bench/xmlrpc_client.py b/examples/bench/xmlrpc_client.py deleted file mode 100644 index a73ddfd..0000000 --- a/examples/bench/xmlrpc_client.py +++ /dev/null @@ -1,6 +0,0 @@ -from timeit import default_timer as timer -from xmlrpclib import ServerProxy - -client = ServerProxy('http://localhost:10002') - -    
\ No newline at end of file diff --git a/examples/bench/xmlrpc_server.py b/examples/bench/xmlrpc_server.py deleted file mode 100644 index 24ab019..0000000 --- a/examples/bench/xmlrpc_server.py +++ /dev/null @@ -1,8 +0,0 @@ -from SimpleXMLRPCServer import SimpleXMLRPCServer - -def echo(x): -    return x - -server = SimpleXMLRPCServer(('localhost',10002)) -server.register_function(echo) -server.serve_forever()
\ No newline at end of file diff --git a/examples/chat/display.py b/examples/chat/display.py deleted file mode 100644 index d4e240a..0000000 --- a/examples/chat/display.py +++ /dev/null @@ -1,41 +0,0 @@ -"""The display part of a simply two process chat app.""" - -# -#    Copyright (c) 2010 Andrew Gwozdziewycz -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. - -import zmq - -def main(addrs): -     -    context = zmq.Context() -    socket = context.socket(zmq.SUB) -    socket.setsockopt(zmq.SUBSCRIBE, "") -    for addr in addrs: -        print "Connecting to: ", addr -        socket.connect(addr) - -    while True: -        msg = socket.recv_pyobj() -        print "%s: %s" % (msg[1], msg[0]) - -if __name__ == '__main__': -    import sys -    if len(sys.argv) < 2: -        print "usage: display.py <address> [,<address>...]" -        raise SystemExit -    main(sys.argv[1:]) diff --git a/examples/chat/prompt.py b/examples/chat/prompt.py deleted file mode 100644 index d9b12ec..0000000 --- a/examples/chat/prompt.py +++ /dev/null @@ -1,39 +0,0 @@ -"""The prompt part of a simply two process chat app.""" - -# -#    Copyright (c) 2010 Andrew Gwozdziewycz -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. - -import zmq - -def main(addr, who): - -    ctx = zmq.Context() -    socket = ctx.socket(zmq.PUB) -    socket.bind(addr) - -    while True: -        msg = raw_input("%s> " % who) -        socket.send_pyobj((msg, who)) - - -if __name__ == '__main__': -    import sys -    if len(sys.argv) != 3: -        print "usage: prompt.py <address> <username>" -        raise SystemExit -    main(sys.argv[1], sys.argv[2]) diff --git a/examples/device/client.py b/examples/device/client.py deleted file mode 100644 index 14a4e26..0000000 --- a/examples/device/client.py +++ /dev/null @@ -1,38 +0,0 @@ -"""A client for the device based server.""" - -# -#    Copyright (c) 2010 Brian E. Granger and Eugene Chernyshov -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. - -import zmq -import os -from time import time - -print 'Client', os.getpid() - -context = zmq.Context(1) - -socket = context.socket(zmq.REQ) -socket.connect('tcp://127.0.0.1:5555') - -while True: -    data = zmq.Message(str(os.getpid())) -    start = time() -    socket.send(data) -    data = socket.recv() -    print time()-start, data - diff --git a/examples/device/server.py b/examples/device/server.py deleted file mode 100644 index b29a3c1..0000000 --- a/examples/device/server.py +++ /dev/null @@ -1,52 +0,0 @@ -"""A device based server.""" - -# -#    Copyright (c) 2010 Brian E. Granger and Eugene Chernyshov -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. - -import zmq -import os -import threading -import time - -print 'Server', os.getpid() - -def routine(context): -    socket = context.socket(zmq.REP) - -    socket.connect("inproc://workers") - -    while True: -        message = socket.recv() -        time.sleep(1) -        socket.send(message) - -context = zmq.Context(1) - -workers = context.socket(zmq.DEALER) -workers.bind("inproc://workers"); - -clients = context.socket(zmq.DEALER) -clients.bind('tcp://127.0.0.1:5555') - -for i in range(10): -    thread = threading.Thread(target=routine, args=(context, )) -    thread.start() - -zmq.device(zmq.QUEUE, clients, workers) - -print "Finished" diff --git a/examples/eventloop/asyncweb.py b/examples/eventloop/asyncweb.py deleted file mode 100644 index 06b03f3..0000000 --- a/examples/eventloop/asyncweb.py +++ /dev/null @@ -1,96 +0,0 @@ -"""Async web request example with tornado. - -Requests to localhost:8888 will be relayed via 0MQ to a slow responder, -who will take 1-5 seconds to respond.  The tornado app will remain responsive -duriung this time, and when the worker replies, the web request will finish. - -A '.' is printed every 100ms to demonstrate that the zmq request is not blocking -the event loop. -""" - - -import sys -import random -import threading -import time - -import zmq -from zmq.eventloop import ioloop, zmqstream - -""" -ioloop.install() must be called prior to instantiating *any* tornado objects, -and ideally before importing anything from tornado, just to be safe. - -install() sets the singleton instance of tornado.ioloop.IOLoop with zmq's -IOLoop. If this is not done properly, multiple IOLoop instances may be -created, which will have the effect of some subset of handlers never being -called, because only one loop will be running. -""" - -ioloop.install() - -import tornado -from tornado import web - - -def slow_responder(): -    """thread for slowly responding to replies.""" -    ctx = zmq.Context.instance() -    socket = ctx.socket(zmq.REP) -    socket.linger = 0 -    socket.bind('tcp://127.0.0.1:5555') -    i=0 -    while True: -        msg = socket.recv() -        print "\nworker received %r\n" % msg -        time.sleep(random.randint(1,5)) -        socket.send(msg + " to you too, #%i" % i) -        i+=1 - -def dot(): -    """callback for showing that IOLoop is still responsive while we wait""" -    sys.stdout.write('.') -    sys.stdout.flush() - -def printer(msg): -    print (msg) - -class TestHandler(web.RequestHandler): -     -    @web.asynchronous -    def get(self): -        ctx = zmq.Context.instance() -        s = ctx.socket(zmq.REQ) -        s.connect('tcp://127.0.0.1:5555') -        # send request to worker -        s.send('hello') -        loop = ioloop.IOLoop.instance() -        self.stream = zmqstream.ZMQStream(s) -        self.stream.on_recv(self.handle_reply) -     -    def handle_reply(self, msg): -        # finish web request with worker's reply -        reply = msg[0] -        print "\nfinishing with %r\n" % reply, -        self.stream.close() -        self.write(reply) -        self.finish() - -def main(): -    worker = threading.Thread(target=slow_responder) -    worker.daemon=True -    worker.start() -     -    application = web.Application([(r"/", TestHandler)]) -    beat = ioloop.PeriodicCallback(dot, 100) -    beat.start() -    application.listen(8888) -    try: -        ioloop.IOLoop.instance().start() -    except KeyboardInterrupt: -        print ' Interrupted' -     -     -if __name__ == "__main__": -    main() - diff --git a/examples/eventloop/echo.py b/examples/eventloop/echo.py deleted file mode 100644 index 9be079b..0000000 --- a/examples/eventloop/echo.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python -"""A trivial ZMQ echo server using the eventloop. - -Authors -------- -* MinRK -""" - -import zmq -from zmq.eventloop import ioloop - -loop = ioloop.IOLoop.instance() - -ctx = zmq.Context() -s = ctx.socket(zmq.REP) -s.bind('tcp://127.0.0.1:5555') - -def rep_handler(sock, events): -    # We don't know how many recv's we can do? -    msg = sock.recv() -    # No guarantee that we can do the send. We need a way of putting the -    # send in the event loop. -    sock.send(msg) - -loop.add_handler(s, rep_handler, zmq.POLLIN) - -loop.start()
\ No newline at end of file diff --git a/examples/eventloop/echostream.py b/examples/eventloop/echostream.py deleted file mode 100644 index 04c1532..0000000 --- a/examples/eventloop/echostream.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python -"""Adapted echo.py to put the send in the event loop using a ZMQStream. - -Authors -------- -* MinRK -""" - -import zmq -from zmq.eventloop import ioloop, zmqstream -loop = ioloop.IOLoop.instance() - -ctx = zmq.Context() -s = ctx.socket(zmq.REP) -s.bind('tcp://127.0.0.1:5555') -stream = zmqstream.ZMQStream(s, loop) - -def echo(msg): -    print " ".join(msg) -    stream.send_multipart(msg) - -stream.on_recv(echo) - -loop.start()
\ No newline at end of file diff --git a/examples/eventloop/web.py b/examples/eventloop/web.py deleted file mode 100644 index 1285f95..0000000 --- a/examples/eventloop/web.py +++ /dev/null @@ -1,46 +0,0 @@ -import zmq -from zmq.eventloop import ioloop, zmqstream - -""" -ioloop.install() must be called prior to instantiating *any* tornado objects, -and ideally before importing anything from tornado, just to be safe. - -install() sets the singleton instance of tornado.ioloop.IOLoop with zmq's -IOLoop. If this is not done properly, multiple IOLoop instances may be -created, which will have the effect of some subset of handlers never being -called, because only one loop will be running. -""" - -ioloop.install() - -import tornado -import tornado.web - - -""" -this application can be used with echostream.py, start echostream.py, -start web.py, then every time you hit http://localhost:8888/, -echostream.py will print out 'hello' -""" - -def printer(msg): -    print (msg) - -ctx = zmq.Context() -s = ctx.socket(zmq.REQ) -s.connect('tcp://127.0.0.1:5555') -stream = zmqstream.ZMQStream(s) -stream.on_recv(printer) - -class TestHandler(tornado.web.RequestHandler): -    def get(self): -        print ("sending hello") -        stream.send("hello") -        self.write("hello") -application = tornado.web.Application([(r"/", TestHandler)]) - -if __name__ == "__main__": -    application.listen(8888) -    ioloop.IOLoop.instance().start() - - diff --git a/examples/gevent/poll.py b/examples/gevent/poll.py deleted file mode 100644 index 1daf80a..0000000 --- a/examples/gevent/poll.py +++ /dev/null @@ -1,42 +0,0 @@ -import gevent -from zmq import green as zmq - -# Connect to both receiving sockets and send 10 messages -def sender(): - -    sender = context.socket(zmq.PUSH) -    sender.connect('inproc://polltest1') -    sender.connect('inproc://polltest2') - -    for i in xrange(10): -        sender.send('test %d' % i) -        gevent.sleep(1) - - -# create zmq context, and bind to pull sockets -context = zmq.Context() -receiver1 = context.socket(zmq.PULL) -receiver1.bind('inproc://polltest1') -receiver2 = context.socket(zmq.PULL) -receiver2.bind('inproc://polltest2') - -gevent.spawn(sender) - -# Create poller and register both reciever sockets -poller = zmq.Poller() -poller.register(receiver1, zmq.POLLIN) -poller.register(receiver2, zmq.POLLIN) - -# Read 10 messages from both reciever sockets -msgcnt = 0 -while msgcnt < 10: -    socks = dict(poller.poll()) -    if receiver1 in socks and socks[receiver1] == zmq.POLLIN: -        print "Message from receiver1: %s" % receiver1.recv() -        msgcnt += 1 - -    if receiver2 in socks and socks[receiver2] == zmq.POLLIN: -        print "Message from receiver2: %s" % receiver2.recv() -        msgcnt += 1 - -print "%d messages received" % msgcnt diff --git a/examples/gevent/reqrep.py b/examples/gevent/reqrep.py deleted file mode 100644 index 2a4f307..0000000 --- a/examples/gevent/reqrep.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -Complex example which is a combination of the rr* examples from the zguide. -""" -from gevent import spawn -import zmq.green as zmq - -# server -context = zmq.Context() -socket = context.socket(zmq.REP) -socket.connect("tcp://localhost:5560") - -def serve(socket): -    while True: -        message = socket.recv() -        print "Received request: ", message -        socket.send("World") -server = spawn(serve, socket) - - -# client -context = zmq.Context() -socket = context.socket(zmq.REQ) -socket.connect("tcp://localhost:5559") - -#  Do 10 requests, waiting each time for a response -def client(): -    for request in range(1,10): -        socket.send("Hello") -        message = socket.recv() -        print "Received reply ", request, "[", message, "]" - - -# broker -frontend = context.socket(zmq.ROUTER) -backend  = context.socket(zmq.DEALER); -frontend.bind("tcp://*:5559") -backend.bind("tcp://*:5560") - -def proxy(socket_from, socket_to): -    while True: -        m = socket_from.recv_multipart() -        socket_to.send_multipart(m) - -a = spawn(proxy, frontend, backend) -b = spawn(proxy, backend, frontend) - -spawn(client).join() diff --git a/examples/gevent/simple.py b/examples/gevent/simple.py deleted file mode 100644 index ae065b3..0000000 --- a/examples/gevent/simple.py +++ /dev/null @@ -1,37 +0,0 @@ -from gevent import spawn, spawn_later -import zmq.green as zmq - -# server -print zmq.Context -ctx = zmq.Context() -sock = ctx.socket(zmq.PUSH) -sock.bind('ipc:///tmp/zmqtest') - -spawn(sock.send_pyobj, ('this', 'is', 'a', 'python', 'tuple')) -spawn_later(1, sock.send_pyobj, {'hi': 1234}) -spawn_later(2, sock.send_pyobj, ({'this': ['is a more complicated object', ':)']}, 42, 42, 42)) -spawn_later(3, sock.send_pyobj, 'foobar') -spawn_later(4, sock.send_pyobj, 'quit') - - -# client -ctx = zmq.Context() # create a new context to kick the wheels -sock = ctx.socket(zmq.PULL) -sock.connect('ipc:///tmp/zmqtest') - -def get_objs(sock): -    while True: -        o = sock.recv_pyobj() -        print 'received python object:', o -        if o == 'quit': -            print 'exiting.' -            break - -def print_every(s, t=None): -    print s -    if t: -        spawn_later(t, print_every, s, t) - -print_every('printing every half second', 0.5) -spawn(get_objs, sock).join() - diff --git a/examples/heartbeat/heart.py b/examples/heartbeat/heart.py deleted file mode 100644 index 175370e..0000000 --- a/examples/heartbeat/heart.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python -"""This launches an echoing rep socket device, -and runs a blocking numpy action. The rep socket should -remain responsive to pings during this time. Use heartbeater.py to -ping this heart, and see the responsiveness. - -Authors -------- -* MinRK -""" - -import time -import numpy -import zmq -from zmq import devices - -ctx = zmq.Context() - -dev = devices.ThreadDevice(zmq.FORWARDER, zmq.SUB, zmq.DEALER) -dev.setsockopt_in(zmq.SUBSCRIBE, "") -dev.connect_in('tcp://127.0.0.1:5555') -dev.connect_out('tcp://127.0.0.1:5556') -dev.start() - -#wait for connections -time.sleep(1) - -A = numpy.random.random((2**11,2**11)) -print "starting blocking loop" -while True: -    tic = time.time() -    numpy.dot(A,A.transpose()) -    print "blocked for %.3f s"%(time.time()-tic) - diff --git a/examples/heartbeat/heartbeater.py b/examples/heartbeat/heartbeater.py deleted file mode 100644 index 180828a..0000000 --- a/examples/heartbeat/heartbeater.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python -""" - -For use with heart.py - -A basic heartbeater using PUB and ROUTER sockets. pings are sent out on the PUB, and hearts -are tracked based on their DEALER identities. - -You can start many hearts with heart.py, and the heartbeater will monitor all of them, and notice when they stop responding. - -Authors -------- -* MinRK -""" - -import time -import zmq -from zmq.eventloop import ioloop, zmqstream - - -class HeartBeater(object): -    """A basic HeartBeater class -    pingstream: a PUB stream -    pongstream: an ROUTER stream""" -     -    def __init__(self, loop, pingstream, pongstream, period=1000): -        self.loop = loop -        self.period = period -         -        self.pingstream = pingstream -        self.pongstream = pongstream -        self.pongstream.on_recv(self.handle_pong) -         -        self.hearts = set() -        self.responses = set() -        self.lifetime = 0 -        self.tic = time.time() -         -        self.caller = ioloop.PeriodicCallback(self.beat, period, self.loop) -        self.caller.start() -     -    def beat(self): -        toc = time.time() -        self.lifetime += toc-self.tic -        self.tic = toc -        print self.lifetime -        # self.message = str(self.lifetime) -        goodhearts = self.hearts.intersection(self.responses) -        heartfailures = self.hearts.difference(goodhearts) -        newhearts = self.responses.difference(goodhearts) -        # print newhearts, goodhearts, heartfailures -        map(self.handle_new_heart, newhearts) -        map(self.handle_heart_failure, heartfailures) -        self.responses = set() -        print "%i beating hearts: %s"%(len(self.hearts),self.hearts) -        self.pingstream.send(str(self.lifetime)) -     -    def handle_new_heart(self, heart): -        print "yay, got new heart %s!"%heart -        self.hearts.add(heart) -     -    def handle_heart_failure(self, heart): -        print "Heart %s failed :("%heart -        self.hearts.remove(heart) -         -     -    def handle_pong(self, msg): -        "if heart is beating" -        if msg[1] == str(self.lifetime): -            self.responses.add(msg[0]) -        else: -            print "got bad heartbeat (possibly old?): %s"%msg[1] -         -# sub.setsockopt(zmq.SUBSCRIBE) - - -if __name__ == '__main__': -    loop = ioloop.IOLoop() -    context = zmq.Context() -    pub = context.socket(zmq.PUB) -    pub.bind('tcp://127.0.0.1:5555') -    router = context.socket(zmq.ROUTER) -    router.bind('tcp://127.0.0.1:5556') -     -    outstream = zmqstream.ZMQStream(pub, loop) -    instream = zmqstream.ZMQStream(router, loop) -     -    hb = HeartBeater(loop, outstream, instream) -     -    loop.start() diff --git a/examples/heartbeat/ping.py b/examples/heartbeat/ping.py deleted file mode 100644 index 933a39a..0000000 --- a/examples/heartbeat/ping.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python -"""For use with pong.py - -This script simply pings a process started by pong.py or tspong.py, to  -demonstrate that zmq remains responsive while Python blocks. - -Authors -------- -* MinRK -""" - -import time -import numpy -import zmq - -ctx = zmq.Context() - -req = ctx.socket(zmq.REQ) -req.connect('tcp://127.0.0.1:10111') - -#wait for connects -time.sleep(1) -n=0 -while True: -    time.sleep(numpy.random.random()) -    for i in range(4): -        n+=1 -        msg = 'ping %i'%n -        tic = time.time() -        req.send(msg) -        resp = req.recv() -        print "%s: %.2f ms" % (msg, 1000*(time.time()-tic)) -        assert msg == resp - diff --git a/examples/heartbeat/pong.py b/examples/heartbeat/pong.py deleted file mode 100644 index 47efb3a..0000000 --- a/examples/heartbeat/pong.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python -"""This launches an echoing rep socket device using  -zmq.devices.ThreadDevice, and runs a blocking numpy action.  -The rep socket should remain responsive to pings during this time. - -Use ping.py to see how responsive it is. - -Authors -------- -* MinRK -""" - -import time -import numpy -import zmq -from zmq import devices - -ctx = zmq.Context() - -dev = devices.ThreadDevice(zmq.FORWARDER, zmq.REP, -1) -dev.bind_in('tcp://127.0.0.1:10111') -dev.setsockopt_in(zmq.IDENTITY, "whoda") -dev.start() - -#wait for connections -time.sleep(1) - -A = numpy.random.random((2**11,2**12)) -print "starting blocking loop" -while True: -    tic = time.time() -    numpy.dot(A,A.transpose()) -    print "blocked for %.3f s"%(time.time()-tic) - diff --git a/examples/logger/zmqlogger.py b/examples/logger/zmqlogger.py deleted file mode 100644 index c55b51b..0000000 --- a/examples/logger/zmqlogger.py +++ /dev/null @@ -1,70 +0,0 @@ -""" -Simple example of using zmq log handlers - -This starts a number of subprocesses with PUBHandlers that generate -log messages at a regular interval.  The main process has a SUB socket, -which aggregates and logs all of the messages to the root logger. -""" - -import logging -from multiprocessing import Process -import os -import random -import sys -import time - -import zmq -from zmq.log.handlers import PUBHandler - -LOG_LEVELS = (logging.DEBUG, logging.INFO, logging.WARN, logging.ERROR, logging.CRITICAL) - -def sub_logger(port, level=logging.DEBUG): -    ctx = zmq.Context() -    sub = ctx.socket(zmq.SUB) -    sub.bind('tcp://127.0.0.1:%i' % port) -    sub.setsockopt(zmq.SUBSCRIBE, "") -    logging.basicConfig(level=level) -     -    while True: -        level, message = sub.recv_multipart() -        if message.endswith('\n'): -            # trim trailing newline, which will get appended again -            message = message[:-1] -        log = getattr(logging, level.lower()) -        log(message) - -def log_worker(port, interval=1, level=logging.DEBUG): -    ctx = zmq.Context() -    pub = ctx.socket(zmq.PUB) -    pub.connect('tcp://127.0.0.1:%i' % port) -     -    logger = logging.getLogger(str(os.getpid())) -    logger.setLevel(level) -    handler = PUBHandler(pub) -    logger.addHandler(handler) -    print "starting logger at %i with level=%s" % (os.getpid(), level) - -    while True: -        level = random.choice(LOG_LEVELS) -        logger.log(level, "Hello from %i!" % os.getpid()) -        time.sleep(interval) - -if __name__ == '__main__': -    if len(sys.argv) > 1: -        n = int(sys.argv[1]) -    else: -        n = 2 -     -    port = 5555 -     -    # start the log generators -    workers = [ Process(target=log_worker, args=(port,), kwargs=dict(level=random.choice(LOG_LEVELS))) for i in range(n) ] -    [ w.start() for w in workers ] -     -    # start the log watcher -    try: -        sub_logger(port) -    except KeyboardInterrupt: -        pass -    finally: -        [ w.terminate() for w in workers ] diff --git a/examples/mongodb/client.py b/examples/mongodb/client.py deleted file mode 100644 index 839dce7..0000000 --- a/examples/mongodb/client.py +++ /dev/null @@ -1,46 +0,0 @@ -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Justin Riley -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import json -import zmq - -class MongoZMQClient(object): -    """ -    Client that connects with MongoZMQ server to add/fetch docs  -    """ - -    def __init__(self, connect_addr='tcp://127.0.0.1:5000'): -        self._context = zmq.Context() -        self._socket = self._context.socket(zmq.DEALER) -        self._socket.connect(connect_addr) - -    def _send_recv_msg(self, msg): -        self._socket.send_multipart(msg) -        return self._socket.recv_multipart()[0] - -    def get_doc(self, keys): -        msg = ['get', json.dumps(keys)] -        json_str = self._send_recv_msg(msg) -        return json.loads(json_str) - -    def add_doc(self, doc): -        msg = ['add', json.dumps(doc)] -        return self._send_recv_msg(msg) - -def main(): -    client = MongoZMQClient() -    for i in range(10): -        doc = {'job': str(i)} -        print "Adding doc", doc -        print client.add_doc(doc) -    for i in range(10): -        query = {'job': str(i)} -        print "Getting doc matching query:", query -        print client.get_doc(query) - -if __name__ == "__main__": -    main() diff --git a/examples/mongodb/controller.py b/examples/mongodb/controller.py deleted file mode 100644 index e154f1c..0000000 --- a/examples/mongodb/controller.py +++ /dev/null @@ -1,91 +0,0 @@ -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Justin Riley -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import sys -import zmq -import pymongo -import pymongo.json_util -import json - -class MongoZMQ(object): -    """ -    ZMQ server that adds/fetches documents (ie dictionaries) to a MongoDB. - -    NOTE: mongod must be started before using this class -    """ - -    def __init__(self, db_name, table_name, bind_addr="tcp://127.0.0.1:5000"): -        """ -        bind_addr: address to bind zmq socket on -        db_name: name of database to write to (created if doesnt exist) -        table_name: name of mongodb 'table' in the db to write to (created if doesnt exist) -        """ -        self._bind_addr = bind_addr -        self._db_name = db_name -        self._table_name = table_name -        self._conn = pymongo.Connection() -        self._db = self._conn[self._db_name] -        self._table = self._db[self._table_name] - -    def _doc_to_json(self, doc): -        return json.dumps(doc,default=pymongo.json_util.default) - -    def add_document(self, doc): -        """ -        Inserts a document (dictionary) into mongo database table -        """ -        print 'adding docment %s' % (doc) -        try: -            self._table.insert(doc) -        except Exception,e: -            return 'Error: %s' % e - -    def get_document_by_keys(self, keys): -        """ -        Attempts to return a single document from database table that matches -        each key/value in keys dictionary. -        """ -        print 'attempting to retrieve document using keys: %s' % keys -        try: -            return self._table.find_one(keys) -        except Exception,e: -            return 'Error: %s' % e - -    def start(self): -        context = zmq.Context() -        socket = context.socket(zmq.ROUTER) -        socket.bind(self._bind_addr) -        while True: -            msg = socket.recv_multipart() -            print "Received msg: ", msg -            if  len(msg) != 3: -                error_msg = 'invalid message received: %s' % msg -                print error_msg -                reply = [msg[0], error_msg] -                socket.send_multipart(reply) -                continue -            id = msg[0] -            operation = msg[1] -            contents = json.loads(msg[2]) -            # always send back the id with ROUTER -            reply = [id] -            if operation == 'add': -                self.add_document(contents) -                reply.append("success") -            elif operation == 'get': -                doc = self.get_document_by_keys(contents) -                json_doc = self._doc_to_json(doc) -                reply.append(json_doc) -            else: -                print 'unknown request' -            socket.send_multipart(reply) - -def main(): -    MongoZMQ('ipcontroller','jobs').start() - -if __name__ == "__main__": -   main() diff --git a/examples/monitoring/simple_monitor.py b/examples/monitoring/simple_monitor.py deleted file mode 100644 index 88cdd4c..0000000 --- a/examples/monitoring/simple_monitor.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- coding: utf-8 -*- -"""Simple example demonstrating the use of the socket monitoring feature.""" - -# This file is part of pyzmq. -# -# Distributed under the terms of the New BSD License. The full -# license is in the file COPYING.BSD, distributed as part of this -# software. -from __future__ import print_function - -__author__ = 'Guido Goldstein' - -import json -import os -import struct -import sys -import threading -import time - -import zmq -from zmq.utils.monitor import recv_monitor_message - -line = lambda : print('-' * 40) - -def logger(monitor): -    done = False -    while monitor.poll(timeout=5000): -        evt = recv_monitor_message(monitor) -        print(json.dumps(evt, indent=1)) -        if evt['event'] == zmq.EVENT_MONITOR_STOPPED: -            break -    print() -    print("Logger done!") -    monitor.close() - -print("libzmq-%s" % zmq.zmq_version()) -if zmq.zmq_version_info() < (4,0): -    raise RuntimeError("monitoring in libzmq version < 4.0 is not supported") - -print("Event names:") -for name in dir(zmq): -    if name.startswith('EVENT_'): -        print("%21s : %4i" % (name, getattr(zmq, name))) - - -ctx = zmq.Context().instance() -rep = ctx.socket(zmq.REP) -req = ctx.socket(zmq.REQ) - -monitor = req.get_monitor_socket() - -t = threading.Thread(target=logger, args=(monitor,)) -t.start() - -line() -print("bind req") -req.bind("tcp://127.0.0.1:6666") -req.bind("tcp://127.0.0.1:6667") -time.sleep(1) - -line() -print("connect rep") -rep.connect("tcp://127.0.0.1:6667") -time.sleep(0.2) -rep.connect("tcp://127.0.0.1:6666") -time.sleep(1) - -line() -print("disconnect rep") -rep.disconnect("tcp://127.0.0.1:6667") -time.sleep(1) -rep.disconnect("tcp://127.0.0.1:6666") -time.sleep(1) - -line() -print("close rep") -rep.close() -time.sleep(1) - -line() -print("close req") -req.close() -time.sleep(1) - -line() -print("joining") -t.join() - -print("END") -ctx.term() diff --git a/examples/poll/pair.py b/examples/poll/pair.py deleted file mode 100644 index 81c8b3a..0000000 --- a/examples/poll/pair.py +++ /dev/null @@ -1,56 +0,0 @@ -"""A thorough test of polling PAIR sockets.""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Brian Granger -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import time -import zmq - -print "Running polling tests for PAIR sockets..." - -addr = 'tcp://127.0.0.1:5555' -ctx = zmq.Context() -s1 = ctx.socket(zmq.PAIR) -s2 = ctx.socket(zmq.PAIR) - -s1.bind(addr) -s2.connect(addr) - -# Sleep to allow sockets to connect. -time.sleep(1.0) - -poller = zmq.Poller() -poller.register(s1, zmq.POLLIN|zmq.POLLOUT) -poller.register(s2, zmq.POLLIN|zmq.POLLOUT) - -# Now make sure that both are send ready. -socks = dict(poller.poll()) -assert socks[s1] == zmq.POLLOUT -assert socks[s2] == zmq.POLLOUT - -# Now do a send on both, wait and test for zmq.POLLOUT|zmq.POLLIN -s1.send('msg1') -s2.send('msg2') -time.sleep(1.0) -socks = dict(poller.poll()) -assert socks[s1] == zmq.POLLOUT|zmq.POLLIN -assert socks[s2] == zmq.POLLOUT|zmq.POLLIN - -# Make sure that both are in POLLOUT after recv. -s1.recv() -s2.recv() -socks = dict(poller.poll()) -assert socks[s1] == zmq.POLLOUT -assert socks[s2] == zmq.POLLOUT - -poller.unregister(s1) -poller.unregister(s2) - -# Wait for everything to finish. -time.sleep(1.0) - -print "Finished."
\ No newline at end of file diff --git a/examples/poll/pubsub.py b/examples/poll/pubsub.py deleted file mode 100644 index a590fa9..0000000 --- a/examples/poll/pubsub.py +++ /dev/null @@ -1,57 +0,0 @@ -"""A thorough test of polling PUB/SUB sockets.""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Brian Granger -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import time -import zmq - -print "Running polling tets for PUB/SUB sockets..." - -addr = 'tcp://127.0.0.1:5555' -ctx = zmq.Context() -s1 = ctx.socket(zmq.PUB) -s2 = ctx.socket(zmq.SUB) -s2.setsockopt(zmq.SUBSCRIBE, '') - -s1.bind(addr) -s2.connect(addr) - -# Sleep to allow sockets to connect. -time.sleep(1.0) - -poller = zmq.Poller() -poller.register(s1, zmq.POLLIN|zmq.POLLOUT) -poller.register(s2, zmq.POLLIN|zmq.POLLOUT) - -# Now make sure that both are send ready. -socks = dict(poller.poll()) -assert socks[s1] == zmq.POLLOUT -assert not socks.has_key(s2) - -# Make sure that s1 stays in POLLOUT after a send. -s1.send('msg1') -socks = dict(poller.poll()) -assert socks[s1] == zmq.POLLOUT - -# Make sure that s2 is POLLIN after waiting. -time.sleep(0.5) -socks = dict(poller.poll()) -assert socks[s2] == zmq.POLLIN - -# Make sure that s2 goes into 0 after recv. -s2.recv() -socks = dict(poller.poll()) -assert not socks.has_key(s2) - -poller.unregister(s1) -poller.unregister(s2) - -# Wait for everything to finish. -time.sleep(1.0) - -print "Finished." diff --git a/examples/poll/reqrep.py b/examples/poll/reqrep.py deleted file mode 100644 index ef4436c..0000000 --- a/examples/poll/reqrep.py +++ /dev/null @@ -1,71 +0,0 @@ -"""A thorough test of polling REQ/REP sockets.""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Brian Granger -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import time -import zmq - -print "Running polling tests for REQ/REP sockets..." - -addr = 'tcp://127.0.0.1:5555' -ctx = zmq.Context() -s1 = ctx.socket(zmq.REP) -s2 = ctx.socket(zmq.REQ) - -s1.bind(addr) -s2.connect(addr) - -# Sleep to allow sockets to connect. -time.sleep(1.0) - -poller = zmq.Poller() -poller.register(s1, zmq.POLLIN|zmq.POLLOUT) -poller.register(s2, zmq.POLLIN|zmq.POLLOUT) - -# Make sure that s1 is in state 0 and s2 is in POLLOUT -socks = dict(poller.poll()) -assert not socks.has_key(s1) -assert socks[s2] == zmq.POLLOUT - -# Make sure that s2 goes immediately into state 0 after send. -s2.send('msg1') -socks = dict(poller.poll()) -assert not socks.has_key(s2) - -# Make sure that s1 goes into POLLIN state after a time.sleep(). -time.sleep(0.5) -socks = dict(poller.poll()) -assert socks[s1] == zmq.POLLIN - -# Make sure that s1 goes into POLLOUT after recv. -s1.recv() -socks = dict(poller.poll()) -assert socks[s1] == zmq.POLLOUT - -# Make sure s1 goes into state 0 after send. -s1.send('msg2') -socks = dict(poller.poll()) -assert not socks.has_key(s1) - -# Wait and then see that s2 is in POLLIN. -time.sleep(0.5) -socks = dict(poller.poll()) -assert socks[s2] == zmq.POLLIN - -# Make sure that s2 is in POLLOUT after recv. -s2.recv() -socks = dict(poller.poll()) -assert socks[s2] == zmq.POLLOUT - -poller.unregister(s1) -poller.unregister(s2) - -# Wait for everything to finish. -time.sleep(1.0) - -print "Finished." diff --git a/examples/pubsub/publisher.py b/examples/pubsub/publisher.py deleted file mode 100644 index a2ce6c9..0000000 --- a/examples/pubsub/publisher.py +++ /dev/null @@ -1,57 +0,0 @@ -"""A test that publishes NumPy arrays. - -Uses REQ/REP (on PUB/SUB socket + 1) to synchronize -""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Brian Granger -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import sys -import time - -import zmq -import numpy - -def sync(bind_to): -    # use bind socket + 1 -    sync_with = ':'.join(bind_to.split(':')[:-1] + -                         [str(int(bind_to.split(':')[-1]) + 1)]) -    ctx = zmq.Context.instance() -    s = ctx.socket(zmq.REP) -    s.bind(sync_with) -    print "Waiting for subscriber to connect..." -    s.recv() -    print "   Done." -    s.send('GO') - -def main(): -    if len (sys.argv) != 4: -        print 'usage: publisher <bind-to> <array-size> <array-count>' -        sys.exit (1) - -    try: -        bind_to = sys.argv[1] -        array_size = int(sys.argv[2]) -        array_count = int (sys.argv[3]) -    except (ValueError, OverflowError), e: -        print 'array-size and array-count must be integers' -        sys.exit (1) - -    ctx = zmq.Context() -    s = ctx.socket(zmq.PUB) -    s.bind(bind_to) - -    sync(bind_to) - -    print "Sending arrays..." -    for i in range(array_count): -        a = numpy.random.rand(array_size, array_size) -        s.send_pyobj(a) -    print "   Done." - -if __name__ == "__main__": -    main() diff --git a/examples/pubsub/subscriber.py b/examples/pubsub/subscriber.py deleted file mode 100644 index b996ad8..0000000 --- a/examples/pubsub/subscriber.py +++ /dev/null @@ -1,74 +0,0 @@ -"""A test that subscribes to NumPy arrays. - -Uses REQ/REP (on PUB/SUB socket + 1) to synchronize -""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Brian Granger -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - - -import sys -import time - -import zmq -import numpy - -def sync(connect_to): -    # use connect socket + 1 -    sync_with = ':'.join(connect_to.split(':')[:-1] + -                         [str(int(connect_to.split(':')[-1]) + 1)] -                        ) -    ctx = zmq.Context.instance() -    s = ctx.socket(zmq.REQ) -    s.connect(sync_with) -    s.send('READY') -    s.recv() - -def main(): -    if len (sys.argv) != 3: -        print 'usage: subscriber <connect_to> <array-count>' -        sys.exit (1) - -    try: -        connect_to = sys.argv[1] -        array_count = int (sys.argv[2]) -    except (ValueError, OverflowError), e: -        print 'array-count must be integers' -        sys.exit (1) - -    ctx = zmq.Context() -    s = ctx.socket(zmq.SUB) -    s.connect(connect_to) -    s.setsockopt(zmq.SUBSCRIBE,'') - -    sync(connect_to) - -    start = time.clock() - -    print "Receiving arrays..." -    for i in range(array_count): -        a = s.recv_pyobj() -    print "   Done." - -    end = time.clock() - -    elapsed = (end - start) * 1000000 -    if elapsed == 0: -    	elapsed = 1 -    throughput = (1000000.0 * float (array_count)) / float (elapsed) -    message_size = a.nbytes -    megabits = float (throughput * message_size * 8) / 1000000 - -    print "message size: %.0f [B]" % (message_size, ) -    print "array count: %.0f" % (array_count, ) -    print "mean throughput: %.0f [msg/s]" % (throughput, ) -    print "mean throughput: %.3f [Mb/s]" % (megabits, ) - -    time.sleep(1.0) - -if __name__ == "__main__": -    main() diff --git a/examples/pubsub/topics_pub.py b/examples/pubsub/topics_pub.py deleted file mode 100755 index 73b3d1c..0000000 --- a/examples/pubsub/topics_pub.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -"""Simple example of publish/subscribe illustrating topics. - -Publisher and subscriber can be started in any order, though if publisher -starts first, any messages sent before subscriber starts are lost.  More than -one subscriber can listen, and they can listen to  different topics. - -Topic filtering is done simply on the start of the string, e.g. listening to -'s' will catch 'sports...' and 'stocks'  while listening to 'w' is enough to -catch 'weather'. -""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Brian Granger -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import itertools -import sys -import time - -import zmq - -def main(): -    if len (sys.argv) != 2: -        print 'usage: publisher <bind-to>' -        sys.exit (1) - -    bind_to = sys.argv[1] - -    all_topics = ['sports.general','sports.football','sports.basketball', -                  'stocks.general','stocks.GOOG','stocks.AAPL', -                  'weather'] - -    ctx = zmq.Context() -    s = ctx.socket(zmq.PUB) -    s.bind(bind_to) - -    print "Starting broadcast on topics:" -    print "   %s" % all_topics -    print "Hit Ctrl-C to stop broadcasting." -    print "Waiting so subscriber sockets can connect..." -    print -    time.sleep(1.0) - -    msg_counter = itertools.count() -    try: -        for topic in itertools.cycle(all_topics): -            msg_body = str(msg_counter.next()) -            print '   Topic: %s, msg:%s' % (topic, msg_body) -            s.send_multipart([topic, msg_body]) -            # short wait so we don't hog the cpu -            time.sleep(0.1) -    except KeyboardInterrupt: -        pass - -    print "Waiting for message queues to flush..." -    time.sleep(0.5) -    print "Done." - -if __name__ == "__main__": -    main() diff --git a/examples/pubsub/topics_sub.py b/examples/pubsub/topics_sub.py deleted file mode 100755 index 4a61fb5..0000000 --- a/examples/pubsub/topics_sub.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -"""Simple example of publish/subscribe illustrating topics. - -Publisher and subscriber can be started in any order, though if publisher -starts first, any messages sent before subscriber starts are lost.  More than -one subscriber can listen, and they can listen to  different topics. - -Topic filtering is done simply on the start of the string, e.g. listening to -'s' will catch 'sports...' and 'stocks'  while listening to 'w' is enough to -catch 'weather'. -""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Brian Granger, Fernando Perez -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import sys -import time - -import zmq -import numpy - -def main(): -    if len (sys.argv) < 2: -        print 'usage: subscriber <connect_to> [topic topic ...]' -        sys.exit (1) - -    connect_to = sys.argv[1] -    topics = sys.argv[2:] - -    ctx = zmq.Context() -    s = ctx.socket(zmq.SUB) -    s.connect(connect_to) - -    # manage subscriptions -    if not topics: -        print "Receiving messages on ALL topics..." -        s.setsockopt(zmq.SUBSCRIBE,'') -    else: -        print "Receiving messages on topics: %s ..." % topics -        for t in topics: -            s.setsockopt(zmq.SUBSCRIBE,t) -    print -    try: -        while True: -            topic, msg = s.recv_multipart() -            print '   Topic: %s, msg:%s' % (topic, msg) -    except KeyboardInterrupt: -        pass -    print "Done." - -if __name__ == "__main__": -    main() diff --git a/examples/security/generate_certificates.py b/examples/security/generate_certificates.py deleted file mode 100644 index 80db258..0000000 --- a/examples/security/generate_certificates.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python - -""" -Generate client and server CURVE certificate files then move them into the -appropriate store directory, private_keys or public_keys. The certificates -generated by this script are used by the stonehouse and ironhouse examples. - -In practice this would be done by hand or some out-of-band process. - -Author: Chris Laws -""" - -import os -import shutil -import zmq.auth - -def generate_certificates(base_dir): -    ''' Generate client and server CURVE certificate files''' -    keys_dir = os.path.join(base_dir, 'certificates') -    public_keys_dir = os.path.join(base_dir, 'public_keys') -    secret_keys_dir = os.path.join(base_dir, 'private_keys') - -    # Create directories for certificates, remove old content if necessary -    for d in [keys_dir, public_keys_dir, secret_keys_dir]: -        if os.path.exists(d): -            shutil.rmtree(d) -        os.mkdir(d) - -    # create new keys in certificates dir -    server_public_file, server_secret_file = zmq.auth.create_certificates(keys_dir, "server") -    client_public_file, client_secret_file = zmq.auth.create_certificates(keys_dir, "client") - -    # move public keys to appropriate directory -    for key_file in os.listdir(keys_dir): -        if key_file.endswith(".key"): -            shutil.move(os.path.join(keys_dir, key_file), -                        os.path.join(public_keys_dir, '.')) - -    # move secret keys to appropriate directory -    for key_file in os.listdir(keys_dir): -        if key_file.endswith(".key_secret"): -            shutil.move(os.path.join(keys_dir, key_file), -                        os.path.join(secret_keys_dir, '.')) - -if __name__ == '__main__': -    if zmq.zmq_version_info() < (4,0): -        raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version())) - -    generate_certificates(os.path.dirname(__file__)) diff --git a/examples/security/grasslands.py b/examples/security/grasslands.py deleted file mode 100644 index cbd3ab9..0000000 --- a/examples/security/grasslands.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -''' -No protection at all. - -All connections are accepted, there is no authentication, and no privacy.  - -This is how ZeroMQ always worked until we built security into the wire  -protocol in early 2013. Internally, it uses a security mechanism called  -"NULL". - -Author: Chris Laws -''' - -import zmq - - -ctx = zmq.Context().instance() - -server = ctx.socket(zmq.PUSH) -server.bind('tcp://*:9000') - -client = ctx.socket(zmq.PULL) -client.connect('tcp://127.0.0.1:9000') - -server.send(b"Hello") -msg = client.recv() -if msg == b"Hello": -    print("Grasslands test OK") diff --git a/examples/security/ioloop-ironhouse.py b/examples/security/ioloop-ironhouse.py deleted file mode 100644 index 11fd400..0000000 --- a/examples/security/ioloop-ironhouse.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/env python - -''' -Ironhouse extends Stonehouse with client public key authentication. - -This is the strongest security model we have today, protecting against every -attack we know about, except end-point attacks (where an attacker plants -spyware on a machine to capture data before it's encrypted, or after it's -decrypted). - -This example demonstrates using the IOLoopAuthenticator. - -Author: Chris Laws -''' - -import logging -import os -import sys - -import zmq -import zmq.auth -from zmq.auth.ioloop import IOLoopAuthenticator -from zmq.eventloop import ioloop, zmqstream - -def echo(server, msg): -    logging.debug("server recvd %s", msg) -    reply = msg + [b'World'] -    logging.debug("server sending %s", reply) -    server.send_multipart(reply) -     -def setup_server(server_secret_file, endpoint='tcp://127.0.0.1:9000'): -    """setup a simple echo server with CURVE auth""" -    server = zmq.Context.instance().socket(zmq.ROUTER) - -    server_public, server_secret = zmq.auth.load_certificate(server_secret_file) -    server.curve_secretkey = server_secret -    server.curve_publickey = server_public -    server.curve_server = True  # must come before bind -    server.bind(endpoint) -     -    server_stream = zmqstream.ZMQStream(server) -    # simple echo -    server_stream.on_recv_stream(echo) -    return server_stream - -def client_msg_recvd(msg): -    logging.debug("client recvd %s", msg) -    logging.info("Ironhouse test OK") -    # stop the loop when we get the reply -    ioloop.IOLoop.instance().stop() - -def setup_client(client_secret_file, server_public_file, endpoint='tcp://127.0.0.1:9000'): -    """setup a simple client with CURVE auth""" -     -    client = zmq.Context.instance().socket(zmq.DEALER) - -    # We need two certificates, one for the client and one for -    # the server. The client must know the server's public key -    # to make a CURVE connection. -    client_public, client_secret = zmq.auth.load_certificate(client_secret_file) -    client.curve_secretkey = client_secret -    client.curve_publickey = client_public - -    server_public, _ = zmq.auth.load_certificate(server_public_file) -    # The client must know the server's public key to make a CURVE connection. -    client.curve_serverkey = server_public -    client.connect(endpoint) -     -    client_stream = zmqstream.ZMQStream(client) -    client_stream.on_recv(client_msg_recvd) -    return client_stream -     - -def run(): -    '''Run Ironhouse example''' - -    # These direcotries are generated by the generate_certificates script -    base_dir = os.path.dirname(__file__) -    keys_dir = os.path.join(base_dir, 'certificates') -    public_keys_dir = os.path.join(base_dir, 'public_keys') -    secret_keys_dir = os.path.join(base_dir, 'private_keys') - -    if not (os.path.exists(keys_dir) and os.path.exists(keys_dir) and os.path.exists(keys_dir)): -        logging.critical("Certificates are missing - run generate_certificates script first") -        sys.exit(1) - -    # Start an authenticator for this context. -    auth = IOLoopAuthenticator() -    auth.allow('127.0.0.1') -    # Tell authenticator to use the certificate in a directory -    auth.configure_curve(domain='*', location=public_keys_dir) -     -    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret") -    server = setup_server(server_secret_file) -    server_public_file = os.path.join(public_keys_dir, "server.key") -    client_secret_file = os.path.join(secret_keys_dir, "client.key_secret") -    client = setup_client(client_secret_file, server_public_file) -    client.send(b'Hello') -     -    auth.start() -    ioloop.IOLoop.instance().start() - -if __name__ == '__main__': -    if zmq.zmq_version_info() < (4,0): -        raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version())) - -    if '-v' in sys.argv: -        level = logging.DEBUG -    else: -        level = logging.INFO - -    logging.basicConfig(level=level, format="[%(levelname)s] %(message)s") - -    run() diff --git a/examples/security/ironhouse.py b/examples/security/ironhouse.py deleted file mode 100644 index 5d9faf1..0000000 --- a/examples/security/ironhouse.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python - -''' -Ironhouse extends Stonehouse with client public key authentication. - -This is the strongest security model we have today, protecting against every -attack we know about, except end-point attacks (where an attacker plants -spyware on a machine to capture data before it's encrypted, or after it's -decrypted). - -Author: Chris Laws -''' - -import logging -import os -import sys - -import zmq -import zmq.auth -from zmq.auth.thread import ThreadAuthenticator - - -def run(): -    ''' Run Ironhouse example ''' - -    # These direcotries are generated by the generate_certificates script -    base_dir = os.path.dirname(__file__) -    keys_dir = os.path.join(base_dir, 'certificates') -    public_keys_dir = os.path.join(base_dir, 'public_keys') -    secret_keys_dir = os.path.join(base_dir, 'private_keys') - -    if not (os.path.exists(keys_dir) and os.path.exists(keys_dir) and os.path.exists(keys_dir)): -        logging.critical("Certificates are missing - run generate_certificates.py script first") -        sys.exit(1) - -    ctx = zmq.Context().instance() - -    # Start an authenticator for this context. -    auth = ThreadAuthenticator(ctx) -    auth.start() -    auth.allow('127.0.0.1') -    # Tell authenticator to use the certificate in a directory -    auth.configure_curve(domain='*', location=public_keys_dir) - -    server = ctx.socket(zmq.PUSH) - -    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret") -    server_public, server_secret = zmq.auth.load_certificate(server_secret_file) -    server.curve_secretkey = server_secret -    server.curve_publickey = server_public -    server.curve_server = True  # must come before bind -    server.bind('tcp://*:9000') - -    client = ctx.socket(zmq.PULL) - -    # We need two certificates, one for the client and one for -    # the server. The client must know the server's public key -    # to make a CURVE connection. -    client_secret_file = os.path.join(secret_keys_dir, "client.key_secret") -    client_public, client_secret = zmq.auth.load_certificate(client_secret_file) -    client.curve_secretkey = client_secret -    client.curve_publickey = client_public - -    server_public_file = os.path.join(public_keys_dir, "server.key") -    server_public, _ = zmq.auth.load_certificate(server_public_file) -    # The client must know the server's public key to make a CURVE connection. -    client.curve_serverkey = server_public -    client.connect('tcp://127.0.0.1:9000') - -    server.send(b"Hello") - -    if client.poll(1000): -        msg = client.recv() -        if msg == b"Hello": -            logging.info("Ironhouse test OK") -    else: -        logging.error("Ironhouse test FAIL") - -    # stop auth thread -    auth.stop() - -if __name__ == '__main__': -    if zmq.zmq_version_info() < (4,0): -        raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version())) - -    if '-v' in sys.argv: -        level = logging.DEBUG -    else: -        level = logging.INFO - -    logging.basicConfig(level=level, format="[%(levelname)s] %(message)s") - -    run() diff --git a/examples/security/stonehouse.py b/examples/security/stonehouse.py deleted file mode 100644 index 276e87a..0000000 --- a/examples/security/stonehouse.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python - -''' -Stonehouse uses the "CURVE" security mechanism. - -This gives us strong encryption on data, and (as far as we know) unbreakable -authentication. Stonehouse is the minimum you would use over public networks, -and assures clients that they are speaking to an authentic server, while -allowing any client to connect. - -Author: Chris Laws -''' - -import logging -import os -import sys -import time - -import zmq -import zmq.auth -from zmq.auth.thread import ThreadAuthenticator - - -def run(): -    ''' Run Stonehouse example ''' - -    # These directories are generated by the generate_certificates script -    base_dir = os.path.dirname(__file__) -    keys_dir = os.path.join(base_dir, 'certificates') -    public_keys_dir = os.path.join(base_dir, 'public_keys') -    secret_keys_dir = os.path.join(base_dir, 'private_keys') - -    if not (os.path.exists(keys_dir) and os.path.exists(keys_dir) and os.path.exists(keys_dir)): -        logging.critical("Certificates are missing: run generate_certificates.py script first") -        sys.exit(1) - -    ctx = zmq.Context().instance() - -    # Start an authenticator for this context. -    auth = ThreadAuthenticator(ctx) -    auth.start() -    auth.allow('127.0.0.1') -    # Tell the authenticator how to handle CURVE requests -    auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY) - -    server = ctx.socket(zmq.PUSH) -    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret") -    server_public, server_secret = zmq.auth.load_certificate(server_secret_file) -    server.curve_secretkey = server_secret -    server.curve_publickey = server_public -    server.curve_server = True  # must come before bind -    server.bind('tcp://*:9000') - -    client = ctx.socket(zmq.PULL) -    # We need two certificates, one for the client and one for -    # the server. The client must know the server's public key -    # to make a CURVE connection. -    client_secret_file = os.path.join(secret_keys_dir, "client.key_secret") -    client_public, client_secret = zmq.auth.load_certificate(client_secret_file) -    client.curve_secretkey = client_secret -    client.curve_publickey = client_public - -    # The client must know the server's public key to make a CURVE connection. -    server_public_file = os.path.join(public_keys_dir, "server.key") -    server_public, _ = zmq.auth.load_certificate(server_public_file) -    client.curve_serverkey = server_public - -    client.connect('tcp://127.0.0.1:9000') - -    server.send(b"Hello") - -    if client.poll(1000): -        msg = client.recv() -        if msg == b"Hello": -            logging.info("Stonehouse test OK") -    else: -        logging.error("Stonehouse test FAIL") - -    # stop auth thread -    auth.stop() - -if __name__ == '__main__': -    if zmq.zmq_version_info() < (4,0): -        raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version())) - -    if '-v' in sys.argv: -        level = logging.DEBUG -    else: -        level = logging.INFO - -    logging.basicConfig(level=level, format="[%(levelname)s] %(message)s") - -    run() diff --git a/examples/security/strawhouse.py b/examples/security/strawhouse.py deleted file mode 100644 index dc75bd7..0000000 --- a/examples/security/strawhouse.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python - -''' -Allow or deny clients based on IP address. - -Strawhouse, which is plain text with filtering on IP addresses. It still -uses the NULL mechanism, but we install an authentication hook that checks -the IP address against a whitelist or blacklist and allows or denies it -accordingly. - -Author: Chris Laws -''' - -import logging -import sys - -import zmq -import zmq.auth -from zmq.auth.thread import ThreadAuthenticator - - -def run(): -    '''Run strawhouse client''' - -    allow_test_pass = False -    deny_test_pass = False - -    ctx = zmq.Context().instance() - -    # Start an authenticator for this context. -    auth = ThreadAuthenticator(ctx) -    auth.start() - -    # Part 1 - demonstrate allowing clients based on IP address -    auth.allow('127.0.0.1') - -    server = ctx.socket(zmq.PUSH) -    server.zap_domain = b'global'  # must come before bind -    server.bind('tcp://*:9000') - -    client_allow = ctx.socket(zmq.PULL) -    client_allow.connect('tcp://127.0.0.1:9000') - -    server.send(b"Hello") - -    msg = client_allow.recv() -    if msg == b"Hello": -        allow_test_pass = True - -    client_allow.close() - -    # Part 2 - demonstrate denying clients based on IP address -    auth.stop() -     -    auth = ThreadAuthenticator(ctx) -    auth.start() -     -    auth.deny('127.0.0.1') - -    client_deny = ctx.socket(zmq.PULL) -    client_deny.connect('tcp://127.0.0.1:9000') -     -    if server.poll(50, zmq.POLLOUT): -        server.send(b"Hello") - -        if client_deny.poll(50): -            msg = client_deny.recv() -        else: -            deny_test_pass = True -    else: -        deny_test_pass = True - -    client_deny.close() - -    auth.stop()  # stop auth thread - -    if allow_test_pass and deny_test_pass: -        logging.info("Strawhouse test OK") -    else: -        logging.error("Strawhouse test FAIL") - - -if __name__ == '__main__': -    if zmq.zmq_version_info() < (4,0): -        raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version())) - -    if '-v' in sys.argv: -        level = logging.DEBUG -    else: -        level = logging.INFO - -    logging.basicConfig(level=level, format="[%(levelname)s] %(message)s") - -    run() diff --git a/examples/security/woodhouse.py b/examples/security/woodhouse.py deleted file mode 100644 index efedee4..0000000 --- a/examples/security/woodhouse.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python - -''' -Woodhouse extends Strawhouse with a name and password check. - -This uses the PLAIN mechanism which does plain-text username and password authentication). -It's not really secure, and anyone sniffing the network (trivial with WiFi) -can capture passwords and then login. - -Author: Chris Laws -''' - -import logging -import sys - -import zmq -import zmq.auth -from zmq.auth.thread import ThreadAuthenticator - -def run(): -    '''Run woodhouse example''' - -    valid_client_test_pass = False -    invalid_client_test_pass = False - -    ctx = zmq.Context().instance() - -    # Start an authenticator for this context. -    auth = ThreadAuthenticator(ctx) -    auth.start() -    auth.allow('127.0.0.1') -    # Instruct authenticator to handle PLAIN requests -    auth.configure_plain(domain='*', passwords={'admin': 'secret'}) - -    server = ctx.socket(zmq.PUSH) -    server.plain_server = True  # must come before bind -    server.bind('tcp://*:9000') - -    client = ctx.socket(zmq.PULL) -    client.plain_username = b'admin' -    client.plain_password = b'secret' -    client.connect('tcp://127.0.0.1:9000') - -    server.send(b"Hello") - -    if client.poll(): -        msg = client.recv() -        if msg == b"Hello": -            valid_client_test_pass = True - -    client.close() - - -    # now use invalid credentials - expect no msg received -    client2 = ctx.socket(zmq.PULL) -    client2.plain_username = b'admin' -    client2.plain_password = b'bogus' -    client2.connect('tcp://127.0.0.1:9000') - -    server.send(b"World") - -    if client2.poll(50): -        msg = client.recv() -        if msg == "World": -            invalid_client_test_pass = False -    else: -        # no message is expected -        invalid_client_test_pass = True - -    # stop auth thread -    auth.stop() - -    if valid_client_test_pass and invalid_client_test_pass: -        logging.info("Woodhouse test OK") -    else: -        logging.error("Woodhouse test FAIL") - - -if __name__ == '__main__': -    if zmq.zmq_version_info() < (4,0): -        raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version())) - -    if '-v' in sys.argv: -        level = logging.DEBUG -    else: -        level = logging.INFO - -    logging.basicConfig(level=level, format="[%(levelname)s] %(message)s") - -    run() diff --git a/examples/serialization/serialsocket.py b/examples/serialization/serialsocket.py deleted file mode 100644 index 7329bb9..0000000 --- a/examples/serialization/serialsocket.py +++ /dev/null @@ -1,74 +0,0 @@ -"""A Socket subclass that adds some serialization methods.""" - -import zlib -import pickle - -import numpy - -import zmq - -class SerializingSocket(zmq.Socket): -    """A class with some extra serialization methods -     -    send_zipped_pickle is just like send_pyobj, but uses -    zlib to compress the stream before sending. -     -    send_array sends numpy arrays with metadata necessary -    for reconstructing the array on the other side (dtype,shape). -    """ -     -    def send_zipped_pickle(self, obj, flags=0, protocol=-1): -        """pack and compress an object with pickle and zlib.""" -        pobj = pickle.dumps(obj, protocol) -        zobj = zlib.compress(pobj) -        print('zipped pickle is %i bytes' % len(zobj)) -        return self.send(zobj, flags=flags) -     -    def recv_zipped_pickle(self, flags=0): -        """reconstruct a Python object sent with zipped_pickle""" -        zobj = self.recv(flags) -        pobj = zlib.decompress(zobj) -        return pickle.loads(pobj) - -    def send_array(self, A, flags=0, copy=True, track=False): -        """send a numpy array with metadata""" -        md = dict( -            dtype = str(A.dtype), -            shape = A.shape, -        ) -        self.send_json(md, flags|zmq.SNDMORE) -        return self.send(A, flags, copy=copy, track=track) - -    def recv_array(self, flags=0, copy=True, track=False): -        """recv a numpy array""" -        md = self.recv_json(flags=flags) -        msg = self.recv(flags=flags, copy=copy, track=track) -        A = numpy.frombuffer(msg, dtype=md['dtype']) -        return A.reshape(md['shape']) - -class SerializingContext(zmq.Context): -    _socket_class = SerializingSocket - -def main(): -    ctx = SerializingContext() -    req = ctx.socket(zmq.REQ) -    rep = ctx.socket(zmq.REP) -     -    rep.bind('inproc://a') -    req.connect('inproc://a') -    A = numpy.ones((1024,1024)) -    print ("Array is %i bytes" % (len(A) * 8)) -     -    # send/recv with pickle+zip -    req.send_zipped_pickle(A) -    B = rep.recv_zipped_pickle() -    # now try non-copying version -    rep.send_array(A, copy=False) -    C = req.recv_array(copy=False) -    print ("Checking zipped pickle...") -    print ("Okay" if (A==B).all() else "Failed") -    print ("Checking send_array...") -    print ("Okay" if (C==B).all() else "Failed") - -if __name__ == '__main__': -    main()
\ No newline at end of file diff --git a/perf/perf.py b/perf/perf.py deleted file mode 100644 index a0254b4..0000000 --- a/perf/perf.py +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. -# -#  Some original test code Copyright (c) 2007-2010 iMatix Corporation, -#  Used under LGPLv3 - -import argparse -import time - -from multiprocessing import Process - -import zmq - -def parse_args(argv=None): - -    parser = argparse.ArgumentParser(description='Run a zmq performance test') -    parser.add_argument('-p', '--poll', action='store_true', -                       help='use a zmq Poller instead of raw send/recv') -    parser.add_argument('-c', '--copy', action='store_true', -                       help='copy messages instead of using zero-copy') -    parser.add_argument('-s', '--size', type=int, default=10240, -                       help='size (in bytes) of the test message') -    parser.add_argument('-n', '--count', type=int, default=10240, -                       help='number of test messages to send') -    parser.add_argument('--url', dest='url', type=str, default='tcp://127.0.0.1:5555', -                       help='the zmq URL on which to run the test') -    parser.add_argument(dest='test', type=str, default='lat', choices=['lat', 'thr'], -                       help='which test to run') -    return parser.parse_args(argv) - -def latency_echo(url, count, poll, copy): -    """echo messages on a REP socket -     -    Should be started before `latency` -    """ -    ctx = zmq.Context() -    s = ctx.socket(zmq.REP) - -    if poll: -        p = zmq.Poller() -        p.register(s) - -    s.bind(url) -     -    block = zmq.NOBLOCK if poll else 0 -     -    for i in range(count): -        if poll: -            res = p.poll() -        msg = s.recv(block, copy=copy) - -        if poll: -            res = p.poll() -        s.send(msg, block, copy=copy) -     -    msg = s.recv() -    assert msg == b'done' -     -    s.close() -    ctx.term() -     -def latency(url, count, size, poll, copy): -    """Perform a latency test""" -    ctx = zmq.Context() -    s = ctx.socket(zmq.REQ) -    s.setsockopt(zmq.LINGER, -1) -    s.connect(url) -    if poll: -        p = zmq.Poller() -        p.register(s) - -    msg = b' ' * size - -    watch = zmq.Stopwatch() - -    block = zmq.NOBLOCK if poll else 0 -    time.sleep(1) -    watch.start() - -    for i in range (0, count): -        if poll: -            res = p.poll() -            assert(res[0][1] & zmq.POLLOUT) -        s.send(msg, block, copy=copy) - -        if poll: -            res = p.poll() -            assert(res[0][1] & zmq.POLLIN) -        msg = s.recv(block, copy=copy) -         -        assert len(msg) == size - -    elapsed = watch.stop() - -    s.send(b'done') - -    latency = elapsed / (count * 2.) - -    print ("message size   : %8i     [B]" % (size, )) -    print ("roundtrip count: %8i     [msgs]" % (count, )) -    print ("mean latency   : %12.3f [µs]" % (latency, )) -    print ("test time      : %12.3f [s]" % (elapsed * 1e-6, )) - -def pusher(url, count, size, copy, poll): -    """send a bunch of messages on a PUSH socket""" -    ctx = zmq.Context() -    s = ctx.socket(zmq.PUSH) - -    #  Add your socket options here. -    #  For example ZMQ_RATE, ZMQ_RECOVERY_IVL and ZMQ_MCAST_LOOP for PGM. - -    if poll: -        p = zmq.Poller() -        p.register(s) - -    s.connect(url) -     -    msg = zmq.Message(b' ' * size) -    block = zmq.NOBLOCK if poll else 0 -     -    for i in range(count): -        if poll: -            res = p.poll() -            assert(res[0][1] & zmq.POLLOUT) -        s.send(msg, block, copy=copy) - -    s.close() -    ctx.term() - -def throughput(url, count, size, poll, copy): -    """recv a bunch of messages on a PULL socket -     -    Should be started before `pusher` -    """ -    ctx = zmq.Context() -    s = ctx.socket(zmq.PULL) - -    #  Add your socket options here. -    #  For example ZMQ_RATE, ZMQ_RECOVERY_IVL and ZMQ_MCAST_LOOP for PGM. - -    if poll: -        p = zmq.Poller() -        p.register(s) - -    s.bind(url) - -    watch = zmq.Stopwatch() -    block = zmq.NOBLOCK if poll else 0 -     -    # Wait for the other side to connect. -    msg = s.recv() -    assert len (msg) == size -     -    watch.start() -    for i in range (count-1): -        if poll: -            res = p.poll() -        msg = s.recv(block, copy=copy) -    elapsed = watch.stop() -    if elapsed == 0: -        elapsed = 1 -     -    throughput = (1e6 * float(count)) / float(elapsed) -    megabits = float(throughput * size * 8) / 1e6 - -    print ("message size   : %8i     [B]" % (size, )) -    print ("message count  : %8i     [msgs]" % (count, )) -    print ("mean throughput: %8.0f     [msg/s]" % (throughput, )) -    print ("mean throughput: %12.3f [Mb/s]" % (megabits, )) -    print ("test time      : %12.3f [s]" % (elapsed * 1e-6, )) - - -def main(): -    args = parse_args() -    tic = time.time() -    if args.test == 'lat': -        bg = Process(target=latency_echo, args=(args.url, args.count, args.poll, args.copy)) -        bg.start() -        latency(args.url, args.count, args.size, args.poll, args.copy) -    elif args.test == 'thr': -        bg = Process(target=throughput, args=(args.url, args.count, args.size, args.poll, args.copy)) -        bg.start() -        pusher(args.url, args.count, args.size, args.poll, args.copy) -    bg.join() -    toc = time.time() -    if (toc - tic) < 3: -        print ("For best results, tests should take at least a few seconds.") - -if __name__ == '__main__': -    main() diff --git a/setup.cfg.android b/setup.cfg.android deleted file mode 100644 index 8b635ad..0000000 --- a/setup.cfg.android +++ /dev/null @@ -1,17 +0,0 @@ -[global] -# the prefix with which libzmq was configured / installed -zmq_prefix = /tmp/zeromq-android -have_sys_un_h = False - -[build_ext] -libraries = python2.6 -# path to your python-for-android -# the result of: -# wget http://python-for-android.googlecode.com/files/python-lib_r16.zip -# unzip python-lib_r16.zip -dpython-lib -library_dirs = ../python-lib/lib/ -include_dirs = ../python-lib/include/python2.6 - -[bdist_egg] -plat-name = linux-armv - diff --git a/setup.cfg.template b/setup.cfg.template deleted file mode 100644 index e81a3dc..0000000 --- a/setup.cfg.template +++ /dev/null @@ -1,12 +0,0 @@ -[global] -# zmq_prefix = /usr/local # (adds zmq_prefix/include to include_dirs and zmq_prefix/lib to library_dirs) -# have_sys_un_h = False # does sys/un.h exist? pyzmq will try to detect it, but you can override -# skip_check_zmq = True # skip checking zmq verson (if it doesn't work for some reason) -# libzmq_extension = True # force building libzmq as an extension (same as --zmq=bundled) -# no_libzmq_extension = True # prevent fallback on building libzmq as an extension if regular build fails -[build_ext] - -# Edit these to add any paths you need to include (e.g. where libzmq is defined) -library_dirs = /usr/local/lib -include_dirs = /usr/local/include - diff --git a/setup.py b/setup.py deleted file mode 100755 index c86ac7e..0000000 --- a/setup.py +++ /dev/null @@ -1,1195 +0,0 @@ -#!/usr/bin/env python -#----------------------------------------------------------------------------- -#  Copyright (C) PyZMQ Developers -#  Distributed under the terms of the Modified BSD License. -# -#  The `configure` subcommand is copied and adaped from h5py -#  h5py source used under the New BSD license -# -#  h5py: <http://code.google.com/p/h5py/> -# -#  The code to bundle libzmq as an Extension is from pyzmq-static -#  pyzmq-static source used under the New BSD license -# -#  pyzmq-static: <https://github.com/brandon-rhodes/pyzmq-static> -#----------------------------------------------------------------------------- - -from __future__ import with_statement - -import copy -import os -import re -import shutil -import subprocess -import sys -import time -import errno -import platform -from traceback import print_exc - - -import distutils -from distutils.core import setup, Command -from distutils.ccompiler import get_default_compiler -from distutils.ccompiler import new_compiler -from distutils.extension import Extension -from distutils.errors import CompileError, LinkError -from distutils.command.build import build -from distutils.command.build_ext import build_ext -from distutils.command.sdist import sdist -from distutils.version import LooseVersion as V - -from unittest import TextTestRunner, TestLoader -from glob import glob -from os.path import splitext, basename, join as pjoin - -from subprocess import Popen, PIPE -import logging - -try: -    from configparser import ConfigParser -except: -    from ConfigParser import ConfigParser - -try: -    import nose -except ImportError: -    nose = None - -# local script imports: -from buildutils import ( -    discover_settings, v_str, save_config, load_config, detect_zmq, merge, -    config_from_prefix, -    info, warn, fatal, debug, line, copy_and_patch_libzmq, localpath, -    fetch_libsodium, stage_libsodium_headers, fetch_libzmq, stage_platform_hpp, -    bundled_version, customize_mingw, -    test_compilation, compile_and_run, -    ) - -#----------------------------------------------------------------------------- -# Flags -#----------------------------------------------------------------------------- - -pypy = 'PyPy' in sys.version - -# reference points for zmq compatibility -min_zmq = (2,1,4) -target_zmq = bundled_version -dev_zmq = (target_zmq[0], target_zmq[1] + 1, 0) - -# set dylib ext: -if sys.platform.startswith('win'): -    lib_ext = '.dll' -elif sys.platform == 'darwin': -    lib_ext = '.dylib' -else: -    lib_ext = '.so' - -# whether any kind of bdist is happening -doing_bdist = any(arg.startswith('bdist') for arg in sys.argv[1:]) - -# allow `--zmq=foo` to be passed at any point, -# but always assign it to configure - -configure_idx = -1 -fetch_idx = -1 -for idx, arg in enumerate(list(sys.argv)): -    # track index of configure and fetch_libzmq -    if arg == 'configure': -        configure_idx = idx -    elif arg == 'fetch_libzmq': -        fetch_idx = idx -     -    if arg.startswith('--zmq='): -        sys.argv.pop(idx) -        if configure_idx < 0: -            if fetch_idx < 0: -                configure_idx = 1 -            else: -                configure_idx = fetch_idx + 1 -            sys.argv.insert(configure_idx, 'configure') -        sys.argv.insert(configure_idx + 1, arg) -        break - -#----------------------------------------------------------------------------- -# Configuration (adapted from h5py: http://h5py.googlecode.com) -#----------------------------------------------------------------------------- - -# --- compiler settings ------------------------------------------------- - -def bundled_settings(): -    """settings for linking extensions against bundled libzmq""" -    settings = {} -    settings['libraries'] = [] -    settings['library_dirs'] = [] -    settings['include_dirs'] = [pjoin("bundled", "zeromq", "include")] -    settings['runtime_library_dirs'] = [] -    # add pthread on freebsd -    # is this necessary? -    if sys.platform.startswith('freebsd'): -        settings['libraries'].append('pthread') -    elif sys.platform.startswith('win'): -        # link against libzmq in build dir: -        plat = distutils.util.get_platform() -        temp = 'temp.%s-%s' % (plat, sys.version[0:3]) -        settings['libraries'].append('libzmq') -        settings['library_dirs'].append(pjoin('build', temp, 'Release', 'buildutils')) -     -    return settings - - -def settings_from_prefix(prefix=None, bundle_libzmq_dylib=False): -    """load appropriate library/include settings from ZMQ prefix""" -    settings = {} -    settings['libraries'] = [] -    settings['include_dirs'] = [] -    settings['library_dirs'] = [] -    settings['runtime_library_dirs'] = [] -    settings['extra_link_args'] = []  -     -    if sys.platform.startswith('win'): -        settings['libraries'].append('libzmq') -         -        if prefix: -            settings['include_dirs'] += [pjoin(prefix, 'include')] -            settings['library_dirs'] += [pjoin(prefix, 'lib')] -    else: - -        # If prefix is not explicitly set, pull it from pkg-config by default. - -        if not prefix: -            try: -                p = Popen('pkg-config --variable=prefix --print-errors libzmq'.split(), stdout=PIPE, stderr=PIPE) -            except OSError as e: -                if e.errno == errno.ENOENT: -                    info("pkg-config not found") -                else: -                    warn("Running pkg-config failed - %s." % e) -                p = None -            if p is not None: -                if p.wait(): -                    info("Did not find libzmq via pkg-config:") -                    info(p.stderr.read().decode()) -                else: -                    prefix = p.stdout.readline().strip().decode() -                    info("Using zmq-prefix %s (found via pkg-config)." % prefix) - -        settings['libraries'].append('zmq') -        # add pthread on freebsd -        if sys.platform.startswith('freebsd'): -            settings['libraries'].append('pthread') -     -        if prefix: -            settings['include_dirs'] += [pjoin(prefix, 'include')] -            if not bundle_libzmq_dylib: -                if sys.platform == 'sunos5': -                  if platform.architecture()[0] == '32bit': -                    settings['library_dirs'] += [pjoin(prefix, 'lib')] -                  else: -                    settings['library_dirs'] += [pjoin(prefix, 'lib/amd64')] -                    settings['extra_link_args'] += ['-m64'] -                else:  -                   settings['library_dirs'] += [pjoin(prefix, 'lib')]   -        else: -            if sys.platform == 'darwin' and os.path.isdir('/opt/local/lib'): -                # allow macports default -                settings['include_dirs'] += ['/opt/local/include'] -                settings['library_dirs'] += ['/opt/local/lib'] -            if os.environ.get('VIRTUAL_ENV', None): -                # find libzmq installed in virtualenv -                env = os.environ['VIRTUAL_ENV'] -                settings['include_dirs'] += [pjoin(env, 'include')] -                settings['library_dirs'] += [pjoin(env, 'lib')] -     -        if bundle_libzmq_dylib: -            # bdist should link against bundled libzmq -            settings['library_dirs'].append('zmq') -            if sys.platform == 'darwin': -                pass -                # unused rpath args for OS X: -                # settings['extra_link_args'] = ['-Wl,-rpath','-Wl,$ORIGIN/..'] -            else: -                settings['runtime_library_dirs'] += ['$ORIGIN/..'] -        elif sys.platform != 'darwin': -            settings['runtime_library_dirs'] += [ -                os.path.abspath(x) for x in settings['library_dirs'] -            ] -     -    return settings - - -#----------------------------------------------------------------------------- -# Extra commands -#----------------------------------------------------------------------------- - -class Configure(build_ext): -    """Configure command adapted from h5py""" - -    description = "Discover ZMQ version and features" -     -    user_options = build_ext.user_options + [ -        ('zmq=', None, "libzmq install prefix"), -        ('build-base=', 'b', "base directory for build library"), # build_base from build -         -    ] -    def initialize_options(self): -        build_ext.initialize_options(self) -        self.zmq = None -        self.build_base = 'build' - -    # DON'T REMOVE: distutils demands these be here even if they do nothing. -    def finalize_options(self): -        build_ext.finalize_options(self) -        self.tempdir = pjoin(self.build_temp, 'scratch') -        self.has_run = False -        self.config = discover_settings(self.build_base) -        if self.zmq is not None: -            merge(self.config, config_from_prefix(self.zmq)) -        self.init_settings_from_config() -     -    def save_config(self, name, cfg): -        """write config to JSON""" -        save_config(name, cfg, self.build_base) -        # write to zmq.utils.[name].json -        save_config(name, cfg, os.path.join('zmq', 'utils')) -        # also write to build_lib, because we might be run after copying to -        # build_lib has already happened. -        build_lib_utils = os.path.join(self.build_lib, 'zmq', 'utils') -        if os.path.exists(build_lib_utils): -            save_config(name, cfg, build_lib_utils) -     -    def init_settings_from_config(self): -        """set up compiler settings, based on config""" -        cfg = self.config -         -        if cfg['libzmq_extension']: -            settings = bundled_settings() -        else: -            settings = settings_from_prefix(cfg['zmq_prefix'], self.bundle_libzmq_dylib) -     -        if 'have_sys_un_h' not in cfg: -            # don't link against anything when checking for sys/un.h -            minus_zmq = copy.deepcopy(settings) -            try: -                minus_zmq['libraries'] = [] -            except Exception: -                pass -            try: -                compile_and_run(self.tempdir, -                    pjoin('buildutils', 'check_sys_un.c'), -                    **minus_zmq -                ) -            except Exception as e: -                warn("No sys/un.h, IPC_PATH_MAX_LEN will be undefined: %s" % e) -                cfg['have_sys_un_h'] = False -            else: -                cfg['have_sys_un_h'] = True -         -            self.save_config('config', cfg) -     -        if cfg['have_sys_un_h']: -            settings['define_macros'] = [('HAVE_SYS_UN_H', 1)] -     -        settings.setdefault('define_macros', []) -     -        # include internal directories -        settings.setdefault('include_dirs', []) -        settings['include_dirs'] += [pjoin('zmq', sub) for sub in ( -            'utils', -            pjoin('backend', 'cython'), -            'devices', -        )] -         -        for ext in self.distribution.ext_modules: -            if ext.name.startswith('zmq.lib'): -                continue -            for attr, value in settings.items(): -                setattr(ext, attr, value) -         -        self.compiler_settings = settings -        self.save_config('compiler', settings) - -    def create_tempdir(self): -        self.erase_tempdir() -        os.makedirs(self.tempdir) -        if sys.platform.startswith('win'): -            # fetch libzmq.dll into local dir -            local_dll = pjoin(self.tempdir, 'libzmq.dll') -            if not self.config['zmq_prefix'] and not os.path.exists(local_dll): -                fatal("ZMQ directory must be specified on Windows via setup.cfg" -                " or 'python setup.py configure --zmq=/path/to/zeromq2'") -             -            try: -                shutil.copy(pjoin(self.config['zmq_prefix'], 'lib', 'libzmq.dll'), local_dll) -            except Exception: -                if not os.path.exists(local_dll): -                    warn("Could not copy libzmq into zmq/, which is usually necessary on Windows." -                    "Please specify zmq prefix via configure --zmq=/path/to/zmq or copy " -                    "libzmq into zmq/ manually.") - -    def erase_tempdir(self): -        try: -            shutil.rmtree(self.tempdir) -        except Exception: -            pass - -    @property -    def compiler_type(self): -        compiler = self.compiler -        if compiler is None: -            return get_default_compiler() -        elif isinstance(compiler, str): -            return compiler -        else: -            return compiler.compiler_type -     -    @property -    def cross_compiling(self): -        return self.config['bdist_egg'].get('plat-name', sys.platform) != sys.platform - -    @property -    def bundle_libzmq_dylib(self): -        """ -        bundle_libzmq_dylib flag for whether external libzmq library will be included in pyzmq: -        only relevant when not building libzmq extension -        """ -        if 'bundle_libzmq_dylib' in self.config: -            return self.config['bundle_libzmq_dylib'] -        elif (sys.platform.startswith('win') or self.cross_compiling) \ -                and not self.config['libzmq_extension']: -            # always bundle libzmq on Windows and cross-compilation -            return True -        elif self.config['zmq_prefix'] and not self.config['libzmq_extension']: -            # only bundle for bdists in sane environments -            return doing_bdist -        else: -            return False - -    def check_zmq_version(self): -        """check the zmq version""" -        cfg = self.config -         -        # build test program -        zmq_prefix = self.config['zmq_prefix'] -        detected = self.test_build(zmq_prefix, self.compiler_settings) -        # now check the libzmq version -         -        vers = tuple(detected['vers']) -        vs = v_str(vers) -        if vers < min_zmq: -            fatal("Detected ZMQ version: %s, but depend on ZMQ >= %s"%( -                    vs, v_str(min_zmq)) -                    +'\n       Using ZMQ=%s' % (zmq_prefix or 'unspecified')) -         -        if vers < target_zmq: -            warn("Detected ZMQ version: %s, but pyzmq targets ZMQ %s." % ( -                    vs, v_str(target_zmq)) -            ) -            warn("libzmq features and fixes introduced after %s will be unavailable." % vs) -            line() -        elif vers >= dev_zmq: -            warn("Detected ZMQ version: %s. Some new features in libzmq may not be exposed by pyzmq." % vs) -            line() - -        if sys.platform.startswith('win'): -            # fetch libzmq.dll into local dir -            local_dll = localpath('zmq','libzmq.dll') -            if not zmq_prefix and not os.path.exists(local_dll): -                fatal("ZMQ directory must be specified on Windows via setup.cfg or 'python setup.py configure --zmq=/path/to/zeromq2'") -            try: -                shutil.copy(pjoin(zmq_prefix, 'lib', 'libzmq.dll'), local_dll) -            except Exception: -                if not os.path.exists(local_dll): -                    warn("Could not copy libzmq into zmq/, which is usually necessary on Windows." -                    "Please specify zmq prefix via configure --zmq=/path/to/zmq or copy " -                    "libzmq into zmq/ manually.") -     -    def bundle_libsodium_extension(self, libzmq): -        bundledir = "bundled" -        ext_modules = self.distribution.ext_modules -        if ext_modules and any(m.name == 'zmq.libsodium' for m in ext_modules): -            # I've already been run -            return -         -        if not os.path.exists(bundledir): -            os.makedirs(bundledir) -         -        line() -        info("Using bundled libsodium") -         -        # fetch sources for libsodium -        fetch_libsodium(bundledir) -         -        # stage headers -        stage_libsodium_headers(pjoin(bundledir, 'libsodium')) -         -        # construct the Extension -        libsodium_src = pjoin(bundledir, 'libsodium', 'src', 'libsodium') -        exclude = pjoin(libsodium_src, 'crypto_stream', 'salsa20', 'amd64_xmm6') # or ref? -        exclude = pjoin(libsodium_src, 'crypto_scalarmult', 'curve25519', 'donna_c64') # or ref? -         -        libsodium_sources = [pjoin('buildutils', 'initlibsodium.c')] -         -        for dir,subdirs,files in os.walk(libsodium_src): -            if dir.startswith(exclude): -                continue -            for f in files: -                if f.endswith('.c'): -                    libsodium_sources.append(pjoin(dir, f)) -         -        libsodium = Extension( -            'zmq.libsodium', -            sources = libsodium_sources, -            include_dirs = [ -                pjoin(libsodium_src, 'include'), -                pjoin(libsodium_src, 'include', 'sodium'), -            ], -        ) -        # register the Extension -        self.distribution.ext_modules.insert(0, libsodium) -         -        if sys.byteorder == 'little': -            libsodium.define_macros.append(("NATIVE_LITTLE_ENDIAN", 1)) -        else: -            libsodium.define_macros.append(("NATIVE_BIG_ENDIAN", 1)) -         -        # tell libzmq about libsodium -        libzmq.define_macros.append(("HAVE_LIBSODIUM", 1)) -        libzmq.include_dirs.extend(libsodium.include_dirs) -         -         -     -    def bundle_libzmq_extension(self): -        bundledir = "bundled" -        ext_modules = self.distribution.ext_modules -        if ext_modules and any(m.name == 'zmq.libzmq' for m in ext_modules): -            # I've already been run -            return -         -        line() -        info("Using bundled libzmq") -         -        # fetch sources for libzmq extension: -        if not os.path.exists(bundledir): -            os.makedirs(bundledir) -         -        fetch_libzmq(bundledir) -         -        stage_platform_hpp(pjoin(bundledir, 'zeromq')) -         -        # construct the Extensions: -        libzmq = Extension( -            'zmq.libzmq', -            sources = [pjoin('buildutils', 'initlibzmq.c')] +  -                        glob(pjoin(bundledir, 'zeromq', 'src', '*.cpp')), -            include_dirs = [ -                pjoin(bundledir, 'zeromq', 'include'), -            ], -        ) -         -        # register the extension: -        self.distribution.ext_modules.insert(0, libzmq) -         -        if sys.platform.startswith('win'): -            # include defines from zeromq msvc project: -            libzmq.define_macros.append(('FD_SETSIZE', 1024)) -            libzmq.define_macros.append(('DLL_EXPORT', 1)) -             -            # When compiling the C++ code inside of libzmq itself, we want to -            # avoid "warning C4530: C++ exception handler used, but unwind -            # semantics are not enabled. Specify /EHsc". -            if self.compiler_type == 'msvc': -                libzmq.extra_compile_args.append('/EHsc') -            elif self.compiler_type == 'mingw32': -                libzmq.define_macros.append(('ZMQ_HAVE_MINGW32', 1)) - -            # And things like sockets come from libraries that must be named. - -            libzmq.libraries.extend(['rpcrt4', 'ws2_32', 'advapi32']) -        else: -            libzmq.include_dirs.append(bundledir) -             -            # check if we need to link against Realtime Extensions library -            cc = new_compiler(compiler=self.compiler_type) -            cc.output_dir = self.build_temp -            if not sys.platform.startswith(('darwin', 'freebsd')): -                line() -                info("checking for timer_create") -                if not cc.has_function('timer_create'): -                    info("no timer_create, linking librt") -                    libzmq.libraries.append('rt') -                else: -                    info("ok") -                 -                if pypy: -                    # seem to need explicit libstdc++ on linux + pypy -                    # not sure why -                    libzmq.libraries.append("stdc++") -         -            # On non-Windows, also bundle libsodium: -            self.bundle_libsodium_extension(libzmq) -         -        # update other extensions, with bundled settings -        self.config['libzmq_extension'] = True -        self.init_settings_from_config() -        self.save_config('config', self.config) -         -     -    def fallback_on_bundled(self): -        """Couldn't build, fallback after waiting a while""" -         -        line() -         -        warn('\n'.join([ -        "Failed to build or run libzmq detection test.", -        "", -        "If you expected pyzmq to link against an installed libzmq, please check to make sure:", -        "", -        "    * You have a C compiler installed", -        "    * A development version of Python is installed (including headers)", -        "    * A development version of ZMQ >= %s is installed (including headers)" % v_str(min_zmq), -        "    * If ZMQ is not in a default location, supply the argument --zmq=<path>", -        "    * If you did recently install ZMQ to a default location,", -        "      try rebuilding the ld cache with `sudo ldconfig`", -        "      or specify zmq's location with `--zmq=/usr/local`", -        "", -        ])) -         -        info('\n'.join([ -            "You can skip all this detection/waiting nonsense if you know", -            "you want pyzmq to bundle libzmq as an extension by passing:", -            "", -            "    `--zmq=bundled`", -            "", -            "I will now try to build libzmq as a Python extension", -            "unless you interrupt me (^C) in the next 10 seconds...", -            "", -        ])) -         -        for i in range(10,0,-1): -            sys.stdout.write('\r%2i...' % i) -            sys.stdout.flush() -            time.sleep(1) -         -        info("") -         -        return self.bundle_libzmq_extension() -         -     -    def test_build(self, prefix, settings): -        """do a test build ob libzmq""" -        self.create_tempdir() -        settings = settings.copy() -        if self.bundle_libzmq_dylib and not sys.platform.startswith('win'): -            # rpath slightly differently here, because libzmq not in .. but ../zmq: -            settings['library_dirs'] = ['zmq'] -            if sys.platform == 'darwin': -                pass -                # unused rpath args for OS X: -                # settings['extra_link_args'] = ['-Wl,-rpath','-Wl,$ORIGIN/../zmq'] -            else: -                settings['runtime_library_dirs'] = [ os.path.abspath(pjoin('.', 'zmq')) ] -         -        line() -        info("Configure: Autodetecting ZMQ settings...") -        info("    Custom ZMQ dir:       %s" % prefix) -        try: -            detected = detect_zmq(self.tempdir, compiler=self.compiler_type, **settings) -        finally: -            self.erase_tempdir() -         -        info("    ZMQ version detected: %s" % v_str(detected['vers'])) -         -        return detected -     - -    def finish_run(self): -        self.save_config('config', self.config) -        line() -     -    def run(self): -        cfg = self.config -         -        if cfg['libzmq_extension']: -            self.bundle_libzmq_extension() -            self.finish_run() -            return -         -        # When cross-compiling and zmq is given explicitly, we can't testbuild -        # (as we can't testrun the binary), we assume things are alright. -        if cfg['skip_check_zmq'] or self.cross_compiling: -            warn("Skipping zmq version check") -            self.finish_run() -            return -         -        zmq_prefix = cfg['zmq_prefix'] -        # There is no available default on Windows, so start with fallback unless -        # zmq was given explicitly, or libzmq extension was explicitly prohibited. -        if sys.platform.startswith("win") and \ -                not cfg['no_libzmq_extension'] and \ -                not zmq_prefix: -            self.fallback_on_bundled() -            self.finish_run() -            return -         -        if zmq_prefix and self.bundle_libzmq_dylib and not sys.platform.startswith('win'): -            copy_and_patch_libzmq(zmq_prefix, 'libzmq'+lib_ext) -         -        # first try with given config or defaults -        try: -            self.check_zmq_version() -        except Exception as e: -            # print the error as distutils would if we let it raise: -            info("\nerror: %s\n" % e) -        else: -            self.finish_run() -            return -         -        # try fallback on /usr/local on *ix if no prefix is given -        if not zmq_prefix and not sys.platform.startswith('win'): -            info("Failed with default libzmq, trying again with /usr/local") -            time.sleep(1) -            zmq_prefix = cfg['zmq_prefix'] = '/usr/local' -            self.init_settings_from_config() -            try: -                self.check_zmq_version() -            except Exception as e: -                # print the error as distutils would if we let it raise: -                info("\nerror: %s\n" % e) -            else: -                # if we get here the second run succeeded, so we need to update compiler -                # settings for the extensions with /usr/local prefix -                self.finish_run() -                return -         -        # finally, fallback on bundled -         -        if cfg['no_libzmq_extension']: -            fatal("Falling back on bundled libzmq," -            " but setup.cfg has explicitly prohibited building the libzmq extension." -            ) -         -        self.fallback_on_bundled() -         -        self.finish_run() - - -class FetchCommand(Command): -    """Fetch libzmq sources, that's it.""" -     -    description = "Fetch libzmq sources into bundled/zeromq" -     -    user_options = [ ] -     -    def initialize_options(self): -        pass -     -    def finalize_options(self): -        pass -     -    def run(self): -        # fetch sources for libzmq extension: -        bundledir = "bundled" -        if os.path.exists(bundledir): -            info("Scrubbing directory: %s" % bundledir) -            shutil.rmtree(bundledir) -        if not os.path.exists(bundledir): -            os.makedirs(bundledir) -        fetch_libsodium(bundledir) -        fetch_libzmq(bundledir) -        for tarball in glob(pjoin(bundledir, '*.tar.gz')): -            os.remove(tarball) -         - - -class TestCommand(Command): -    """Custom distutils command to run the test suite.""" - -    description = "Test PyZMQ (must have been built inplace: `setup.py build_ext --inplace`)" - -    user_options = [ ] - -    def initialize_options(self): -        self._dir = os.getcwd() - -    def finalize_options(self): -        pass -     -    def run_nose(self): -        """Run the test suite with nose.""" -        nose = 'nose.__main__' if sys.version_info < (2,7) else 'nose' -        if subprocess.call([sys.executable, '-m', nose, '-vvx', pjoin(self._dir, 'zmq', 'tests')]): -            sys.exit(1) -     -    def run_unittest(self): -        """Finds all the tests modules in zmq/tests/ and runs them.""" -        testfiles = [ ] -        for t in glob(pjoin(self._dir, 'zmq', 'tests', '*.py')): -            name = splitext(basename(t))[0] -            if name.startswith('test_'): -                testfiles.append('.'.join( -                    ['zmq.tests', name]) -                ) -        tests = TestLoader().loadTestsFromNames(testfiles) -        t = TextTestRunner(verbosity = 2) -        t.run(tests) -     -    def run(self): -        """Run the test suite, with nose, or unittest if nose is unavailable""" -        # crude check for inplace build: -        try: -            import zmq -        except ImportError: -            print_exc() -            fatal('\n       '.join(["Could not import zmq!", -            "You must build pyzmq with 'python setup.py build_ext --inplace' for 'python setup.py test' to work.", -            "If you did build pyzmq in-place, then this is a real error."])) -            sys.exit(1) -         -        info("Testing pyzmq-%s with libzmq-%s" % (zmq.pyzmq_version(), zmq.zmq_version())) -         -        if nose is None: -            warn("nose unavailable, falling back on unittest. Skipped tests will appear as ERRORs.") -            return self.run_unittest() -        else: -            return self.run_nose() - -class GitRevisionCommand(Command): -    """find the current git revision and add it to zmq.sugar.version.__revision__""" -     -    description = "Store current git revision in version.py" -     -    user_options = [ ] -     -    def initialize_options(self): -        self.version_py = pjoin('zmq','sugar','version.py') -     -    def run(self): -        try: -            p = Popen('git log -1'.split(), stdin=PIPE, stdout=PIPE, stderr=PIPE) -        except IOError: -            warn("No git found, skipping git revision") -            return -         -        if p.wait(): -            warn("checking git branch failed") -            info(p.stderr.read()) -            return -         -        line = p.stdout.readline().decode().strip() -        if not line.startswith('commit'): -            warn("bad commit line: %r" % line) -            return -         -        rev = line.split()[-1] -         -        # now that we have the git revision, we can apply it to version.py -        with open(self.version_py) as f: -            lines = f.readlines() -         -        for i,line in enumerate(lines): -            if line.startswith('__revision__'): -                lines[i] = "__revision__ = '%s'\n"%rev -                break -        with open(self.version_py, 'w') as f: -            f.writelines(lines) -     -    def finalize_options(self): -        pass - -class CleanCommand(Command): -    """Custom distutils command to clean the .so and .pyc files.""" -    user_options = [('all', 'a', -         "remove all build output, not just temporary by-products") -    ] - -    boolean_options = ['all'] - -    def initialize_options(self): -        self.all = None - -    def finalize_options(self): -        pass - -    def run(self): -        self._clean_me = [] -        self._clean_trees = [] -        for root, dirs, files in list(os.walk('buildutils')): -            for f in files: -                if os.path.splitext(f)[-1] == '.pyc': -                    self._clean_me.append(pjoin(root, f)) - -        for root, dirs, files in list(os.walk('zmq')): -            for f in files: -                if os.path.splitext(f)[-1] in ('.pyc', '.so', '.o', '.pyd', '.json'): -                    self._clean_me.append(pjoin(root, f)) -                # remove generated cython files -                if self.all and os.path.splitext(f)[-1] == '.c': -                    self._clean_me.append(pjoin(root, f)) - -            for d in dirs: -                if d == '__pycache__': -                    self._clean_trees.append(pjoin(root, d)) -         -        for d in ('build', 'conf'): -            if os.path.exists(d): -                self._clean_trees.append(d) - -        bundled = glob(pjoin('zmq', 'libzmq*')) -        self._clean_me.extend(bundled) -        for clean_me in self._clean_me: -            try: -                os.unlink(clean_me) -            except Exception: -                pass -        for clean_tree in self._clean_trees: -            try: -                shutil.rmtree(clean_tree) -            except Exception: -                pass - - -class CheckSDist(sdist): -    """Custom sdist that ensures Cython has compiled all pyx files to c.""" - -    def initialize_options(self): -        sdist.initialize_options(self) -        self._pyxfiles = [] -        for root, dirs, files in os.walk('zmq'): -            for f in files: -                if f.endswith('.pyx'): -                    self._pyxfiles.append(pjoin(root, f)) -    def run(self): -        self.run_command('fetch_libzmq') -        if 'cython' in cmdclass: -            self.run_command('cython') -        else: -            for pyxfile in self._pyxfiles: -                cfile = pyxfile[:-3]+'c' -                msg = "C-source file '%s' not found."%(cfile)+\ -                " Run 'setup.py cython' before sdist." -                assert os.path.isfile(cfile), msg -        sdist.run(self) - -class CheckingBuildExt(build_ext): -    """Subclass build_ext to get clearer report if Cython is necessary.""" -     -    def check_cython_extensions(self, extensions): -        for ext in extensions: -          for src in ext.sources: -            if not os.path.exists(src): -                fatal("""Cython-generated file '%s' not found. -                Cython >= 0.16 is required to compile pyzmq from a development branch. -                Please install Cython or download a release package of pyzmq. -                """%src) -     -    def build_extensions(self): -        self.check_cython_extensions(self.extensions) -        self.check_extensions_list(self.extensions) -         -        if self.compiler.compiler_type == 'mingw32': -            customize_mingw(self.compiler) -         -        for ext in self.extensions: -             -            self.build_extension(ext) -     -    def run(self): -        # check version, to prevent confusing undefined constant errors -        self.distribution.run_command('configure') -        build_ext.run(self) - - -class ConstantsCommand(Command): -    """Rebuild templated files for constants -     -    To be run after adding new constants to `utils/constant_names`. -    """ -    user_options = [] -    def initialize_options(self): -        return  -     -    def finalize_options(self): -        pass -     -    def run(self): -        from buildutils.constants import render_constants -        render_constants() - -#----------------------------------------------------------------------------- -# Extensions -#----------------------------------------------------------------------------- - -cmdclass = {'test':TestCommand, 'clean':CleanCommand, 'revision':GitRevisionCommand, -            'configure': Configure, 'fetch_libzmq': FetchCommand, -            'sdist': CheckSDist, 'constants': ConstantsCommand, -        } - -if 'bdist_wheel' in sys.argv and sys.platform == 'darwin': -    from wheel.bdist_wheel import bdist_wheel -     -    class bdist_wheel_mac_tag(bdist_wheel): -        """add 'current' platform tags to wheels -         -        A 10.6-intel wheel works on all 10.X >= 10.6 and arch in 32,64,intel. -         -        Since that would produce a ludicrous filename, just add the two most common: -         -        - current-intel -        - current-x86_64 -         -        partial workaround for pypa/pip#1465 -        """ -        def get_tag(self): -            import platform -            impl, abi, plat = bdist_wheel.get_tag(self) -            plat_tag_re = re.compile(r'macosx_(\d+)_(\d+)_(.+)') -            m = plat_tag_re.match(plat) -            if m: -                plat_tags = [plat] -                major, minor, arch = m.groups() -                arches = [arch] -                if arch == 'intel': -                    arches.append('x86_64') -                host_list = re.findall('\d+', platform.mac_ver()[0]) -                host = (int(host_list[0]), int(host_list[1])) -                host_s = '%s_%s' % tuple(host_list[:2]) -                target = (int(major), int(minor)) -                if host > target or len(arches) > 1: -                    for arch in arches: -                        plat_tags.append('macosx_%s_%s' % (host_s, arch)) -                 -                plat = '.'.join(sorted(set(plat_tags))) -            return (impl, abi, plat) -     -    cmdclass['bdist_wheel'] = bdist_wheel_mac_tag -     -     -def makename(path, ext): -    return os.path.abspath(pjoin('zmq', *path)) + ext - -pxd = lambda *path: makename(path, '.pxd') -pxi = lambda *path: makename(path, '.pxi') -pyx = lambda *path: makename(path, '.pyx') -dotc = lambda *path: makename(path, '.c') - -libzmq = pxd('backend', 'cython', 'libzmq') -buffers = pxd('utils', 'buffers') -message = pxd('backend', 'cython', 'message') -context = pxd('backend', 'cython', 'context') -socket = pxd('backend', 'cython', 'socket') -utils = pxd('backend', 'cython', 'utils') -checkrc = pxd('backend', 'cython', 'checkrc') -monqueue = pxd('devices', 'monitoredqueue') - -submodules = { -    'backend.cython' : {'constants': [libzmq, pxi('backend', 'cython', 'constants')], -            'error':[libzmq, checkrc], -            '_poll':[libzmq, socket, context, checkrc], -            'utils':[libzmq, utils, checkrc], -            'context':[context, libzmq, checkrc], -            'message':[libzmq, buffers, message, checkrc], -            'socket':[context, message, socket, libzmq, buffers, checkrc], -            '_device':[libzmq, socket, context, checkrc], -            '_version':[libzmq], -    }, -    'devices' : { -            'monitoredqueue':[buffers, libzmq, monqueue, socket, context, checkrc], -    }, -} - -try: -    import Cython -    if V(Cython.__version__) < V('0.16'): -        raise ImportError("Cython >= 0.16 required, found %s" % Cython.__version__) -    from Cython.Distutils import build_ext as build_ext_c -    cython=True -except Exception: -    cython=False -    suffix = '.c' -    cmdclass['build_ext'] = CheckingBuildExt -     -    class MissingCython(Command): -         -        user_options = [] -         -        def initialize_options(self): -            pass -         -        def finalize_options(self): -            pass -         -        def run(self): -            try: -                import Cython -            except ImportError: -                warn("Cython is missing") -            else: -                cv = getattr(Cython, "__version__", None) -                if cv is None or V(cv) < V('0.16'): -                    warn( -                        "Cython >= 0.16 is required for compiling Cython sources, " -                        "found: %s" % (cv or "super old") -                    ) -    cmdclass['cython'] = MissingCython -else: -     -    suffix = '.pyx' -     -    class CythonCommand(build_ext_c): -        """Custom distutils command subclassed from Cython.Distutils.build_ext -        to compile pyx->c, and stop there. All this does is override the  -        C-compile method build_extension() with a no-op.""" -         -        description = "Compile Cython sources to C" -         -        def build_extension(self, ext): -            pass -     -    class zbuild_ext(build_ext_c): -         -        def build_extensions(self): -            if self.compiler.compiler_type == 'mingw32': -                customize_mingw(self.compiler) -            return build_ext_c.build_extensions(self) -         -        def run(self): -            self.distribution.run_command('configure') -            return build_ext.run(self) -     -    cmdclass['cython'] = CythonCommand -    cmdclass['build_ext'] =  zbuild_ext - -extensions = [] -for submod, packages in submodules.items(): -    for pkg in sorted(packages): -        sources = [pjoin('zmq', submod.replace('.', os.path.sep), pkg+suffix)] -        if suffix == '.pyx': -            sources.extend(packages[pkg]) -        ext = Extension( -            'zmq.%s.%s'%(submod, pkg), -            sources = sources, -            include_dirs=[pjoin('zmq', sub) for sub in ('utils',pjoin('backend', 'cython'),'devices')], -        ) -        if suffix == '.pyx' and ext.sources[0].endswith('.c'): -            # undo setuptools stupidly clobbering cython sources: -            ext.sources = sources -        extensions.append(ext) - -if pypy: -    # add dummy extension, to ensure build_ext runs -    dummy_ext = Extension('dummy', sources=[]) -    extensions = [dummy_ext] -     -    bld_ext = cmdclass['build_ext'] -    class pypy_build_ext(bld_ext): -        """hack to build pypy extension only after building bundled libzmq -         -        otherwise it will fail when libzmq is bundled. -        """ -        def build_extensions(self): -            self.extensions.remove(dummy_ext) -            bld_ext.build_extensions(self) -            # build ffi extension after bundled libzmq, -            # because it may depend on linking it -            here = os.getcwd() -            sys.path.insert(0, self.build_lib) -            try: -                from zmq.backend.cffi import ffi -            except ImportError as e: -                warn("Couldn't get CFFI extension: %s" % e) -            else: -                ext = ffi.verifier.get_extension() -                self.extensions.append(ext) -                self.build_extension(ext) -            finally: -                sys.path.pop(0) - -     -    # How many build_ext subclasses is this? 5? Gross. -    cmdclass['build_ext'] = pypy_build_ext - - -package_data = {'zmq': ['*.pxd'], -                'zmq.backend.cython': ['*.pxd'], -                'zmq.devices': ['*.pxd'], -                'zmq.utils': ['*.pxd', '*.h', '*.json'], -} - -package_data['zmq'].append('libzmq'+lib_ext) - -def extract_version(): -    """extract pyzmq version from sugar/version.py, so it's not multiply defined""" -    with open(pjoin('zmq', 'sugar', 'version.py')) as f: -        while True: -            line = f.readline() -            if line.startswith('VERSION'): -                lines = [] -                while line and not line.startswith('def'): -                    lines.append(line) -                    line = f.readline() -                break -    exec(''.join(lines), globals()) -    return __version__ - -def find_packages(): -    """adapted from IPython's setupbase.find_packages()""" -    packages = [] -    for dir,subdirs,files in os.walk('zmq'): -        package = dir.replace(os.path.sep, '.') -        if '__init__.py' not in files: -            # not a package -            continue -        packages.append(package) -    return packages - -#----------------------------------------------------------------------------- -# Main setup -#----------------------------------------------------------------------------- - -long_desc = \ -""" -PyZMQ is the official Python binding for the ZeroMQ Messaging Library (http://www.zeromq.org). -""" - -setup_args = dict( -    name = "pyzmq", -    version = extract_version(), -    packages = find_packages(), -    ext_modules = extensions, -    package_data = package_data, -    author = "Brian E. Granger, Min Ragan-Kelley", -    author_email = "zeromq-dev@lists.zeromq.org", -    url = 'http://github.com/zeromq/pyzmq', -    download_url = 'http://github.com/zeromq/pyzmq/releases', -    description = "Python bindings for 0MQ", -    long_description = long_desc,  -    license = "LGPL+BSD", -    cmdclass = cmdclass, -    classifiers = [ -        'Development Status :: 5 - Production/Stable', -        'Intended Audience :: Developers', -        'Intended Audience :: Science/Research', -        'Intended Audience :: System Administrators', -        'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', -        'License :: OSI Approved :: BSD License', -        'Operating System :: MacOS :: MacOS X', -        'Operating System :: Microsoft :: Windows', -        'Operating System :: POSIX', -        'Topic :: System :: Networking', -        'Programming Language :: Python :: 2', -        'Programming Language :: Python :: 2.6', -        'Programming Language :: Python :: 2.7', -        'Programming Language :: Python :: 3', -        'Programming Language :: Python :: 3.2', -        'Programming Language :: Python :: 3.3', -    ], -) -if 'setuptools' in sys.modules and pypy: -    setup_args['install_requires'] = [ -        'py', -        'cffi', -    ] - -setup(**setup_args) - diff --git a/setupegg.py b/setupegg.py deleted file mode 100644 index 2c2c9aa..0000000 --- a/setupegg.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python -"""Wrapper to run setup.py using setuptools.""" - -import os, sys - -# now, import setuptools and call the actual setup -import setuptools -try: -    execfile('setup.py') -except NameError: -    exec( open('setup.py','rb').read() ) diff --git a/tox.ini b/tox.ini deleted file mode 100644 index b3ffc41..0000000 --- a/tox.ini +++ /dev/null @@ -1,27 +0,0 @@ -# Tox (http://tox.testrun.org/) is a tool for running tests -# in multiple virtualenvs. This configuration file will run the -# test suite on all supported python versions. To use it, "pip install tox" -# and then run "tox" from this directory. - -[tox] -envlist = pypy, py26, py27, py32, py33 - -[testenv] -changedir = {toxworkdir} -commands = -    python -V -    python -c 'import zmq; print("pyzmq-%s" % zmq.pyzmq_version())' -    python -c 'import zmq; print("libzmq-%s" % zmq.zmq_version())' -    nosetests zmq.tests -deps = -    nose - -[testenv:py27] -deps =  -    gevent -    {[testenv]deps} -[testenv:pypy] -deps = -    py -    cffi -    nose diff --git a/zmq/__init__.py b/zmq/__init__.py deleted file mode 100644 index cf4a1f7..0000000 --- a/zmq/__init__.py +++ /dev/null @@ -1,63 +0,0 @@ -"""Python bindings for 0MQ.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import os -import sys -import glob - -# load bundled libzmq, if there is one: - -here = os.path.dirname(__file__) - -bundled = [] -bundled_sodium = [] -for ext in ('pyd', 'so', 'dll', 'dylib'): -    bundled_sodium.extend(glob.glob(os.path.join(here, 'libsodium*.%s*' % ext))) -    bundled.extend(glob.glob(os.path.join(here, 'libzmq*.%s*' % ext))) - -if bundled: -    import ctypes -    if bundled_sodium: -        if bundled[0].endswith('.pyd'): -            # a Windows Extension -            _libsodium = ctypes.cdll.LoadLibrary(bundled_sodium[0]) -        else: -            _libsodium = ctypes.CDLL(bundled_sodium[0], mode=ctypes.RTLD_GLOBAL) -    if bundled[0].endswith('.pyd'): -        # a Windows Extension -        _libzmq = ctypes.cdll.LoadLibrary(bundled[0]) -    else: -        _libzmq = ctypes.CDLL(bundled[0], mode=ctypes.RTLD_GLOBAL) -    del ctypes -else: -    import zipimport -    try: -        if isinstance(__loader__, zipimport.zipimporter): -            # a zipped pyzmq egg -            from zmq import libzmq as _libzmq -    except (NameError, ImportError): -        pass -    finally: -        del zipimport - -del os, sys, glob, here, bundled, bundled_sodium, ext - -# zmq top-level imports - -from zmq.backend import * -from zmq import sugar -from zmq.sugar import * -from zmq import devices - -def get_includes(): -    """Return a list of directories to include for linking against pyzmq with cython.""" -    from os.path import join, dirname, abspath, pardir -    base = dirname(__file__) -    parent = abspath(join(base, pardir)) -    return [ parent ] + [ join(parent, base, subdir) for subdir in ('utils',) ] - - -__all__ = ['get_includes'] + sugar.__all__ + backend.__all__ - diff --git a/zmq/auth/__init__.py b/zmq/auth/__init__.py deleted file mode 100644 index 11d3ad6..0000000 --- a/zmq/auth/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Utilities for ZAP authentication. - -To run authentication in a background thread, see :mod:`zmq.auth.thread`. -For integration with the tornado eventloop, see :mod:`zmq.auth.ioloop`. - -.. versionadded:: 14.1 -""" - -from .base import * -from .certs import * diff --git a/zmq/auth/base.py b/zmq/auth/base.py deleted file mode 100644 index 9b4aaed..0000000 --- a/zmq/auth/base.py +++ /dev/null @@ -1,272 +0,0 @@ -"""Base implementation of 0MQ authentication.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import logging - -import zmq -from zmq.utils import z85 -from zmq.utils.strtypes import bytes, unicode, b, u -from zmq.error import _check_version - -from .certs import load_certificates - - -CURVE_ALLOW_ANY = '*' -VERSION = b'1.0' - -class Authenticator(object): -    """Implementation of ZAP authentication for zmq connections. - -    Note: -    - libzmq provides four levels of security: default NULL (which the Authenticator does -      not see), and authenticated NULL, PLAIN, and CURVE, which the Authenticator can see. -    - until you add policies, all incoming NULL connections are allowed -    (classic ZeroMQ behavior), and all PLAIN and CURVE connections are denied. -    """ - -    def __init__(self, context=None, encoding='utf-8', log=None): -        _check_version((4,0), "security") -        self.context = context or zmq.Context.instance() -        self.encoding = encoding -        self.allow_any = False -        self.zap_socket = None -        self.whitelist = set() -        self.blacklist = set() -        # passwords is a dict keyed by domain and contains values -        # of dicts with username:password pairs. -        self.passwords = {} -        # certs is dict keyed by domain and contains values -        # of dicts keyed by the public keys from the specified location. -        self.certs = {} -        self.log = log or logging.getLogger('zmq.auth') -     -    def start(self): -        """Create and bind the ZAP socket""" -        self.zap_socket = self.context.socket(zmq.REP) -        self.zap_socket.linger = 1 -        self.zap_socket.bind("inproc://zeromq.zap.01") - -    def stop(self): -        """Close the ZAP socket""" -        if self.zap_socket: -            self.zap_socket.close() -        self.zap_socket = None - -    def allow(self, *addresses): -        """Allow (whitelist) IP address(es). -         -        Connections from addresses not in the whitelist will be rejected. -         -        - For NULL, all clients from this address will be accepted. -        - For PLAIN and CURVE, they will be allowed to continue with authentication. -         -        whitelist is mutually exclusive with blacklist. -        """ -        if self.blacklist: -            raise ValueError("Only use a whitelist or a blacklist, not both") -        self.whitelist.update(addresses) - -    def deny(self, *addresses): -        """Deny (blacklist) IP address(es). -         -        Addresses not in the blacklist will be allowed to continue with authentication. -         -        Blacklist is mutually exclusive with whitelist. -        """ -        if self.whitelist: -            raise ValueError("Only use a whitelist or a blacklist, not both") -        self.blacklist.update(addresses) - -    def configure_plain(self, domain='*', passwords=None): -        """Configure PLAIN authentication for a given domain. -         -        PLAIN authentication uses a plain-text password file. -        To cover all domains, use "*". -        You can modify the password file at any time; it is reloaded automatically. -        """ -        if passwords: -            self.passwords[domain] = passwords - -    def configure_curve(self, domain='*', location=None): -        """Configure CURVE authentication for a given domain. -         -        CURVE authentication uses a directory that holds all public client certificates, -        i.e. their public keys. -         -        To cover all domains, use "*". -         -        You can add and remove certificates in that directory at any time. -         -        To allow all client keys without checking, specify CURVE_ALLOW_ANY for the location. -        """ -        # If location is CURVE_ALLOW_ANY then allow all clients. Otherwise -        # treat location as a directory that holds the certificates. -        if location == CURVE_ALLOW_ANY: -            self.allow_any = True -        else: -            self.allow_any = False -            try: -                self.certs[domain] = load_certificates(location) -            except Exception as e: -                self.log.error("Failed to load CURVE certs from %s: %s", location, e) - -    def handle_zap_message(self, msg): -        """Perform ZAP authentication""" -        if len(msg) < 6: -            self.log.error("Invalid ZAP message, not enough frames: %r", msg) -            if len(msg) < 2: -                self.log.error("Not enough information to reply") -            else: -                self._send_zap_reply(msg[1], b"400", b"Not enough frames") -            return -         -        version, request_id, domain, address, identity, mechanism = msg[:6] -        credentials = msg[6:] -         -        domain = u(domain, self.encoding, 'replace') -        address = u(address, self.encoding, 'replace') - -        if (version != VERSION): -            self.log.error("Invalid ZAP version: %r", msg) -            self._send_zap_reply(request_id, b"400", b"Invalid version") -            return - -        self.log.debug("version: %r, request_id: %r, domain: %r," -                      " address: %r, identity: %r, mechanism: %r", -                      version, request_id, domain, -                      address, identity, mechanism, -        ) - - -        # Is address is explicitly whitelisted or blacklisted? -        allowed = False -        denied = False -        reason = b"NO ACCESS" - -        if self.whitelist: -            if address in self.whitelist: -                allowed = True -                self.log.debug("PASSED (whitelist) address=%s", address) -            else: -                denied = True -                reason = b"Address not in whitelist" -                self.log.debug("DENIED (not in whitelist) address=%s", address) - -        elif self.blacklist: -            if address in self.blacklist: -                denied = True -                reason = b"Address is blacklisted" -                self.log.debug("DENIED (blacklist) address=%s", address) -            else: -                allowed = True -                self.log.debug("PASSED (not in blacklist) address=%s", address) - -        # Perform authentication mechanism-specific checks if necessary -        username = u("user") -        if not denied: - -            if mechanism == b'NULL' and not allowed: -                # For NULL, we allow if the address wasn't blacklisted -                self.log.debug("ALLOWED (NULL)") -                allowed = True - -            elif mechanism == b'PLAIN': -                # For PLAIN, even a whitelisted address must authenticate -                if len(credentials) != 2: -                    self.log.error("Invalid PLAIN credentials: %r", credentials) -                    self._send_zap_reply(request_id, b"400", b"Invalid credentials") -                    return -                username, password = [ u(c, self.encoding, 'replace') for c in credentials ] -                allowed, reason = self._authenticate_plain(domain, username, password) - -            elif mechanism == b'CURVE': -                # For CURVE, even a whitelisted address must authenticate -                if len(credentials) != 1: -                    self.log.error("Invalid CURVE credentials: %r", credentials) -                    self._send_zap_reply(request_id, b"400", b"Invalid credentials") -                    return -                key = credentials[0] -                allowed, reason = self._authenticate_curve(domain, key) - -        if allowed: -            self._send_zap_reply(request_id, b"200", b"OK", username) -        else: -            self._send_zap_reply(request_id, b"400", reason) - -    def _authenticate_plain(self, domain, username, password): -        """PLAIN ZAP authentication""" -        allowed = False -        reason = b"" -        if self.passwords: -            # If no domain is not specified then use the default domain -            if not domain: -                domain = '*' - -            if domain in self.passwords: -                if username in self.passwords[domain]: -                    if password == self.passwords[domain][username]: -                        allowed = True -                    else: -                        reason = b"Invalid password" -                else: -                    reason = b"Invalid username" -            else: -                reason = b"Invalid domain" - -            if allowed: -                self.log.debug("ALLOWED (PLAIN) domain=%s username=%s password=%s", -                    domain, username, password, -                ) -            else: -                self.log.debug("DENIED %s", reason) - -        else: -            reason = b"No passwords defined" -            self.log.debug("DENIED (PLAIN) %s", reason) - -        return allowed, reason - -    def _authenticate_curve(self, domain, client_key): -        """CURVE ZAP authentication""" -        allowed = False -        reason = b"" -        if self.allow_any: -            allowed = True -            reason = b"OK" -            self.log.debug("ALLOWED (CURVE allow any client)") -        else: -            # If no explicit domain is specified then use the default domain -            if not domain: -                domain = '*' - -            if domain in self.certs: -                # The certs dict stores keys in z85 format, convert binary key to z85 bytes -                z85_client_key = z85.encode(client_key) -                if z85_client_key in self.certs[domain] or self.certs[domain] == b'OK': -                    allowed = True -                    reason = b"OK" -                else: -                    reason = b"Unknown key" - -                status = "ALLOWED" if allowed else "DENIED" -                self.log.debug("%s (CURVE) domain=%s client_key=%s", -                    status, domain, z85_client_key, -                ) -            else: -                reason = b"Unknown domain" - -        return allowed, reason - -    def _send_zap_reply(self, request_id, status_code, status_text, user_id='user'): -        """Send a ZAP reply to finish the authentication.""" -        user_id = user_id if status_code == b'200' else b'' -        if isinstance(user_id, unicode): -            user_id = user_id.encode(self.encoding, 'replace') -        metadata = b''  # not currently used -        self.log.debug("ZAP reply code=%s text=%s", status_code, status_text) -        reply = [VERSION, request_id, status_code, status_text, user_id, metadata] -        self.zap_socket.send_multipart(reply) - -__all__ = ['Authenticator', 'CURVE_ALLOW_ANY'] diff --git a/zmq/auth/certs.py b/zmq/auth/certs.py deleted file mode 100644 index 4d26ad7..0000000 --- a/zmq/auth/certs.py +++ /dev/null @@ -1,119 +0,0 @@ -"""0MQ authentication related functions and classes.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import datetime -import glob -import io -import os -import zmq -from zmq.utils.strtypes import bytes, unicode, b, u - - -_cert_secret_banner = u("""#   ****  Generated on {0} by pyzmq  **** -#   ZeroMQ CURVE **Secret** Certificate -#   DO NOT PROVIDE THIS FILE TO OTHER USERS nor change its permissions. - -""") - -_cert_public_banner = u("""#   ****  Generated on {0} by pyzmq  **** -#   ZeroMQ CURVE Public Certificate -#   Exchange securely, or use a secure mechanism to verify the contents -#   of this file after exchange. Store public certificates in your home -#   directory, in the .curve subdirectory. - -""") - -def _write_key_file(key_filename, banner, public_key, secret_key=None, metadata=None, encoding='utf-8'): -    """Create a certificate file""" -    if isinstance(public_key, bytes): -        public_key = public_key.decode(encoding) -    if isinstance(secret_key, bytes): -        secret_key = secret_key.decode(encoding) -    with io.open(key_filename, 'w', encoding='utf8') as f: -        f.write(banner.format(datetime.datetime.now())) - -        f.write(u('metadata\n')) -        if metadata: -            for k, v in metadata.items(): -                if isinstance(v, bytes): -                    v = v.decode(encoding) -                f.write(u("    {0} = {1}\n").format(k, v)) - -        f.write(u('curve\n')) -        f.write(u("    public-key = \"{0}\"\n").format(public_key)) - -        if secret_key: -            f.write(u("    secret-key = \"{0}\"\n").format(secret_key)) - - -def create_certificates(key_dir, name, metadata=None): -    """Create zmq certificates. -     -    Returns the file paths to the public and secret certificate files. -    """ -    public_key, secret_key = zmq.curve_keypair() -    base_filename = os.path.join(key_dir, name) -    secret_key_file = "{0}.key_secret".format(base_filename) -    public_key_file = "{0}.key".format(base_filename) -    now = datetime.datetime.now() - -    _write_key_file(public_key_file, -                    _cert_public_banner.format(now), -                    public_key) - -    _write_key_file(secret_key_file, -                    _cert_secret_banner.format(now), -                    public_key, -                    secret_key=secret_key, -                    metadata=metadata) - -    return public_key_file, secret_key_file - - -def load_certificate(filename): -    """Load public and secret key from a zmq certificate. -     -    Returns (public_key, secret_key) -     -    If the certificate file only contains the public key, -    secret_key will be None. -    """ -    public_key = None -    secret_key = None -    if not os.path.exists(filename): -        raise IOError("Invalid certificate file: {0}".format(filename)) - -    with open(filename, 'rb') as f: -        for line in f: -            line = line.strip() -            if line.startswith(b'#'): -                continue -            if line.startswith(b'public-key'): -                public_key = line.split(b"=", 1)[1].strip(b' \t\'"') -            if line.startswith(b'secret-key'): -                secret_key = line.split(b"=", 1)[1].strip(b' \t\'"') -            if public_key and secret_key: -                break -     -    return public_key, secret_key - - -def load_certificates(directory='.'): -    """Load public keys from all certificates in a directory""" -    certs = {} -    if not os.path.isdir(directory): -        raise IOError("Invalid certificate directory: {0}".format(directory)) -    # Follow czmq pattern of public keys stored in *.key files. -    glob_string = os.path.join(directory, "*.key") -     -    cert_files = glob.glob(glob_string) -    for cert_file in cert_files: -        public_key, _ = load_certificate(cert_file) -        if public_key: -            certs[public_key] = 'OK' -    return certs - -__all__ = ['create_certificates', 'load_certificate', 'load_certificates'] diff --git a/zmq/auth/ioloop.py b/zmq/auth/ioloop.py deleted file mode 100644 index 1f448b4..0000000 --- a/zmq/auth/ioloop.py +++ /dev/null @@ -1,34 +0,0 @@ -"""ZAP Authenticator integrated with the tornado IOLoop. - -.. versionadded:: 14.1 -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from zmq.eventloop import ioloop, zmqstream -from .base import Authenticator - - -class IOLoopAuthenticator(Authenticator): -    """ZAP authentication for use in the tornado IOLoop""" - -    def __init__(self, context=None, encoding='utf-8', log=None, io_loop=None): -        super(IOLoopAuthenticator, self).__init__(context) -        self.zap_stream = None -        self.io_loop = io_loop or ioloop.IOLoop.instance() - -    def start(self): -        """Start ZAP authentication""" -        super(IOLoopAuthenticator, self).start() -        self.zap_stream = zmqstream.ZMQStream(self.zap_socket, self.io_loop) -        self.zap_stream.on_recv(self.handle_zap_message) - -    def stop(self): -        """Stop ZAP authentication""" -        if self.zap_stream: -            self.zap_stream.close() -            self.zap_stream = None -        super(IOLoopAuthenticator, self).stop() - -__all__ = ['IOLoopAuthenticator'] diff --git a/zmq/auth/thread.py b/zmq/auth/thread.py deleted file mode 100644 index 8c3355a..0000000 --- a/zmq/auth/thread.py +++ /dev/null @@ -1,184 +0,0 @@ -"""ZAP Authenticator in a Python Thread. - -.. versionadded:: 14.1 -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import logging -from threading import Thread - -import zmq -from zmq.utils import jsonapi -from zmq.utils.strtypes import bytes, unicode, b, u - -from .base import Authenticator - -class AuthenticationThread(Thread): -    """A Thread for running a zmq Authenticator -     -    This is run in the background by ThreadedAuthenticator -    """ - -    def __init__(self, context, endpoint, encoding='utf-8', log=None): -        super(AuthenticationThread, self).__init__() -        self.context = context or zmq.Context.instance() -        self.encoding = encoding -        self.log = log = log or logging.getLogger('zmq.auth') -        self.authenticator = Authenticator(context, encoding=encoding, log=log) - -        # create a socket to communicate back to main thread. -        self.pipe = context.socket(zmq.PAIR) -        self.pipe.linger = 1 -        self.pipe.connect(endpoint) - -    def run(self): -        """ Start the Authentication Agent thread task """ -        self.authenticator.start() -        zap = self.authenticator.zap_socket -        poller = zmq.Poller() -        poller.register(self.pipe, zmq.POLLIN) -        poller.register(zap, zmq.POLLIN) -        while True: -            try: -                socks = dict(poller.poll()) -            except zmq.ZMQError: -                break  # interrupted - -            if self.pipe in socks and socks[self.pipe] == zmq.POLLIN: -                terminate = self._handle_pipe() -                if terminate: -                    break - -            if zap in socks and socks[zap] == zmq.POLLIN: -                self._handle_zap() - -        self.pipe.close() -        self.authenticator.stop() - -    def _handle_zap(self): -        """ -        Handle a message from the ZAP socket. -        """ -        msg = self.authenticator.zap_socket.recv_multipart() -        if not msg: return -        self.authenticator.handle_zap_message(msg) - -    def _handle_pipe(self): -        """ -        Handle a message from front-end API. -        """ -        terminate = False - -        # Get the whole message off the pipe in one go -        msg = self.pipe.recv_multipart() - -        if msg is None: -            terminate = True -            return terminate - -        command = msg[0] -        self.log.debug("auth received API command %r", command) - -        if command == b'ALLOW': -            addresses = [u(m, self.encoding) for m in msg[1:]] -            try: -                self.authenticator.allow(*addresses) -            except Exception as e: -                self.log.exception("Failed to allow %s", addresses) - -        elif command == b'DENY': -            addresses = [u(m, self.encoding) for m in msg[1:]] -            try: -                self.authenticator.deny(*addresses) -            except Exception as e: -                self.log.exception("Failed to deny %s", addresses) - -        elif command == b'PLAIN': -            domain = u(msg[1], self.encoding) -            json_passwords = msg[2] -            self.authenticator.configure_plain(domain, jsonapi.loads(json_passwords)) - -        elif command == b'CURVE': -            # For now we don't do anything with domains -            domain = u(msg[1], self.encoding) - -            # If location is CURVE_ALLOW_ANY, allow all clients. Otherwise -            # treat location as a directory that holds the certificates. -            location = u(msg[2], self.encoding) -            self.authenticator.configure_curve(domain, location) - -        elif command == b'TERMINATE': -            terminate = True - -        else: -            self.log.error("Invalid auth command from API: %r", command) - -        return terminate - -def _inherit_docstrings(cls): -    """inherit docstrings from Authenticator, so we don't duplicate them""" -    for name, method in cls.__dict__.items(): -        if name.startswith('_'): -            continue -        upstream_method = getattr(Authenticator, name, None) -        if not method.__doc__: -            method.__doc__ = upstream_method.__doc__ -    return cls - -@_inherit_docstrings -class ThreadAuthenticator(object): -    """Run ZAP authentication in a background thread""" - -    def __init__(self, context=None, encoding='utf-8', log=None): -        self.context = context or zmq.Context.instance() -        self.log = log -        self.encoding = encoding -        self.pipe = None -        self.pipe_endpoint = "inproc://{0}.inproc".format(id(self)) -        self.thread = None - -    def allow(self, *addresses): -        self.pipe.send_multipart([b'ALLOW'] + [b(a, self.encoding) for a in addresses]) - -    def deny(self, *addresses): -        self.pipe.send_multipart([b'DENY'] + [b(a, self.encoding) for a in addresses]) - -    def configure_plain(self, domain='*', passwords=None): -        self.pipe.send_multipart([b'PLAIN', b(domain, self.encoding), jsonapi.dumps(passwords or {})]) - -    def configure_curve(self, domain='*', location=''): -        domain = b(domain, self.encoding) -        location = b(location, self.encoding) -        self.pipe.send_multipart([b'CURVE', domain, location]) - -    def start(self): -        """Start the authentication thread""" -        # create a socket to communicate with auth thread. -        self.pipe = self.context.socket(zmq.PAIR) -        self.pipe.linger = 1 -        self.pipe.bind(self.pipe_endpoint) -        self.thread = AuthenticationThread(self.context, self.pipe_endpoint, encoding=self.encoding, log=self.log) -        self.thread.start() - -    def stop(self): -        """Stop the authentication thread""" -        if self.pipe: -            self.pipe.send(b'TERMINATE') -            if self.is_alive(): -                self.thread.join() -            self.thread = None -            self.pipe.close() -            self.pipe = None - -    def is_alive(self): -        """Is the ZAP thread currently running?""" -        if self.thread and self.thread.is_alive(): -            return True -        return False - -    def __del__(self): -        self.stop() - -__all__ = ['ThreadAuthenticator'] diff --git a/zmq/backend/__init__.py b/zmq/backend/__init__.py deleted file mode 100644 index 7cac725..0000000 --- a/zmq/backend/__init__.py +++ /dev/null @@ -1,45 +0,0 @@ -"""Import basic exposure of libzmq C API as a backend""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import os -import platform -import sys - -from zmq.utils.sixcerpt import reraise - -from .select import public_api, select_backend - -if 'PYZMQ_BACKEND' in os.environ: -    backend = os.environ['PYZMQ_BACKEND'] -    if backend in ('cython', 'cffi'): -        backend = 'zmq.backend.%s' % backend -    _ns = select_backend(backend) -else: -    # default to cython, fallback to cffi -    # (reverse on PyPy) -    if platform.python_implementation() == 'PyPy': -        first, second = ('zmq.backend.cffi', 'zmq.backend.cython') -    else: -        first, second = ('zmq.backend.cython', 'zmq.backend.cffi') - -    try: -        _ns = select_backend(first) -    except Exception: -        exc_info = sys.exc_info() -        exc = exc_info[1] -        try: -            _ns = select_backend(second) -        except ImportError: -            # prevent 'During handling of the above exception...' on py3 -            # can't use `raise ... from` on Python 2 -            if hasattr(exc, '__cause__'): -                exc.__cause__ = None -            # raise the *first* error, not the fallback -            reraise(*exc_info) - -globals().update(_ns) - -__all__ = public_api diff --git a/zmq/backend/cffi/__init__.py b/zmq/backend/cffi/__init__.py deleted file mode 100644 index da98024..0000000 --- a/zmq/backend/cffi/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -"""CFFI backend (for PyPY)""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import imp -import os.path -import sys - -import cffi.vengine_cpy -import cffi.vengine_gen -_ma_triplet = None - -def vengine_gen_find_module(self, module_name, path, so_suffixes): -    global _ma_triplet -    if _ma_triplet is None: -        try: -            import subprocess as sp -            p = sp.Popen(["gcc", "-print-multiarch"], stdout=sp.PIPE) -            _ma_triplet = str(p.communicate()[0].decode().strip()) -        except: -            import warnings -            warnings.warn('failed to detect multiarch paths, please install gcc') - -    for so_suffix in so_suffixes + ['.%s-%s.so' % (imp.get_tag(), _ma_triplet)]: -        basename = module_name + so_suffix -        if path is None: -            path = sys.path -            # import from non root package would try __pycache__ which is -            # cleaned by pypy installation -            path.insert(0, "/usr/lib/pypy/dist-packages/zmq/backend/cffi") -        for dirname in path: -            filename = os.path.join(dirname, basename) -            if os.path.isfile(filename): -                return filename - - -cffi.vengine_gen.VGenericEngine.find_module = vengine_gen_find_module - -from zmq.backend.cffi import (constants, error, message, context, socket, -                           _poll, devices, utils) - -__all__ = [] -for submod in (constants, error, message, context, socket, -               _poll, devices, utils): -    __all__.extend(submod.__all__) - -from .constants import * -from .error import * -from .message import * -from .context import * -from .socket import * -from .devices import * -from ._poll import * -from ._cffi import zmq_version_info, ffi -from .utils import * diff --git a/zmq/backend/cffi/_cffi.py b/zmq/backend/cffi/_cffi.py deleted file mode 100644 index 97b947f..0000000 --- a/zmq/backend/cffi/_cffi.py +++ /dev/null @@ -1,238 +0,0 @@ -# coding: utf-8 -"""The main CFFI wrapping of libzmq""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import json -import os -from os.path import dirname, join -from cffi import FFI - -from zmq.utils.constant_names import all_names, no_prefix - - -ffi = FFI() - -base_zmq_version = (3,2,2) - -core_functions = \ -''' -void* zmq_socket(void *context, int type); -int zmq_close(void *socket); - -int zmq_bind(void *socket, const char *endpoint); -int zmq_connect(void *socket, const char *endpoint); - -int zmq_errno(void); -const char * zmq_strerror(int errnum); - -void* zmq_stopwatch_start(void); -unsigned long zmq_stopwatch_stop(void *watch); -void zmq_sleep(int seconds_); -int zmq_device(int device, void *frontend, void *backend); -''' - -core32_functions = \ -''' -int zmq_unbind(void *socket, const char *endpoint); -int zmq_disconnect(void *socket, const char *endpoint); -void* zmq_ctx_new(); -int zmq_ctx_destroy(void *context); -int zmq_ctx_get(void *context, int opt); -int zmq_ctx_set(void *context, int opt, int optval); -int zmq_proxy(void *frontend, void *backend, void *capture); -int zmq_socket_monitor(void *socket, const char *addr, int events); -''' - -core40_functions = \ -''' -int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key); -''' - -message32_functions = \ -''' -typedef struct { ...; } zmq_msg_t; -typedef ... zmq_free_fn; - -int zmq_msg_init(zmq_msg_t *msg); -int zmq_msg_init_size(zmq_msg_t *msg, size_t size); -int zmq_msg_init_data(zmq_msg_t *msg, -                      void *data, -                      size_t size, -                      zmq_free_fn *ffn, -                      void *hint); - -size_t zmq_msg_size(zmq_msg_t *msg); -void *zmq_msg_data(zmq_msg_t *msg); -int zmq_msg_close(zmq_msg_t *msg); - -int zmq_msg_send(zmq_msg_t *msg, void *socket, int flags); -int zmq_msg_recv(zmq_msg_t *msg, void *socket, int flags); -''' - -sockopt_functions = \ -''' -int zmq_getsockopt(void *socket, -                   int option_name, -                   void *option_value, -                   size_t *option_len); - -int zmq_setsockopt(void *socket, -                   int option_name, -                   const void *option_value, -                   size_t option_len); -''' - -polling_functions = \ -''' -typedef struct -{ -    void *socket; -    int fd; -    short events; -    short revents; -} zmq_pollitem_t; - -int zmq_poll(zmq_pollitem_t *items, int nitems, long timeout); -''' - -extra_functions = \ -''' -void * memcpy(void *restrict s1, const void *restrict s2, size_t n); -int get_ipc_path_max_len(void); -''' - -def load_compiler_config(): -    import zmq -    zmq_dir = "zmq" -    zmq_parent = dirname(zmq_dir) -     -    fname = join(dirname(zmq.__file__), 'utils', 'compiler.json') -    if os.path.exists(fname): -        with open(fname) as f: -            cfg = json.load(f) -    else: -        cfg = {} -     -    cfg.setdefault("include_dirs", []) -    cfg.setdefault("library_dirs", []) -    cfg.setdefault("runtime_library_dirs", []) -    cfg.setdefault("libraries", ["zmq"]) -     -    # cast to str, because cffi can't handle unicode paths (?!) -    cfg['libraries'] = [str(lib) for lib in cfg['libraries']] -    for key in ("include_dirs", "library_dirs", "runtime_library_dirs"): -        # interpret paths relative to parent of zmq (like source tree) -        abs_paths = [] -        for p in cfg[key]: -            if p.startswith('zmq'): -                p = join(zmq_parent, p) -            abs_paths.append(str(p)) -        cfg[key] = abs_paths -    return cfg - -cfg = load_compiler_config() - -def zmq_version_info(): -    ffi_check = FFI() -    ffi_check.cdef('void zmq_version(int *major, int *minor, int *patch);') -    cfg = load_compiler_config() -    C_check_version = ffi_check.verify('#include <zmq.h>', -        libraries=cfg['libraries'], -        include_dirs=cfg['include_dirs'], -        library_dirs=cfg['library_dirs'], -        runtime_library_dirs=cfg['runtime_library_dirs'], -    ) -    major = ffi.new('int*') -    minor = ffi.new('int*') -    patch = ffi.new('int*') - -    C_check_version.zmq_version(major, minor, patch) - -    return (int(major[0]), int(minor[0]), int(patch[0])) - -def _make_defines(names): -    _names = [] -    for name in names: -        define_line = "#define %s ..." % (name) -        _names.append(define_line) - -    return "\n".join(_names) - -c_constant_names = [] -for name in all_names: -    if no_prefix(name): -        c_constant_names.append(name) -    else: -        c_constant_names.append("ZMQ_" + name) - -constants = _make_defines(c_constant_names) - -try: -    _version_info = zmq_version_info() -except Exception as e: -    raise ImportError("PyZMQ CFFI backend couldn't find zeromq: %s\n" -    "Please check that you have zeromq headers and libraries." % e) - -if _version_info >= (3,2,2): -    functions = '\n'.join([constants, -                         core_functions, -                         core32_functions, -                         core40_functions, -                         message32_functions, -                         sockopt_functions, -                         polling_functions, -                         extra_functions, -    ]) -else: -    raise ImportError("PyZMQ CFFI backend requires zeromq >= 3.2.2," -        " but found %i.%i.%i" % _version_info -    ) - - -ffi.cdef(functions) - -C = ffi.verify(''' -    #include <stdio.h> -    #include <sys/un.h> -    #include <string.h> -     -    #include <zmq.h> -    #include <zmq_utils.h> -    #include "zmq_compat.h" - -int get_ipc_path_max_len(void) { -    struct sockaddr_un *dummy; -    return sizeof(dummy->sun_path) - 1; -} - -''', -    libraries=cfg['libraries'], -    include_dirs=cfg['include_dirs'], -    library_dirs=cfg['library_dirs'], -    runtime_library_dirs=cfg['runtime_library_dirs'], -) - -nsp = new_sizet_pointer = lambda length: ffi.new('size_t*', length) - -new_uint64_pointer = lambda: (ffi.new('uint64_t*'), -                              nsp(ffi.sizeof('uint64_t'))) -new_int64_pointer = lambda: (ffi.new('int64_t*'), -                             nsp(ffi.sizeof('int64_t'))) -new_int_pointer = lambda: (ffi.new('int*'), -                           nsp(ffi.sizeof('int'))) -new_binary_data = lambda length: (ffi.new('char[%d]' % (length)), -                                  nsp(ffi.sizeof('char') * length)) - -value_uint64_pointer = lambda val : (ffi.new('uint64_t*', val), -                                     ffi.sizeof('uint64_t')) -value_int64_pointer = lambda val: (ffi.new('int64_t*', val), -                                   ffi.sizeof('int64_t')) -value_int_pointer = lambda val: (ffi.new('int*', val), -                                 ffi.sizeof('int')) -value_binary_data = lambda val, length: (ffi.new('char[%d]' % (length + 1), val), -                                         ffi.sizeof('char') * length) - -IPC_PATH_MAX_LEN = C.get_ipc_path_max_len() diff --git a/zmq/backend/cffi/_poll.py b/zmq/backend/cffi/_poll.py deleted file mode 100644 index 9bca34c..0000000 --- a/zmq/backend/cffi/_poll.py +++ /dev/null @@ -1,56 +0,0 @@ -# coding: utf-8 -"""zmq poll function""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from ._cffi import C, ffi, zmq_version_info - -from .constants import * - -from zmq.error import _check_rc - - -def _make_zmq_pollitem(socket, flags): -    zmq_socket = socket._zmq_socket -    zmq_pollitem = ffi.new('zmq_pollitem_t*') -    zmq_pollitem.socket = zmq_socket -    zmq_pollitem.fd = 0 -    zmq_pollitem.events = flags -    zmq_pollitem.revents = 0 -    return zmq_pollitem[0] - -def _make_zmq_pollitem_fromfd(socket_fd, flags): -    zmq_pollitem = ffi.new('zmq_pollitem_t*') -    zmq_pollitem.socket = ffi.NULL -    zmq_pollitem.fd = socket_fd -    zmq_pollitem.events = flags -    zmq_pollitem.revents = 0 -    return zmq_pollitem[0] - -def zmq_poll(sockets, timeout): -    cffi_pollitem_list = [] -    low_level_to_socket_obj = {} -    for item in sockets: -        if isinstance(item[0], int): -            low_level_to_socket_obj[item[0]] = item -            cffi_pollitem_list.append(_make_zmq_pollitem_fromfd(item[0], item[1])) -        else: -            low_level_to_socket_obj[item[0]._zmq_socket] = item -            cffi_pollitem_list.append(_make_zmq_pollitem(item[0], item[1])) -    items = ffi.new('zmq_pollitem_t[]', cffi_pollitem_list) -    list_length = ffi.cast('int', len(cffi_pollitem_list)) -    c_timeout = ffi.cast('long', timeout) -    rc = C.zmq_poll(items, list_length, c_timeout) -    _check_rc(rc) -    result = [] -    for index in range(len(items)): -        if not items[index].socket == ffi.NULL: -            if items[index].revents > 0: -                result.append((low_level_to_socket_obj[items[index].socket][0], -                            items[index].revents)) -        else: -            result.append((items[index].fd, items[index].revents)) -    return result - -__all__ = ['zmq_poll'] diff --git a/zmq/backend/cffi/constants.py b/zmq/backend/cffi/constants.py deleted file mode 100644 index ee293e7..0000000 --- a/zmq/backend/cffi/constants.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding: utf-8 -"""zmq constants""" - -from ._cffi import C, c_constant_names -from zmq.utils.constant_names import all_names - -g = globals() -for cname in c_constant_names: -    if cname.startswith("ZMQ_"): -        name = cname[4:] -    else: -        name = cname -    g[name] = getattr(C, cname) - -__all__ = all_names diff --git a/zmq/backend/cffi/context.py b/zmq/backend/cffi/context.py deleted file mode 100644 index 16a7b25..0000000 --- a/zmq/backend/cffi/context.py +++ /dev/null @@ -1,100 +0,0 @@ -# coding: utf-8 -"""zmq Context class""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import weakref - -from ._cffi import C, ffi - -from .socket import * -from .constants import * - -from zmq.error import ZMQError, _check_rc - -class Context(object): -    _zmq_ctx = None -    _iothreads = None -    _closed = None -    _sockets = None -    _shadow = False - -    def __init__(self, io_threads=1, shadow=None): -         -        if shadow: -            self._zmq_ctx = ffi.cast("void *", shadow) -            self._shadow = True -        else: -            self._shadow = False -            if not io_threads >= 0: -                raise ZMQError(EINVAL) -         -            self._zmq_ctx = C.zmq_ctx_new() -        if self._zmq_ctx == ffi.NULL: -            raise ZMQError(C.zmq_errno()) -        if not shadow: -            C.zmq_ctx_set(self._zmq_ctx, IO_THREADS, io_threads) -        self._closed = False -        self._sockets = set() -     -    @property -    def underlying(self): -        """The address of the underlying libzmq context""" -        return int(ffi.cast('size_t', self._zmq_ctx)) -     -    @property -    def closed(self): -        return self._closed - -    def _add_socket(self, socket): -        ref = weakref.ref(socket) -        self._sockets.add(ref) -        return ref - -    def _rm_socket(self, ref): -        if ref in self._sockets: -            self._sockets.remove(ref) - -    def set(self, option, value): -        """set a context option -         -        see zmq_ctx_set -        """ -        rc = C.zmq_ctx_set(self._zmq_ctx, option, value) -        _check_rc(rc) - -    def get(self, option): -        """get context option -         -        see zmq_ctx_get -        """ -        rc = C.zmq_ctx_get(self._zmq_ctx, option) -        _check_rc(rc) -        return rc - -    def term(self): -        if self.closed: -            return - -        C.zmq_ctx_destroy(self._zmq_ctx) - -        self._zmq_ctx = None -        self._closed = True - -    def destroy(self, linger=None): -        if self.closed: -            return - -        sockets = self._sockets -        self._sockets = set() -        for s in sockets: -            s = s() -            if s and not s.closed: -                if linger: -                    s.setsockopt(LINGER, linger) -                s.close() -         -        self.term() - -__all__ = ['Context'] diff --git a/zmq/backend/cffi/devices.py b/zmq/backend/cffi/devices.py deleted file mode 100644 index c7a514a..0000000 --- a/zmq/backend/cffi/devices.py +++ /dev/null @@ -1,24 +0,0 @@ -# coding: utf-8 -"""zmq device functions""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from ._cffi import C, ffi, zmq_version_info -from .socket import Socket -from zmq.error import ZMQError, _check_rc - -def device(device_type, frontend, backend): -    rc = C.zmq_proxy(frontend._zmq_socket, backend._zmq_socket, ffi.NULL) -    _check_rc(rc) - -def proxy(frontend, backend, capture=None): -    if isinstance(capture, Socket): -        capture = capture._zmq_socket -    else: -        capture = ffi.NULL - -    rc = C.zmq_proxy(frontend._zmq_socket, backend._zmq_socket, capture) -    _check_rc(rc) - -__all__ = ['device', 'proxy'] diff --git a/zmq/backend/cffi/error.py b/zmq/backend/cffi/error.py deleted file mode 100644 index 3bb64de..0000000 --- a/zmq/backend/cffi/error.py +++ /dev/null @@ -1,13 +0,0 @@ -"""zmq error functions""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from ._cffi import C, ffi - -def strerror(errno): -    return ffi.string(C.zmq_strerror(errno)) - -zmq_errno = C.zmq_errno - -__all__ = ['strerror', 'zmq_errno'] diff --git a/zmq/backend/cffi/message.py b/zmq/backend/cffi/message.py deleted file mode 100644 index 1dc34f2..0000000 --- a/zmq/backend/cffi/message.py +++ /dev/null @@ -1,68 +0,0 @@ -"""Dummy Frame object""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from ._cffi import ffi, C - -import zmq - -try: -    view = memoryview -except NameError: -    view = buffer - -_content = lambda x: x.tobytes() if type(x) == memoryview else x - -class Frame(object): -    _data = None -    tracker = None -    closed = False -    more = False -    buffer = None - - -    def __init__(self, data, track=False): -        try: -            view(data) -        except TypeError: -            raise - -        self._data = data - -        if isinstance(data, unicode): -            raise TypeError("Unicode objects not allowed. Only: str/bytes, " + -                            "buffer interfaces.") - -        self.more = False -        self.tracker = None -        self.closed = False -        if track: -            self.tracker = zmq.MessageTracker() - -        self.buffer = view(self.bytes) - -    @property -    def bytes(self): -        data = _content(self._data) -        return data - -    def __len__(self): -        return len(self.bytes) - -    def __eq__(self, other): -        return self.bytes == _content(other) - -    def __str__(self): -        if str is unicode: -            return self.bytes.decode() -        else: -            return self.bytes - -    @property -    def done(self): -        return True - -Message = Frame - -__all__ = ['Frame', 'Message'] diff --git a/zmq/backend/cffi/socket.py b/zmq/backend/cffi/socket.py deleted file mode 100644 index 7e2afbe..0000000 --- a/zmq/backend/cffi/socket.py +++ /dev/null @@ -1,245 +0,0 @@ -# coding: utf-8 -"""zmq Socket class""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import random -import codecs - -import errno as errno_mod - -from ._cffi import (C, ffi, new_uint64_pointer, new_int64_pointer, -                    new_int_pointer, new_binary_data, value_uint64_pointer, -                    value_int64_pointer, value_int_pointer, value_binary_data, -                    IPC_PATH_MAX_LEN) - -from .message import Frame -from .constants import * - -import zmq -from zmq.error import ZMQError, _check_rc, _check_version -from zmq.utils.strtypes import unicode - - -def new_pointer_from_opt(option, length=0): -    from zmq.sugar.constants import int_sockopts,   \ -                                    int64_sockopts, \ -                                    bytes_sockopts -    if option in int64_sockopts: -        return new_int64_pointer() -    elif option in int_sockopts: -        return new_int_pointer() -    elif option in bytes_sockopts: -        return new_binary_data(length) -    else: -        raise ZMQError(zmq.EINVAL) - -def value_from_opt_pointer(option, opt_pointer, length=0): -    from zmq.sugar.constants import int_sockopts,   \ -                                    int64_sockopts, \ -                                    bytes_sockopts -    if option in int64_sockopts: -        return int(opt_pointer[0]) -    elif option in int_sockopts: -        return int(opt_pointer[0]) -    elif option in bytes_sockopts: -        return ffi.buffer(opt_pointer, length)[:] -    else: -        raise ZMQError(zmq.EINVAL) - -def initialize_opt_pointer(option, value, length=0): -    from zmq.sugar.constants import int_sockopts,   \ -                                    int64_sockopts, \ -                                    bytes_sockopts -    if option in int64_sockopts: -        return value_int64_pointer(value) -    elif option in int_sockopts: -        return value_int_pointer(value) -    elif option in bytes_sockopts: -        return value_binary_data(value, length) -    else: -        raise ZMQError(zmq.EINVAL) - - -class Socket(object): -    context = None -    socket_type = None -    _zmq_socket = None -    _closed = None -    _ref = None -    _shadow = False - -    def __init__(self, context=None, socket_type=None, shadow=None): -        self.context = context -        if shadow is not None: -            self._zmq_socket = ffi.cast("void *", shadow) -            self._shadow = True -        else: -            self._shadow = False -            self._zmq_socket = C.zmq_socket(context._zmq_ctx, socket_type) -        if self._zmq_socket == ffi.NULL: -            raise ZMQError() -        self._closed = False -        if context: -            self._ref = context._add_socket(self) -     -    @property -    def underlying(self): -        """The address of the underlying libzmq socket""" -        return int(ffi.cast('size_t', self._zmq_socket)) -     -    @property -    def closed(self): -        return self._closed - -    def close(self, linger=None): -        rc = 0 -        if not self._closed and hasattr(self, '_zmq_socket'): -            if self._zmq_socket is not None: -                rc = C.zmq_close(self._zmq_socket) -            self._closed = True -            if self.context: -                self.context._rm_socket(self._ref) -        return rc - -    def bind(self, address): -        if isinstance(address, unicode): -            address = address.encode('utf8') -        rc = C.zmq_bind(self._zmq_socket, address) -        if rc < 0: -            if IPC_PATH_MAX_LEN and C.zmq_errno() == errno_mod.ENAMETOOLONG: -                # py3compat: address is bytes, but msg wants str -                if str is unicode: -                    address = address.decode('utf-8', 'replace') -                path = address.split('://', 1)[-1] -                msg = ('ipc path "{0}" is longer than {1} ' -                                'characters (sizeof(sockaddr_un.sun_path)).' -                                .format(path, IPC_PATH_MAX_LEN)) -                raise ZMQError(C.zmq_errno(), msg=msg) -            else: -                _check_rc(rc) - -    def unbind(self, address): -        _check_version((3,2), "unbind") -        if isinstance(address, unicode): -            address = address.encode('utf8') -        rc = C.zmq_unbind(self._zmq_socket, address) -        _check_rc(rc) - -    def connect(self, address): -        if isinstance(address, unicode): -            address = address.encode('utf8') -        rc = C.zmq_connect(self._zmq_socket, address) -        _check_rc(rc) - -    def disconnect(self, address): -        _check_version((3,2), "disconnect") -        if isinstance(address, unicode): -            address = address.encode('utf8') -        rc = C.zmq_disconnect(self._zmq_socket, address) -        _check_rc(rc) - -    def set(self, option, value): -        length = None -        if isinstance(value, unicode): -            raise TypeError("unicode not allowed, use bytes") -         -        if isinstance(value, bytes): -            if option not in zmq.constants.bytes_sockopts: -                raise TypeError("not a bytes sockopt: %s" % option) -            length = len(value) -         -        c_data = initialize_opt_pointer(option, value, length) - -        c_value_pointer = c_data[0] -        c_sizet = c_data[1] - -        rc = C.zmq_setsockopt(self._zmq_socket, -                               option, -                               ffi.cast('void*', c_value_pointer), -                               c_sizet) -        _check_rc(rc) - -    def get(self, option): -        c_data = new_pointer_from_opt(option, length=255) - -        c_value_pointer = c_data[0] -        c_sizet_pointer = c_data[1] - -        rc = C.zmq_getsockopt(self._zmq_socket, -                               option, -                               c_value_pointer, -                               c_sizet_pointer) -        _check_rc(rc) -         -        sz = c_sizet_pointer[0] -        v = value_from_opt_pointer(option, c_value_pointer, sz) -        if option != zmq.IDENTITY and option in zmq.constants.bytes_sockopts and v.endswith(b'\0'): -            v = v[:-1] -        return v - -    def send(self, message, flags=0, copy=False, track=False): -        if isinstance(message, unicode): -            raise TypeError("Message must be in bytes, not an unicode Object") - -        if isinstance(message, Frame): -            message = message.bytes - -        zmq_msg = ffi.new('zmq_msg_t*') -        c_message = ffi.new('char[]', message) -        rc = C.zmq_msg_init_size(zmq_msg, len(message)) -        C.memcpy(C.zmq_msg_data(zmq_msg), c_message, len(message)) - -        rc = C.zmq_msg_send(zmq_msg, self._zmq_socket, flags) -        C.zmq_msg_close(zmq_msg) -        _check_rc(rc) - -        if track: -            return zmq.MessageTracker() - -    def recv(self, flags=0, copy=True, track=False): -        zmq_msg = ffi.new('zmq_msg_t*') -        C.zmq_msg_init(zmq_msg) - -        rc = C.zmq_msg_recv(zmq_msg, self._zmq_socket, flags) - -        if rc < 0: -            C.zmq_msg_close(zmq_msg) -            _check_rc(rc) - -        _buffer = ffi.buffer(C.zmq_msg_data(zmq_msg), C.zmq_msg_size(zmq_msg)) -        value = _buffer[:] -        C.zmq_msg_close(zmq_msg) - -        frame = Frame(value, track=track) -        frame.more = self.getsockopt(RCVMORE) - -        if copy: -            return frame.bytes -        else: -            return frame -     -    def monitor(self, addr, events=-1): -        """s.monitor(addr, flags) - -        Start publishing socket events on inproc. -        See libzmq docs for zmq_monitor for details. -         -        Note: requires libzmq >= 3.2 -         -        Parameters -        ---------- -        addr : str -            The inproc url used for monitoring. -        events : int [default: zmq.EVENT_ALL] -            The zmq event bitmask for which events will be sent to the monitor. -        """ -         -        _check_version((3,2), "monitor") -        if events < 0: -            events = zmq.EVENT_ALL -        rc = C.zmq_socket_monitor(self._zmq_socket, addr, events) - - -__all__ = ['Socket', 'IPC_PATH_MAX_LEN'] diff --git a/zmq/backend/cffi/utils.py b/zmq/backend/cffi/utils.py deleted file mode 100644 index 8630a36..0000000 --- a/zmq/backend/cffi/utils.py +++ /dev/null @@ -1,50 +0,0 @@ -# coding: utf-8 -"""miscellaneous zmq_utils wrapping""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from ._cffi import ffi, C - -from zmq.error import ZMQError, _check_rc, _check_version - -def curve_keypair(): -    """generate a Z85 keypair for use with zmq.CURVE security -     -    Requires libzmq (≥ 4.0) to have been linked with libsodium. -     -    Returns -    ------- -    (public, secret) : two bytestrings -        The public and private keypair as 40 byte z85-encoded bytestrings. -    """ -    _check_version((3,2), "monitor") -    public = ffi.new('char[64]') -    private = ffi.new('char[64]') -    rc = C.zmq_curve_keypair(public, private) -    _check_rc(rc) -    return ffi.buffer(public)[:40], ffi.buffer(private)[:40] - - -class Stopwatch(object): -    def __init__(self): -        self.watch = ffi.NULL - -    def start(self): -        if self.watch == ffi.NULL: -            self.watch = C.zmq_stopwatch_start() -        else: -            raise ZMQError('Stopwatch is already runing.') - -    def stop(self): -        if self.watch == ffi.NULL: -            raise ZMQError('Must start the Stopwatch before calling stop.') -        else: -            time = C.zmq_stopwatch_stop(self.watch) -            self.watch = ffi.NULL -            return time - -    def sleep(self, seconds): -        C.zmq_sleep(seconds) - -__all__ = ['curve_keypair', 'Stopwatch'] diff --git a/zmq/backend/cython/__init__.py b/zmq/backend/cython/__init__.py deleted file mode 100644 index e535818..0000000 --- a/zmq/backend/cython/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Python bindings for core 0MQ objects.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Lesser GNU Public License (LGPL). - -from . import (constants, error, message, context, -                      socket, utils, _poll, _version, _device ) - -__all__ = [] -for submod in (constants, error, message, context, -               socket, utils, _poll, _version, _device): -    __all__.extend(submod.__all__) - -from .constants import * -from .error import * -from .message import * -from .context import * -from .socket import * -from ._poll import * -from .utils import * -from ._device import * -from ._version import * - diff --git a/zmq/backend/cython/_device.pyx b/zmq/backend/cython/_device.pyx deleted file mode 100644 index eea0a00..0000000 --- a/zmq/backend/cython/_device.pyx +++ /dev/null @@ -1,89 +0,0 @@ -"""Python binding for 0MQ device function.""" - -# -#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from libzmq cimport zmq_device, zmq_proxy, ZMQ_VERSION_MAJOR -from zmq.backend.cython.socket cimport Socket as cSocket -from zmq.backend.cython.checkrc cimport _check_rc - -#----------------------------------------------------------------------------- -# Basic device API -#----------------------------------------------------------------------------- - -def device(int device_type, cSocket frontend, cSocket backend=None): -    """device(device_type, frontend, backend) - -    Start a zeromq device. -     -    .. deprecated:: libzmq-3.2 -        Use zmq.proxy - -    Parameters -    ---------- -    device_type : (QUEUE, FORWARDER, STREAMER) -        The type of device to start. -    frontend : Socket -        The Socket instance for the incoming traffic. -    backend : Socket -        The Socket instance for the outbound traffic. -    """ -    if ZMQ_VERSION_MAJOR >= 3: -        return proxy(frontend, backend) - -    cdef int rc = 0 -    with nogil: -        rc = zmq_device(device_type, frontend.handle, backend.handle) -    _check_rc(rc) -    return rc - -def proxy(cSocket frontend, cSocket backend, cSocket capture=None): -    """proxy(frontend, backend, capture) -     -    Start a zeromq proxy (replacement for device). -     -    .. versionadded:: libzmq-3.2 -    .. versionadded:: 13.0 -     -    Parameters -    ---------- -    frontend : Socket -        The Socket instance for the incoming traffic. -    backend : Socket -        The Socket instance for the outbound traffic. -    capture : Socket (optional) -        The Socket instance for capturing traffic. -    """ -    cdef int rc = 0 -    cdef void* capture_handle -    if isinstance(capture, cSocket): -        capture_handle = capture.handle -    else: -        capture_handle = NULL -    with nogil: -        rc = zmq_proxy(frontend.handle, backend.handle, capture_handle) -    _check_rc(rc) -    return rc - -__all__ = ['device', 'proxy'] - diff --git a/zmq/backend/cython/_poll.pyx b/zmq/backend/cython/_poll.pyx deleted file mode 100644 index 5bed46b..0000000 --- a/zmq/backend/cython/_poll.pyx +++ /dev/null @@ -1,137 +0,0 @@ -"""0MQ polling related functions and classes.""" - -# -#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from libc.stdlib cimport free, malloc - -from libzmq cimport zmq_pollitem_t, ZMQ_VERSION_MAJOR -from libzmq cimport zmq_poll as zmq_poll_c -from socket cimport Socket - -import sys - -from zmq.backend.cython.checkrc cimport _check_rc - -#----------------------------------------------------------------------------- -# Polling related methods -#----------------------------------------------------------------------------- - -# version-independent typecheck for int/long -if sys.version_info[0] >= 3: -    int_t = int -else: -    int_t = (int,long) - - -def zmq_poll(sockets, long timeout=-1): -    """zmq_poll(sockets, timeout=-1) - -    Poll a set of 0MQ sockets, native file descs. or sockets. - -    Parameters -    ---------- -    sockets : list of tuples of (socket, flags) -        Each element of this list is a two-tuple containing a socket -        and a flags. The socket may be a 0MQ socket or any object with -        a ``fileno()`` method. The flags can be zmq.POLLIN (for detecting -        for incoming messages), zmq.POLLOUT (for detecting that send is OK) -        or zmq.POLLIN|zmq.POLLOUT for detecting both. -    timeout : int -        The number of milliseconds to poll for. Negative means no timeout. -    """ -    cdef int rc, i -    cdef zmq_pollitem_t *pollitems = NULL -    cdef int nsockets = <int>len(sockets) -    cdef Socket current_socket -     -    if nsockets == 0: -        return [] -     -    pollitems = <zmq_pollitem_t *>malloc(nsockets*sizeof(zmq_pollitem_t)) -    if pollitems == NULL: -        raise MemoryError("Could not allocate poll items") -         -    if ZMQ_VERSION_MAJOR < 3: -        # timeout is us in 2.x, ms in 3.x -        # expected input is ms (matches 3.x) -        timeout = 1000*timeout -     -    for i in range(nsockets): -        s, events = sockets[i] -        if isinstance(s, Socket): -            pollitems[i].socket = (<Socket>s).handle -            pollitems[i].events = events -            pollitems[i].revents = 0 -        elif isinstance(s, int_t): -            pollitems[i].socket = NULL -            pollitems[i].fd = s -            pollitems[i].events = events -            pollitems[i].revents = 0 -        elif hasattr(s, 'fileno'): -            try: -                fileno = int(s.fileno()) -            except: -                free(pollitems) -                raise ValueError('fileno() must return a valid integer fd') -            else: -                pollitems[i].socket = NULL -                pollitems[i].fd = fileno -                pollitems[i].events = events -                pollitems[i].revents = 0 -        else: -            free(pollitems) -            raise TypeError( -                "Socket must be a 0MQ socket, an integer fd or have " -                "a fileno() method: %r" % s -            ) -     - -    with nogil: -        rc = zmq_poll_c(pollitems, nsockets, timeout) -     -    if rc < 0: -        free(pollitems) -        _check_rc(rc) -     -    results = [] -    for i in range(nsockets): -        revents = pollitems[i].revents -        # for compatibility with select.poll: -        # - only return sockets with non-zero status -        # - return the fd for plain sockets -        if revents > 0: -            if pollitems[i].socket != NULL: -                s = sockets[i][0] -            else: -                s = pollitems[i].fd -            results.append((s, revents)) - -    free(pollitems) -    return results - -#----------------------------------------------------------------------------- -# Symbols to export -#----------------------------------------------------------------------------- - -__all__ = [ 'zmq_poll' ] diff --git a/zmq/backend/cython/_version.pyx b/zmq/backend/cython/_version.pyx deleted file mode 100644 index 02cf6fc..0000000 --- a/zmq/backend/cython/_version.pyx +++ /dev/null @@ -1,43 +0,0 @@ -"""PyZMQ and 0MQ version functions.""" - -# -#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from libzmq cimport _zmq_version - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - -def zmq_version_info(): -    """zmq_version_info() - -    Return the version of ZeroMQ itself as a 3-tuple of ints. -    """ -    cdef int major, minor, patch -    _zmq_version(&major, &minor, &patch) -    return (major, minor, patch) - - -__all__ = ['zmq_version_info'] - diff --git a/zmq/backend/cython/checkrc.pxd b/zmq/backend/cython/checkrc.pxd deleted file mode 100644 index 3bf69fc..0000000 --- a/zmq/backend/cython/checkrc.pxd +++ /dev/null @@ -1,23 +0,0 @@ -from libc.errno cimport EINTR, EAGAIN -from cpython cimport PyErr_CheckSignals -from libzmq cimport zmq_errno, ZMQ_ETERM - -cdef inline int _check_rc(int rc) except -1: -    """internal utility for checking zmq return condition -     -    and raising the appropriate Exception class -    """ -    cdef int errno = zmq_errno() -    PyErr_CheckSignals() -    if rc < 0: -        if errno == EAGAIN: -            from zmq.error import Again -            raise Again(errno) -        elif errno == ZMQ_ETERM: -            from zmq.error import ContextTerminated -            raise ContextTerminated(errno) -        else: -            from zmq.error import ZMQError -            raise ZMQError(errno) -        # return -1 -    return 0 diff --git a/zmq/backend/cython/constant_enums.pxi b/zmq/backend/cython/constant_enums.pxi deleted file mode 100644 index a34d9a4..0000000 --- a/zmq/backend/cython/constant_enums.pxi +++ /dev/null @@ -1,137 +0,0 @@ -cdef extern from "zmq.h" nogil: - -    enum: ZMQ_VERSION -    enum: ZMQ_VERSION_MAJOR -    enum: ZMQ_VERSION_MINOR -    enum: ZMQ_VERSION_PATCH -    enum: ZMQ_NOBLOCK -    enum: ZMQ_DONTWAIT -    enum: ZMQ_POLLIN -    enum: ZMQ_POLLOUT -    enum: ZMQ_POLLERR -    enum: ZMQ_SNDMORE -    enum: ZMQ_STREAMER -    enum: ZMQ_FORWARDER -    enum: ZMQ_QUEUE -    enum: ZMQ_IO_THREADS_DFLT -    enum: ZMQ_MAX_SOCKETS_DFLT -    enum: ZMQ_PAIR -    enum: ZMQ_PUB -    enum: ZMQ_SUB -    enum: ZMQ_REQ -    enum: ZMQ_REP -    enum: ZMQ_DEALER -    enum: ZMQ_ROUTER -    enum: ZMQ_PULL -    enum: ZMQ_PUSH -    enum: ZMQ_XPUB -    enum: ZMQ_XSUB -    enum: ZMQ_UPSTREAM -    enum: ZMQ_DOWNSTREAM -    enum: ZMQ_STREAM -    enum: ZMQ_EVENT_CONNECTED -    enum: ZMQ_EVENT_CONNECT_DELAYED -    enum: ZMQ_EVENT_CONNECT_RETRIED -    enum: ZMQ_EVENT_LISTENING -    enum: ZMQ_EVENT_BIND_FAILED -    enum: ZMQ_EVENT_ACCEPTED -    enum: ZMQ_EVENT_ACCEPT_FAILED -    enum: ZMQ_EVENT_CLOSED -    enum: ZMQ_EVENT_CLOSE_FAILED -    enum: ZMQ_EVENT_DISCONNECTED -    enum: ZMQ_EVENT_ALL -    enum: ZMQ_EVENT_MONITOR_STOPPED -    enum: ZMQ_NULL -    enum: ZMQ_PLAIN -    enum: ZMQ_CURVE -    enum: ZMQ_EAGAIN "EAGAIN" -    enum: ZMQ_EINVAL "EINVAL" -    enum: ZMQ_EFAULT "EFAULT" -    enum: ZMQ_ENOMEM "ENOMEM" -    enum: ZMQ_ENODEV "ENODEV" -    enum: ZMQ_EMSGSIZE "EMSGSIZE" -    enum: ZMQ_EAFNOSUPPORT "EAFNOSUPPORT" -    enum: ZMQ_ENETUNREACH "ENETUNREACH" -    enum: ZMQ_ECONNABORTED "ECONNABORTED" -    enum: ZMQ_ECONNRESET "ECONNRESET" -    enum: ZMQ_ENOTCONN "ENOTCONN" -    enum: ZMQ_ETIMEDOUT "ETIMEDOUT" -    enum: ZMQ_EHOSTUNREACH "EHOSTUNREACH" -    enum: ZMQ_ENETRESET "ENETRESET" -    enum: ZMQ_HAUSNUMERO -    enum: ZMQ_ENOTSUP "ENOTSUP" -    enum: ZMQ_EPROTONOSUPPORT "EPROTONOSUPPORT" -    enum: ZMQ_ENOBUFS "ENOBUFS" -    enum: ZMQ_ENETDOWN "ENETDOWN" -    enum: ZMQ_EADDRINUSE "EADDRINUSE" -    enum: ZMQ_EADDRNOTAVAIL "EADDRNOTAVAIL" -    enum: ZMQ_ECONNREFUSED "ECONNREFUSED" -    enum: ZMQ_EINPROGRESS "EINPROGRESS" -    enum: ZMQ_ENOTSOCK "ENOTSOCK" -    enum: ZMQ_EFSM "EFSM" -    enum: ZMQ_ENOCOMPATPROTO "ENOCOMPATPROTO" -    enum: ZMQ_ETERM "ETERM" -    enum: ZMQ_EMTHREAD "EMTHREAD" -    enum: ZMQ_IO_THREADS -    enum: ZMQ_MAX_SOCKETS -    enum: ZMQ_MORE -    enum: ZMQ_IDENTITY -    enum: ZMQ_SUBSCRIBE -    enum: ZMQ_UNSUBSCRIBE -    enum: ZMQ_LAST_ENDPOINT -    enum: ZMQ_TCP_ACCEPT_FILTER -    enum: ZMQ_PLAIN_USERNAME -    enum: ZMQ_PLAIN_PASSWORD -    enum: ZMQ_CURVE_PUBLICKEY -    enum: ZMQ_CURVE_SECRETKEY -    enum: ZMQ_CURVE_SERVERKEY -    enum: ZMQ_ZAP_DOMAIN -    enum: ZMQ_CONNECT_RID -    enum: ZMQ_RECONNECT_IVL_MAX -    enum: ZMQ_SNDTIMEO -    enum: ZMQ_RCVTIMEO -    enum: ZMQ_SNDHWM -    enum: ZMQ_RCVHWM -    enum: ZMQ_MULTICAST_HOPS -    enum: ZMQ_IPV4ONLY -    enum: ZMQ_ROUTER_BEHAVIOR -    enum: ZMQ_TCP_KEEPALIVE -    enum: ZMQ_TCP_KEEPALIVE_CNT -    enum: ZMQ_TCP_KEEPALIVE_IDLE -    enum: ZMQ_TCP_KEEPALIVE_INTVL -    enum: ZMQ_DELAY_ATTACH_ON_CONNECT -    enum: ZMQ_XPUB_VERBOSE -    enum: ZMQ_FD -    enum: ZMQ_EVENTS -    enum: ZMQ_TYPE -    enum: ZMQ_LINGER -    enum: ZMQ_RECONNECT_IVL -    enum: ZMQ_BACKLOG -    enum: ZMQ_ROUTER_MANDATORY -    enum: ZMQ_FAIL_UNROUTABLE -    enum: ZMQ_ROUTER_RAW -    enum: ZMQ_IMMEDIATE -    enum: ZMQ_IPV6 -    enum: ZMQ_MECHANISM -    enum: ZMQ_PLAIN_SERVER -    enum: ZMQ_CURVE_SERVER -    enum: ZMQ_PROBE_ROUTER -    enum: ZMQ_REQ_RELAXED -    enum: ZMQ_REQ_CORRELATE -    enum: ZMQ_CONFLATE -    enum: ZMQ_ROUTER_HANDOVER -    enum: ZMQ_TOS -    enum: ZMQ_IPC_FILTER_PID -    enum: ZMQ_IPC_FILTER_UID -    enum: ZMQ_IPC_FILTER_GID -    enum: ZMQ_AFFINITY -    enum: ZMQ_MAXMSGSIZE -    enum: ZMQ_HWM -    enum: ZMQ_SWAP -    enum: ZMQ_MCAST_LOOP -    enum: ZMQ_RECOVERY_IVL_MSEC -    enum: ZMQ_RATE -    enum: ZMQ_RECOVERY_IVL -    enum: ZMQ_SNDBUF -    enum: ZMQ_RCVBUF -    enum: ZMQ_RCVMORE diff --git a/zmq/backend/cython/constants.pxi b/zmq/backend/cython/constants.pxi deleted file mode 100644 index 983cfd7..0000000 --- a/zmq/backend/cython/constants.pxi +++ /dev/null @@ -1,280 +0,0 @@ -#----------------------------------------------------------------------------- -# Python module level constants -#----------------------------------------------------------------------------- - -VERSION = ZMQ_VERSION -VERSION_MAJOR = ZMQ_VERSION_MAJOR -VERSION_MINOR = ZMQ_VERSION_MINOR -VERSION_PATCH = ZMQ_VERSION_PATCH -NOBLOCK = ZMQ_NOBLOCK -DONTWAIT = ZMQ_DONTWAIT -POLLIN = ZMQ_POLLIN -POLLOUT = ZMQ_POLLOUT -POLLERR = ZMQ_POLLERR -SNDMORE = ZMQ_SNDMORE -STREAMER = ZMQ_STREAMER -FORWARDER = ZMQ_FORWARDER -QUEUE = ZMQ_QUEUE -IO_THREADS_DFLT = ZMQ_IO_THREADS_DFLT -MAX_SOCKETS_DFLT = ZMQ_MAX_SOCKETS_DFLT -PAIR = ZMQ_PAIR -PUB = ZMQ_PUB -SUB = ZMQ_SUB -REQ = ZMQ_REQ -REP = ZMQ_REP -DEALER = ZMQ_DEALER -ROUTER = ZMQ_ROUTER -PULL = ZMQ_PULL -PUSH = ZMQ_PUSH -XPUB = ZMQ_XPUB -XSUB = ZMQ_XSUB -UPSTREAM = ZMQ_UPSTREAM -DOWNSTREAM = ZMQ_DOWNSTREAM -STREAM = ZMQ_STREAM -EVENT_CONNECTED = ZMQ_EVENT_CONNECTED -EVENT_CONNECT_DELAYED = ZMQ_EVENT_CONNECT_DELAYED -EVENT_CONNECT_RETRIED = ZMQ_EVENT_CONNECT_RETRIED -EVENT_LISTENING = ZMQ_EVENT_LISTENING -EVENT_BIND_FAILED = ZMQ_EVENT_BIND_FAILED -EVENT_ACCEPTED = ZMQ_EVENT_ACCEPTED -EVENT_ACCEPT_FAILED = ZMQ_EVENT_ACCEPT_FAILED -EVENT_CLOSED = ZMQ_EVENT_CLOSED -EVENT_CLOSE_FAILED = ZMQ_EVENT_CLOSE_FAILED -EVENT_DISCONNECTED = ZMQ_EVENT_DISCONNECTED -EVENT_ALL = ZMQ_EVENT_ALL -EVENT_MONITOR_STOPPED = ZMQ_EVENT_MONITOR_STOPPED -globals()['NULL'] = ZMQ_NULL -PLAIN = ZMQ_PLAIN -CURVE = ZMQ_CURVE -EAGAIN = ZMQ_EAGAIN -EINVAL = ZMQ_EINVAL -EFAULT = ZMQ_EFAULT -ENOMEM = ZMQ_ENOMEM -ENODEV = ZMQ_ENODEV -EMSGSIZE = ZMQ_EMSGSIZE -EAFNOSUPPORT = ZMQ_EAFNOSUPPORT -ENETUNREACH = ZMQ_ENETUNREACH -ECONNABORTED = ZMQ_ECONNABORTED -ECONNRESET = ZMQ_ECONNRESET -ENOTCONN = ZMQ_ENOTCONN -ETIMEDOUT = ZMQ_ETIMEDOUT -EHOSTUNREACH = ZMQ_EHOSTUNREACH -ENETRESET = ZMQ_ENETRESET -HAUSNUMERO = ZMQ_HAUSNUMERO -ENOTSUP = ZMQ_ENOTSUP -EPROTONOSUPPORT = ZMQ_EPROTONOSUPPORT -ENOBUFS = ZMQ_ENOBUFS -ENETDOWN = ZMQ_ENETDOWN -EADDRINUSE = ZMQ_EADDRINUSE -EADDRNOTAVAIL = ZMQ_EADDRNOTAVAIL -ECONNREFUSED = ZMQ_ECONNREFUSED -EINPROGRESS = ZMQ_EINPROGRESS -ENOTSOCK = ZMQ_ENOTSOCK -EFSM = ZMQ_EFSM -ENOCOMPATPROTO = ZMQ_ENOCOMPATPROTO -ETERM = ZMQ_ETERM -EMTHREAD = ZMQ_EMTHREAD -IO_THREADS = ZMQ_IO_THREADS -MAX_SOCKETS = ZMQ_MAX_SOCKETS -MORE = ZMQ_MORE -IDENTITY = ZMQ_IDENTITY -SUBSCRIBE = ZMQ_SUBSCRIBE -UNSUBSCRIBE = ZMQ_UNSUBSCRIBE -LAST_ENDPOINT = ZMQ_LAST_ENDPOINT -TCP_ACCEPT_FILTER = ZMQ_TCP_ACCEPT_FILTER -PLAIN_USERNAME = ZMQ_PLAIN_USERNAME -PLAIN_PASSWORD = ZMQ_PLAIN_PASSWORD -CURVE_PUBLICKEY = ZMQ_CURVE_PUBLICKEY -CURVE_SECRETKEY = ZMQ_CURVE_SECRETKEY -CURVE_SERVERKEY = ZMQ_CURVE_SERVERKEY -ZAP_DOMAIN = ZMQ_ZAP_DOMAIN -CONNECT_RID = ZMQ_CONNECT_RID -RECONNECT_IVL_MAX = ZMQ_RECONNECT_IVL_MAX -SNDTIMEO = ZMQ_SNDTIMEO -RCVTIMEO = ZMQ_RCVTIMEO -SNDHWM = ZMQ_SNDHWM -RCVHWM = ZMQ_RCVHWM -MULTICAST_HOPS = ZMQ_MULTICAST_HOPS -IPV4ONLY = ZMQ_IPV4ONLY -ROUTER_BEHAVIOR = ZMQ_ROUTER_BEHAVIOR -TCP_KEEPALIVE = ZMQ_TCP_KEEPALIVE -TCP_KEEPALIVE_CNT = ZMQ_TCP_KEEPALIVE_CNT -TCP_KEEPALIVE_IDLE = ZMQ_TCP_KEEPALIVE_IDLE -TCP_KEEPALIVE_INTVL = ZMQ_TCP_KEEPALIVE_INTVL -DELAY_ATTACH_ON_CONNECT = ZMQ_DELAY_ATTACH_ON_CONNECT -XPUB_VERBOSE = ZMQ_XPUB_VERBOSE -FD = ZMQ_FD -EVENTS = ZMQ_EVENTS -TYPE = ZMQ_TYPE -LINGER = ZMQ_LINGER -RECONNECT_IVL = ZMQ_RECONNECT_IVL -BACKLOG = ZMQ_BACKLOG -ROUTER_MANDATORY = ZMQ_ROUTER_MANDATORY -FAIL_UNROUTABLE = ZMQ_FAIL_UNROUTABLE -ROUTER_RAW = ZMQ_ROUTER_RAW -IMMEDIATE = ZMQ_IMMEDIATE -IPV6 = ZMQ_IPV6 -MECHANISM = ZMQ_MECHANISM -PLAIN_SERVER = ZMQ_PLAIN_SERVER -CURVE_SERVER = ZMQ_CURVE_SERVER -PROBE_ROUTER = ZMQ_PROBE_ROUTER -REQ_RELAXED = ZMQ_REQ_RELAXED -REQ_CORRELATE = ZMQ_REQ_CORRELATE -CONFLATE = ZMQ_CONFLATE -ROUTER_HANDOVER = ZMQ_ROUTER_HANDOVER -TOS = ZMQ_TOS -IPC_FILTER_PID = ZMQ_IPC_FILTER_PID -IPC_FILTER_UID = ZMQ_IPC_FILTER_UID -IPC_FILTER_GID = ZMQ_IPC_FILTER_GID -AFFINITY = ZMQ_AFFINITY -MAXMSGSIZE = ZMQ_MAXMSGSIZE -HWM = ZMQ_HWM -SWAP = ZMQ_SWAP -MCAST_LOOP = ZMQ_MCAST_LOOP -RECOVERY_IVL_MSEC = ZMQ_RECOVERY_IVL_MSEC -RATE = ZMQ_RATE -RECOVERY_IVL = ZMQ_RECOVERY_IVL -SNDBUF = ZMQ_SNDBUF -RCVBUF = ZMQ_RCVBUF -RCVMORE = ZMQ_RCVMORE - -#----------------------------------------------------------------------------- -# Symbols to export -#----------------------------------------------------------------------------- -__all__ = [ -  "VERSION", -  "VERSION_MAJOR", -  "VERSION_MINOR", -  "VERSION_PATCH", -  "NOBLOCK", -  "DONTWAIT", -  "POLLIN", -  "POLLOUT", -  "POLLERR", -  "SNDMORE", -  "STREAMER", -  "FORWARDER", -  "QUEUE", -  "IO_THREADS_DFLT", -  "MAX_SOCKETS_DFLT", -  "PAIR", -  "PUB", -  "SUB", -  "REQ", -  "REP", -  "DEALER", -  "ROUTER", -  "PULL", -  "PUSH", -  "XPUB", -  "XSUB", -  "UPSTREAM", -  "DOWNSTREAM", -  "STREAM", -  "EVENT_CONNECTED", -  "EVENT_CONNECT_DELAYED", -  "EVENT_CONNECT_RETRIED", -  "EVENT_LISTENING", -  "EVENT_BIND_FAILED", -  "EVENT_ACCEPTED", -  "EVENT_ACCEPT_FAILED", -  "EVENT_CLOSED", -  "EVENT_CLOSE_FAILED", -  "EVENT_DISCONNECTED", -  "EVENT_ALL", -  "EVENT_MONITOR_STOPPED", -  "NULL", -  "PLAIN", -  "CURVE", -  "EAGAIN", -  "EINVAL", -  "EFAULT", -  "ENOMEM", -  "ENODEV", -  "EMSGSIZE", -  "EAFNOSUPPORT", -  "ENETUNREACH", -  "ECONNABORTED", -  "ECONNRESET", -  "ENOTCONN", -  "ETIMEDOUT", -  "EHOSTUNREACH", -  "ENETRESET", -  "HAUSNUMERO", -  "ENOTSUP", -  "EPROTONOSUPPORT", -  "ENOBUFS", -  "ENETDOWN", -  "EADDRINUSE", -  "EADDRNOTAVAIL", -  "ECONNREFUSED", -  "EINPROGRESS", -  "ENOTSOCK", -  "EFSM", -  "ENOCOMPATPROTO", -  "ETERM", -  "EMTHREAD", -  "IO_THREADS", -  "MAX_SOCKETS", -  "MORE", -  "IDENTITY", -  "SUBSCRIBE", -  "UNSUBSCRIBE", -  "LAST_ENDPOINT", -  "TCP_ACCEPT_FILTER", -  "PLAIN_USERNAME", -  "PLAIN_PASSWORD", -  "CURVE_PUBLICKEY", -  "CURVE_SECRETKEY", -  "CURVE_SERVERKEY", -  "ZAP_DOMAIN", -  "CONNECT_RID", -  "RECONNECT_IVL_MAX", -  "SNDTIMEO", -  "RCVTIMEO", -  "SNDHWM", -  "RCVHWM", -  "MULTICAST_HOPS", -  "IPV4ONLY", -  "ROUTER_BEHAVIOR", -  "TCP_KEEPALIVE", -  "TCP_KEEPALIVE_CNT", -  "TCP_KEEPALIVE_IDLE", -  "TCP_KEEPALIVE_INTVL", -  "DELAY_ATTACH_ON_CONNECT", -  "XPUB_VERBOSE", -  "FD", -  "EVENTS", -  "TYPE", -  "LINGER", -  "RECONNECT_IVL", -  "BACKLOG", -  "ROUTER_MANDATORY", -  "FAIL_UNROUTABLE", -  "ROUTER_RAW", -  "IMMEDIATE", -  "IPV6", -  "MECHANISM", -  "PLAIN_SERVER", -  "CURVE_SERVER", -  "PROBE_ROUTER", -  "REQ_RELAXED", -  "REQ_CORRELATE", -  "CONFLATE", -  "ROUTER_HANDOVER", -  "TOS", -  "IPC_FILTER_PID", -  "IPC_FILTER_UID", -  "IPC_FILTER_GID", -  "AFFINITY", -  "MAXMSGSIZE", -  "HWM", -  "SWAP", -  "MCAST_LOOP", -  "RECOVERY_IVL_MSEC", -  "RATE", -  "RECOVERY_IVL", -  "SNDBUF", -  "RCVBUF", -  "RCVMORE", -] diff --git a/zmq/backend/cython/constants.pyx b/zmq/backend/cython/constants.pyx deleted file mode 100644 index f924f03..0000000 --- a/zmq/backend/cython/constants.pyx +++ /dev/null @@ -1,32 +0,0 @@ -"""0MQ Constants.""" - -# -#    Copyright (c) 2010 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from libzmq cimport * - -#----------------------------------------------------------------------------- -# Python module level constants -#----------------------------------------------------------------------------- - -include "constants.pxi" diff --git a/zmq/backend/cython/context.pxd b/zmq/backend/cython/context.pxd deleted file mode 100644 index 9c9267a..0000000 --- a/zmq/backend/cython/context.pxd +++ /dev/null @@ -1,41 +0,0 @@ -"""0MQ Context class declaration.""" - -# -#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - -cdef class Context: - -    cdef object __weakref__     # enable weakref -    cdef void *handle           # The C handle for the underlying zmq object. -    cdef bint _shadow           # whether the Context is a shadow wrapper of another -    cdef void **_sockets        # A C-array containg socket handles -    cdef size_t _n_sockets      # the number of sockets -    cdef size_t _max_sockets    # the size of the _sockets array -    cdef int _pid               # the pid of the process which created me (for fork safety) -     -    cdef public bint closed   # bool property for a closed context. -    cdef inline int _term(self) -    # helpers for events on _sockets in Socket.__cinit__()/close() -    cdef inline void _add_socket(self, void* handle) -    cdef inline void _remove_socket(self, void* handle) - diff --git a/zmq/backend/cython/context.pyx b/zmq/backend/cython/context.pyx deleted file mode 100644 index b527e5d..0000000 --- a/zmq/backend/cython/context.pyx +++ /dev/null @@ -1,243 +0,0 @@ -"""0MQ Context class.""" -# coding: utf-8 - -# Copyright (c) PyZMQ Developers. -# Distributed under the terms of the Lesser GNU Public License (LGPL). - -from libc.stdlib cimport free, malloc, realloc - -from libzmq cimport * - -cdef extern from "getpid_compat.h": -    int getpid() - -from zmq.error import ZMQError -from zmq.backend.cython.checkrc cimport _check_rc - - -_instance = None - -cdef class Context: -    """Context(io_threads=1) - -    Manage the lifecycle of a 0MQ context. - -    Parameters -    ---------- -    io_threads : int -        The number of IO threads. -    """ -     -    # no-op for the signature -    def __init__(self, io_threads=1, shadow=0): -        pass -     -    def __cinit__(self, int io_threads=1, size_t shadow=0, **kwargs): -        self.handle = NULL -        self._sockets = NULL -        if shadow: -            self.handle = <void *>shadow -            self._shadow = True -        else: -            self._shadow = False -            if ZMQ_VERSION_MAJOR >= 3: -                self.handle = zmq_ctx_new() -            else: -                self.handle = zmq_init(io_threads) -         -        if self.handle == NULL: -            raise ZMQError() -         -        cdef int rc = 0 -        if ZMQ_VERSION_MAJOR >= 3 and not self._shadow: -            rc = zmq_ctx_set(self.handle, ZMQ_IO_THREADS, io_threads) -            _check_rc(rc) -         -        self.closed = False -        self._n_sockets = 0 -        self._max_sockets = 32 -         -        self._sockets = <void **>malloc(self._max_sockets*sizeof(void *)) -        if self._sockets == NULL: -            raise MemoryError("Could not allocate _sockets array") -         -        self._pid = getpid() -     -    def __dealloc__(self): -        """don't touch members in dealloc, just cleanup allocations""" -        cdef int rc -        if self._sockets != NULL: -            free(self._sockets) -            self._sockets = NULL -            self._n_sockets = 0 - -        # we can't call object methods in dealloc as it -        # might already be partially deleted -        if not self._shadow: -            self._term() -     -    cdef inline void _add_socket(self, void* handle): -        """Add a socket handle to be closed when Context terminates. -         -        This is to be called in the Socket constructor. -        """ -        if self._n_sockets >= self._max_sockets: -            self._max_sockets *= 2 -            self._sockets = <void **>realloc(self._sockets, self._max_sockets*sizeof(void *)) -            if self._sockets == NULL: -                raise MemoryError("Could not reallocate _sockets array") -         -        self._sockets[self._n_sockets] = handle -        self._n_sockets += 1 - -    cdef inline void _remove_socket(self, void* handle): -        """Remove a socket from the collected handles. -         -        This should be called by Socket.close, to prevent trying to -        close a socket a second time. -        """ -        cdef bint found = False -         -        for idx in range(self._n_sockets): -            if self._sockets[idx] == handle: -                found=True -                break -         -        if found: -            self._n_sockets -= 1 -            if self._n_sockets: -                # move last handle to closed socket's index -                self._sockets[idx] = self._sockets[self._n_sockets] -     -     -    @property -    def underlying(self): -        """The address of the underlying libzmq context""" -        return <size_t> self.handle -     -    # backward-compat, though nobody is using it -    _handle = underlying -     -    cdef inline int _term(self): -        cdef int rc=0 -        if self.handle != NULL and not self.closed and getpid() == self._pid: -            with nogil: -                rc = zmq_ctx_destroy(self.handle) -        self.handle = NULL -        return rc -     -    def term(self): -        """ctx.term() - -        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. -        """ -        cdef int rc -        rc = self._term() -        self.closed = True -     -    def set(self, int option, optval): -        """ctx.set(option, optval) - -        Set a context option. - -        See the 0MQ API documentation for zmq_ctx_set -        for details on specific options. -         -        .. versionadded:: libzmq-3.2 -        .. versionadded:: 13.0 - -        Parameters -        ---------- -        option : int -            The option to set.  Available values will depend on your -            version of libzmq.  Examples include:: -             -                zmq.IO_THREADS, zmq.MAX_SOCKETS -         -        optval : int -            The value of the option to set. -        """ -        cdef int optval_int_c -        cdef int rc -        cdef char* optval_c - -        if self.closed: -            raise RuntimeError("Context has been destroyed") -         -        if not isinstance(optval, int): -            raise TypeError('expected int, got: %r' % optval) -        optval_int_c = optval -        rc = zmq_ctx_set(self.handle, option, optval_int_c) -        _check_rc(rc) - -    def get(self, int option): -        """ctx.get(option) - -        Get the value of a context option. - -        See the 0MQ API documentation for zmq_ctx_get -        for details on specific options. -         -        .. versionadded:: libzmq-3.2 -        .. versionadded:: 13.0 - -        Parameters -        ---------- -        option : int -            The option to get.  Available values will depend on your -            version of libzmq.  Examples include:: -             -                zmq.IO_THREADS, zmq.MAX_SOCKETS -             -        Returns -        ------- -        optval : int -            The value of the option as an integer. -        """ -        cdef int optval_int_c -        cdef size_t sz -        cdef int rc - -        if self.closed: -            raise RuntimeError("Context has been destroyed") - -        rc = zmq_ctx_get(self.handle, option) -        _check_rc(rc) - -        return rc - -    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: -                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() != ZMQ_ENOTSOCK: -                    raise ZMQError() -                self._n_sockets -= 1 -                self._sockets[0] = self._sockets[self._n_sockets] -        self.term() -     -__all__ = ['Context'] diff --git a/zmq/backend/cython/error.pyx b/zmq/backend/cython/error.pyx deleted file mode 100644 index 85e785f..0000000 --- a/zmq/backend/cython/error.pyx +++ /dev/null @@ -1,56 +0,0 @@ -"""0MQ Error classes and functions.""" - -# -#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -# allow const char* -cdef extern from *: -    ctypedef char* const_char_ptr "const char*" - -from libzmq cimport zmq_strerror, zmq_errno as zmq_errno_c - -from zmq.utils.strtypes import bytes - -def strerror(int errno): -    """strerror(errno) - -    Return the error string given the error number. -    """ -    cdef const_char_ptr str_e -    # char * will be a bytes object: -    str_e = zmq_strerror(errno) -    if str is bytes: -        # Python 2: str is bytes, so we already have the right type -        return str_e -    else: -        # Python 3: decode bytes to unicode str -        return str_e.decode() - -def zmq_errno(): -    """zmq_errno() -     -    Return the integer errno of the most recent zmq error. -    """ -    return zmq_errno_c() - -__all__ = ['strerror', 'zmq_errno'] diff --git a/zmq/backend/cython/libzmq.pxd b/zmq/backend/cython/libzmq.pxd deleted file mode 100644 index cc1ec53..0000000 --- a/zmq/backend/cython/libzmq.pxd +++ /dev/null @@ -1,107 +0,0 @@ -"""All the C imports for 0MQ""" - -# -#    Copyright (c) 2010 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Import the C header files -#----------------------------------------------------------------------------- - -cdef extern from *: -    ctypedef void* const_void_ptr "const void *" - -cdef extern from "zmq_compat.h": -    ctypedef signed long long int64_t "pyzmq_int64_t" - -include "constant_enums.pxi" - -cdef extern from "zmq.h" nogil: - -    void _zmq_version "zmq_version"(int *major, int *minor, int *patch) -     -    ctypedef int fd_t "ZMQ_FD_T" -     -    enum: errno -    char *zmq_strerror (int errnum) -    int zmq_errno() - -    void *zmq_ctx_new () -    int zmq_ctx_destroy (void *context) -    int zmq_ctx_set (void *context, int option, int optval) -    int zmq_ctx_get (void *context, int option) -    void *zmq_init (int io_threads) -    int zmq_term (void *context) -     -    # blackbox def for zmq_msg_t -    ctypedef void * zmq_msg_t "zmq_msg_t" -     -    ctypedef void zmq_free_fn(void *data, void *hint) -     -    int zmq_msg_init (zmq_msg_t *msg) -    int zmq_msg_init_size (zmq_msg_t *msg, size_t size) -    int zmq_msg_init_data (zmq_msg_t *msg, void *data, -        size_t size, zmq_free_fn *ffn, void *hint) -    int zmq_msg_send (zmq_msg_t *msg, void *s, int flags) -    int zmq_msg_recv (zmq_msg_t *msg, void *s, int flags) -    int zmq_msg_close (zmq_msg_t *msg) -    int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src) -    int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src) -    void *zmq_msg_data (zmq_msg_t *msg) -    size_t zmq_msg_size (zmq_msg_t *msg) -    int zmq_msg_more (zmq_msg_t *msg) -    int zmq_msg_get (zmq_msg_t *msg, int option) -    int zmq_msg_set (zmq_msg_t *msg, int option, int optval) - -    void *zmq_socket (void *context, int type) -    int zmq_close (void *s) -    int zmq_setsockopt (void *s, int option, void *optval, size_t optvallen) -    int zmq_getsockopt (void *s, int option, void *optval, size_t *optvallen) -    int zmq_bind (void *s, char *addr) -    int zmq_connect (void *s, char *addr) -    int zmq_unbind (void *s, char *addr) -    int zmq_disconnect (void *s, char *addr) - -    int zmq_socket_monitor (void *s, char *addr, int flags) -     -    # send/recv -    int zmq_sendbuf (void *s, const_void_ptr buf, size_t n, int flags) -    int zmq_recvbuf (void *s, void *buf, size_t n, int flags) - -    ctypedef struct zmq_pollitem_t: -        void *socket -        int fd -        short events -        short revents - -    int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout) - -    int zmq_device (int device_, void *insocket_, void *outsocket_) -    int zmq_proxy (void *frontend, void *backend, void *capture) - -cdef extern from "zmq_utils.h" nogil: - -    void *zmq_stopwatch_start () -    unsigned long zmq_stopwatch_stop (void *watch_) -    void zmq_sleep (int seconds_) -    int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key) - diff --git a/zmq/backend/cython/message.pxd b/zmq/backend/cython/message.pxd deleted file mode 100644 index 4781195..0000000 --- a/zmq/backend/cython/message.pxd +++ /dev/null @@ -1,63 +0,0 @@ -"""0MQ Message related class declarations.""" - -# -#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from cpython cimport PyBytes_FromStringAndSize - -from libzmq cimport zmq_msg_t, zmq_msg_data, zmq_msg_size - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - -cdef class MessageTracker(object): - -    cdef set events  # Message Event objects to track. -    cdef set peers   # Other Message or MessageTracker objects. - - -cdef class Frame: - -    cdef zmq_msg_t zmq_msg -    cdef object _data      # The actual message data as a Python object. -    cdef object _buffer    # A Python Buffer/View of the message contents -    cdef object _bytes     # A bytes/str copy of the message. -    cdef bint _failed_init # Flag to handle failed zmq_msg_init -    cdef public object tracker_event  # Event for use with zmq_free_fn. -    cdef public object tracker        # MessageTracker object. -    cdef public bint more             # whether RCVMORE was set - -    cdef Frame fast_copy(self) # Create shallow copy of Message object. -    cdef object _getbuffer(self) # Construct self._buffer. - - -cdef inline object copy_zmq_msg_bytes(zmq_msg_t *zmq_msg): -    """ Copy the data from a zmq_msg_t """ -    cdef char *data_c = NULL -    cdef Py_ssize_t data_len_c -    data_c = <char *>zmq_msg_data(zmq_msg) -    data_len_c = zmq_msg_size(zmq_msg) -    return PyBytes_FromStringAndSize(data_c, data_len_c) - - diff --git a/zmq/backend/cython/message.pyx b/zmq/backend/cython/message.pyx deleted file mode 100644 index bef6e78..0000000 --- a/zmq/backend/cython/message.pyx +++ /dev/null @@ -1,356 +0,0 @@ -"""0MQ Message related classes.""" - -# -#    Copyright (c) 2013 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -# get version-independent aliases: -cdef extern from "pyversion_compat.h": -    pass - -from cpython cimport Py_DECREF, Py_INCREF - -from buffers cimport asbuffer_r, viewfromobject_r - -cdef extern from "Python.h": -    ctypedef int Py_ssize_t - -from libzmq cimport * - -from libc.stdio cimport fprintf, stderr as cstderr -from libc.stdlib cimport malloc, free -from libc.string cimport memcpy - -import time - -try: -    # below 3.3 -    from threading import _Event as Event -except (ImportError, AttributeError): -    # python throws ImportError, cython throws AttributeError -    from threading import Event - -import zmq -from zmq.backend.cython.checkrc cimport _check_rc -from zmq.utils.strtypes import bytes,unicode,basestring - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - -ctypedef struct zhint: -    void *ctx -    size_t id - -cdef void free_python_msg(void *data, void *vhint) nogil: -    """A pure-C function for DECREF'ing Python-owned message data. -     -    Sends a message on a PUSH socket -     -    The hint is a `zhint` struct with two values: -     -    ctx (void *): pointer to the Garbage Collector's context -    id (size_t): the id to be used to construct a zmq_msg_t that should be sent on a PUSH socket, -       signaling the Garbage Collector to remove its reference to the object. -     -    - A PUSH socket is created in the context, -    - it is connected to the garbage collector inproc channel, -    - it sends the gc message -    - the PUSH socket is closed -     -    When the Garbage Collector's PULL socket receives the message, -    it deletes its reference to the object, -    allowing Python to free the memory. -    """ -    cdef void *push -    cdef zmq_msg_t msg -    cdef zhint *hint = <zhint *> vhint -    if hint != NULL: -        zmq_msg_init_size(&msg, sizeof(size_t)) -        memcpy(zmq_msg_data(&msg), &hint.id, sizeof(size_t)) -         -        push = zmq_socket(hint.ctx, ZMQ_PUSH) -        if push == NULL: -            # this will happen if the context has been terminated -            return -        rc = zmq_connect(push, "inproc://pyzmq.gc.01") -        if rc < 0: -            fprintf(cstderr, "pyzmq-gc connect failed: %s\n", zmq_strerror(zmq_errno())) -            return -         -        rc = zmq_msg_send(&msg, push, 0) -        if rc < 0: -            fprintf(cstderr, "pyzmq-gc send failed: %s\n", zmq_strerror(zmq_errno())) -         -        zmq_msg_close(&msg) -        zmq_close(push) -        free(hint) - -gc = None - -cdef class Frame: -    """Frame(data=None, track=False) - -    A zmq message Frame class for non-copy send/recvs. - -    This class is only needed if you want to do non-copying send and recvs. -    When you pass a string to this class, like ``Frame(s)``, the  -    ref-count of `s` is increased by two: once because the Frame saves `s` as  -    an instance attribute and another because a ZMQ message is created that -    points to the buffer of `s`. This second ref-count increase makes sure -    that `s` lives until all messages that use it have been sent. Once 0MQ -    sends all the messages and it doesn't need the buffer of s, 0MQ will call -    ``Py_DECREF(s)``. - -    Parameters -    ---------- - -    data : object, optional -        any object that provides the buffer interface will be used to -        construct the 0MQ message data. -    track : bool [default: False] -        whether a MessageTracker_ should be created to track this object. -        Tracking a message has a cost at creation, because it creates a threadsafe -        Event object. -     -    """ - -    def __cinit__(self, object data=None, track=False, **kwargs): -        cdef int rc -        cdef char *data_c = NULL -        cdef Py_ssize_t data_len_c=0 -        cdef zhint *hint - -        # init more as False -        self.more = False - -        # Save the data object in case the user wants the the data as a str. -        self._data = data -        self._failed_init = True  # bool switch for dealloc -        self._buffer = None       # buffer view of data -        self._bytes = None        # bytes copy of data - -        # Event and MessageTracker for monitoring when zmq is done with data: -        if track: -            evt = Event() -            self.tracker_event = evt -            self.tracker = zmq.MessageTracker(evt) -        else: -            self.tracker_event = None -            self.tracker = None - -        if isinstance(data, unicode): -            raise TypeError("Unicode objects not allowed. Only: str/bytes, buffer interfaces.") - -        if data is None: -            rc = zmq_msg_init(&self.zmq_msg) -            _check_rc(rc) -            self._failed_init = False -            return -        else: -            asbuffer_r(data, <void **>&data_c, &data_len_c) -         -        # create the hint for zmq_free_fn -        # two pointers: the gc context and a message to be sent to the gc PULL socket -        # allows libzmq to signal to Python when it is done with Python-owned memory. -        global gc -        if gc is None: -            from zmq.utils.garbage import gc -         -        hint = <zhint *> malloc(sizeof(zhint)) -        hint.id = gc.store(data, self.tracker_event) -        hint.ctx = <void *> <size_t> gc._context.underlying -         -        rc = zmq_msg_init_data( -                &self.zmq_msg, <void *>data_c, data_len_c,  -                <zmq_free_fn *>free_python_msg, <void *>hint -            ) -        if rc != 0: -            free(hint) -            _check_rc(rc) -        self._failed_init = False -     -    def __init__(self, object data=None, track=False): -        """Enforce signature""" -        pass - -    def __dealloc__(self): -        cdef int rc -        if self._failed_init: -            return -        # This simply decreases the 0MQ ref-count of zmq_msg. -        with nogil: -            rc = zmq_msg_close(&self.zmq_msg) -        _check_rc(rc) -     -    # buffer interface code adapted from petsc4py by Lisandro Dalcin, a BSD project -     -    def __getbuffer__(self, Py_buffer* buffer, int flags): -        # new-style (memoryview) buffer interface -        buffer.buf = zmq_msg_data(&self.zmq_msg) -        buffer.len = zmq_msg_size(&self.zmq_msg) -         -        buffer.obj = self -        buffer.readonly = 1 -        buffer.format = "B" -        buffer.ndim = 0 -        buffer.shape = NULL -        buffer.strides = NULL -        buffer.suboffsets = NULL -        buffer.itemsize = 1 -        buffer.internal = NULL -     -    def __getsegcount__(self, Py_ssize_t *lenp): -        # required for getreadbuffer -        if lenp != NULL: -            lenp[0] = zmq_msg_size(&self.zmq_msg) -        return 1 -     -    def __getreadbuffer__(self, Py_ssize_t idx, void **p): -        # old-style (buffer) interface -        cdef char *data_c = NULL -        cdef Py_ssize_t data_len_c -        if idx != 0: -            raise SystemError("accessing non-existent buffer segment") -        # read-only, because we don't want to allow -        # editing of the message in-place -        data_c = <char *>zmq_msg_data(&self.zmq_msg) -        data_len_c = zmq_msg_size(&self.zmq_msg) -        if p != NULL: -            p[0] = <void*>data_c -        return data_len_c -     -    # end buffer interface -     -    def __copy__(self): -        """Create a shallow copy of the message. - -        This does not copy the contents of the Frame, just the pointer. -        This will increment the 0MQ ref count of the message, but not -        the ref count of the Python object. That is only done once when -        the Python is first turned into a 0MQ message. -        """ -        return self.fast_copy() - -    cdef Frame fast_copy(self): -        """Fast, cdef'd version of shallow copy of the Frame.""" -        cdef Frame new_msg -        new_msg = Frame() -        # This does not copy the contents, but just increases the ref-count  -        # of the zmq_msg by one. -        zmq_msg_copy(&new_msg.zmq_msg, &self.zmq_msg) -        # Copy the ref to data so the copy won't create a copy when str is -        # called. -        if self._data is not None: -            new_msg._data = self._data -        if self._buffer is not None: -            new_msg._buffer = self._buffer -        if self._bytes is not None: -            new_msg._bytes = self._bytes - -        # Frame copies share the tracker and tracker_event -        new_msg.tracker_event = self.tracker_event -        new_msg.tracker = self.tracker - -        return new_msg - -    def __len__(self): -        """Return the length of the message in bytes.""" -        cdef size_t sz -        sz = zmq_msg_size(&self.zmq_msg) -        return sz -        # return <int>zmq_msg_size(&self.zmq_msg) - -    def __str__(self): -        """Return the str form of the message.""" -        if isinstance(self._data, bytes): -            b = self._data -        else: -            b = self.bytes -        if str is unicode: -            return b.decode() -        else: -            return b - -    cdef inline object _getbuffer(self): -        """Create a Python buffer/view of the message data. - -        This will be called only once, the first time the `buffer` property -        is accessed. Subsequent calls use a cached copy. -        """ -        if self._data is None: -            return viewfromobject_r(self) -        else: -            return viewfromobject_r(self._data) -     -    @property -    def buffer(self): -        """A read-only buffer view of the message contents.""" -        if self._buffer is None: -            self._buffer = self._getbuffer() -        return self._buffer - -    @property -    def bytes(self): -        """The message content as a Python bytes object. - -        The first time this property is accessed, a copy of the message  -        contents is made. From then on that same copy of the message is -        returned. -        """ -        if self._bytes is None: -            self._bytes = copy_zmq_msg_bytes(&self.zmq_msg) -        return self._bytes -     -    def set(self, int option, int value): -        """Frame.set(option, value) -         -        Set a Frame option. -         -        See the 0MQ API documentation for zmq_msg_set -        for details on specific options. -         -        .. versionadded:: libzmq-3.2 -        .. versionadded:: 13.0 -        """ -        cdef int rc = zmq_msg_set(&self.zmq_msg, option, value) -        _check_rc(rc) -     -    def get(self, int option): -        """Frame.get(option) -         -        Get a Frame option. -         -        See the 0MQ API documentation for zmq_msg_get -        for details on specific options. -         -        .. versionadded:: libzmq-3.2 -        .. versionadded:: 13.0 -        """ -        cdef int rc = zmq_msg_get(&self.zmq_msg, option) -        _check_rc(rc) -        return rc - -# legacy Message name -Message = Frame - -__all__ = ['Frame', 'Message'] diff --git a/zmq/backend/cython/rebuffer.pyx b/zmq/backend/cython/rebuffer.pyx deleted file mode 100644 index 402e3b6..0000000 --- a/zmq/backend/cython/rebuffer.pyx +++ /dev/null @@ -1,104 +0,0 @@ -""" -Utility for changing itemsize of memoryviews, and getting -numpy arrays from byte-arrays that should be interpreted with a different -itemsize. - -Authors -------- -* MinRK -""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010-2012 Brian Granger, Min Ragan-Kelley -# -#  This file is part of pyzmq -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -from libc.stdlib cimport malloc -from buffers cimport * - -cdef inline object _rebuffer(object obj, char * format, int itemsize): -    """clobber the format & itemsize of a 1-D - -    This is the Python 3 model, but will work on Python >= 2.6. Currently, -    we use it only on >= 3.0. -    """ -    cdef Py_buffer view -    cdef int flags = PyBUF_SIMPLE -    cdef int mode = 0 -    # cdef Py_ssize_t *shape, *strides, *suboffsets -     -    mode = check_buffer(obj) -    if mode == 0: -        raise TypeError("%r does not provide a buffer interface."%obj) - -    if mode == 3: -        flags = PyBUF_ANY_CONTIGUOUS -        if format: -            flags |= PyBUF_FORMAT -        PyObject_GetBuffer(obj, &view, flags) -        assert view.ndim <= 1, "Can only reinterpret 1-D memoryviews" -        assert view.len % itemsize == 0, "Buffer of length %i not divisible into items of size %i"%(view.len, itemsize) -        # hack the format -        view.ndim = 1 -        view.format = format -        view.itemsize = itemsize -        view.strides = <Py_ssize_t *>malloc(sizeof(Py_ssize_t)) -        view.strides[0] = itemsize -        view.shape = <Py_ssize_t *>malloc(sizeof(Py_ssize_t)) -        view.shape[0] = view.len/itemsize -        view.suboffsets = <Py_ssize_t *>malloc(sizeof(Py_ssize_t)) -        view.suboffsets[0] = 0 -        # for debug: make buffer writable, for zero-copy testing -        # view.readonly = 0 -         -        return PyMemoryView_FromBuffer(&view) -    else: -        raise TypeError("This funciton is only for new-style buffer objects.") - -def rebuffer(obj, format, itemsize): -    """Change the itemsize of a memoryview. -     -    Only for 1D contiguous buffers. -    """ -    return _rebuffer(obj, format, itemsize) - -def array_from_buffer(view, dtype, shape): -    """Get a numpy array from a memoryview, regardless of the itemsize of the original -    memoryview.  This is important, because pyzmq does not send memoryview shape data -    over the wire, so we need to change the memoryview itemsize before calling -    asarray. -    """ -    import numpy -    A = numpy.array([],dtype=dtype) -    ref = viewfromobject(A,0) -    fmt = ref.format.encode() -    buf = viewfromobject(view, 0) -    buf = _rebuffer(view, fmt, ref.itemsize) -    return numpy.asarray(buf, dtype=dtype).reshape(shape) - -def print_view_info(obj): -    """simple utility for printing info on a new-style buffer object""" -    cdef Py_buffer view -    cdef int flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT -    cdef int mode = 0 -     -    mode = check_buffer(obj) -    if mode == 0: -        raise TypeError("%r does not provide a buffer interface."%obj) - -    if mode == 3: -        PyObject_GetBuffer(obj, &view, flags) -        print <size_t>view.buf, view.len, view.format, view.ndim, -        if view.ndim: -            if view.shape: -                print view.shape[0], -            if view.strides: -                print view.strides[0], -            if view.suboffsets: -                print view.suboffsets[0], -        print -    
\ No newline at end of file diff --git a/zmq/backend/cython/socket.pxd b/zmq/backend/cython/socket.pxd deleted file mode 100644 index b8a331e..0000000 --- a/zmq/backend/cython/socket.pxd +++ /dev/null @@ -1,47 +0,0 @@ -"""0MQ Socket class declaration.""" - -# -#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from context cimport Context - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - - -cdef class Socket: - -    cdef object __weakref__     # enable weakref -    cdef void *handle           # The C handle for the underlying zmq object. -    cdef bint _shadow           # whether the Socket is a shadow wrapper of another -    # Hold on to a reference to the context to make sure it is not garbage -    # collected until the socket it done with it. -    cdef public Context context # The zmq Context object that owns this. -    cdef public bint _closed    # bool property for a closed socket. -    cdef int _pid               # the pid of the process which created me (for fork safety) - -    # cpdef methods for direct-cython access: -    cpdef object send(self, object data, int flags=*, copy=*, track=*) -    cpdef object recv(self, int flags=*, copy=*, track=*) - diff --git a/zmq/backend/cython/socket.pyx b/zmq/backend/cython/socket.pyx deleted file mode 100644 index 9267364..0000000 --- a/zmq/backend/cython/socket.pyx +++ /dev/null @@ -1,669 +0,0 @@ -"""0MQ Socket class.""" - -# -#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Cython Imports -#----------------------------------------------------------------------------- - -# get version-independent aliases: -cdef extern from "pyversion_compat.h": -    pass - -from libc.errno cimport ENAMETOOLONG -from libc.string cimport memcpy - -from cpython cimport PyBytes_FromStringAndSize -from cpython cimport PyBytes_AsString, PyBytes_Size -from cpython cimport Py_DECREF, Py_INCREF - -from buffers cimport asbuffer_r, viewfromobject_r - -from libzmq cimport * -from message cimport Frame, copy_zmq_msg_bytes - -from context cimport Context - -cdef extern from "Python.h": -    ctypedef int Py_ssize_t - -cdef extern from "ipcmaxlen.h": -    int get_ipc_path_max_len() - -cdef extern from "getpid_compat.h": -    int getpid() - - -#----------------------------------------------------------------------------- -# Python Imports -#----------------------------------------------------------------------------- - -import copy as copy_mod -import time -import sys -import random -import struct -import codecs - -from zmq.utils import jsonapi - -try: -    import cPickle -    pickle = cPickle -except: -    cPickle = None -    import pickle - -import zmq -from zmq.backend.cython import constants -from zmq.backend.cython.constants import * -from zmq.backend.cython.checkrc cimport _check_rc -from zmq.error import ZMQError, ZMQBindError, _check_version -from zmq.utils.strtypes import bytes,unicode,basestring - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - -IPC_PATH_MAX_LEN = get_ipc_path_max_len() - -# inline some small socket submethods: -# true methods frequently cannot be inlined, acc. Cython docs - -cdef inline _check_closed(Socket s): -    """raise ENOTSUP if socket is closed -     -    Does not do a deep check -    """ -    if s._closed: -        raise ZMQError(ENOTSOCK) - -cdef inline _check_closed_deep(Socket s): -    """thorough check of whether the socket has been closed, -    even if by another entity (e.g. ctx.destroy). -     -    Only used by the `closed` property. -     -    returns True if closed, False otherwise -    """ -    cdef int rc -    cdef int errno -    cdef int stype -    cdef size_t sz=sizeof(int) -    if s._closed: -        return True -    else: -        rc = zmq_getsockopt(s.handle, ZMQ_TYPE, <void *>&stype, &sz) -        if rc < 0 and zmq_errno() == ENOTSOCK: -            s._closed = True -            return True -        else: -            _check_rc(rc) -    return False - -cdef inline Frame _recv_frame(void *handle, int flags=0, track=False): -    """Receive a message in a non-copying manner and return a Frame.""" -    cdef int rc -    cdef Frame msg -    msg = Frame(track=track) - -    with nogil: -        rc = zmq_msg_recv(&msg.zmq_msg, handle, flags) -     -    _check_rc(rc) -    return msg - -cdef inline object _recv_copy(void *handle, int flags=0): -    """Receive a message and return a copy""" -    cdef zmq_msg_t zmq_msg -    with nogil: -        zmq_msg_init (&zmq_msg) -        rc = zmq_msg_recv(&zmq_msg, handle, flags) -    _check_rc(rc) -    msg_bytes = copy_zmq_msg_bytes(&zmq_msg) -    zmq_msg_close(&zmq_msg) -    return msg_bytes - -cdef inline object _send_frame(void *handle, Frame msg, int flags=0): -    """Send a Frame on this socket in a non-copy manner.""" -    cdef int rc -    cdef Frame msg_copy - -    # Always copy so the original message isn't garbage collected. -    # This doesn't do a real copy, just a reference. -    msg_copy = msg.fast_copy() - -    with nogil: -        rc = zmq_msg_send(&msg_copy.zmq_msg, handle, flags) - -    _check_rc(rc) -    return msg.tracker - - -cdef inline object _send_copy(void *handle, object msg, int flags=0): -    """Send a message on this socket by copying its content.""" -    cdef int rc, rc2 -    cdef zmq_msg_t data -    cdef char *msg_c -    cdef Py_ssize_t msg_c_len=0 - -    # copy to c array: -    asbuffer_r(msg, <void **>&msg_c, &msg_c_len) - -    # Copy the msg before sending. This avoids any complications with -    # the GIL, etc. -    # If zmq_msg_init_* fails we must not call zmq_msg_close (Bus Error) -    rc = zmq_msg_init_size(&data, msg_c_len) - -    _check_rc(rc) - -    with nogil: -        memcpy(zmq_msg_data(&data), msg_c, zmq_msg_size(&data)) -        rc = zmq_msg_send(&data, handle, flags) -        rc2 = zmq_msg_close(&data) -    _check_rc(rc) -    _check_rc(rc2) - - -cdef class Socket: -    """Socket(context, socket_type) - -    A 0MQ socket. - -    These objects will generally be constructed via the socket() method of a Context object. -     -    Note: 0MQ Sockets are *not* threadsafe. **DO NOT** share them across threads. -     -    Parameters -    ---------- -    context : Context -        The 0MQ Context this Socket belongs to. -    socket_type : int -        The socket type, which can be any of the 0MQ socket types:  -        REQ, REP, PUB, SUB, PAIR, DEALER, ROUTER, PULL, PUSH, XPUB, XSUB. -     -    See Also -    -------- -    .Context.socket : method for creating a socket bound to a Context. -    """ -     -    # no-op for the signature -    def __init__(self, context=None, socket_type=-1, shadow=0): -        pass -     -    def __cinit__(self, Context context=None, int socket_type=-1, size_t shadow=0, *args, **kwargs): -        cdef Py_ssize_t c_handle - -        self.handle = NULL -        self.context = context -        if shadow: -            self._shadow = True -            self.handle = <void *>shadow -        else: -            if context is None: -                raise TypeError("context must be specified") -            if socket_type < 0: -                raise TypeError("socket_type must be specified") -            self._shadow = False -            self.handle = zmq_socket(context.handle, socket_type) -        if self.handle == NULL: -            raise ZMQError() -        self._closed = False -        self._pid = getpid() -        if context: -            context._add_socket(self.handle) - -    def __dealloc__(self): -        """remove from context's list -         -        But be careful that context might not exist if called during gc -        """ -        if self.handle != NULL and not self._shadow and getpid() == self._pid: -            # during gc, self.context might be NULL -            if self.context: -                self.context._remove_socket(self.handle) -     -    @property -    def underlying(self): -        """The address of the underlying libzmq socket""" -        return <size_t> self.handle -     -    @property -    def closed(self): -        return _check_closed_deep(self) -     -    def close(self, linger=None): -        """s.close(linger=None) - -        Close the socket. -         -        If linger is specified, LINGER sockopt will be set prior to closing. - -        This can be called to close the socket by hand. If this is not -        called, the socket will automatically be closed when it is -        garbage collected. -        """ -        cdef int rc=0 -        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 getpid() == self._pid: -            if setlinger: -                zmq_setsockopt(self.handle, ZMQ_LINGER, &linger_c, sizeof(int)) -            rc = zmq_close(self.handle) -            if rc != 0 and zmq_errno() != ENOTSOCK: -                # ignore ENOTSOCK (closed by Context) -                _check_rc(rc) -            self._closed = True -            # during gc, self.context might be NULL -            if self.context: -                self.context._remove_socket(self.handle) -            self.handle = NULL - -    def set(self, int option, optval): -        """s.set(option, optval) - -        Set socket options. - -        See the 0MQ API documentation for details on specific options. - -        Parameters -        ---------- -        option : int -            The option to set.  Available values will depend on your -            version of libzmq.  Examples include:: -             -                zmq.SUBSCRIBE, UNSUBSCRIBE, IDENTITY, HWM, LINGER, FD -         -        optval : int or bytes -            The value of the option to set. -        """ -        cdef int64_t optval_int64_c -        cdef int optval_int_c -        cdef int rc -        cdef char* optval_c -        cdef Py_ssize_t sz - -        _check_closed(self) -        if isinstance(optval, unicode): -            raise TypeError("unicode not allowed, use setsockopt_string") - -        if option in zmq.constants.bytes_sockopts: -            if not isinstance(optval, bytes): -                raise TypeError('expected bytes, got: %r' % optval) -            optval_c = PyBytes_AsString(optval) -            sz = PyBytes_Size(optval) -            rc = zmq_setsockopt( -                    self.handle, option, -                    optval_c, sz -                ) -        elif option in zmq.constants.int64_sockopts: -            if not isinstance(optval, int): -                raise TypeError('expected int, got: %r' % optval) -            optval_int64_c = optval -            rc = zmq_setsockopt( -                    self.handle, option, -                    &optval_int64_c, sizeof(int64_t) -                ) -        else: -            # default is to assume int, which is what most new sockopts will be -            # this lets pyzmq work with newer libzmq which may add constants -            # pyzmq has not yet added, rather than artificially raising. Invalid -            # sockopts will still raise just the same, but it will be libzmq doing -            # the raising. -            if not isinstance(optval, int): -                raise TypeError('expected int, got: %r' % optval) -            optval_int_c = optval -            rc = zmq_setsockopt( -                    self.handle, option, -                    &optval_int_c, sizeof(int) -                ) - -        _check_rc(rc) - -    def get(self, int option): -        """s.get(option) - -        Get the value of a socket option. - -        See the 0MQ API documentation for details on specific options. - -        Parameters -        ---------- -        option : int -            The option to get.  Available values will depend on your -            version of libzmq.  Examples include:: -             -                zmq.IDENTITY, HWM, LINGER, FD, EVENTS - -        Returns -        ------- -        optval : int or bytes -            The value of the option as a bytestring or int. -        """ -        cdef int64_t optval_int64_c -        cdef int optval_int_c -        cdef fd_t optval_fd_c -        cdef char identity_str_c [255] -        cdef size_t sz -        cdef int rc - -        _check_closed(self) - -        if option in zmq.constants.bytes_sockopts: -            sz = 255 -            rc = zmq_getsockopt(self.handle, option, <void *>identity_str_c, &sz) -            _check_rc(rc) -            # strip null-terminated strings *except* identity -            if option != ZMQ_IDENTITY and sz > 0 and (<char *>identity_str_c)[sz-1] == b'\0': -                sz -= 1 -            result = PyBytes_FromStringAndSize(<char *>identity_str_c, sz) -        elif option in zmq.constants.int64_sockopts: -            sz = sizeof(int64_t) -            rc = zmq_getsockopt(self.handle, option, <void *>&optval_int64_c, &sz) -            _check_rc(rc) -            result = optval_int64_c -        elif option == ZMQ_FD: -            sz = sizeof(fd_t) -            rc = zmq_getsockopt(self.handle, option, <void *>&optval_fd_c, &sz) -            _check_rc(rc) -            result = optval_fd_c -        else: -            # default is to assume int, which is what most new sockopts will be -            # this lets pyzmq work with newer libzmq which may add constants -            # pyzmq has not yet added, rather than artificially raising. Invalid -            # sockopts will still raise just the same, but it will be libzmq doing -            # the raising. -            sz = sizeof(int) -            rc = zmq_getsockopt(self.handle, option, <void *>&optval_int_c, &sz) -            _check_rc(rc) -            result = optval_int_c - -        return result -     -    def bind(self, addr): -        """s.bind(addr) - -        Bind the socket to an address. - -        This causes the socket to listen on a network port. Sockets on the -        other side of this connection will use ``Socket.connect(addr)`` to -        connect to this socket. - -        Parameters -        ---------- -        addr : str -            The address string. This has the form 'protocol://interface:port', -            for example 'tcp://127.0.0.1:5555'. Protocols supported include -            tcp, udp, pgm, epgm, inproc and ipc. If the address is unicode, it is -            encoded to utf-8 first. -        """ -        cdef int rc -        cdef char* c_addr - -        _check_closed(self) -        if isinstance(addr, unicode): -            addr = addr.encode('utf-8') -        if not isinstance(addr, bytes): -            raise TypeError('expected str, got: %r' % addr) -        c_addr = addr -        rc = zmq_bind(self.handle, c_addr) -        if rc != 0: -            if IPC_PATH_MAX_LEN and zmq_errno() == ENAMETOOLONG: -                # py3compat: addr is bytes, but msg wants str -                if str is unicode: -                    addr = addr.decode('utf-8', 'replace') -                path = addr.split('://', 1)[-1] -                msg = ('ipc path "{0}" is longer than {1} ' -                                'characters (sizeof(sockaddr_un.sun_path)). ' -                                'zmq.IPC_PATH_MAX_LEN constant can be used ' -                                'to check addr length (if it is defined).' -                                .format(path, IPC_PATH_MAX_LEN)) -                raise ZMQError(msg=msg) -        _check_rc(rc) - -    def connect(self, addr): -        """s.connect(addr) - -        Connect to a remote 0MQ socket. - -        Parameters -        ---------- -        addr : str -            The address string. This has the form 'protocol://interface:port', -            for example 'tcp://127.0.0.1:5555'. Protocols supported are -            tcp, upd, pgm, inproc and ipc. If the address is unicode, it is -            encoded to utf-8 first. -        """ -        cdef int rc -        cdef char* c_addr - -        _check_closed(self) -        if isinstance(addr, unicode): -            addr = addr.encode('utf-8') -        if not isinstance(addr, bytes): -            raise TypeError('expected str, got: %r' % addr) -        c_addr = addr -         -        rc = zmq_connect(self.handle, c_addr) -        if rc != 0: -            raise ZMQError() - -    def unbind(self, addr): -        """s.unbind(addr) -         -        Unbind from an address (undoes a call to bind). -         -        .. versionadded:: libzmq-3.2 -        .. versionadded:: 13.0 - -        Parameters -        ---------- -        addr : str -            The address string. This has the form 'protocol://interface:port', -            for example 'tcp://127.0.0.1:5555'. Protocols supported are -            tcp, upd, pgm, inproc and ipc. If the address is unicode, it is -            encoded to utf-8 first. -        """ -        cdef int rc -        cdef char* c_addr - -        _check_version((3,2), "unbind") -        _check_closed(self) -        if isinstance(addr, unicode): -            addr = addr.encode('utf-8') -        if not isinstance(addr, bytes): -            raise TypeError('expected str, got: %r' % addr) -        c_addr = addr -         -        rc = zmq_unbind(self.handle, c_addr) -        if rc != 0: -            raise ZMQError() - -    def disconnect(self, addr): -        """s.disconnect(addr) - -        Disconnect from a remote 0MQ socket (undoes a call to connect). -         -        .. versionadded:: libzmq-3.2 -        .. versionadded:: 13.0 - -        Parameters -        ---------- -        addr : str -            The address string. This has the form 'protocol://interface:port', -            for example 'tcp://127.0.0.1:5555'. Protocols supported are -            tcp, upd, pgm, inproc and ipc. If the address is unicode, it is -            encoded to utf-8 first. -        """ -        cdef int rc -        cdef char* c_addr -         -        _check_version((3,2), "disconnect") -        _check_closed(self) -        if isinstance(addr, unicode): -            addr = addr.encode('utf-8') -        if not isinstance(addr, bytes): -            raise TypeError('expected str, got: %r' % addr) -        c_addr = addr -         -        rc = zmq_disconnect(self.handle, c_addr) -        if rc != 0: -            raise ZMQError() - -    def monitor(self, addr, int events=ZMQ_EVENT_ALL): -        """s.monitor(addr, flags) - -        Start publishing socket events on inproc. -        See libzmq docs for zmq_monitor for details. -         -        While this function is available from libzmq 3.2, -        pyzmq cannot parse monitor messages from libzmq prior to 4.0. -         -        .. versionadded: libzmq-3.2 -        .. versionadded: 14.0 -         -        Parameters -        ---------- -        addr : str -            The inproc url used for monitoring. -        events : int [default: zmq.EVENT_ALL] -            The zmq event bitmask for which events will be sent to the monitor. -        """ -        cdef int rc, c_flags -        cdef char* c_addr -         -        _check_version((3,2), "monitor") -        if isinstance(addr, unicode): -            addr = addr.encode('utf-8') -        if not isinstance(addr, bytes): -            raise TypeError('expected str, got: %r' % addr) -        c_addr = addr -        c_flags = events -        rc = zmq_socket_monitor(self.handle, c_addr, c_flags) -        _check_rc(rc) - -    #------------------------------------------------------------------------- -    # Sending and receiving messages -    #------------------------------------------------------------------------- - -    cpdef object send(self, object data, int flags=0, copy=True, track=False): -        """s.send(data, flags=0, copy=True, track=False) - -        Send a message on this socket. - -        This queues the message to be sent by the IO thread at a later time. - -        Parameters -        ---------- -        data : object, str, Frame -            The content of the message. -        flags : int -            Any supported flag: NOBLOCK, SNDMORE. -        copy : bool -            Should the message be sent in a copying or non-copying manner. -        track : bool -            Should the message be tracked for notification that ZMQ has -            finished with it? (ignored if copy=True) - -        Returns -        ------- -        None : if `copy` or not track -            None if message was sent, raises an exception otherwise. -        MessageTracker : if track and not copy -            a MessageTracker object, whose `pending` property will -            be True until the send is completed. -         -        Raises -        ------ -        TypeError -            If a unicode object is passed -        ValueError -            If `track=True`, but an untracked Frame is passed. -        ZMQError -            If the send does not succeed for any reason. -         -        """ -        _check_closed(self) -         -        if isinstance(data, unicode): -            raise TypeError("unicode not allowed, use send_string") -         -        if copy: -            # msg.bytes never returns the input data object -            # it is always a copy, but always the same copy -            if isinstance(data, Frame): -                data = data.buffer -            return _send_copy(self.handle, data, flags) -        else: -            if isinstance(data, Frame): -                if track and not data.tracker: -                    raise ValueError('Not a tracked message') -                msg = data -            else: -                msg = Frame(data, track=track) -            return _send_frame(self.handle, msg, flags) - -    cpdef object recv(self, int flags=0, copy=True, track=False): -        """s.recv(flags=0, copy=True, track=False) - -        Receive a message. - -        Parameters -        ---------- -        flags : int -            Any supported flag: NOBLOCK. If NOBLOCK is set, this method -            will raise a ZMQError with EAGAIN if a message is not ready. -            If NOBLOCK is not set, then this method will block until a -            message arrives. -        copy : bool -            Should the message be received in a copying or non-copying manner? -            If False a Frame object is returned, if True a string copy of -            message is returned. -        track : bool -            Should the message be tracked for notification that ZMQ has -            finished with it? (ignored if copy=True) - -        Returns -        ------- -        msg : bytes, Frame -            The received message frame.  If `copy` is False, then it will be a Frame, -            otherwise it will be bytes. -             -        Raises -        ------ -        ZMQError -            for any of the reasons zmq_msg_recv might fail. -        """ -        _check_closed(self) -         -        if copy: -            return _recv_copy(self.handle, flags) -        else: -            frame = _recv_frame(self.handle, flags, track) -            frame.more = self.getsockopt(zmq.RCVMORE) -            return frame -     - -__all__ = ['Socket', 'IPC_PATH_MAX_LEN'] diff --git a/zmq/backend/cython/utils.pxd b/zmq/backend/cython/utils.pxd deleted file mode 100644 index 1d7117f..0000000 --- a/zmq/backend/cython/utils.pxd +++ /dev/null @@ -1,29 +0,0 @@ -"""Wrap zmq_utils.h""" - -# -#    Copyright (c) 2010 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - - -cdef class Stopwatch: -    cdef void *watch # The C handle for the underlying zmq object - diff --git a/zmq/backend/cython/utils.pyx b/zmq/backend/cython/utils.pyx deleted file mode 100644 index 3283cee..0000000 --- a/zmq/backend/cython/utils.pyx +++ /dev/null @@ -1,111 +0,0 @@ -"""0MQ utils.""" - -# -#    Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley -# -#    This file is part of pyzmq. -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from libzmq cimport zmq_stopwatch_start, zmq_stopwatch_stop, zmq_sleep, zmq_curve_keypair - -from zmq.error import ZMQError, _check_rc, _check_version - -#----------------------------------------------------------------------------- -# Code -#----------------------------------------------------------------------------- - -def curve_keypair(): -    """generate a Z85 keypair for use with zmq.CURVE security -     -    Requires libzmq (≥ 4.0) to have been linked with libsodium. -     -    .. versionadded:: libzmq-4.0 -    .. versionadded:: 14.0 -     -    Returns -    ------- -    (public, secret) : two bytestrings -        The public and private keypair as 40 byte z85-encoded bytestrings. -    """ -    cdef int rc -    cdef char[64] public_key -    cdef char[64] secret_key -    _check_version((4,0), "curve_keypair") -    rc = zmq_curve_keypair (public_key, secret_key) -    _check_rc(rc) -    return public_key, secret_key - - -cdef class Stopwatch: -    """Stopwatch() - -    A simple stopwatch based on zmq_stopwatch_start/stop. - -    This class should be used for benchmarking and timing 0MQ code. -    """ - -    def __cinit__(self): -        self.watch = NULL - -    def __dealloc__(self): -        # copy of self.stop() we can't call object methods in dealloc as it -        # might already be partially deleted -        if self.watch: -            zmq_stopwatch_stop(self.watch) -            self.watch = NULL - -    def start(self): -        """s.start() - -        Start the stopwatch. -        """ -        if self.watch == NULL: -            self.watch = zmq_stopwatch_start() -        else: -            raise ZMQError('Stopwatch is already running.') - -    def stop(self): -        """s.stop() - -        Stop the stopwatch. -         -        Returns -        ------- -        t : unsigned long int -            the number of microseconds since ``start()`` was called. -        """ -        cdef unsigned long time -        if self.watch == NULL: -            raise ZMQError('Must start the Stopwatch before calling stop.') -        else: -            time = zmq_stopwatch_stop(self.watch) -            self.watch = NULL -            return time - -    def sleep(self, int seconds): -        """s.sleep(seconds) - -        Sleep for an integer number of seconds. -        """ -        with nogil: -            zmq_sleep(seconds) - - -__all__ = ['curve_keypair', 'Stopwatch'] diff --git a/zmq/backend/select.py b/zmq/backend/select.py deleted file mode 100644 index eda159c..0000000 --- a/zmq/backend/select.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Import basic exposure of libzmq C API as a backend""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -public_api = [ -    'Context', -    'Socket', -    'Frame', -    'Message', -    'Stopwatch', -    'device', -    'proxy', -    'zmq_poll', -    'strerror', -    'zmq_errno', -    'curve_keypair', -    'constants', -    'zmq_version_info', -    'IPC_PATH_MAX_LEN', -] - -def select_backend(name): -    """Select the pyzmq backend""" -    try: -        mod = __import__(name, fromlist=public_api) -    except ImportError: -        raise -    except Exception as e: -        import sys -        from zmq.utils.sixcerpt import reraise -        exc_info = sys.exc_info() -        reraise(ImportError, ImportError("Importing %s failed with %s" % (name, e)), exc_info[2]) -     -    ns = {} -    for key in public_api: -        ns[key] = getattr(mod, key) -    return ns diff --git a/zmq/devices/__init__.py b/zmq/devices/__init__.py deleted file mode 100644 index 2371596..0000000 --- a/zmq/devices/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -"""0MQ Device classes for running in background threads or processes.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from zmq import device -from zmq.devices import basedevice, proxydevice, monitoredqueue, monitoredqueuedevice - -from zmq.devices.basedevice import * -from zmq.devices.proxydevice import * -from zmq.devices.monitoredqueue import * -from zmq.devices.monitoredqueuedevice import * - -__all__ = ['device'] -for submod in (basedevice, proxydevice, monitoredqueue, monitoredqueuedevice): -    __all__.extend(submod.__all__) diff --git a/zmq/devices/basedevice.py b/zmq/devices/basedevice.py deleted file mode 100644 index 7ba1b7a..0000000 --- a/zmq/devices/basedevice.py +++ /dev/null @@ -1,229 +0,0 @@ -"""Classes for running 0MQ Devices in the background.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import time -from threading import Thread -from multiprocessing import Process - -from zmq import device, QUEUE, Context, ETERM, ZMQError - - -class Device: -    """A 0MQ Device to be run in the background. -     -    You do not pass Socket instances to this, but rather Socket types:: - -        Device(device_type, in_socket_type, out_socket_type) - -    For instance:: - -        dev = Device(zmq.QUEUE, zmq.DEALER, zmq.ROUTER) - -    Similar to zmq.device, but socket types instead of sockets themselves are -    passed, and the sockets are created in the work thread, to avoid issues -    with thread safety. As a result, additional bind_{in|out} and -    connect_{in|out} methods and setsockopt_{in|out} allow users to specify -    connections for the sockets. -     -    Parameters -    ---------- -    device_type : int -        The 0MQ Device type -    {in|out}_type : int -        zmq socket types, to be passed later to context.socket(). e.g. -        zmq.PUB, zmq.SUB, zmq.REQ. If out_type is < 0, then in_socket is used -        for both in_socket and out_socket. -         -    Methods -    ------- -    bind_{in_out}(iface) -        passthrough for ``{in|out}_socket.bind(iface)``, to be called in the thread -    connect_{in_out}(iface) -        passthrough for ``{in|out}_socket.connect(iface)``, to be called in the -        thread -    setsockopt_{in_out}(opt,value) -        passthrough for ``{in|out}_socket.setsockopt(opt, value)``, to be called in -        the thread -     -    Attributes -    ---------- -    daemon : int -        sets whether the thread should be run as a daemon -        Default is true, because if it is false, the thread will not -        exit unless it is killed -    context_factory : callable (class attribute) -        Function for creating the Context. This will be Context.instance -        in ThreadDevices, and Context in ProcessDevices.  The only reason -        it is not instance() in ProcessDevices is that there may be a stale -        Context instance already initialized, and the forked environment -        should *never* try to use it. -    """ -     -    context_factory = Context.instance -    """Callable that returns a context. Typically either Context.instance or Context, -    depending on whether the device should share the global instance or not. -    """ - -    def __init__(self, device_type=QUEUE, in_type=None, out_type=None): -        self.device_type = device_type -        if in_type is None: -            raise TypeError("in_type must be specified") -        if out_type is None: -            raise TypeError("out_type must be specified") -        self.in_type = in_type -        self.out_type = out_type -        self._in_binds = [] -        self._in_connects = [] -        self._in_sockopts = [] -        self._out_binds = [] -        self._out_connects = [] -        self._out_sockopts = [] -        self.daemon = True -        self.done = False -     -    def bind_in(self, addr): -        """Enqueue ZMQ address for binding on in_socket. - -        See zmq.Socket.bind for details. -        """ -        self._in_binds.append(addr) -     -    def connect_in(self, addr): -        """Enqueue ZMQ address for connecting on in_socket. - -        See zmq.Socket.connect for details. -        """ -        self._in_connects.append(addr) -     -    def setsockopt_in(self, opt, value): -        """Enqueue setsockopt(opt, value) for in_socket - -        See zmq.Socket.setsockopt for details. -        """ -        self._in_sockopts.append((opt, value)) -     -    def bind_out(self, addr): -        """Enqueue ZMQ address for binding on out_socket. - -        See zmq.Socket.bind for details. -        """ -        self._out_binds.append(addr) -     -    def connect_out(self, addr): -        """Enqueue ZMQ address for connecting on out_socket. - -        See zmq.Socket.connect for details. -        """ -        self._out_connects.append(addr) -     -    def setsockopt_out(self, opt, value): -        """Enqueue setsockopt(opt, value) for out_socket - -        See zmq.Socket.setsockopt for details. -        """ -        self._out_sockopts.append((opt, value)) -     -    def _setup_sockets(self): -        ctx = self.context_factory() -         -        self._context = ctx -         -        # create the sockets -        ins = ctx.socket(self.in_type) -        if self.out_type < 0: -            outs = ins -        else: -            outs = ctx.socket(self.out_type) -         -        # set sockopts (must be done first, in case of zmq.IDENTITY) -        for opt,value in self._in_sockopts: -            ins.setsockopt(opt, value) -        for opt,value in self._out_sockopts: -            outs.setsockopt(opt, value) -         -        for iface in self._in_binds: -            ins.bind(iface) -        for iface in self._out_binds: -            outs.bind(iface) -         -        for iface in self._in_connects: -            ins.connect(iface) -        for iface in self._out_connects: -            outs.connect(iface) -         -        return ins,outs -     -    def run_device(self): -        """The runner method. - -        Do not call me directly, instead call ``self.start()``, just like a Thread. -        """ -        ins,outs = self._setup_sockets() -        device(self.device_type, ins, outs) -     -    def run(self): -        """wrap run_device in try/catch ETERM""" -        try: -            self.run_device() -        except ZMQError as e: -            if e.errno == ETERM: -                # silence TERM errors, because this should be a clean shutdown -                pass -            else: -                raise -        finally: -            self.done = True -     -    def start(self): -        """Start the device. Override me in subclass for other launchers.""" -        return self.run() - -    def join(self,timeout=None): -        """wait for me to finish, like Thread.join. -         -        Reimplemented appropriately by subclasses.""" -        tic = time.time() -        toc = tic -        while not self.done and not (timeout is not None and toc-tic > timeout): -            time.sleep(.001) -            toc = time.time() - - -class BackgroundDevice(Device): -    """Base class for launching Devices in background processes and threads.""" - -    launcher=None -    _launch_class=None - -    def start(self): -        self.launcher = self._launch_class(target=self.run) -        self.launcher.daemon = self.daemon -        return self.launcher.start() - -    def join(self, timeout=None): -        return self.launcher.join(timeout=timeout) - - -class ThreadDevice(BackgroundDevice): -    """A Device that will be run in a background Thread. - -    See Device for details. -    """ -    _launch_class=Thread - -class ProcessDevice(BackgroundDevice): -    """A Device that will be run in a background Process. - -    See Device for details. -    """ -    _launch_class=Process -    context_factory = Context -    """Callable that returns a context. Typically either Context.instance or Context, -    depending on whether the device should share the global instance or not. -    """ - - -__all__ = ['Device', 'ThreadDevice', 'ProcessDevice'] diff --git a/zmq/devices/monitoredqueue.pxd b/zmq/devices/monitoredqueue.pxd deleted file mode 100644 index 1e26ed8..0000000 --- a/zmq/devices/monitoredqueue.pxd +++ /dev/null @@ -1,177 +0,0 @@ -"""MonitoredQueue class declarations. - -Authors -------- -* MinRK -* Brian Granger -""" - -# -#    Copyright (c) 2010 Min Ragan-Kelley, Brian Granger -# -#    This file is part of pyzmq, but is derived and adapted from zmq_queue.cpp -#    originally from libzmq-2.1.6, used under LGPLv3 -# -#    pyzmq 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. -# -#    pyzmq 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 <http://www.gnu.org/licenses/>. -# - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from libzmq cimport * - -#----------------------------------------------------------------------------- -# MonitoredQueue C functions -#----------------------------------------------------------------------------- - -cdef inline int _relay(void *insocket_, void *outsocket_, void *sidesocket_,  -                zmq_msg_t msg, zmq_msg_t side_msg, zmq_msg_t id_msg, -                bint swap_ids) nogil: -    cdef int rc -    cdef int64_t flag_2 -    cdef int flag_3 -    cdef int flags -    cdef bint more -    cdef size_t flagsz -    cdef void * flag_ptr -     -    if ZMQ_VERSION_MAJOR < 3: -        flagsz = sizeof (int64_t) -        flag_ptr = &flag_2 -    else: -        flagsz = sizeof (int) -        flag_ptr = &flag_3 -     -    if swap_ids:# both router, must send second identity first -        # recv two ids into msg, id_msg -        rc = zmq_msg_recv(&msg, insocket_, 0) -        if rc < 0: return rc -         -        rc = zmq_msg_recv(&id_msg, insocket_, 0) -        if rc < 0: return rc - -        # send second id (id_msg) first -        #!!!! always send a copy before the original !!!! -        rc = zmq_msg_copy(&side_msg, &id_msg) -        if rc < 0: return rc -        rc = zmq_msg_send(&side_msg, outsocket_, ZMQ_SNDMORE) -        if rc < 0: return rc -        rc = zmq_msg_send(&id_msg, sidesocket_, ZMQ_SNDMORE) -        if rc < 0: return rc -        # send first id (msg) second -        rc = zmq_msg_copy(&side_msg, &msg) -        if rc < 0: return rc -        rc = zmq_msg_send(&side_msg, outsocket_, ZMQ_SNDMORE) -        if rc < 0: return rc -        rc = zmq_msg_send(&msg, sidesocket_, ZMQ_SNDMORE) -        if rc < 0: return rc -    while (True): -        rc = zmq_msg_recv(&msg, insocket_, 0) -        if rc < 0: return rc -        # assert (rc == 0) -        rc = zmq_getsockopt (insocket_, ZMQ_RCVMORE, flag_ptr, &flagsz) -        if rc < 0: return rc -        flags = 0 -        if ZMQ_VERSION_MAJOR < 3: -            if flag_2: -                flags |= ZMQ_SNDMORE -        else: -            if flag_3: -                flags |= ZMQ_SNDMORE -            # LABEL has been removed: -            # rc = zmq_getsockopt (insocket_, ZMQ_RCVLABEL, flag_ptr, &flagsz) -            # if flag_3: -            #     flags |= ZMQ_SNDLABEL -        # assert (rc == 0) - -        rc = zmq_msg_copy(&side_msg, &msg) -        if rc < 0: return rc -        if flags: -            rc = zmq_msg_send(&side_msg, outsocket_, flags) -            if rc < 0: return rc -            # only SNDMORE for side-socket -            rc = zmq_msg_send(&msg, sidesocket_, ZMQ_SNDMORE) -            if rc < 0: return rc -        else: -            rc = zmq_msg_send(&side_msg, outsocket_, 0) -            if rc < 0: return rc -            rc = zmq_msg_send(&msg, sidesocket_, 0) -            if rc < 0: return rc -            break -    return rc - -# the MonitoredQueue C function, adapted from zmq::queue.cpp : -cdef inline int c_monitored_queue (void *insocket_, void *outsocket_, -                        void *sidesocket_, zmq_msg_t *in_msg_ptr,  -                        zmq_msg_t *out_msg_ptr, int swap_ids) nogil: -    """The actual C function for a monitored queue device.  - -    See ``monitored_queue()`` for details. -    """ -     -    cdef zmq_msg_t msg -    cdef int rc = zmq_msg_init (&msg) -    cdef zmq_msg_t id_msg -    rc = zmq_msg_init (&id_msg) -    if rc < 0: return rc -    cdef zmq_msg_t side_msg -    rc = zmq_msg_init (&side_msg) -    if rc < 0: return rc -     -    cdef zmq_pollitem_t items [2] -    items [0].socket = insocket_ -    items [0].fd = 0 -    items [0].events = ZMQ_POLLIN -    items [0].revents = 0 -    items [1].socket = outsocket_ -    items [1].fd = 0 -    items [1].events = ZMQ_POLLIN -    items [1].revents = 0 -    # I don't think sidesocket should be polled? -    # items [2].socket = sidesocket_ -    # items [2].fd = 0 -    # items [2].events = ZMQ_POLLIN -    # items [2].revents = 0 -     -    while (True): -     -        # //  Wait while there are either requests or replies to process. -        rc = zmq_poll (&items [0], 2, -1) -        if rc < 0: return rc -        # //  The algorithm below asumes ratio of request and replies processed -        # //  under full load to be 1:1. Although processing requests replies -        # //  first is tempting it is suspectible to DoS attacks (overloading -        # //  the system with unsolicited replies). -        #  -        # //  Process a request. -        if (items [0].revents & ZMQ_POLLIN): -            # send in_prefix to side socket -            rc = zmq_msg_copy(&side_msg, in_msg_ptr) -            if rc < 0: return rc -            rc = zmq_msg_send(&side_msg, sidesocket_, ZMQ_SNDMORE) -            if rc < 0: return rc -            # relay the rest of the message -            rc = _relay(insocket_, outsocket_, sidesocket_, msg, side_msg, id_msg, swap_ids) -            if rc < 0: return rc -        if (items [1].revents & ZMQ_POLLIN): -            # send out_prefix to side socket -            rc = zmq_msg_copy(&side_msg, out_msg_ptr) -            if rc < 0: return rc -            rc = zmq_msg_send(&side_msg, sidesocket_, ZMQ_SNDMORE) -            if rc < 0: return rc -            # relay the rest of the message -            rc = _relay(outsocket_, insocket_, sidesocket_, msg, side_msg, id_msg, swap_ids) -            if rc < 0: return rc -    return rc diff --git a/zmq/devices/monitoredqueue.py b/zmq/devices/monitoredqueue.py deleted file mode 100644 index c6d9142..0000000 --- a/zmq/devices/monitoredqueue.py +++ /dev/null @@ -1,37 +0,0 @@ -"""pure Python monitored_queue function - -For use when Cython extension is unavailable (PyPy). - -Authors -------- -* MinRK -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import zmq - -def _relay(ins, outs, sides, prefix, swap_ids): -    msg = ins.recv_multipart() -    if swap_ids: -        msg[:2] = msg[:2][::-1] -    outs.send_multipart(msg) -    sides.send_multipart([prefix] + msg) - -def monitored_queue(in_socket, out_socket, mon_socket, -                    in_prefix=b'in', out_prefix=b'out'): -     -    swap_ids = in_socket.type == zmq.ROUTER and out_socket.type == zmq.ROUTER -     -    poller = zmq.Poller() -    poller.register(in_socket, zmq.POLLIN) -    poller.register(out_socket, zmq.POLLIN) -    while True: -        events = dict(poller.poll()) -        if in_socket in events: -            _relay(in_socket, out_socket, mon_socket, in_prefix, swap_ids) -        if out_socket in events: -            _relay(out_socket, in_socket, mon_socket, out_prefix, swap_ids) - -__all__ = ['monitored_queue'] diff --git a/zmq/devices/monitoredqueue.pyx b/zmq/devices/monitoredqueue.pyx deleted file mode 100644 index d5fec64..0000000 --- a/zmq/devices/monitoredqueue.pyx +++ /dev/null @@ -1,103 +0,0 @@ -"""MonitoredQueue classes and functions. - -Authors -------- -* MinRK -* Brian Granger -""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010-2012 Brian Granger, Min Ragan-Kelley -# -#  This file is part of pyzmq -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -cdef extern from "Python.h": -    ctypedef int Py_ssize_t - -from libc.string cimport memcpy - -from buffers cimport asbuffer_r -from libzmq cimport * - -from zmq.backend.cython.socket cimport Socket -from zmq.backend.cython.checkrc cimport _check_rc - -from zmq import ROUTER, ZMQError - -#----------------------------------------------------------------------------- -# MonitoredQueue functions -#----------------------------------------------------------------------------- - - -def monitored_queue(Socket in_socket, Socket out_socket, Socket mon_socket, -                    bytes in_prefix=b'in', bytes out_prefix=b'out'): -    """monitored_queue(in_socket, out_socket, mon_socket, -                       in_prefix=b'in', out_prefix=b'out') -     -    Start a monitored queue device. -     -    A monitored queue is very similar to the zmq.proxy device (monitored queue came first). -     -    Differences from zmq.proxy: -     -    - monitored_queue supports both in and out being ROUTER sockets -      (via swapping IDENTITY prefixes). -    - monitor messages are prefixed, making in and out messages distinguishable. -     -    Parameters -    ---------- -    in_socket : Socket -        One of the sockets to the Queue. Its messages will be prefixed with -        'in'. -    out_socket : Socket -        One of the sockets to the Queue. Its messages will be prefixed with -        'out'. The only difference between in/out socket is this prefix. -    mon_socket : Socket -        This socket sends out every message received by each of the others -        with an in/out prefix specifying which one it was. -    in_prefix : str -        Prefix added to broadcast messages from in_socket. -    out_prefix : str -        Prefix added to broadcast messages from out_socket. -    """ -     -    cdef void *ins=in_socket.handle -    cdef void *outs=out_socket.handle -    cdef void *mons=mon_socket.handle -    cdef zmq_msg_t in_msg -    cdef zmq_msg_t out_msg -    cdef bint swap_ids -    cdef char *msg_c = NULL -    cdef Py_ssize_t msg_c_len -    cdef int rc - -    # force swap_ids if both ROUTERs -    swap_ids = (in_socket.type == ROUTER and out_socket.type == ROUTER) -     -    # build zmq_msg objects from str prefixes -    asbuffer_r(in_prefix, <void **>&msg_c, &msg_c_len) -    rc = zmq_msg_init_size(&in_msg, msg_c_len) -    _check_rc(rc) -     -    memcpy(zmq_msg_data(&in_msg), msg_c, zmq_msg_size(&in_msg)) -     -    asbuffer_r(out_prefix, <void **>&msg_c, &msg_c_len) -     -    rc = zmq_msg_init_size(&out_msg, msg_c_len) -    _check_rc(rc) -     -    with nogil: -        memcpy(zmq_msg_data(&out_msg), msg_c, zmq_msg_size(&out_msg)) -        rc = c_monitored_queue(ins, outs, mons, &in_msg, &out_msg, swap_ids) -    _check_rc(rc) -    return rc - -__all__ = ['monitored_queue'] diff --git a/zmq/devices/monitoredqueuedevice.py b/zmq/devices/monitoredqueuedevice.py deleted file mode 100644 index 9723f86..0000000 --- a/zmq/devices/monitoredqueuedevice.py +++ /dev/null @@ -1,66 +0,0 @@ -"""MonitoredQueue classes and functions.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -from zmq import ZMQError, PUB -from zmq.devices.proxydevice import ProxyBase, Proxy, ThreadProxy, ProcessProxy -from zmq.devices.monitoredqueue import monitored_queue - - -class MonitoredQueueBase(ProxyBase): -    """Base class for overriding methods.""" -     -    _in_prefix = b'' -    _out_prefix = b'' -     -    def __init__(self, in_type, out_type, mon_type=PUB, in_prefix=b'in', out_prefix=b'out'): -         -        ProxyBase.__init__(self, in_type=in_type, out_type=out_type, mon_type=mon_type) -         -        self._in_prefix = in_prefix -        self._out_prefix = out_prefix - -    def run_device(self): -        ins,outs,mons = self._setup_sockets() -        monitored_queue(ins, outs, mons, self._in_prefix, self._out_prefix) - - -class MonitoredQueue(MonitoredQueueBase, Proxy): -    """Class for running monitored_queue in the background. - -    See zmq.devices.Device for most of the spec. MonitoredQueue differs from Proxy, -    only in that it adds a ``prefix`` to messages sent on the monitor socket, -    with a different prefix for each direction. -     -    MQ also supports ROUTER on both sides, which zmq.proxy does not. - -    If a message arrives on `in_sock`, it will be prefixed with `in_prefix` on the monitor socket. -    If it arrives on out_sock, it will be prefixed with `out_prefix`. - -    A PUB socket is the most logical choice for the mon_socket, but it is not required. -    """ -    pass - - -class ThreadMonitoredQueue(MonitoredQueueBase, ThreadProxy): -    """Run zmq.monitored_queue in a background thread. -     -    See MonitoredQueue and Proxy for details. -    """ -    pass - - -class ProcessMonitoredQueue(MonitoredQueueBase, ProcessProxy): -    """Run zmq.monitored_queue in a background thread. -     -    See MonitoredQueue and Proxy for details. -    """ - - -__all__ = [ -    'MonitoredQueue', -    'ThreadMonitoredQueue', -    'ProcessMonitoredQueue' -] diff --git a/zmq/devices/proxydevice.py b/zmq/devices/proxydevice.py deleted file mode 100644 index 68be3f1..0000000 --- a/zmq/devices/proxydevice.py +++ /dev/null @@ -1,90 +0,0 @@ -"""Proxy classes and functions.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import zmq -from zmq.devices.basedevice import Device, ThreadDevice, ProcessDevice - - -class ProxyBase(object): -    """Base class for overriding methods.""" -     -    def __init__(self, in_type, out_type, mon_type=zmq.PUB): -         -        Device.__init__(self, in_type=in_type, out_type=out_type) -        self.mon_type = mon_type -        self._mon_binds = [] -        self._mon_connects = [] -        self._mon_sockopts = [] - -    def bind_mon(self, addr): -        """Enqueue ZMQ address for binding on mon_socket. - -        See zmq.Socket.bind for details. -        """ -        self._mon_binds.append(addr) - -    def connect_mon(self, addr): -        """Enqueue ZMQ address for connecting on mon_socket. - -        See zmq.Socket.bind for details. -        """ -        self._mon_connects.append(addr) - -    def setsockopt_mon(self, opt, value): -        """Enqueue setsockopt(opt, value) for mon_socket - -        See zmq.Socket.setsockopt for details. -        """ -        self._mon_sockopts.append((opt, value)) - -    def _setup_sockets(self): -        ins,outs = Device._setup_sockets(self) -        ctx = self._context -        mons = ctx.socket(self.mon_type) -         -        # set sockopts (must be done first, in case of zmq.IDENTITY) -        for opt,value in self._mon_sockopts: -            mons.setsockopt(opt, value) -         -        for iface in self._mon_binds: -            mons.bind(iface) -         -        for iface in self._mon_connects: -            mons.connect(iface) -         -        return ins,outs,mons -     -    def run_device(self): -        ins,outs,mons = self._setup_sockets() -        zmq.proxy(ins, outs, mons) - -class Proxy(ProxyBase, Device): -    """Threadsafe Proxy object. - -    See zmq.devices.Device for most of the spec. This subclass adds a -    <method>_mon version of each <method>_{in|out} method, for configuring the -    monitor socket. - -    A Proxy is a 3-socket ZMQ Device that functions just like a -    QUEUE, except each message is also sent out on the monitor socket. - -    A PUB socket is the most logical choice for the mon_socket, but it is not required. -    """ -    pass - -class ThreadProxy(ProxyBase, ThreadDevice): -    """Proxy in a Thread. See Proxy for more.""" -    pass - -class ProcessProxy(ProxyBase, ProcessDevice): -    """Proxy in a Process. See Proxy for more.""" -    pass - - -__all__ = [ -    'Proxy', -    'ThreadProxy', -    'ProcessProxy', -] diff --git a/zmq/error.py b/zmq/error.py deleted file mode 100644 index 48cdaaf..0000000 --- a/zmq/error.py +++ /dev/null @@ -1,164 +0,0 @@ -"""0MQ Error classes and functions.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -class ZMQBaseError(Exception): -    """Base exception class for 0MQ errors in Python.""" -    pass - -class ZMQError(ZMQBaseError): -    """Wrap an errno style error. - -    Parameters -    ---------- -    errno : int -        The ZMQ errno or None.  If None, then ``zmq_errno()`` is called and -        used. -    msg : string -        Description of the error or None. -    """ -    errno = None - -    def __init__(self, errno=None, msg=None): -        """Wrap an errno style error. - -        Parameters -        ---------- -        errno : int -            The ZMQ errno or None.  If None, then ``zmq_errno()`` is called and -            used. -        msg : string -            Description of the error or None. -        """ -        from zmq.backend import strerror, zmq_errno -        if errno is None: -            errno = zmq_errno() -        if isinstance(errno, int): -            self.errno = errno -            if msg is None: -                self.strerror = strerror(errno) -            else: -                self.strerror = msg -        else: -            if msg is None: -                self.strerror = str(errno) -            else: -                self.strerror = msg -        # flush signals, because there could be a SIGINT -        # waiting to pounce, resulting in uncaught exceptions. -        # Doing this here means getting SIGINT during a blocking -        # libzmq call will raise a *catchable* KeyboardInterrupt -        # PyErr_CheckSignals() - -    def __str__(self): -        return self.strerror -     -    def __repr__(self): -        return "ZMQError('%s')"%self.strerror - - -class ZMQBindError(ZMQBaseError): -    """An error for ``Socket.bind_to_random_port()``. -     -    See Also -    -------- -    .Socket.bind_to_random_port -    """ -    pass - - -class NotDone(ZMQBaseError): -    """Raised when timeout is reached while waiting for 0MQ to finish with a Message -     -    See Also -    -------- -    .MessageTracker.wait : object for tracking when ZeroMQ is done -    """ -    pass - - -class ContextTerminated(ZMQError): -    """Wrapper for zmq.ETERM -     -    .. versionadded:: 13.0 -    """ -    pass - - -class Again(ZMQError): -    """Wrapper for zmq.EAGAIN -     -    .. versionadded:: 13.0 -    """ -    pass - - -def _check_rc(rc, errno=None): -    """internal utility for checking zmq return condition -     -    and raising the appropriate Exception class -    """ -    if rc < 0: -        from zmq.backend import zmq_errno -        if errno is None: -            errno = zmq_errno() -        from zmq import EAGAIN, ETERM -        if errno == EAGAIN: -            raise Again(errno) -        elif errno == ETERM: -            raise ContextTerminated(errno) -        else: -            raise ZMQError(errno) - -_zmq_version_info = None -_zmq_version = None - -class ZMQVersionError(NotImplementedError): -    """Raised when a feature is not provided by the linked version of libzmq. -     -    .. versionadded:: 14.2 -    """ -    min_version = None -    def __init__(self, min_version, msg='Feature'): -        global _zmq_version -        if _zmq_version is None: -            from zmq import zmq_version -            _zmq_version = zmq_version() -        self.msg = msg -        self.min_version = min_version -        self.version = _zmq_version -     -    def __repr__(self): -        return "ZMQVersionError('%s')" % str(self) -     -    def __str__(self): -        return "%s requires libzmq >= %s, have %s" % (self.msg, self.min_version, self.version) - - -def _check_version(min_version_info, msg='Feature'): -    """Check for libzmq -     -    raises ZMQVersionError if current zmq version is not at least min_version -     -    min_version_info is a tuple of integers, and will be compared against zmq.zmq_version_info(). -    """ -    global _zmq_version_info -    if _zmq_version_info is None: -        from zmq import zmq_version_info -        _zmq_version_info = zmq_version_info() -    if _zmq_version_info < min_version_info: -        min_version = '.'.join(str(v) for v in min_version_info) -        raise ZMQVersionError(min_version, msg) - - -__all__ = [ -    'ZMQBaseError', -    'ZMQBindError', -    'ZMQError', -    'NotDone', -    'ContextTerminated', -    'Again', -    'ZMQVersionError', -] diff --git a/zmq/eventloop/__init__.py b/zmq/eventloop/__init__.py deleted file mode 100644 index 568e8e8..0000000 --- a/zmq/eventloop/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""A Tornado based event loop for PyZMQ.""" - -from zmq.eventloop.ioloop import IOLoop - -__all__ = ['IOLoop']
\ No newline at end of file diff --git a/zmq/eventloop/ioloop.py b/zmq/eventloop/ioloop.py deleted file mode 100644 index 35f4c41..0000000 --- a/zmq/eventloop/ioloop.py +++ /dev/null @@ -1,193 +0,0 @@ -# coding: utf-8 -"""tornado IOLoop API with zmq compatibility - -If you have tornado ≥ 3.0, this is a subclass of tornado's IOLoop, -otherwise we ship a minimal subset of tornado in zmq.eventloop.minitornado. - -The minimal shipped version of tornado's IOLoop does not include -support for concurrent futures - this will only be available if you -have tornado ≥ 3.0. -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from __future__ import absolute_import, division, with_statement - -import os -import time -import warnings - -from zmq import ( -    Poller, -    POLLIN, POLLOUT, POLLERR, -    ZMQError, ETERM, -) - -try: -    import tornado -    tornado_version = tornado.version_info -except (ImportError, AttributeError): -    tornado_version = () - -try: -    # tornado ≥ 3 -    from tornado.ioloop import PollIOLoop, PeriodicCallback -    from tornado.log import gen_log -except ImportError: -    from .minitornado.ioloop import PollIOLoop, PeriodicCallback -    from .minitornado.log import gen_log - - -class DelayedCallback(PeriodicCallback): -    """Schedules the given callback to be called once. - -    The callback is called once, after callback_time milliseconds. - -    `start` must be called after the DelayedCallback is created. -     -    The timeout is calculated from when `start` is called. -    """ -    def __init__(self, callback, callback_time, io_loop=None): -        # PeriodicCallback require callback_time to be positive -        warnings.warn("""DelayedCallback is deprecated. -        Use loop.add_timeout instead.""", DeprecationWarning) -        callback_time = max(callback_time, 1e-3) -        super(DelayedCallback, self).__init__(callback, callback_time, io_loop) -     -    def start(self): -        """Starts the timer.""" -        self._running = True -        self._firstrun = True -        self._next_timeout = time.time() + self.callback_time / 1000.0 -        self.io_loop.add_timeout(self._next_timeout, self._run) -     -    def _run(self): -        if not self._running: return -        self._running = False -        try: -            self.callback() -        except Exception: -            gen_log.error("Error in delayed callback", exc_info=True) - - -class ZMQPoller(object): -    """A poller that can be used in the tornado IOLoop. -     -    This simply wraps a regular zmq.Poller, scaling the timeout -    by 1000, so that it is in seconds rather than milliseconds. -    """ -     -    def __init__(self): -        self._poller = Poller() -     -    @staticmethod -    def _map_events(events): -        """translate IOLoop.READ/WRITE/ERROR event masks into zmq.POLLIN/OUT/ERR""" -        z_events = 0 -        if events & IOLoop.READ: -            z_events |= POLLIN -        if events & IOLoop.WRITE: -            z_events |= POLLOUT -        if events & IOLoop.ERROR: -            z_events |= POLLERR -        return z_events -     -    @staticmethod -    def _remap_events(z_events): -        """translate zmq.POLLIN/OUT/ERR event masks into IOLoop.READ/WRITE/ERROR""" -        events = 0 -        if z_events & POLLIN: -            events |= IOLoop.READ -        if z_events & POLLOUT: -            events |= IOLoop.WRITE -        if z_events & POLLERR: -            events |= IOLoop.ERROR -        return events -     -    def register(self, fd, events): -        return self._poller.register(fd, self._map_events(events)) -     -    def modify(self, fd, events): -        return self._poller.modify(fd, self._map_events(events)) -     -    def unregister(self, fd): -        return self._poller.unregister(fd) -     -    def poll(self, timeout): -        """poll in seconds rather than milliseconds. -         -        Event masks will be IOLoop.READ/WRITE/ERROR -        """ -        z_events = self._poller.poll(1000*timeout) -        return [ (fd,self._remap_events(evt)) for (fd,evt) in z_events ] -     -    def close(self): -        pass - - -class ZMQIOLoop(PollIOLoop): -    """ZMQ subclass of tornado's IOLoop""" -    def initialize(self, impl=None, **kwargs): -        impl = ZMQPoller() if impl is None else impl -        super(ZMQIOLoop, self).initialize(impl=impl, **kwargs) -     -    @staticmethod -    def instance(): -        """Returns a global `IOLoop` instance. -         -        Most applications have a single, global `IOLoop` running on the -        main thread.  Use this method to get this instance from -        another thread.  To get the current thread's `IOLoop`, use `current()`. -        """ -        # install ZMQIOLoop as the active IOLoop implementation -        # when using tornado 3 -        if tornado_version >= (3,): -            PollIOLoop.configure(ZMQIOLoop) -        return PollIOLoop.instance() -     -    def start(self): -        try: -            super(ZMQIOLoop, self).start() -        except ZMQError as e: -            if e.errno == ETERM: -                # quietly return on ETERM -                pass -            else: -                raise e - - -if tornado_version >= (3,0) and tornado_version < (3,1): -    def backport_close(self, all_fds=False): -        """backport IOLoop.close to 3.0 from 3.1 (supports fd.close() method)""" -        from zmq.eventloop.minitornado.ioloop import PollIOLoop as mini_loop -        return mini_loop.close.__get__(self)(all_fds) -    ZMQIOLoop.close = backport_close - - -# public API name -IOLoop = ZMQIOLoop - - -def install(): -    """set the tornado IOLoop instance with the pyzmq IOLoop. -     -    After calling this function, tornado's IOLoop.instance() and pyzmq's -    IOLoop.instance() will return the same object. -     -    An assertion error will be raised if tornado's IOLoop has been initialized -    prior to calling this function. -    """ -    from tornado import ioloop -    # check if tornado's IOLoop is already initialized to something other -    # than the pyzmq IOLoop instance: -    assert (not ioloop.IOLoop.initialized()) or \ -        ioloop.IOLoop.instance() is IOLoop.instance(), "tornado IOLoop already initialized" -     -    if tornado_version >= (3,): -        # tornado 3 has an official API for registering new defaults, yay! -        ioloop.IOLoop.configure(ZMQIOLoop) -    else: -        # we have to set the global instance explicitly -        ioloop.IOLoop._instance = IOLoop.instance() - diff --git a/zmq/eventloop/minitornado/__init__.py b/zmq/eventloop/minitornado/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/zmq/eventloop/minitornado/__init__.py +++ /dev/null diff --git a/zmq/eventloop/minitornado/concurrent.py b/zmq/eventloop/minitornado/concurrent.py deleted file mode 100644 index 519b23d..0000000 --- a/zmq/eventloop/minitornado/concurrent.py +++ /dev/null @@ -1,11 +0,0 @@ -"""pyzmq does not ship tornado's futures, -this just raises informative NotImplementedErrors to avoid having to change too much code. -""" - -class NotImplementedFuture(object): -    def __init__(self, *args, **kwargs): -        raise NotImplementedError("pyzmq does not ship tornado's Futures, " -            "install tornado >= 3.0 for future support." -        ) - -Future = TracebackFuture = NotImplementedFuture diff --git a/zmq/eventloop/minitornado/ioloop.py b/zmq/eventloop/minitornado/ioloop.py deleted file mode 100644 index 710a3ec..0000000 --- a/zmq/eventloop/minitornado/ioloop.py +++ /dev/null @@ -1,829 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009 Facebook -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -#     http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""An I/O event loop for non-blocking sockets. - -Typical applications will use a single `IOLoop` object, in the -`IOLoop.instance` singleton.  The `IOLoop.start` method should usually -be called at the end of the ``main()`` function.  Atypical applications may -use more than one `IOLoop`, such as one `IOLoop` per thread, or per `unittest` -case. - -In addition to I/O events, the `IOLoop` can also schedule time-based events. -`IOLoop.add_timeout` is a non-blocking alternative to `time.sleep`. -""" - -from __future__ import absolute_import, division, print_function, with_statement - -import datetime -import errno -import functools -import heapq -import logging -import numbers -import os -import select -import sys -import threading -import time -import traceback - -from .concurrent import Future, TracebackFuture -from .log import app_log, gen_log -from . import stack_context -from .util import Configurable - -try: -    import signal -except ImportError: -    signal = None - -try: -    import thread  # py2 -except ImportError: -    import _thread as thread  # py3 - -from .platform.auto import set_close_exec, Waker - - -class TimeoutError(Exception): -    pass - - -class IOLoop(Configurable): -    """A level-triggered I/O loop. - -    We use ``epoll`` (Linux) or ``kqueue`` (BSD and Mac OS X) if they -    are available, or else we fall back on select(). If you are -    implementing a system that needs to handle thousands of -    simultaneous connections, you should use a system that supports -    either ``epoll`` or ``kqueue``. - -    Example usage for a simple TCP server:: - -        import errno -        import functools -        import ioloop -        import socket - -        def connection_ready(sock, fd, events): -            while True: -                try: -                    connection, address = sock.accept() -                except socket.error, e: -                    if e.args[0] not in (errno.EWOULDBLOCK, errno.EAGAIN): -                        raise -                    return -                connection.setblocking(0) -                handle_connection(connection, address) - -        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) -        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) -        sock.setblocking(0) -        sock.bind(("", port)) -        sock.listen(128) - -        io_loop = ioloop.IOLoop.instance() -        callback = functools.partial(connection_ready, sock) -        io_loop.add_handler(sock.fileno(), callback, io_loop.READ) -        io_loop.start() - -    """ -    # Constants from the epoll module -    _EPOLLIN = 0x001 -    _EPOLLPRI = 0x002 -    _EPOLLOUT = 0x004 -    _EPOLLERR = 0x008 -    _EPOLLHUP = 0x010 -    _EPOLLRDHUP = 0x2000 -    _EPOLLONESHOT = (1 << 30) -    _EPOLLET = (1 << 31) - -    # Our events map exactly to the epoll events -    NONE = 0 -    READ = _EPOLLIN -    WRITE = _EPOLLOUT -    ERROR = _EPOLLERR | _EPOLLHUP - -    # Global lock for creating global IOLoop instance -    _instance_lock = threading.Lock() - -    _current = threading.local() - -    @staticmethod -    def instance(): -        """Returns a global `IOLoop` instance. - -        Most applications have a single, global `IOLoop` running on the -        main thread.  Use this method to get this instance from -        another thread.  To get the current thread's `IOLoop`, use `current()`. -        """ -        if not hasattr(IOLoop, "_instance"): -            with IOLoop._instance_lock: -                if not hasattr(IOLoop, "_instance"): -                    # New instance after double check -                    IOLoop._instance = IOLoop() -        return IOLoop._instance - -    @staticmethod -    def initialized(): -        """Returns true if the singleton instance has been created.""" -        return hasattr(IOLoop, "_instance") - -    def install(self): -        """Installs this `IOLoop` object as the singleton instance. - -        This is normally not necessary as `instance()` will create -        an `IOLoop` on demand, but you may want to call `install` to use -        a custom subclass of `IOLoop`. -        """ -        assert not IOLoop.initialized() -        IOLoop._instance = self - -    @staticmethod -    def current(): -        """Returns the current thread's `IOLoop`. - -        If an `IOLoop` is currently running or has been marked as current -        by `make_current`, returns that instance.  Otherwise returns -        `IOLoop.instance()`, i.e. the main thread's `IOLoop`. - -        A common pattern for classes that depend on ``IOLoops`` is to use -        a default argument to enable programs with multiple ``IOLoops`` -        but not require the argument for simpler applications:: - -            class MyClass(object): -                def __init__(self, io_loop=None): -                    self.io_loop = io_loop or IOLoop.current() - -        In general you should use `IOLoop.current` as the default when -        constructing an asynchronous object, and use `IOLoop.instance` -        when you mean to communicate to the main thread from a different -        one. -        """ -        current = getattr(IOLoop._current, "instance", None) -        if current is None: -            return IOLoop.instance() -        return current - -    def make_current(self): -        """Makes this the `IOLoop` for the current thread. - -        An `IOLoop` automatically becomes current for its thread -        when it is started, but it is sometimes useful to call -        `make_current` explictly before starting the `IOLoop`, -        so that code run at startup time can find the right -        instance. -        """ -        IOLoop._current.instance = self - -    @staticmethod -    def clear_current(): -        IOLoop._current.instance = None - -    @classmethod -    def configurable_base(cls): -        return IOLoop - -    @classmethod -    def configurable_default(cls): -        # this is the only patch to IOLoop: -        from zmq.eventloop.ioloop import ZMQIOLoop -        return ZMQIOLoop -        # the remainder of this method is unused, -        # but left for preservation reasons -        if hasattr(select, "epoll"): -            from tornado.platform.epoll import EPollIOLoop -            return EPollIOLoop -        if hasattr(select, "kqueue"): -            # Python 2.6+ on BSD or Mac -            from tornado.platform.kqueue import KQueueIOLoop -            return KQueueIOLoop -        from tornado.platform.select import SelectIOLoop -        return SelectIOLoop - -    def initialize(self): -        pass - -    def close(self, all_fds=False): -        """Closes the `IOLoop`, freeing any resources used. - -        If ``all_fds`` is true, all file descriptors registered on the -        IOLoop will be closed (not just the ones created by the -        `IOLoop` itself). - -        Many applications will only use a single `IOLoop` that runs for the -        entire lifetime of the process.  In that case closing the `IOLoop` -        is not necessary since everything will be cleaned up when the -        process exits.  `IOLoop.close` is provided mainly for scenarios -        such as unit tests, which create and destroy a large number of -        ``IOLoops``. - -        An `IOLoop` must be completely stopped before it can be closed.  This -        means that `IOLoop.stop()` must be called *and* `IOLoop.start()` must -        be allowed to return before attempting to call `IOLoop.close()`. -        Therefore the call to `close` will usually appear just after -        the call to `start` rather than near the call to `stop`. - -        .. versionchanged:: 3.1 -           If the `IOLoop` implementation supports non-integer objects -           for "file descriptors", those objects will have their -           ``close`` method when ``all_fds`` is true. -        """ -        raise NotImplementedError() - -    def add_handler(self, fd, handler, events): -        """Registers the given handler to receive the given events for fd. - -        The ``events`` argument is a bitwise or of the constants -        ``IOLoop.READ``, ``IOLoop.WRITE``, and ``IOLoop.ERROR``. - -        When an event occurs, ``handler(fd, events)`` will be run. -        """ -        raise NotImplementedError() - -    def update_handler(self, fd, events): -        """Changes the events we listen for fd.""" -        raise NotImplementedError() - -    def remove_handler(self, fd): -        """Stop listening for events on fd.""" -        raise NotImplementedError() - -    def set_blocking_signal_threshold(self, seconds, action): -        """Sends a signal if the `IOLoop` is blocked for more than -        ``s`` seconds. - -        Pass ``seconds=None`` to disable.  Requires Python 2.6 on a unixy -        platform. - -        The action parameter is a Python signal handler.  Read the -        documentation for the `signal` module for more information. -        If ``action`` is None, the process will be killed if it is -        blocked for too long. -        """ -        raise NotImplementedError() - -    def set_blocking_log_threshold(self, seconds): -        """Logs a stack trace if the `IOLoop` is blocked for more than -        ``s`` seconds. - -        Equivalent to ``set_blocking_signal_threshold(seconds, -        self.log_stack)`` -        """ -        self.set_blocking_signal_threshold(seconds, self.log_stack) - -    def log_stack(self, signal, frame): -        """Signal handler to log the stack trace of the current thread. - -        For use with `set_blocking_signal_threshold`. -        """ -        gen_log.warning('IOLoop blocked for %f seconds in\n%s', -                        self._blocking_signal_threshold, -                        ''.join(traceback.format_stack(frame))) - -    def start(self): -        """Starts the I/O loop. - -        The loop will run until one of the callbacks calls `stop()`, which -        will make the loop stop after the current event iteration completes. -        """ -        raise NotImplementedError() - -    def stop(self): -        """Stop the I/O loop. - -        If the event loop is not currently running, the next call to `start()` -        will return immediately. - -        To use asynchronous methods from otherwise-synchronous code (such as -        unit tests), you can start and stop the event loop like this:: - -          ioloop = IOLoop() -          async_method(ioloop=ioloop, callback=ioloop.stop) -          ioloop.start() - -        ``ioloop.start()`` will return after ``async_method`` has run -        its callback, whether that callback was invoked before or -        after ``ioloop.start``. - -        Note that even after `stop` has been called, the `IOLoop` is not -        completely stopped until `IOLoop.start` has also returned. -        Some work that was scheduled before the call to `stop` may still -        be run before the `IOLoop` shuts down. -        """ -        raise NotImplementedError() - -    def run_sync(self, func, timeout=None): -        """Starts the `IOLoop`, runs the given function, and stops the loop. - -        If the function returns a `.Future`, the `IOLoop` will run -        until the future is resolved.  If it raises an exception, the -        `IOLoop` will stop and the exception will be re-raised to the -        caller. - -        The keyword-only argument ``timeout`` may be used to set -        a maximum duration for the function.  If the timeout expires, -        a `TimeoutError` is raised. - -        This method is useful in conjunction with `tornado.gen.coroutine` -        to allow asynchronous calls in a ``main()`` function:: - -            @gen.coroutine -            def main(): -                # do stuff... - -            if __name__ == '__main__': -                IOLoop.instance().run_sync(main) -        """ -        future_cell = [None] - -        def run(): -            try: -                result = func() -            except Exception: -                future_cell[0] = TracebackFuture() -                future_cell[0].set_exc_info(sys.exc_info()) -            else: -                if isinstance(result, Future): -                    future_cell[0] = result -                else: -                    future_cell[0] = Future() -                    future_cell[0].set_result(result) -            self.add_future(future_cell[0], lambda future: self.stop()) -        self.add_callback(run) -        if timeout is not None: -            timeout_handle = self.add_timeout(self.time() + timeout, self.stop) -        self.start() -        if timeout is not None: -            self.remove_timeout(timeout_handle) -        if not future_cell[0].done(): -            raise TimeoutError('Operation timed out after %s seconds' % timeout) -        return future_cell[0].result() - -    def time(self): -        """Returns the current time according to the `IOLoop`'s clock. - -        The return value is a floating-point number relative to an -        unspecified time in the past. - -        By default, the `IOLoop`'s time function is `time.time`.  However, -        it may be configured to use e.g. `time.monotonic` instead. -        Calls to `add_timeout` that pass a number instead of a -        `datetime.timedelta` should use this function to compute the -        appropriate time, so they can work no matter what time function -        is chosen. -        """ -        return time.time() - -    def add_timeout(self, deadline, callback): -        """Runs the ``callback`` at the time ``deadline`` from the I/O loop. - -        Returns an opaque handle that may be passed to -        `remove_timeout` to cancel. - -        ``deadline`` may be a number denoting a time (on the same -        scale as `IOLoop.time`, normally `time.time`), or a -        `datetime.timedelta` object for a deadline relative to the -        current time. - -        Note that it is not safe to call `add_timeout` from other threads. -        Instead, you must use `add_callback` to transfer control to the -        `IOLoop`'s thread, and then call `add_timeout` from there. -        """ -        raise NotImplementedError() - -    def remove_timeout(self, timeout): -        """Cancels a pending timeout. - -        The argument is a handle as returned by `add_timeout`.  It is -        safe to call `remove_timeout` even if the callback has already -        been run. -        """ -        raise NotImplementedError() - -    def add_callback(self, callback, *args, **kwargs): -        """Calls the given callback on the next I/O loop iteration. - -        It is safe to call this method from any thread at any time, -        except from a signal handler.  Note that this is the **only** -        method in `IOLoop` that makes this thread-safety guarantee; all -        other interaction with the `IOLoop` must be done from that -        `IOLoop`'s thread.  `add_callback()` may be used to transfer -        control from other threads to the `IOLoop`'s thread. - -        To add a callback from a signal handler, see -        `add_callback_from_signal`. -        """ -        raise NotImplementedError() - -    def add_callback_from_signal(self, callback, *args, **kwargs): -        """Calls the given callback on the next I/O loop iteration. - -        Safe for use from a Python signal handler; should not be used -        otherwise. - -        Callbacks added with this method will be run without any -        `.stack_context`, to avoid picking up the context of the function -        that was interrupted by the signal. -        """ -        raise NotImplementedError() - -    def add_future(self, future, callback): -        """Schedules a callback on the ``IOLoop`` when the given -        `.Future` is finished. - -        The callback is invoked with one argument, the -        `.Future`. -        """ -        assert isinstance(future, Future) -        callback = stack_context.wrap(callback) -        future.add_done_callback( -            lambda future: self.add_callback(callback, future)) - -    def _run_callback(self, callback): -        """Runs a callback with error handling. - -        For use in subclasses. -        """ -        try: -            callback() -        except Exception: -            self.handle_callback_exception(callback) - -    def handle_callback_exception(self, callback): -        """This method is called whenever a callback run by the `IOLoop` -        throws an exception. - -        By default simply logs the exception as an error.  Subclasses -        may override this method to customize reporting of exceptions. - -        The exception itself is not passed explicitly, but is available -        in `sys.exc_info`. -        """ -        app_log.error("Exception in callback %r", callback, exc_info=True) - - -class PollIOLoop(IOLoop): -    """Base class for IOLoops built around a select-like function. - -    For concrete implementations, see `tornado.platform.epoll.EPollIOLoop` -    (Linux), `tornado.platform.kqueue.KQueueIOLoop` (BSD and Mac), or -    `tornado.platform.select.SelectIOLoop` (all platforms). -    """ -    def initialize(self, impl, time_func=None): -        super(PollIOLoop, self).initialize() -        self._impl = impl -        if hasattr(self._impl, 'fileno'): -            set_close_exec(self._impl.fileno()) -        self.time_func = time_func or time.time -        self._handlers = {} -        self._events = {} -        self._callbacks = [] -        self._callback_lock = threading.Lock() -        self._timeouts = [] -        self._cancellations = 0 -        self._running = False -        self._stopped = False -        self._closing = False -        self._thread_ident = None -        self._blocking_signal_threshold = None - -        # Create a pipe that we send bogus data to when we want to wake -        # the I/O loop when it is idle -        self._waker = Waker() -        self.add_handler(self._waker.fileno(), -                         lambda fd, events: self._waker.consume(), -                         self.READ) - -    def close(self, all_fds=False): -        with self._callback_lock: -            self._closing = True -        self.remove_handler(self._waker.fileno()) -        if all_fds: -            for fd in self._handlers.keys(): -                try: -                    close_method = getattr(fd, 'close', None) -                    if close_method is not None: -                        close_method() -                    else: -                        os.close(fd) -                except Exception: -                    gen_log.debug("error closing fd %s", fd, exc_info=True) -        self._waker.close() -        self._impl.close() - -    def add_handler(self, fd, handler, events): -        self._handlers[fd] = stack_context.wrap(handler) -        self._impl.register(fd, events | self.ERROR) - -    def update_handler(self, fd, events): -        self._impl.modify(fd, events | self.ERROR) - -    def remove_handler(self, fd): -        self._handlers.pop(fd, None) -        self._events.pop(fd, None) -        try: -            self._impl.unregister(fd) -        except Exception: -            gen_log.debug("Error deleting fd from IOLoop", exc_info=True) - -    def set_blocking_signal_threshold(self, seconds, action): -        if not hasattr(signal, "setitimer"): -            gen_log.error("set_blocking_signal_threshold requires a signal module " -                          "with the setitimer method") -            return -        self._blocking_signal_threshold = seconds -        if seconds is not None: -            signal.signal(signal.SIGALRM, -                          action if action is not None else signal.SIG_DFL) - -    def start(self): -        if not logging.getLogger().handlers: -            # The IOLoop catches and logs exceptions, so it's -            # important that log output be visible.  However, python's -            # default behavior for non-root loggers (prior to python -            # 3.2) is to print an unhelpful "no handlers could be -            # found" message rather than the actual log entry, so we -            # must explicitly configure logging if we've made it this -            # far without anything. -            logging.basicConfig() -        if self._stopped: -            self._stopped = False -            return -        old_current = getattr(IOLoop._current, "instance", None) -        IOLoop._current.instance = self -        self._thread_ident = thread.get_ident() -        self._running = True - -        # signal.set_wakeup_fd closes a race condition in event loops: -        # a signal may arrive at the beginning of select/poll/etc -        # before it goes into its interruptible sleep, so the signal -        # will be consumed without waking the select.  The solution is -        # for the (C, synchronous) signal handler to write to a pipe, -        # which will then be seen by select. -        # -        # In python's signal handling semantics, this only matters on the -        # main thread (fortunately, set_wakeup_fd only works on the main -        # thread and will raise a ValueError otherwise). -        # -        # If someone has already set a wakeup fd, we don't want to -        # disturb it.  This is an issue for twisted, which does its -        # SIGCHILD processing in response to its own wakeup fd being -        # written to.  As long as the wakeup fd is registered on the IOLoop, -        # the loop will still wake up and everything should work. -        old_wakeup_fd = None -        if hasattr(signal, 'set_wakeup_fd') and os.name == 'posix': -            # requires python 2.6+, unix.  set_wakeup_fd exists but crashes -            # the python process on windows. -            try: -                old_wakeup_fd = signal.set_wakeup_fd(self._waker.write_fileno()) -                if old_wakeup_fd != -1: -                    # Already set, restore previous value.  This is a little racy, -                    # but there's no clean get_wakeup_fd and in real use the -                    # IOLoop is just started once at the beginning. -                    signal.set_wakeup_fd(old_wakeup_fd) -                    old_wakeup_fd = None -            except ValueError:  # non-main thread -                pass - -        while True: -            poll_timeout = 3600.0 - -            # Prevent IO event starvation by delaying new callbacks -            # to the next iteration of the event loop. -            with self._callback_lock: -                callbacks = self._callbacks -                self._callbacks = [] -            for callback in callbacks: -                self._run_callback(callback) - -            if self._timeouts: -                now = self.time() -                while self._timeouts: -                    if self._timeouts[0].callback is None: -                        # the timeout was cancelled -                        heapq.heappop(self._timeouts) -                        self._cancellations -= 1 -                    elif self._timeouts[0].deadline <= now: -                        timeout = heapq.heappop(self._timeouts) -                        self._run_callback(timeout.callback) -                    else: -                        seconds = self._timeouts[0].deadline - now -                        poll_timeout = min(seconds, poll_timeout) -                        break -                if (self._cancellations > 512 -                        and self._cancellations > (len(self._timeouts) >> 1)): -                    # Clean up the timeout queue when it gets large and it's -                    # more than half cancellations. -                    self._cancellations = 0 -                    self._timeouts = [x for x in self._timeouts -                                      if x.callback is not None] -                    heapq.heapify(self._timeouts) - -            if self._callbacks: -                # If any callbacks or timeouts called add_callback, -                # we don't want to wait in poll() before we run them. -                poll_timeout = 0.0 - -            if not self._running: -                break - -            if self._blocking_signal_threshold is not None: -                # clear alarm so it doesn't fire while poll is waiting for -                # events. -                signal.setitimer(signal.ITIMER_REAL, 0, 0) - -            try: -                event_pairs = self._impl.poll(poll_timeout) -            except Exception as e: -                # Depending on python version and IOLoop implementation, -                # different exception types may be thrown and there are -                # two ways EINTR might be signaled: -                # * e.errno == errno.EINTR -                # * e.args is like (errno.EINTR, 'Interrupted system call') -                if (getattr(e, 'errno', None) == errno.EINTR or -                    (isinstance(getattr(e, 'args', None), tuple) and -                     len(e.args) == 2 and e.args[0] == errno.EINTR)): -                    continue -                else: -                    raise - -            if self._blocking_signal_threshold is not None: -                signal.setitimer(signal.ITIMER_REAL, -                                 self._blocking_signal_threshold, 0) - -            # Pop one fd at a time from the set of pending fds and run -            # its handler. Since that handler may perform actions on -            # other file descriptors, there may be reentrant calls to -            # this IOLoop that update self._events -            self._events.update(event_pairs) -            while self._events: -                fd, events = self._events.popitem() -                try: -                    self._handlers[fd](fd, events) -                except (OSError, IOError) as e: -                    if e.args[0] == errno.EPIPE: -                        # Happens when the client closes the connection -                        pass -                    else: -                        app_log.error("Exception in I/O handler for fd %s", -                                      fd, exc_info=True) -                except Exception: -                    app_log.error("Exception in I/O handler for fd %s", -                                  fd, exc_info=True) -        # reset the stopped flag so another start/stop pair can be issued -        self._stopped = False -        if self._blocking_signal_threshold is not None: -            signal.setitimer(signal.ITIMER_REAL, 0, 0) -        IOLoop._current.instance = old_current -        if old_wakeup_fd is not None: -            signal.set_wakeup_fd(old_wakeup_fd) - -    def stop(self): -        self._running = False -        self._stopped = True -        self._waker.wake() - -    def time(self): -        return self.time_func() - -    def add_timeout(self, deadline, callback): -        timeout = _Timeout(deadline, stack_context.wrap(callback), self) -        heapq.heappush(self._timeouts, timeout) -        return timeout - -    def remove_timeout(self, timeout): -        # Removing from a heap is complicated, so just leave the defunct -        # timeout object in the queue (see discussion in -        # http://docs.python.org/library/heapq.html). -        # If this turns out to be a problem, we could add a garbage -        # collection pass whenever there are too many dead timeouts. -        timeout.callback = None -        self._cancellations += 1 - -    def add_callback(self, callback, *args, **kwargs): -        with self._callback_lock: -            if self._closing: -                raise RuntimeError("IOLoop is closing") -            list_empty = not self._callbacks -            self._callbacks.append(functools.partial( -                stack_context.wrap(callback), *args, **kwargs)) -        if list_empty and thread.get_ident() != self._thread_ident: -            # If we're in the IOLoop's thread, we know it's not currently -            # polling.  If we're not, and we added the first callback to an -            # empty list, we may need to wake it up (it may wake up on its -            # own, but an occasional extra wake is harmless).  Waking -            # up a polling IOLoop is relatively expensive, so we try to -            # avoid it when we can. -            self._waker.wake() - -    def add_callback_from_signal(self, callback, *args, **kwargs): -        with stack_context.NullContext(): -            if thread.get_ident() != self._thread_ident: -                # if the signal is handled on another thread, we can add -                # it normally (modulo the NullContext) -                self.add_callback(callback, *args, **kwargs) -            else: -                # If we're on the IOLoop's thread, we cannot use -                # the regular add_callback because it may deadlock on -                # _callback_lock.  Blindly insert into self._callbacks. -                # This is safe because the GIL makes list.append atomic. -                # One subtlety is that if the signal interrupted the -                # _callback_lock block in IOLoop.start, we may modify -                # either the old or new version of self._callbacks, -                # but either way will work. -                self._callbacks.append(functools.partial( -                    stack_context.wrap(callback), *args, **kwargs)) - - -class _Timeout(object): -    """An IOLoop timeout, a UNIX timestamp and a callback""" - -    # Reduce memory overhead when there are lots of pending callbacks -    __slots__ = ['deadline', 'callback'] - -    def __init__(self, deadline, callback, io_loop): -        if isinstance(deadline, numbers.Real): -            self.deadline = deadline -        elif isinstance(deadline, datetime.timedelta): -            self.deadline = io_loop.time() + _Timeout.timedelta_to_seconds(deadline) -        else: -            raise TypeError("Unsupported deadline %r" % deadline) -        self.callback = callback - -    @staticmethod -    def timedelta_to_seconds(td): -        """Equivalent to td.total_seconds() (introduced in python 2.7).""" -        return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6) / float(10 ** 6) - -    # Comparison methods to sort by deadline, with object id as a tiebreaker -    # to guarantee a consistent ordering.  The heapq module uses __le__ -    # in python2.5, and __lt__ in 2.6+ (sort() and most other comparisons -    # use __lt__). -    def __lt__(self, other): -        return ((self.deadline, id(self)) < -                (other.deadline, id(other))) - -    def __le__(self, other): -        return ((self.deadline, id(self)) <= -                (other.deadline, id(other))) - - -class PeriodicCallback(object): -    """Schedules the given callback to be called periodically. - -    The callback is called every ``callback_time`` milliseconds. - -    `start` must be called after the `PeriodicCallback` is created. -    """ -    def __init__(self, callback, callback_time, io_loop=None): -        self.callback = callback -        if callback_time <= 0: -            raise ValueError("Periodic callback must have a positive callback_time") -        self.callback_time = callback_time -        self.io_loop = io_loop or IOLoop.current() -        self._running = False -        self._timeout = None - -    def start(self): -        """Starts the timer.""" -        self._running = True -        self._next_timeout = self.io_loop.time() -        self._schedule_next() - -    def stop(self): -        """Stops the timer.""" -        self._running = False -        if self._timeout is not None: -            self.io_loop.remove_timeout(self._timeout) -            self._timeout = None - -    def _run(self): -        if not self._running: -            return -        try: -            self.callback() -        except Exception: -            app_log.error("Error in periodic callback", exc_info=True) -        self._schedule_next() - -    def _schedule_next(self): -        if self._running: -            current_time = self.io_loop.time() -            while self._next_timeout <= current_time: -                self._next_timeout += self.callback_time / 1000.0 -            self._timeout = self.io_loop.add_timeout(self._next_timeout, self._run) diff --git a/zmq/eventloop/minitornado/log.py b/zmq/eventloop/minitornado/log.py deleted file mode 100644 index 49051e8..0000000 --- a/zmq/eventloop/minitornado/log.py +++ /dev/null @@ -1,6 +0,0 @@ -"""minimal subset of tornado.log for zmq.eventloop.minitornado""" - -import logging - -app_log = logging.getLogger("tornado.application") -gen_log = logging.getLogger("tornado.general") diff --git a/zmq/eventloop/minitornado/platform/__init__.py b/zmq/eventloop/minitornado/platform/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/zmq/eventloop/minitornado/platform/__init__.py +++ /dev/null diff --git a/zmq/eventloop/minitornado/platform/auto.py b/zmq/eventloop/minitornado/platform/auto.py deleted file mode 100644 index b40ccd9..0000000 --- a/zmq/eventloop/minitornado/platform/auto.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2011 Facebook -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -#     http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Implementation of platform-specific functionality. - -For each function or class described in `tornado.platform.interface`, -the appropriate platform-specific implementation exists in this module. -Most code that needs access to this functionality should do e.g.:: - -    from tornado.platform.auto import set_close_exec -""" - -from __future__ import absolute_import, division, print_function, with_statement - -import os - -if os.name == 'nt': -    from .common import Waker -    from .windows import set_close_exec -else: -    from .posix import set_close_exec, Waker - -try: -    # monotime monkey-patches the time module to have a monotonic function -    # in versions of python before 3.3. -    import monotime -except ImportError: -    pass -try: -    from time import monotonic as monotonic_time -except ImportError: -    monotonic_time = None diff --git a/zmq/eventloop/minitornado/platform/common.py b/zmq/eventloop/minitornado/platform/common.py deleted file mode 100644 index 2d75dc1..0000000 --- a/zmq/eventloop/minitornado/platform/common.py +++ /dev/null @@ -1,91 +0,0 @@ -"""Lowest-common-denominator implementations of platform functionality.""" -from __future__ import absolute_import, division, print_function, with_statement - -import errno -import socket - -from . import interface - - -class Waker(interface.Waker): -    """Create an OS independent asynchronous pipe. - -    For use on platforms that don't have os.pipe() (or where pipes cannot -    be passed to select()), but do have sockets.  This includes Windows -    and Jython. -    """ -    def __init__(self): -        # Based on Zope async.py: http://svn.zope.org/zc.ngi/trunk/src/zc/ngi/async.py - -        self.writer = socket.socket() -        # Disable buffering -- pulling the trigger sends 1 byte, -        # and we want that sent immediately, to wake up ASAP. -        self.writer.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - -        count = 0 -        while 1: -            count += 1 -            # Bind to a local port; for efficiency, let the OS pick -            # a free port for us. -            # Unfortunately, stress tests showed that we may not -            # be able to connect to that port ("Address already in -            # use") despite that the OS picked it.  This appears -            # to be a race bug in the Windows socket implementation. -            # So we loop until a connect() succeeds (almost always -            # on the first try).  See the long thread at -            # http://mail.zope.org/pipermail/zope/2005-July/160433.html -            # for hideous details. -            a = socket.socket() -            a.bind(("127.0.0.1", 0)) -            a.listen(1) -            connect_address = a.getsockname()  # assigned (host, port) pair -            try: -                self.writer.connect(connect_address) -                break    # success -            except socket.error as detail: -                if (not hasattr(errno, 'WSAEADDRINUSE') or -                        detail[0] != errno.WSAEADDRINUSE): -                    # "Address already in use" is the only error -                    # I've seen on two WinXP Pro SP2 boxes, under -                    # Pythons 2.3.5 and 2.4.1. -                    raise -                # (10048, 'Address already in use') -                # assert count <= 2 # never triggered in Tim's tests -                if count >= 10:  # I've never seen it go above 2 -                    a.close() -                    self.writer.close() -                    raise socket.error("Cannot bind trigger!") -                # Close `a` and try again.  Note:  I originally put a short -                # sleep() here, but it didn't appear to help or hurt. -                a.close() - -        self.reader, addr = a.accept() -        self.reader.setblocking(0) -        self.writer.setblocking(0) -        a.close() -        self.reader_fd = self.reader.fileno() - -    def fileno(self): -        return self.reader.fileno() - -    def write_fileno(self): -        return self.writer.fileno() - -    def wake(self): -        try: -            self.writer.send(b"x") -        except (IOError, socket.error): -            pass - -    def consume(self): -        try: -            while True: -                result = self.reader.recv(1024) -                if not result: -                    break -        except (IOError, socket.error): -            pass - -    def close(self): -        self.reader.close() -        self.writer.close() diff --git a/zmq/eventloop/minitornado/platform/interface.py b/zmq/eventloop/minitornado/platform/interface.py deleted file mode 100644 index 07da6ba..0000000 --- a/zmq/eventloop/minitornado/platform/interface.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2011 Facebook -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -#     http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Interfaces for platform-specific functionality. - -This module exists primarily for documentation purposes and as base classes -for other tornado.platform modules.  Most code should import the appropriate -implementation from `tornado.platform.auto`. -""" - -from __future__ import absolute_import, division, print_function, with_statement - - -def set_close_exec(fd): -    """Sets the close-on-exec bit (``FD_CLOEXEC``)for a file descriptor.""" -    raise NotImplementedError() - - -class Waker(object): -    """A socket-like object that can wake another thread from ``select()``. - -    The `~tornado.ioloop.IOLoop` will add the Waker's `fileno()` to -    its ``select`` (or ``epoll`` or ``kqueue``) calls.  When another -    thread wants to wake up the loop, it calls `wake`.  Once it has woken -    up, it will call `consume` to do any necessary per-wake cleanup.  When -    the ``IOLoop`` is closed, it closes its waker too. -    """ -    def fileno(self): -        """Returns the read file descriptor for this waker. - -        Must be suitable for use with ``select()`` or equivalent on the -        local platform. -        """ -        raise NotImplementedError() - -    def write_fileno(self): -        """Returns the write file descriptor for this waker.""" -        raise NotImplementedError() - -    def wake(self): -        """Triggers activity on the waker's file descriptor.""" -        raise NotImplementedError() - -    def consume(self): -        """Called after the listen has woken up to do any necessary cleanup.""" -        raise NotImplementedError() - -    def close(self): -        """Closes the waker's file descriptor(s).""" -        raise NotImplementedError() diff --git a/zmq/eventloop/minitornado/platform/posix.py b/zmq/eventloop/minitornado/platform/posix.py deleted file mode 100644 index ccffbb6..0000000 --- a/zmq/eventloop/minitornado/platform/posix.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2011 Facebook -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -#     http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Posix implementations of platform-specific functionality.""" - -from __future__ import absolute_import, division, print_function, with_statement - -import fcntl -import os - -from . import interface - - -def set_close_exec(fd): -    flags = fcntl.fcntl(fd, fcntl.F_GETFD) -    fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC) - - -def _set_nonblocking(fd): -    flags = fcntl.fcntl(fd, fcntl.F_GETFL) -    fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) - - -class Waker(interface.Waker): -    def __init__(self): -        r, w = os.pipe() -        _set_nonblocking(r) -        _set_nonblocking(w) -        set_close_exec(r) -        set_close_exec(w) -        self.reader = os.fdopen(r, "rb", 0) -        self.writer = os.fdopen(w, "wb", 0) - -    def fileno(self): -        return self.reader.fileno() - -    def write_fileno(self): -        return self.writer.fileno() - -    def wake(self): -        try: -            self.writer.write(b"x") -        except IOError: -            pass - -    def consume(self): -        try: -            while True: -                result = self.reader.read() -                if not result: -                    break -        except IOError: -            pass - -    def close(self): -        self.reader.close() -        self.writer.close() diff --git a/zmq/eventloop/minitornado/platform/windows.py b/zmq/eventloop/minitornado/platform/windows.py deleted file mode 100644 index 817bdca..0000000 --- a/zmq/eventloop/minitornado/platform/windows.py +++ /dev/null @@ -1,20 +0,0 @@ -# NOTE: win32 support is currently experimental, and not recommended -# for production use. - - -from __future__ import absolute_import, division, print_function, with_statement -import ctypes -import ctypes.wintypes - -# See: http://msdn.microsoft.com/en-us/library/ms724935(VS.85).aspx -SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation -SetHandleInformation.argtypes = (ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD, ctypes.wintypes.DWORD) -SetHandleInformation.restype = ctypes.wintypes.BOOL - -HANDLE_FLAG_INHERIT = 0x00000001 - - -def set_close_exec(fd): -    success = SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 0) -    if not success: -        raise ctypes.GetLastError() diff --git a/zmq/eventloop/minitornado/stack_context.py b/zmq/eventloop/minitornado/stack_context.py deleted file mode 100644 index 226d804..0000000 --- a/zmq/eventloop/minitornado/stack_context.py +++ /dev/null @@ -1,376 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 Facebook -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -#     http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""`StackContext` allows applications to maintain threadlocal-like state -that follows execution as it moves to other execution contexts. - -The motivating examples are to eliminate the need for explicit -``async_callback`` wrappers (as in `tornado.web.RequestHandler`), and to -allow some additional context to be kept for logging. - -This is slightly magic, but it's an extension of the idea that an -exception handler is a kind of stack-local state and when that stack -is suspended and resumed in a new context that state needs to be -preserved.  `StackContext` shifts the burden of restoring that state -from each call site (e.g.  wrapping each `.AsyncHTTPClient` callback -in ``async_callback``) to the mechanisms that transfer control from -one context to another (e.g. `.AsyncHTTPClient` itself, `.IOLoop`, -thread pools, etc). - -Example usage:: - -    @contextlib.contextmanager -    def die_on_error(): -        try: -            yield -        except Exception: -            logging.error("exception in asynchronous operation",exc_info=True) -            sys.exit(1) - -    with StackContext(die_on_error): -        # Any exception thrown here *or in callback and its desendents* -        # will cause the process to exit instead of spinning endlessly -        # in the ioloop. -        http_client.fetch(url, callback) -    ioloop.start() - -Most applications shouln't have to work with `StackContext` directly. -Here are a few rules of thumb for when it's necessary: - -* If you're writing an asynchronous library that doesn't rely on a -  stack_context-aware library like `tornado.ioloop` or `tornado.iostream` -  (for example, if you're writing a thread pool), use -  `.stack_context.wrap()` before any asynchronous operations to capture the -  stack context from where the operation was started. - -* If you're writing an asynchronous library that has some shared -  resources (such as a connection pool), create those shared resources -  within a ``with stack_context.NullContext():`` block.  This will prevent -  ``StackContexts`` from leaking from one request to another. - -* If you want to write something like an exception handler that will -  persist across asynchronous calls, create a new `StackContext` (or -  `ExceptionStackContext`), and make your asynchronous calls in a ``with`` -  block that references your `StackContext`. -""" - -from __future__ import absolute_import, division, print_function, with_statement - -import sys -import threading - -from .util import raise_exc_info - - -class StackContextInconsistentError(Exception): -    pass - - -class _State(threading.local): -    def __init__(self): -        self.contexts = (tuple(), None) -_state = _State() - - -class StackContext(object): -    """Establishes the given context as a StackContext that will be transferred. - -    Note that the parameter is a callable that returns a context -    manager, not the context itself.  That is, where for a -    non-transferable context manager you would say:: - -      with my_context(): - -    StackContext takes the function itself rather than its result:: - -      with StackContext(my_context): - -    The result of ``with StackContext() as cb:`` is a deactivation -    callback.  Run this callback when the StackContext is no longer -    needed to ensure that it is not propagated any further (note that -    deactivating a context does not affect any instances of that -    context that are currently pending).  This is an advanced feature -    and not necessary in most applications. -    """ -    def __init__(self, context_factory): -        self.context_factory = context_factory -        self.contexts = [] -        self.active = True - -    def _deactivate(self): -        self.active = False - -    # StackContext protocol -    def enter(self): -        context = self.context_factory() -        self.contexts.append(context) -        context.__enter__() - -    def exit(self, type, value, traceback): -        context = self.contexts.pop() -        context.__exit__(type, value, traceback) - -    # Note that some of this code is duplicated in ExceptionStackContext -    # below.  ExceptionStackContext is more common and doesn't need -    # the full generality of this class. -    def __enter__(self): -        self.old_contexts = _state.contexts -        self.new_contexts = (self.old_contexts[0] + (self,), self) -        _state.contexts = self.new_contexts - -        try: -            self.enter() -        except: -            _state.contexts = self.old_contexts -            raise - -        return self._deactivate - -    def __exit__(self, type, value, traceback): -        try: -            self.exit(type, value, traceback) -        finally: -            final_contexts = _state.contexts -            _state.contexts = self.old_contexts - -            # Generator coroutines and with-statements with non-local -            # effects interact badly.  Check here for signs of -            # the stack getting out of sync. -            # Note that this check comes after restoring _state.context -            # so that if it fails things are left in a (relatively) -            # consistent state. -            if final_contexts is not self.new_contexts: -                raise StackContextInconsistentError( -                    'stack_context inconsistency (may be caused by yield ' -                    'within a "with StackContext" block)') - -            # Break up a reference to itself to allow for faster GC on CPython. -            self.new_contexts = None - - -class ExceptionStackContext(object): -    """Specialization of StackContext for exception handling. - -    The supplied ``exception_handler`` function will be called in the -    event of an uncaught exception in this context.  The semantics are -    similar to a try/finally clause, and intended use cases are to log -    an error, close a socket, or similar cleanup actions.  The -    ``exc_info`` triple ``(type, value, traceback)`` will be passed to the -    exception_handler function. - -    If the exception handler returns true, the exception will be -    consumed and will not be propagated to other exception handlers. -    """ -    def __init__(self, exception_handler): -        self.exception_handler = exception_handler -        self.active = True - -    def _deactivate(self): -        self.active = False - -    def exit(self, type, value, traceback): -        if type is not None: -            return self.exception_handler(type, value, traceback) - -    def __enter__(self): -        self.old_contexts = _state.contexts -        self.new_contexts = (self.old_contexts[0], self) -        _state.contexts = self.new_contexts - -        return self._deactivate - -    def __exit__(self, type, value, traceback): -        try: -            if type is not None: -                return self.exception_handler(type, value, traceback) -        finally: -            final_contexts = _state.contexts -            _state.contexts = self.old_contexts - -            if final_contexts is not self.new_contexts: -                raise StackContextInconsistentError( -                    'stack_context inconsistency (may be caused by yield ' -                    'within a "with StackContext" block)') - -            # Break up a reference to itself to allow for faster GC on CPython. -            self.new_contexts = None - - -class NullContext(object): -    """Resets the `StackContext`. - -    Useful when creating a shared resource on demand (e.g. an -    `.AsyncHTTPClient`) where the stack that caused the creating is -    not relevant to future operations. -    """ -    def __enter__(self): -        self.old_contexts = _state.contexts -        _state.contexts = (tuple(), None) - -    def __exit__(self, type, value, traceback): -        _state.contexts = self.old_contexts - - -def _remove_deactivated(contexts): -    """Remove deactivated handlers from the chain""" -    # Clean ctx handlers -    stack_contexts = tuple([h for h in contexts[0] if h.active]) - -    # Find new head -    head = contexts[1] -    while head is not None and not head.active: -        head = head.old_contexts[1] - -    # Process chain -    ctx = head -    while ctx is not None: -        parent = ctx.old_contexts[1] - -        while parent is not None: -            if parent.active: -                break -            ctx.old_contexts = parent.old_contexts -            parent = parent.old_contexts[1] - -        ctx = parent - -    return (stack_contexts, head) - - -def wrap(fn): -    """Returns a callable object that will restore the current `StackContext` -    when executed. - -    Use this whenever saving a callback to be executed later in a -    different execution context (either in a different thread or -    asynchronously in the same thread). -    """ -    # Check if function is already wrapped -    if fn is None or hasattr(fn, '_wrapped'): -        return fn - -    # Capture current stack head -    # TODO: Any other better way to store contexts and update them in wrapped function? -    cap_contexts = [_state.contexts] - -    def wrapped(*args, **kwargs): -        ret = None -        try: -            # Capture old state -            current_state = _state.contexts - -            # Remove deactivated items -            cap_contexts[0] = contexts = _remove_deactivated(cap_contexts[0]) - -            # Force new state -            _state.contexts = contexts - -            # Current exception -            exc = (None, None, None) -            top = None - -            # Apply stack contexts -            last_ctx = 0 -            stack = contexts[0] - -            # Apply state -            for n in stack: -                try: -                    n.enter() -                    last_ctx += 1 -                except: -                    # Exception happened. Record exception info and store top-most handler -                    exc = sys.exc_info() -                    top = n.old_contexts[1] - -            # Execute callback if no exception happened while restoring state -            if top is None: -                try: -                    ret = fn(*args, **kwargs) -                except: -                    exc = sys.exc_info() -                    top = contexts[1] - -            # If there was exception, try to handle it by going through the exception chain -            if top is not None: -                exc = _handle_exception(top, exc) -            else: -                # Otherwise take shorter path and run stack contexts in reverse order -                while last_ctx > 0: -                    last_ctx -= 1 -                    c = stack[last_ctx] - -                    try: -                        c.exit(*exc) -                    except: -                        exc = sys.exc_info() -                        top = c.old_contexts[1] -                        break -                else: -                    top = None - -                # If if exception happened while unrolling, take longer exception handler path -                if top is not None: -                    exc = _handle_exception(top, exc) - -            # If exception was not handled, raise it -            if exc != (None, None, None): -                raise_exc_info(exc) -        finally: -            _state.contexts = current_state -        return ret - -    wrapped._wrapped = True -    return wrapped - - -def _handle_exception(tail, exc): -    while tail is not None: -        try: -            if tail.exit(*exc): -                exc = (None, None, None) -        except: -            exc = sys.exc_info() - -        tail = tail.old_contexts[1] - -    return exc - - -def run_with_stack_context(context, func): -    """Run a coroutine ``func`` in the given `StackContext`. - -    It is not safe to have a ``yield`` statement within a ``with StackContext`` -    block, so it is difficult to use stack context with `.gen.coroutine`. -    This helper function runs the function in the correct context while -    keeping the ``yield`` and ``with`` statements syntactically separate. - -    Example:: - -        @gen.coroutine -        def incorrect(): -            with StackContext(ctx): -                # ERROR: this will raise StackContextInconsistentError -                yield other_coroutine() - -        @gen.coroutine -        def correct(): -            yield run_with_stack_context(StackContext(ctx), other_coroutine) - -    .. versionadded:: 3.1 -    """ -    with context: -        return func() diff --git a/zmq/eventloop/minitornado/util.py b/zmq/eventloop/minitornado/util.py deleted file mode 100644 index c1e2eb9..0000000 --- a/zmq/eventloop/minitornado/util.py +++ /dev/null @@ -1,184 +0,0 @@ -"""Miscellaneous utility functions and classes. - -This module is used internally by Tornado.  It is not necessarily expected -that the functions and classes defined here will be useful to other -applications, but they are documented here in case they are. - -The one public-facing part of this module is the `Configurable` class -and its `~Configurable.configure` method, which becomes a part of the -interface of its subclasses, including `.AsyncHTTPClient`, `.IOLoop`, -and `.Resolver`. -""" - -from __future__ import absolute_import, division, print_function, with_statement - -import sys - - -def import_object(name): -    """Imports an object by name. - -    import_object('x') is equivalent to 'import x'. -    import_object('x.y.z') is equivalent to 'from x.y import z'. - -    >>> import tornado.escape -    >>> import_object('tornado.escape') is tornado.escape -    True -    >>> import_object('tornado.escape.utf8') is tornado.escape.utf8 -    True -    >>> import_object('tornado') is tornado -    True -    >>> import_object('tornado.missing_module') -    Traceback (most recent call last): -        ... -    ImportError: No module named missing_module -    """ -    if name.count('.') == 0: -        return __import__(name, None, None) - -    parts = name.split('.') -    obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0) -    try: -        return getattr(obj, parts[-1]) -    except AttributeError: -        raise ImportError("No module named %s" % parts[-1]) - - -# Fake unicode literal support:  Python 3.2 doesn't have the u'' marker for -# literal strings, and alternative solutions like "from __future__ import -# unicode_literals" have other problems (see PEP 414).  u() can be applied -# to ascii strings that include \u escapes (but they must not contain -# literal non-ascii characters). -if type('') is not type(b''): -    def u(s): -        return s -    bytes_type = bytes -    unicode_type = str -    basestring_type = str -else: -    def u(s): -        return s.decode('unicode_escape') -    bytes_type = str -    unicode_type = unicode -    basestring_type = basestring - - -if sys.version_info > (3,): -    exec(""" -def raise_exc_info(exc_info): -    raise exc_info[1].with_traceback(exc_info[2]) - -def exec_in(code, glob, loc=None): -    if isinstance(code, str): -        code = compile(code, '<string>', 'exec', dont_inherit=True) -    exec(code, glob, loc) -""") -else: -    exec(""" -def raise_exc_info(exc_info): -    raise exc_info[0], exc_info[1], exc_info[2] - -def exec_in(code, glob, loc=None): -    if isinstance(code, basestring): -        # exec(string) inherits the caller's future imports; compile -        # the string first to prevent that. -        code = compile(code, '<string>', 'exec', dont_inherit=True) -    exec code in glob, loc -""") - - -class Configurable(object): -    """Base class for configurable interfaces. - -    A configurable interface is an (abstract) class whose constructor -    acts as a factory function for one of its implementation subclasses. -    The implementation subclass as well as optional keyword arguments to -    its initializer can be set globally at runtime with `configure`. - -    By using the constructor as the factory method, the interface -    looks like a normal class, `isinstance` works as usual, etc.  This -    pattern is most useful when the choice of implementation is likely -    to be a global decision (e.g. when `~select.epoll` is available, -    always use it instead of `~select.select`), or when a -    previously-monolithic class has been split into specialized -    subclasses. - -    Configurable subclasses must define the class methods -    `configurable_base` and `configurable_default`, and use the instance -    method `initialize` instead of ``__init__``. -    """ -    __impl_class = None -    __impl_kwargs = None - -    def __new__(cls, **kwargs): -        base = cls.configurable_base() -        args = {} -        if cls is base: -            impl = cls.configured_class() -            if base.__impl_kwargs: -                args.update(base.__impl_kwargs) -        else: -            impl = cls -        args.update(kwargs) -        instance = super(Configurable, cls).__new__(impl) -        # initialize vs __init__ chosen for compatiblity with AsyncHTTPClient -        # singleton magic.  If we get rid of that we can switch to __init__ -        # here too. -        instance.initialize(**args) -        return instance - -    @classmethod -    def configurable_base(cls): -        """Returns the base class of a configurable hierarchy. - -        This will normally return the class in which it is defined. -        (which is *not* necessarily the same as the cls classmethod parameter). -        """ -        raise NotImplementedError() - -    @classmethod -    def configurable_default(cls): -        """Returns the implementation class to be used if none is configured.""" -        raise NotImplementedError() - -    def initialize(self): -        """Initialize a `Configurable` subclass instance. - -        Configurable classes should use `initialize` instead of ``__init__``. -        """ - -    @classmethod -    def configure(cls, impl, **kwargs): -        """Sets the class to use when the base class is instantiated. - -        Keyword arguments will be saved and added to the arguments passed -        to the constructor.  This can be used to set global defaults for -        some parameters. -        """ -        base = cls.configurable_base() -        if isinstance(impl, (unicode_type, bytes_type)): -            impl = import_object(impl) -        if impl is not None and not issubclass(impl, cls): -            raise ValueError("Invalid subclass of %s" % cls) -        base.__impl_class = impl -        base.__impl_kwargs = kwargs - -    @classmethod -    def configured_class(cls): -        """Returns the currently configured class.""" -        base = cls.configurable_base() -        if cls.__impl_class is None: -            base.__impl_class = cls.configurable_default() -        return base.__impl_class - -    @classmethod -    def _save_configuration(cls): -        base = cls.configurable_base() -        return (base.__impl_class, base.__impl_kwargs) - -    @classmethod -    def _restore_configuration(cls, saved): -        base = cls.configurable_base() -        base.__impl_class = saved[0] -        base.__impl_kwargs = saved[1] - diff --git a/zmq/eventloop/zmqstream.py b/zmq/eventloop/zmqstream.py deleted file mode 100644 index 86a97e4..0000000 --- a/zmq/eventloop/zmqstream.py +++ /dev/null @@ -1,529 +0,0 @@ -# -# Copyright 2009 Facebook -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -#     http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""A utility class to send to and recv from a non-blocking socket.""" - -from __future__ import with_statement - -import sys - -import zmq -from zmq.utils import jsonapi - -try: -    import cPickle as pickle -except ImportError: -    import pickle - -from .ioloop import IOLoop - -try: -    # gen_log will only import from >= 3.0 -    from tornado.log import gen_log -    from tornado import stack_context -except ImportError: -    from .minitornado.log import gen_log -    from .minitornado import stack_context - -try: -    from queue import Queue -except ImportError: -    from Queue import Queue - -from zmq.utils.strtypes import bytes, unicode, basestring - -try: -    callable -except NameError: -    callable = lambda obj: hasattr(obj, '__call__') - - -class ZMQStream(object): -    """A utility class to register callbacks when a zmq socket sends and receives -     -    For use with zmq.eventloop.ioloop - -    There are three main methods -     -    Methods: -     -    * **on_recv(callback, copy=True):** -        register a callback to be run every time the socket has something to receive -    * **on_send(callback):** -        register a callback to be run every time you call send -    * **send(self, msg, flags=0, copy=False, callback=None):** -        perform a send that will trigger the callback -        if callback is passed, on_send is also called. -         -        There are also send_multipart(), send_json(), send_pyobj() -     -    Three other methods for deactivating the callbacks: -     -    * **stop_on_recv():** -        turn off the recv callback -    * **stop_on_send():** -        turn off the send callback -     -    which simply call ``on_<evt>(None)``. -     -    The entire socket interface, excluding direct recv methods, is also -    provided, primarily through direct-linking the methods. -    e.g. -     -    >>> stream.bind is stream.socket.bind -    True -     -    """ -     -    socket = None -    io_loop = None -    poller = None -     -    def __init__(self, socket, io_loop=None): -        self.socket = socket -        self.io_loop = io_loop or IOLoop.instance() -        self.poller = zmq.Poller() -         -        self._send_queue = Queue() -        self._recv_callback = None -        self._send_callback = None -        self._close_callback = None -        self._recv_copy = False -        self._flushed = False -         -        self._state = self.io_loop.ERROR -        self._init_io_state() -         -        # shortcircuit some socket methods -        self.bind = self.socket.bind -        self.bind_to_random_port = self.socket.bind_to_random_port -        self.connect = self.socket.connect -        self.setsockopt = self.socket.setsockopt -        self.getsockopt = self.socket.getsockopt -        self.setsockopt_string = self.socket.setsockopt_string -        self.getsockopt_string = self.socket.getsockopt_string -        self.setsockopt_unicode = self.socket.setsockopt_unicode -        self.getsockopt_unicode = self.socket.getsockopt_unicode -     -     -    def stop_on_recv(self): -        """Disable callback and automatic receiving.""" -        return self.on_recv(None) -     -    def stop_on_send(self): -        """Disable callback on sending.""" -        return self.on_send(None) -     -    def stop_on_err(self): -        """DEPRECATED, does nothing""" -        gen_log.warn("on_err does nothing, and will be removed") -     -    def on_err(self, callback): -        """DEPRECATED, does nothing""" -        gen_log.warn("on_err does nothing, and will be removed") -     -    def on_recv(self, callback, copy=True): -        """Register a callback for when a message is ready to recv. -         -        There can be only one callback registered at a time, so each -        call to `on_recv` replaces previously registered callbacks. -         -        on_recv(None) disables recv event polling. -         -        Use on_recv_stream(callback) instead, to register a callback that will receive -        both this ZMQStream and the message, instead of just the message. -         -        Parameters -        ---------- -         -        callback : callable -            callback must take exactly one argument, which will be a -            list, as returned by socket.recv_multipart() -            if callback is None, recv callbacks are disabled. -        copy : bool -            copy is passed directly to recv, so if copy is False, -            callback will receive Message objects. If copy is True, -            then callback will receive bytes/str objects. -         -        Returns : None -        """ -         -        self._check_closed() -        assert callback is None or callable(callback) -        self._recv_callback = stack_context.wrap(callback) -        self._recv_copy = copy -        if callback is None: -            self._drop_io_state(self.io_loop.READ) -        else: -            self._add_io_state(self.io_loop.READ) -     -    def on_recv_stream(self, callback, copy=True): -        """Same as on_recv, but callback will get this stream as first argument -         -        callback must take exactly two arguments, as it will be called as:: -         -            callback(stream, msg) -         -        Useful when a single callback should be used with multiple streams. -        """ -        if callback is None: -            self.stop_on_recv() -        else: -            self.on_recv(lambda msg: callback(self, msg), copy=copy) -     -    def on_send(self, callback): -        """Register a callback to be called on each send -         -        There will be two arguments:: -         -            callback(msg, status) -         -        * `msg` will be the list of sendable objects that was just sent -        * `status` will be the return result of socket.send_multipart(msg) - -          MessageTracker or None. -         -        Non-copying sends return a MessageTracker object whose -        `done` attribute will be True when the send is complete. -        This allows users to track when an object is safe to write to -        again. -         -        The second argument will always be None if copy=True -        on the send. -         -        Use on_send_stream(callback) to register a callback that will be passed -        this ZMQStream as the first argument, in addition to the other two. -         -        on_send(None) disables recv event polling. -         -        Parameters -        ---------- -         -        callback : callable -            callback must take exactly two arguments, which will be -            the message being sent (always a list), -            and the return result of socket.send_multipart(msg) - -            MessageTracker or None. -             -            if callback is None, send callbacks are disabled. -        """ -         -        self._check_closed() -        assert callback is None or callable(callback) -        self._send_callback = stack_context.wrap(callback) -         -     -    def on_send_stream(self, callback): -        """Same as on_send, but callback will get this stream as first argument -         -        Callback will be passed three arguments:: -         -            callback(stream, msg, status) -         -        Useful when a single callback should be used with multiple streams. -        """ -        if callback is None: -            self.stop_on_send() -        else: -            self.on_send(lambda msg, status: callback(self, msg, status)) -         -         -    def send(self, msg, flags=0, copy=True, track=False, callback=None): -        """Send a message, optionally also register a new callback for sends. -        See zmq.socket.send for details. -        """ -        return self.send_multipart([msg], flags=flags, copy=copy, track=track, callback=callback) - -    def send_multipart(self, msg, flags=0, copy=True, track=False, callback=None): -        """Send a multipart message, optionally also register a new callback for sends. -        See zmq.socket.send_multipart for details. -        """ -        kwargs = dict(flags=flags, copy=copy, track=track) -        self._send_queue.put((msg, kwargs)) -        callback = callback or self._send_callback -        if callback is not None: -            self.on_send(callback) -        else: -            # noop callback -            self.on_send(lambda *args: None) -        self._add_io_state(self.io_loop.WRITE) -     -    def send_string(self, u, flags=0, encoding='utf-8', callback=None): -        """Send a unicode message with an encoding. -        See zmq.socket.send_unicode for details. -        """ -        if not isinstance(u, basestring): -            raise TypeError("unicode/str objects only") -        return self.send(u.encode(encoding), flags=flags, callback=callback) -     -    send_unicode = send_string -     -    def send_json(self, obj, flags=0, callback=None): -        """Send json-serialized version of an object. -        See zmq.socket.send_json for details. -        """ -        if jsonapi is None: -            raise ImportError('jsonlib{1,2}, json or simplejson library is required.') -        else: -            msg = jsonapi.dumps(obj) -            return self.send(msg, flags=flags, callback=callback) - -    def send_pyobj(self, obj, flags=0, protocol=-1, callback=None): -        """Send a Python object as a message using pickle to serialize. - -        See zmq.socket.send_json for details. -        """ -        msg = pickle.dumps(obj, protocol) -        return self.send(msg, flags, callback=callback) -     -    def _finish_flush(self): -        """callback for unsetting _flushed flag.""" -        self._flushed = False -     -    def flush(self, flag=zmq.POLLIN|zmq.POLLOUT, limit=None): -        """Flush pending messages. - -        This method safely handles all pending incoming and/or outgoing messages, -        bypassing the inner loop, passing them to the registered callbacks. - -        A limit can be specified, to prevent blocking under high load. - -        flush will return the first time ANY of these conditions are met: -            * No more events matching the flag are pending. -            * the total number of events handled reaches the limit. - -        Note that if ``flag|POLLIN != 0``, recv events will be flushed even if no callback -        is registered, unlike normal IOLoop operation. This allows flush to be -        used to remove *and ignore* incoming messages. - -        Parameters -        ---------- -        flag : int, default=POLLIN|POLLOUT -                0MQ poll flags. -                If flag|POLLIN,  recv events will be flushed. -                If flag|POLLOUT, send events will be flushed. -                Both flags can be set at once, which is the default. -        limit : None or int, optional -                The maximum number of messages to send or receive. -                Both send and recv count against this limit. - -        Returns -        ------- -        int : count of events handled (both send and recv) -        """ -        self._check_closed() -        # unset self._flushed, so callbacks will execute, in case flush has -        # already been called this iteration -        already_flushed = self._flushed -        self._flushed = False -        # initialize counters -        count = 0 -        def update_flag(): -            """Update the poll flag, to prevent registering POLLOUT events -            if we don't have pending sends.""" -            return flag & zmq.POLLIN | (self.sending() and flag & zmq.POLLOUT) -        flag = update_flag() -        if not flag: -            # nothing to do -            return 0 -        self.poller.register(self.socket, flag) -        events = self.poller.poll(0) -        while events and (not limit or count < limit): -            s,event = events[0] -            if event & zmq.POLLIN: # receiving -                self._handle_recv() -                count += 1 -                if self.socket is None: -                    # break if socket was closed during callback -                    break -            if event & zmq.POLLOUT and self.sending(): -                self._handle_send() -                count += 1 -                if self.socket is None: -                    # break if socket was closed during callback -                    break -             -            flag = update_flag() -            if flag: -                self.poller.register(self.socket, flag) -                events = self.poller.poll(0) -            else: -                events = [] -        if count: # only bypass loop if we actually flushed something -            # skip send/recv callbacks this iteration -            self._flushed = True -            # reregister them at the end of the loop -            if not already_flushed: # don't need to do it again -                self.io_loop.add_callback(self._finish_flush) -        elif already_flushed: -            self._flushed = True - -        # update ioloop poll state, which may have changed -        self._rebuild_io_state() -        return count -     -    def set_close_callback(self, callback): -        """Call the given callback when the stream is closed.""" -        self._close_callback = stack_context.wrap(callback) -     -    def close(self, linger=None): -        """Close this stream.""" -        if self.socket is not None: -            self.io_loop.remove_handler(self.socket) -            self.socket.close(linger) -            self.socket = None -            if self._close_callback: -                self._run_callback(self._close_callback) - -    def receiving(self): -        """Returns True if we are currently receiving from the stream.""" -        return self._recv_callback is not None - -    def sending(self): -        """Returns True if we are currently sending to the stream.""" -        return not self._send_queue.empty() - -    def closed(self): -        return self.socket is None - -    def _run_callback(self, callback, *args, **kwargs): -        """Wrap running callbacks in try/except to allow us to -        close our socket.""" -        try: -            # Use a NullContext to ensure that all StackContexts are run -            # inside our blanket exception handler rather than outside. -            with stack_context.NullContext(): -                callback(*args, **kwargs) -        except: -            gen_log.error("Uncaught exception, closing connection.", -                          exc_info=True) -            # Close the socket on an uncaught exception from a user callback -            # (It would eventually get closed when the socket object is -            # gc'd, but we don't want to rely on gc happening before we -            # run out of file descriptors) -            self.close() -            # Re-raise the exception so that IOLoop.handle_callback_exception -            # can see it and log the error -            raise - -    def _handle_events(self, fd, events): -        """This method is the actual handler for IOLoop, that gets called whenever -        an event on my socket is posted. It dispatches to _handle_recv, etc.""" -        # print "handling events" -        if not self.socket: -            gen_log.warning("Got events for closed stream %s", fd) -            return -        try: -            # dispatch events: -            if events & IOLoop.ERROR: -                gen_log.error("got POLLERR event on ZMQStream, which doesn't make sense") -                return -            if events & IOLoop.READ: -                self._handle_recv() -                if not self.socket: -                    return -            if events & IOLoop.WRITE: -                self._handle_send() -                if not self.socket: -                    return - -            # rebuild the poll state -            self._rebuild_io_state() -        except: -            gen_log.error("Uncaught exception, closing connection.", -                          exc_info=True) -            self.close() -            raise -             -    def _handle_recv(self): -        """Handle a recv event.""" -        if self._flushed: -            return -        try: -            msg = self.socket.recv_multipart(zmq.NOBLOCK, copy=self._recv_copy) -        except zmq.ZMQError as e: -            if e.errno == zmq.EAGAIN: -                # state changed since poll event -                pass -            else: -                gen_log.error("RECV Error: %s"%zmq.strerror(e.errno)) -        else: -            if self._recv_callback: -                callback = self._recv_callback -                # self._recv_callback = None -                self._run_callback(callback, msg) -                 -        # self.update_state() -         - -    def _handle_send(self): -        """Handle a send event.""" -        if self._flushed: -            return -        if not self.sending(): -            gen_log.error("Shouldn't have handled a send event") -            return -         -        msg, kwargs = self._send_queue.get() -        try: -            status = self.socket.send_multipart(msg, **kwargs) -        except zmq.ZMQError as e: -            gen_log.error("SEND Error: %s", e) -            status = e -        if self._send_callback: -            callback = self._send_callback -            self._run_callback(callback, msg, status) -         -        # self.update_state() -     -    def _check_closed(self): -        if not self.socket: -            raise IOError("Stream is closed") -     -    def _rebuild_io_state(self): -        """rebuild io state based on self.sending() and receiving()""" -        if self.socket is None: -            return -        state = self.io_loop.ERROR -        if self.receiving(): -            state |= self.io_loop.READ -        if self.sending(): -            state |= self.io_loop.WRITE -        if state != self._state: -            self._state = state -            self._update_handler(state) -     -    def _add_io_state(self, state): -        """Add io_state to poller.""" -        if not self._state & state: -            self._state = self._state | state -            self._update_handler(self._state) -     -    def _drop_io_state(self, state): -        """Stop poller from watching an io_state.""" -        if self._state & state: -            self._state = self._state & (~state) -            self._update_handler(self._state) -     -    def _update_handler(self, state): -        """Update IOLoop handler with state.""" -        if self.socket is None: -            return -        self.io_loop.update_handler(self.socket, state) -     -    def _init_io_state(self): -        """initialize the ioloop event handler""" -        with stack_context.NullContext(): -            self.io_loop.add_handler(self.socket, self._handle_events, self._state) - diff --git a/zmq/green/__init__.py b/zmq/green/__init__.py deleted file mode 100644 index ff7e596..0000000 --- a/zmq/green/__init__.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -#----------------------------------------------------------------------------- -#  Copyright (C) 2011-2012 Travis Cline -# -#  This file is part of pyzmq -#  It is adapted from upstream project zeromq_gevent under the New BSD License -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -"""zmq.green - gevent compatibility with zeromq. - -Usage ------ - -Instead of importing zmq directly, do so in the following manner: - -.. - -    import zmq.green as zmq - - -Any calls that would have blocked the current thread will now only block the -current green thread. - -This compatibility is accomplished by ensuring the nonblocking flag is set -before any blocking operation and the ØMQ file descriptor is polled internally -to trigger needed events. -""" - -from zmq import * -from zmq.green.core import _Context, _Socket -from zmq.green.poll import _Poller -Context = _Context -Socket = _Socket -Poller = _Poller - -from zmq.green.device import device - diff --git a/zmq/green/core.py b/zmq/green/core.py deleted file mode 100644 index 9fc73e3..0000000 --- a/zmq/green/core.py +++ /dev/null @@ -1,287 +0,0 @@ -#----------------------------------------------------------------------------- -#  Copyright (C) 2011-2012 Travis Cline -# -#  This file is part of pyzmq -#  It is adapted from upstream project zeromq_gevent under the New BSD License -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -"""This module wraps the :class:`Socket` and :class:`Context` found in :mod:`pyzmq <zmq>` to be non blocking -""" - -from __future__ import print_function - -import sys -import time -import warnings - -import zmq - -from zmq import Context as _original_Context -from zmq import Socket as _original_Socket -from .poll import _Poller - -import gevent -from gevent.event import AsyncResult -from gevent.hub import get_hub - -if hasattr(zmq, 'RCVTIMEO'): -    TIMEOS = (zmq.RCVTIMEO, zmq.SNDTIMEO) -else: -    TIMEOS = () - -def _stop(evt): -    """simple wrapper for stopping an Event, allowing for method rename in gevent 1.0""" -    try: -        evt.stop() -    except AttributeError as e: -        # gevent<1.0 compat -        evt.cancel() - -class _Socket(_original_Socket): -    """Green version of :class:`zmq.Socket` - -    The following methods are overridden: - -        * send -        * recv - -    To ensure that the ``zmq.NOBLOCK`` flag is set and that sending or receiving -    is deferred to the hub if a ``zmq.EAGAIN`` (retry) error is raised. -     -    The `__state_changed` method is triggered when the zmq.FD for the socket is -    marked as readable and triggers the necessary read and write events (which -    are waited for in the recv and send methods). - -    Some double underscore prefixes are used to minimize pollution of -    :class:`zmq.Socket`'s namespace. -    """ -    __in_send_multipart = False -    __in_recv_multipart = False -    __writable = None -    __readable = None -    _state_event = None -    _gevent_bug_timeout = 11.6 # timeout for not trusting gevent -    _debug_gevent = False # turn on if you think gevent is missing events -    _poller_class = _Poller -     -    def __init__(self, context, socket_type): -        _original_Socket.__init__(self, context, socket_type) -        self.__in_send_multipart = False -        self.__in_recv_multipart = False -        self.__setup_events() -         - -    def __del__(self): -        self.close() - -    def close(self, linger=None): -        super(_Socket, self).close(linger) -        self.__cleanup_events() - -    def __cleanup_events(self): -        # close the _state_event event, keeps the number of active file descriptors down -        if getattr(self, '_state_event', None): -            _stop(self._state_event) -            self._state_event = None -        # if the socket has entered a close state resume any waiting greenlets -        self.__writable.set() -        self.__readable.set() - -    def __setup_events(self): -        self.__readable = AsyncResult() -        self.__writable = AsyncResult() -        self.__readable.set() -        self.__writable.set() -         -        try: -            self._state_event = get_hub().loop.io(self.getsockopt(zmq.FD), 1) # read state watcher -            self._state_event.start(self.__state_changed) -        except AttributeError: -            # for gevent<1.0 compatibility -            from gevent.core import read_event -            self._state_event = read_event(self.getsockopt(zmq.FD), self.__state_changed, persist=True) - -    def __state_changed(self, event=None, _evtype=None): -        if self.closed: -            self.__cleanup_events() -            return -        try: -            # avoid triggering __state_changed from inside __state_changed -            events = super(_Socket, self).getsockopt(zmq.EVENTS) -        except zmq.ZMQError as exc: -            self.__writable.set_exception(exc) -            self.__readable.set_exception(exc) -        else: -            if events & zmq.POLLOUT: -                self.__writable.set() -            if events & zmq.POLLIN: -                self.__readable.set() - -    def _wait_write(self): -        assert self.__writable.ready(), "Only one greenlet can be waiting on this event" -        self.__writable = AsyncResult() -        # timeout is because libzmq cannot be trusted to properly signal a new send event: -        # this is effectively a maximum poll interval of 1s -        tic = time.time() -        dt = self._gevent_bug_timeout -        if dt: -            timeout = gevent.Timeout(seconds=dt) -        else: -            timeout = None -        try: -            if timeout: -                timeout.start() -            self.__writable.get(block=True) -        except gevent.Timeout as t: -            if t is not timeout: -                raise -            toc = time.time() -            # gevent bug: get can raise timeout even on clean return -            # don't display zmq bug warning for gevent bug (this is getting ridiculous) -            if self._debug_gevent and timeout and toc-tic > dt and \ -                    self.getsockopt(zmq.EVENTS) & zmq.POLLOUT: -                print("BUG: gevent may have missed a libzmq send event on %i!" % self.FD, file=sys.stderr) -        finally: -            if timeout: -                timeout.cancel() -            self.__writable.set() - -    def _wait_read(self): -        assert self.__readable.ready(), "Only one greenlet can be waiting on this event" -        self.__readable = AsyncResult() -        # timeout is because libzmq cannot always be trusted to play nice with libevent. -        # I can only confirm that this actually happens for send, but lets be symmetrical -        # with our dirty hacks. -        # this is effectively a maximum poll interval of 1s -        tic = time.time() -        dt = self._gevent_bug_timeout -        if dt: -            timeout = gevent.Timeout(seconds=dt) -        else: -            timeout = None -        try: -            if timeout: -                timeout.start() -            self.__readable.get(block=True) -        except gevent.Timeout as t: -            if t is not timeout: -                raise -            toc = time.time() -            # gevent bug: get can raise timeout even on clean return -            # don't display zmq bug warning for gevent bug (this is getting ridiculous) -            if self._debug_gevent and timeout and toc-tic > dt and \ -                    self.getsockopt(zmq.EVENTS) & zmq.POLLIN: -                print("BUG: gevent may have missed a libzmq recv event on %i!" % self.FD, file=sys.stderr) -        finally: -            if timeout: -                timeout.cancel() -            self.__readable.set() - -    def send(self, data, flags=0, copy=True, track=False): -        """send, which will only block current greenlet -         -        state_changed always fires exactly once (success or fail) at the -        end of this method. -        """ -         -        # if we're given the NOBLOCK flag act as normal and let the EAGAIN get raised -        if flags & zmq.NOBLOCK: -            try: -                msg = super(_Socket, self).send(data, flags, copy, track) -            finally: -                if not self.__in_send_multipart: -                    self.__state_changed() -            return msg -        # ensure the zmq.NOBLOCK flag is part of flags -        flags |= zmq.NOBLOCK -        while True: # Attempt to complete this operation indefinitely, blocking the current greenlet -            try: -                # attempt the actual call -                msg = super(_Socket, self).send(data, flags, copy, track) -            except zmq.ZMQError as e: -                # if the raised ZMQError is not EAGAIN, reraise -                if e.errno != zmq.EAGAIN: -                    if not self.__in_send_multipart: -                        self.__state_changed() -                    raise -            else: -                if not self.__in_send_multipart: -                    self.__state_changed() -                return msg -            # defer to the event loop until we're notified the socket is writable -            self._wait_write() - -    def recv(self, flags=0, copy=True, track=False): -        """recv, which will only block current greenlet -         -        state_changed always fires exactly once (success or fail) at the -        end of this method. -        """ -        if flags & zmq.NOBLOCK: -            try: -                msg = super(_Socket, self).recv(flags, copy, track) -            finally: -                if not self.__in_recv_multipart: -                    self.__state_changed() -            return msg -         -        flags |= zmq.NOBLOCK -        while True: -            try: -                msg = super(_Socket, self).recv(flags, copy, track) -            except zmq.ZMQError as e: -                if e.errno != zmq.EAGAIN: -                    if not self.__in_recv_multipart: -                        self.__state_changed() -                    raise -            else: -                if not self.__in_recv_multipart: -                    self.__state_changed() -                return msg -            self._wait_read() -     -    def send_multipart(self, *args, **kwargs): -        """wrap send_multipart to prevent state_changed on each partial send""" -        self.__in_send_multipart = True -        try: -            msg = super(_Socket, self).send_multipart(*args, **kwargs) -        finally: -            self.__in_send_multipart = False -            self.__state_changed() -        return msg -     -    def recv_multipart(self, *args, **kwargs): -        """wrap recv_multipart to prevent state_changed on each partial recv""" -        self.__in_recv_multipart = True -        try: -            msg = super(_Socket, self).recv_multipart(*args, **kwargs) -        finally: -            self.__in_recv_multipart = False -            self.__state_changed() -        return msg -     -    def get(self, opt): -        """trigger state_changed on getsockopt(EVENTS)""" -        if opt in TIMEOS: -            warnings.warn("TIMEO socket options have no effect in zmq.green", UserWarning) -        optval = super(_Socket, self).get(opt) -        if opt == zmq.EVENTS: -            self.__state_changed() -        return optval -     -    def set(self, opt, val): -        """set socket option""" -        if opt in TIMEOS: -            warnings.warn("TIMEO socket options have no effect in zmq.green", UserWarning) -        return super(_Socket, self).set(opt, val) - - -class _Context(_original_Context): -    """Replacement for :class:`zmq.Context` - -    Ensures that the greened Socket above is used in calls to `socket`. -    """ -    _socket_class = _Socket diff --git a/zmq/green/device.py b/zmq/green/device.py deleted file mode 100644 index 4b07023..0000000 --- a/zmq/green/device.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import zmq -from zmq.green import Poller - -def device(device_type, isocket, osocket): -    """Start a zeromq device (gevent-compatible). -     -    Unlike the true zmq.device, this does not release the GIL. - -    Parameters -    ---------- -    device_type : (QUEUE, FORWARDER, STREAMER) -        The type of device to start (ignored). -    isocket : Socket -        The Socket instance for the incoming traffic. -    osocket : Socket -        The Socket instance for the outbound traffic. -    """ -    p = Poller() -    if osocket == -1: -        osocket = isocket -    p.register(isocket, zmq.POLLIN) -    p.register(osocket, zmq.POLLIN) -     -    while True: -        events = dict(p.poll()) -        if isocket in events: -            osocket.send_multipart(isocket.recv_multipart()) -        if osocket in events: -            isocket.send_multipart(osocket.recv_multipart()) diff --git a/zmq/green/eventloop/__init__.py b/zmq/green/eventloop/__init__.py deleted file mode 100644 index c5150ef..0000000 --- a/zmq/green/eventloop/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from zmq.green.eventloop.ioloop import IOLoop - -__all__ = ['IOLoop']
\ No newline at end of file diff --git a/zmq/green/eventloop/ioloop.py b/zmq/green/eventloop/ioloop.py deleted file mode 100644 index e12fd5e..0000000 --- a/zmq/green/eventloop/ioloop.py +++ /dev/null @@ -1,33 +0,0 @@ -from zmq.eventloop.ioloop import * -from zmq.green import Poller - -RealIOLoop = IOLoop -RealZMQPoller = ZMQPoller - -class IOLoop(RealIOLoop): -     -    def initialize(self, impl=None): -        impl = _poll() if impl is None else impl -        super(IOLoop, self).initialize(impl) - -    @staticmethod -    def instance(): -        """Returns a global `IOLoop` instance. -         -        Most applications have a single, global `IOLoop` running on the -        main thread.  Use this method to get this instance from -        another thread.  To get the current thread's `IOLoop`, use `current()`. -        """ -        # install this class as the active IOLoop implementation -        # when using tornado 3 -        if tornado_version >= (3,): -            PollIOLoop.configure(IOLoop) -        return PollIOLoop.instance() - - -class ZMQPoller(RealZMQPoller): -    """gevent-compatible version of ioloop.ZMQPoller""" -    def __init__(self): -        self._poller = Poller() - -_poll = ZMQPoller diff --git a/zmq/green/eventloop/zmqstream.py b/zmq/green/eventloop/zmqstream.py deleted file mode 100644 index 90fbd1f..0000000 --- a/zmq/green/eventloop/zmqstream.py +++ /dev/null @@ -1,11 +0,0 @@ -from zmq.eventloop.zmqstream import * - -from zmq.green.eventloop.ioloop import IOLoop - -RealZMQStream = ZMQStream - -class ZMQStream(RealZMQStream): -     -    def __init__(self, socket, io_loop=None): -        io_loop = io_loop or IOLoop.instance() -        super(ZMQStream, self).__init__(socket, io_loop=io_loop) diff --git a/zmq/green/poll.py b/zmq/green/poll.py deleted file mode 100644 index 8f01612..0000000 --- a/zmq/green/poll.py +++ /dev/null @@ -1,95 +0,0 @@ -import zmq -import gevent -from gevent import select - -from zmq import Poller as _original_Poller - - -class _Poller(_original_Poller): -    """Replacement for :class:`zmq.Poller` - -    Ensures that the greened Poller below is used in calls to -    :meth:`zmq.Poller.poll`. -    """ -    _gevent_bug_timeout = 1.33 # minimum poll interval, for working around gevent bug - -    def _get_descriptors(self): -        """Returns three elements tuple with socket descriptors ready -        for gevent.select.select -        """ -        rlist = [] -        wlist = [] -        xlist = [] - -        for socket, flags in self.sockets: -            if isinstance(socket, zmq.Socket): -                rlist.append(socket.getsockopt(zmq.FD)) -                continue -            elif isinstance(socket, int): -                fd = socket -            elif hasattr(socket, 'fileno'): -                try: -                    fd = int(socket.fileno()) -                except: -                    raise ValueError('fileno() must return an valid integer fd') -            else: -                raise TypeError('Socket must be a 0MQ socket, an integer fd ' -                                'or have a fileno() method: %r' % socket) - -            if flags & zmq.POLLIN: -                rlist.append(fd) -            if flags & zmq.POLLOUT: -                wlist.append(fd) -            if flags & zmq.POLLERR: -                xlist.append(fd) - -        return (rlist, wlist, xlist) - -    def poll(self, timeout=-1): -        """Overridden method to ensure that the green version of -        Poller is used. - -        Behaves the same as :meth:`zmq.core.Poller.poll` -        """ - -        if timeout is None: -            timeout = -1 - -        if timeout < 0: -            timeout = -1 - -        rlist = None -        wlist = None -        xlist = None - -        if timeout > 0: -            tout = gevent.Timeout.start_new(timeout/1000.0) - -        try: -            # Loop until timeout or events available -            rlist, wlist, xlist = self._get_descriptors() -            while True: -                events = super(_Poller, self).poll(0) -                if events or timeout == 0: -                    return events - -                # wait for activity on sockets in a green way -                # set a minimum poll frequency, -                # because gevent < 1.0 cannot be trusted to catch edge-triggered FD events -                _bug_timeout = gevent.Timeout.start_new(self._gevent_bug_timeout) -                try: -                    select.select(rlist, wlist, xlist) -                except gevent.Timeout as t: -                    if t is not _bug_timeout: -                        raise -                finally: -                    _bug_timeout.cancel() - -        except gevent.Timeout as t: -            if t is not tout: -                raise -            return [] -        finally: -           if timeout > 0: -               tout.cancel() - diff --git a/zmq/log/__init__.py b/zmq/log/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/zmq/log/__init__.py +++ /dev/null diff --git a/zmq/log/handlers.py b/zmq/log/handlers.py deleted file mode 100644 index 5ff21bf..0000000 --- a/zmq/log/handlers.py +++ /dev/null @@ -1,146 +0,0 @@ -"""pyzmq logging handlers. - -This mainly defines the PUBHandler object for publishing logging messages over -a zmq.PUB socket. - -The PUBHandler can be used with the regular logging module, as in:: - -    >>> import logging -    >>> handler = PUBHandler('tcp://127.0.0.1:12345') -    >>> handler.root_topic = 'foo' -    >>> logger = logging.getLogger('foobar') -    >>> logger.setLevel(logging.DEBUG) -    >>> logger.addHandler(handler) - -After this point, all messages logged by ``logger`` will be published on the -PUB socket. - -Code adapted from StarCluster: - -    http://github.com/jtriley/StarCluster/blob/master/starcluster/logger.py -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import logging -from logging import INFO, DEBUG, WARN, ERROR, FATAL - -import zmq -from zmq.utils.strtypes import bytes, unicode, cast_bytes - - -TOPIC_DELIM="::" # delimiter for splitting topics on the receiving end. - - -class PUBHandler(logging.Handler): -    """A basic logging handler that emits log messages through a PUB socket. - -    Takes a PUB socket already bound to interfaces or an interface to bind to. - -    Example:: - -        sock = context.socket(zmq.PUB) -        sock.bind('inproc://log') -        handler = PUBHandler(sock) - -    Or:: - -        handler = PUBHandler('inproc://loc') - -    These are equivalent. - -    Log messages handled by this handler are broadcast with ZMQ topics -    ``this.root_topic`` comes first, followed by the log level -    (DEBUG,INFO,etc.), followed by any additional subtopics specified in the -    message by: log.debug("subtopic.subsub::the real message") -    """ -    root_topic="" -    socket = None -     -    formatters = { -        logging.DEBUG: logging.Formatter( -        "%(levelname)s %(filename)s:%(lineno)d - %(message)s\n"), -        logging.INFO: logging.Formatter("%(message)s\n"), -        logging.WARN: logging.Formatter( -        "%(levelname)s %(filename)s:%(lineno)d - %(message)s\n"), -        logging.ERROR: logging.Formatter( -        "%(levelname)s %(filename)s:%(lineno)d - %(message)s - %(exc_info)s\n"), -        logging.CRITICAL: logging.Formatter( -        "%(levelname)s %(filename)s:%(lineno)d - %(message)s\n")} -     -    def __init__(self, interface_or_socket, context=None): -        logging.Handler.__init__(self) -        if isinstance(interface_or_socket, zmq.Socket): -            self.socket = interface_or_socket -            self.ctx = self.socket.context -        else: -            self.ctx = context or zmq.Context() -            self.socket = self.ctx.socket(zmq.PUB) -            self.socket.bind(interface_or_socket) - -    def format(self,record): -        """Format a record.""" -        return self.formatters[record.levelno].format(record) - -    def emit(self, record): -        """Emit a log message on my socket.""" -        try: -            topic, record.msg = record.msg.split(TOPIC_DELIM,1) -        except Exception: -            topic = "" -        try: -            bmsg = cast_bytes(self.format(record)) -        except Exception: -            self.handleError(record) -            return -         -        topic_list = [] - -        if self.root_topic: -            topic_list.append(self.root_topic) - -        topic_list.append(record.levelname) - -        if topic: -            topic_list.append(topic) - -        btopic = b'.'.join(cast_bytes(t) for t in topic_list) - -        self.socket.send_multipart([btopic, bmsg]) - - -class TopicLogger(logging.Logger): -    """A simple wrapper that takes an additional argument to log methods. - -    All the regular methods exist, but instead of one msg argument, two -    arguments: topic, msg are passed. - -    That is:: - -        logger.debug('msg') - -    Would become:: - -        logger.debug('topic.sub', 'msg') -    """ -    def log(self, level, topic, msg, *args, **kwargs): -        """Log 'msg % args' with level and topic. - -        To pass exception information, use the keyword argument exc_info -        with a True value:: - -            logger.log(level, "zmq.fun", "We have a %s",  -                    "mysterious problem", exc_info=1) -        """ -        logging.Logger.log(self, level, '%s::%s'%(topic,msg), *args, **kwargs) - -# Generate the methods of TopicLogger, since they are just adding a -# topic prefix to a message. -for name in "debug warn warning error critical fatal".split(): -    meth = getattr(logging.Logger,name) -    setattr(TopicLogger, name,  -            lambda self, level, topic, msg, *args, **kwargs:  -                meth(self, level, topic+TOPIC_DELIM+msg,*args, **kwargs)) -     diff --git a/zmq/ssh/__init__.py b/zmq/ssh/__init__.py deleted file mode 100644 index 57f0956..0000000 --- a/zmq/ssh/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from zmq.ssh.tunnel import * diff --git a/zmq/ssh/forward.py b/zmq/ssh/forward.py deleted file mode 100644 index 2d61946..0000000 --- a/zmq/ssh/forward.py +++ /dev/null @@ -1,91 +0,0 @@ -# -# This file is adapted from a paramiko demo, and thus licensed under LGPL 2.1. -# Original Copyright (C) 2003-2007  Robey Pointer <robeypointer@gmail.com> -# Edits Copyright (C) 2010 The IPython Team -# -# Paramiko is free software; you can redistribute it and/or modify it under the -# terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 2.1 of the License, or (at your option) -# any later version. -# -# Paramiko is distrubuted 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 GNU Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with Paramiko; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA. - -""" -Sample script showing how to do local port forwarding over paramiko. - -This script connects to the requested SSH server and sets up local port -forwarding (the openssh -L option) from a local port through a tunneled -connection to a destination reachable from the SSH server machine. -""" - -from __future__ import print_function - -import logging -import select -try:  # Python 3 -    import socketserver -except ImportError:  # Python 2 -    import SocketServer as socketserver - -logger = logging.getLogger('ssh') - -class ForwardServer (socketserver.ThreadingTCPServer): -    daemon_threads = True -    allow_reuse_address = True -     - -class Handler (socketserver.BaseRequestHandler): - -    def handle(self): -        try: -            chan = self.ssh_transport.open_channel('direct-tcpip', -                                                   (self.chain_host, self.chain_port), -                                                   self.request.getpeername()) -        except Exception as e: -            logger.debug('Incoming request to %s:%d failed: %s' % (self.chain_host, -                                                              self.chain_port, -                                                              repr(e))) -            return -        if chan is None: -            logger.debug('Incoming request to %s:%d was rejected by the SSH server.' % -                    (self.chain_host, self.chain_port)) -            return - -        logger.debug('Connected!  Tunnel open %r -> %r -> %r' % (self.request.getpeername(), -                                                            chan.getpeername(), (self.chain_host, self.chain_port))) -        while True: -            r, w, x = select.select([self.request, chan], [], []) -            if self.request in r: -                data = self.request.recv(1024) -                if len(data) == 0: -                    break -                chan.send(data) -            if chan in r: -                data = chan.recv(1024) -                if len(data) == 0: -                    break -                self.request.send(data) -        chan.close() -        self.request.close() -        logger.debug('Tunnel closed ') - - -def forward_tunnel(local_port, remote_host, remote_port, transport): -    # this is a little convoluted, but lets me configure things for the Handler -    # object.  (SocketServer doesn't give Handlers any way to access the outer -    # server normally.) -    class SubHander (Handler): -        chain_host = remote_host -        chain_port = remote_port -        ssh_transport = transport -    ForwardServer(('127.0.0.1', local_port), SubHander).serve_forever() - - -__all__ = ['forward_tunnel'] diff --git a/zmq/ssh/tunnel.py b/zmq/ssh/tunnel.py deleted file mode 100644 index 2e0b623..0000000 --- a/zmq/ssh/tunnel.py +++ /dev/null @@ -1,358 +0,0 @@ -"""Basic ssh tunnel utilities, and convenience functions for tunneling -zeromq connections. -""" - -# Copyright (C) 2010-2011  IPython Development Team -# Copyright (C) 2011- PyZMQ Developers -# -# Redistributed from IPython under the terms of the BSD License. - - -from __future__ import print_function - -import atexit -import os -import signal -import socket -import sys -import warnings -from getpass import getpass, getuser -from multiprocessing import Process - -try: -    with warnings.catch_warnings(): -        warnings.simplefilter('ignore', DeprecationWarning) -        import paramiko -except ImportError: -    paramiko = None -else: -    from .forward import forward_tunnel - - -try: -    import pexpect -except ImportError: -    pexpect = None - - -_random_ports = set() - -def select_random_ports(n): -    """Selects and return n random ports that are available.""" -    ports = [] -    for i in range(n): -        sock = socket.socket() -        sock.bind(('', 0)) -        while sock.getsockname()[1] in _random_ports: -            sock.close() -            sock = socket.socket() -            sock.bind(('', 0)) -        ports.append(sock) -    for i, sock in enumerate(ports): -        port = sock.getsockname()[1] -        sock.close() -        ports[i] = port -        _random_ports.add(port) -    return ports - - -#----------------------------------------------------------------------------- -# Check for passwordless login -#----------------------------------------------------------------------------- - -def try_passwordless_ssh(server, keyfile, paramiko=None): -    """Attempt to make an ssh connection without a password. -    This is mainly used for requiring password input only once -    when many tunnels may be connected to the same server. -     -    If paramiko is None, the default for the platform is chosen. -    """ -    if paramiko is None: -        paramiko = sys.platform == 'win32' -    if not paramiko: -        f = _try_passwordless_openssh -    else: -        f = _try_passwordless_paramiko -    return f(server, keyfile) - -def _try_passwordless_openssh(server, keyfile): -    """Try passwordless login with shell ssh command.""" -    if pexpect is None: -        raise ImportError("pexpect unavailable, use paramiko") -    cmd = 'ssh -f '+ server -    if keyfile: -        cmd += ' -i ' + keyfile -    cmd += ' exit' -    p = pexpect.spawn(cmd) -    while True: -        try: -            p.expect('[Pp]assword:', timeout=.1) -        except pexpect.TIMEOUT: -            continue -        except pexpect.EOF: -            return True -        else: -            return False - -def _try_passwordless_paramiko(server, keyfile): -    """Try passwordless login with paramiko.""" -    if paramiko is None: -        msg = "Paramiko unavaliable, " -        if sys.platform == 'win32': -            msg += "Paramiko is required for ssh tunneled connections on Windows." -        else: -            msg += "use OpenSSH." -        raise ImportError(msg) -    username, server, port = _split_server(server) -    client = paramiko.SSHClient() -    client.load_system_host_keys() -    client.set_missing_host_key_policy(paramiko.WarningPolicy()) -    try: -        client.connect(server, port, username=username, key_filename=keyfile, -               look_for_keys=True) -    except paramiko.AuthenticationException: -        return False -    else: -        client.close() -        return True - - -def tunnel_connection(socket, addr, server, keyfile=None, password=None, paramiko=None, timeout=60): -    """Connect a socket to an address via an ssh tunnel. -     -    This is a wrapper for socket.connect(addr), when addr is not accessible -    from the local machine.  It simply creates an ssh tunnel using the remaining args, -    and calls socket.connect('tcp://localhost:lport') where lport is the randomly -    selected local port of the tunnel. -     -    """ -    new_url, tunnel = open_tunnel(addr, server, keyfile=keyfile, password=password, paramiko=paramiko, timeout=timeout) -    socket.connect(new_url) -    return tunnel - - -def open_tunnel(addr, server, keyfile=None, password=None, paramiko=None, timeout=60): -    """Open a tunneled connection from a 0MQ url. -     -    For use inside tunnel_connection. -     -    Returns -    ------- -     -    (url, tunnel) : (str, object) -        The 0MQ url that has been forwarded, and the tunnel object -    """ -     -    lport = select_random_ports(1)[0] -    transport, addr = addr.split('://') -    ip,rport = addr.split(':') -    rport = int(rport) -    if paramiko is None: -        paramiko = sys.platform == 'win32' -    if paramiko: -        tunnelf = paramiko_tunnel -    else: -        tunnelf = openssh_tunnel -     -    tunnel = tunnelf(lport, rport, server, remoteip=ip, keyfile=keyfile, password=password, timeout=timeout) -    return 'tcp://127.0.0.1:%i'%lport, tunnel - -def openssh_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60): -    """Create an ssh tunnel using command-line ssh that connects port lport -    on this machine to localhost:rport on server.  The tunnel -    will automatically close when not in use, remaining open -    for a minimum of timeout seconds for an initial connection. -     -    This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`, -    as seen from `server`. -     -    keyfile and password may be specified, but ssh config is checked for defaults. -     -    Parameters -    ---------- -     -    lport : int -        local port for connecting to the tunnel from this machine. -    rport : int -        port on the remote machine to connect to. -    server : str -        The ssh server to connect to. The full ssh server string will be parsed. -        user@server:port -    remoteip : str [Default: 127.0.0.1] -        The remote ip, specifying the destination of the tunnel. -        Default is localhost, which means that the tunnel would redirect -        localhost:lport on this machine to localhost:rport on the *server*. -         -    keyfile : str; path to public key file -        This specifies a key to be used in ssh login, default None. -        Regular default ssh keys will be used without specifying this argument. -    password : str;  -        Your ssh password to the ssh server. Note that if this is left None, -        you will be prompted for it if passwordless key based login is unavailable. -    timeout : int [default: 60] -        The time (in seconds) after which no activity will result in the tunnel -        closing.  This prevents orphaned tunnels from running forever. -    """ -    if pexpect is None: -        raise ImportError("pexpect unavailable, use paramiko_tunnel") -    ssh="ssh " -    if keyfile: -        ssh += "-i " + keyfile -     -    if ':' in server: -        server, port = server.split(':') -        ssh += " -p %s" % port -     -    cmd = "%s -O check %s" % (ssh, server) -    (output, exitstatus) = pexpect.run(cmd, withexitstatus=True) -    if not exitstatus: -        pid = int(output[output.find("(pid=")+5:output.find(")")])  -        cmd = "%s -O forward -L 127.0.0.1:%i:%s:%i %s" % ( -            ssh, lport, remoteip, rport, server) -        (output, exitstatus) = pexpect.run(cmd, withexitstatus=True) -        if not exitstatus: -            atexit.register(_stop_tunnel, cmd.replace("-O forward", "-O cancel", 1)) -            return pid -    cmd = "%s -f -S none -L 127.0.0.1:%i:%s:%i %s sleep %i" % ( -        ssh, lport, remoteip, rport, server, timeout) -    tunnel = pexpect.spawn(cmd) -    failed = False -    while True: -        try: -            tunnel.expect('[Pp]assword:', timeout=.1) -        except pexpect.TIMEOUT: -            continue -        except pexpect.EOF: -            if tunnel.exitstatus: -                print(tunnel.exitstatus) -                print(tunnel.before) -                print(tunnel.after) -                raise RuntimeError("tunnel '%s' failed to start"%(cmd)) -            else: -                return tunnel.pid -        else: -            if failed: -                print("Password rejected, try again") -                password=None -            if password is None: -                password = getpass("%s's password: "%(server)) -            tunnel.sendline(password) -            failed = True -     -def _stop_tunnel(cmd): -    pexpect.run(cmd) - -def _split_server(server): -    if '@' in server: -        username,server = server.split('@', 1) -    else: -        username = getuser() -    if ':' in server: -        server, port = server.split(':') -        port = int(port) -    else: -        port = 22 -    return username, server, port - -def paramiko_tunnel(lport, rport, server, remoteip='127.0.0.1', keyfile=None, password=None, timeout=60): -    """launch a tunner with paramiko in a subprocess. This should only be used -    when shell ssh is unavailable (e.g. Windows). -     -    This creates a tunnel redirecting `localhost:lport` to `remoteip:rport`, -    as seen from `server`. -     -    If you are familiar with ssh tunnels, this creates the tunnel: -     -    ssh server -L localhost:lport:remoteip:rport -     -    keyfile and password may be specified, but ssh config is checked for defaults. -     -     -    Parameters -    ---------- -     -    lport : int -        local port for connecting to the tunnel from this machine. -    rport : int -        port on the remote machine to connect to. -    server : str -        The ssh server to connect to. The full ssh server string will be parsed. -        user@server:port -    remoteip : str [Default: 127.0.0.1] -        The remote ip, specifying the destination of the tunnel. -        Default is localhost, which means that the tunnel would redirect -        localhost:lport on this machine to localhost:rport on the *server*. -         -    keyfile : str; path to public key file -        This specifies a key to be used in ssh login, default None. -        Regular default ssh keys will be used without specifying this argument. -    password : str;  -        Your ssh password to the ssh server. Note that if this is left None, -        you will be prompted for it if passwordless key based login is unavailable. -    timeout : int [default: 60] -        The time (in seconds) after which no activity will result in the tunnel -        closing.  This prevents orphaned tunnels from running forever. -     -    """ -    if paramiko is None: -        raise ImportError("Paramiko not available") -     -    if password is None: -        if not _try_passwordless_paramiko(server, keyfile): -            password = getpass("%s's password: "%(server)) - -    p = Process(target=_paramiko_tunnel,  -            args=(lport, rport, server, remoteip),  -            kwargs=dict(keyfile=keyfile, password=password)) -    p.daemon=False -    p.start() -    atexit.register(_shutdown_process, p) -    return p -     -def _shutdown_process(p): -    if p.is_alive(): -        p.terminate() - -def _paramiko_tunnel(lport, rport, server, remoteip, keyfile=None, password=None): -    """Function for actually starting a paramiko tunnel, to be passed -    to multiprocessing.Process(target=this), and not called directly. -    """ -    username, server, port = _split_server(server) -    client = paramiko.SSHClient() -    client.load_system_host_keys() -    client.set_missing_host_key_policy(paramiko.WarningPolicy()) - -    try: -        client.connect(server, port, username=username, key_filename=keyfile, -                       look_for_keys=True, password=password) -#    except paramiko.AuthenticationException: -#        if password is None: -#            password = getpass("%s@%s's password: "%(username, server)) -#            client.connect(server, port, username=username, password=password) -#        else: -#            raise -    except Exception as e: -        print('*** Failed to connect to %s:%d: %r' % (server, port, e)) -        sys.exit(1) - -    # Don't let SIGINT kill the tunnel subprocess -    signal.signal(signal.SIGINT, signal.SIG_IGN) - -    try: -        forward_tunnel(lport, remoteip, rport, client.get_transport()) -    except KeyboardInterrupt: -        print('SIGINT: Port forwarding stopped cleanly') -        sys.exit(0) -    except Exception as e: -        print("Port forwarding stopped uncleanly: %s"%e) -        sys.exit(255) - -if sys.platform == 'win32': -    ssh_tunnel = paramiko_tunnel -else: -    ssh_tunnel = openssh_tunnel - -     -__all__ = ['tunnel_connection', 'ssh_tunnel', 'openssh_tunnel', 'paramiko_tunnel', 'try_passwordless_ssh'] - - diff --git a/zmq/sugar/__init__.py b/zmq/sugar/__init__.py deleted file mode 100644 index d0510a4..0000000 --- a/zmq/sugar/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -"""pure-Python sugar wrappers for core 0MQ objects.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -from zmq.sugar import ( -    constants, context, frame, poll, socket, tracker, version -) -from zmq import error - -__all__ = ['constants'] -for submod in ( -    constants, context, error, frame, poll, socket, tracker, version -): -    __all__.extend(submod.__all__) - -from zmq.error import * -from zmq.sugar.context import * -from zmq.sugar.tracker import * -from zmq.sugar.socket import * -from zmq.sugar.constants import * -from zmq.sugar.frame import * -from zmq.sugar.poll import * -# from zmq.sugar.stopwatch import * -# from zmq.sugar._device import * -from zmq.sugar.version import * diff --git a/zmq/sugar/attrsettr.py b/zmq/sugar/attrsettr.py deleted file mode 100644 index 4bbd36d..0000000 --- a/zmq/sugar/attrsettr.py +++ /dev/null @@ -1,52 +0,0 @@ -# coding: utf-8 -"""Mixin for mapping set/getattr to self.set/get""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -from . import constants - -class AttributeSetter(object): -     -    def __setattr__(self, key, value): -        """set zmq options by attribute""" -         -        # regular setattr only allowed for class-defined attributes -        for obj in [self] + self.__class__.mro(): -            if key in obj.__dict__: -                object.__setattr__(self, key, value) -                return -         -        upper_key = key.upper() -        try: -            opt = getattr(constants, upper_key) -        except AttributeError: -            raise AttributeError("%s has no such option: %s" % ( -                self.__class__.__name__, upper_key) -            ) -        else: -            self._set_attr_opt(upper_key, opt, value) -     -    def _set_attr_opt(self, name, opt, value): -        """override if setattr should do something other than call self.set""" -        self.set(opt, value) -     -    def __getattr__(self, key): -        """get zmq options by attribute""" -        upper_key = key.upper() -        try: -            opt = getattr(constants, upper_key) -        except AttributeError: -            raise AttributeError("%s has no such option: %s" % ( -                self.__class__.__name__, upper_key) -            ) -        else: -            return self._get_attr_opt(upper_key, opt) - -    def _get_attr_opt(self, name, opt): -        """override if getattr should do something other than call self.get""" -        return self.get(opt) -     - -__all__ = ['AttributeSetter'] diff --git a/zmq/sugar/constants.py b/zmq/sugar/constants.py deleted file mode 100644 index 58b2263..0000000 --- a/zmq/sugar/constants.py +++ /dev/null @@ -1,91 +0,0 @@ -"""0MQ Constants.""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from zmq.backend import constants -from zmq.utils.constant_names import ( -    base_names, -    switched_sockopt_names, -    int_sockopt_names, -    int64_sockopt_names, -    bytes_sockopt_names, -    ctx_opt_names, -    msg_opt_names, -) - -#----------------------------------------------------------------------------- -# Python module level constants -#----------------------------------------------------------------------------- - -__all__ = [ -    'int_sockopts', -    'int64_sockopts', -    'bytes_sockopts', -    'ctx_opts', -    'ctx_opt_names', -    ] - -int_sockopts    = set() -int64_sockopts  = set() -bytes_sockopts  = set() -ctx_opts        = set() -msg_opts        = set() - - -if constants.VERSION < 30000: -    int64_sockopt_names.extend(switched_sockopt_names) -else: -    int_sockopt_names.extend(switched_sockopt_names) - -def _add_constant(name, container=None): -    """add a constant to be defined -     -    optionally add it to one of the sets for use in get/setopt checkers -    """ -    c = getattr(constants, name, -1) -    if c == -1: -        return -    globals()[name] = c -    __all__.append(name) -    if container is not None: -        container.add(c) -    return c -     -for name in base_names: -    _add_constant(name) - -for name in int_sockopt_names: -    _add_constant(name, int_sockopts) - -for name in int64_sockopt_names: -    _add_constant(name, int64_sockopts) - -for name in bytes_sockopt_names: -    _add_constant(name, bytes_sockopts) - -for name in ctx_opt_names: -    _add_constant(name, ctx_opts) - -for name in msg_opt_names: -    _add_constant(name, msg_opts) - -# ensure some aliases are always defined -aliases = [ -    ('DONTWAIT', 'NOBLOCK'), -    ('XREQ', 'DEALER'), -    ('XREP', 'ROUTER'), -] -for group in aliases: -    undefined = set() -    found = None -    for name in group: -        value = getattr(constants, name, -1) -        if value != -1: -            found = value -        else: -            undefined.add(name) -    if found is not None: -        for name in undefined: -            globals()[name] = found -            __all__.append(name) diff --git a/zmq/sugar/context.py b/zmq/sugar/context.py deleted file mode 100644 index 86a9c5d..0000000 --- a/zmq/sugar/context.py +++ /dev/null @@ -1,192 +0,0 @@ -# coding: utf-8 -"""Python bindings for 0MQ.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import atexit -import weakref - -from zmq.backend import Context as ContextBase -from . import constants -from .attrsettr import AttributeSetter -from .constants import ENOTSUP, ctx_opt_names -from .socket import Socket -from zmq.error import ZMQError - -from zmq.utils.interop import cast_int_addr - - -class Context(ContextBase, AttributeSetter): -    """Create a zmq Context -     -    A zmq Context creates sockets via its ``ctx.socket`` method. -    """ -    sockopts = None -    _instance = None -    _shadow = False -    _exiting = False -     -    def __init__(self, io_threads=1, **kwargs): -        super(Context, self).__init__(io_threads=io_threads, **kwargs) -        if kwargs.get('shadow', False): -            self._shadow = True -        else: -            self._shadow = False -        self.sockopts = {} -         -        self._exiting = False -        if not self._shadow: -            ctx_ref = weakref.ref(self) -            def _notify_atexit(): -                ctx = ctx_ref() -                if ctx is not None: -                    ctx._exiting = True -            atexit.register(_notify_atexit) -     -    def __del__(self): -        """deleting a Context should terminate it, without trying non-threadsafe destroy""" -        if not self._shadow and not self._exiting: -            self.term() -     -    def __enter__(self): -        return self -     -    def __exit__(self, *args, **kwargs): -        self.term() -     -    @classmethod -    def shadow(cls, address): -        """Shadow an existing libzmq context -         -        address is the integer address of the libzmq context -        or an FFI pointer to it. -         -        .. versionadded:: 14.1 -        """ -        address = cast_int_addr(address) -        return cls(shadow=address) -     -    @classmethod -    def shadow_pyczmq(cls, ctx): -        """Shadow an existing pyczmq context -         -        ctx is the FFI `zctx_t *` pointer -         -        .. versionadded:: 14.1 -        """ -        from pyczmq import zctx -         -        underlying = zctx.underlying(ctx) -        address = cast_int_addr(underlying) -        return cls(shadow=address) - -    # static method copied from tornado IOLoop.instance -    @classmethod -    def instance(cls, io_threads=1): -        """Returns a global Context instance. - -        Most single-threaded applications have a single, global Context. -        Use this method instead of passing around Context instances -        throughout your code. - -        A common pattern for classes that depend on Contexts is to use -        a default argument to enable programs with multiple Contexts -        but not require the argument for simpler applications: - -            class MyClass(object): -                def __init__(self, context=None): -                    self.context = context or Context.instance() -        """ -        if cls._instance is None or cls._instance.closed: -            cls._instance = cls(io_threads=io_threads) -        return cls._instance -     -    #------------------------------------------------------------------------- -    # Hooks for ctxopt completion -    #------------------------------------------------------------------------- -     -    def __dir__(self): -        keys = dir(self.__class__) - -        for collection in ( -            ctx_opt_names, -        ): -            keys.extend(collection) -        return keys - -    #------------------------------------------------------------------------- -    # Creating Sockets -    #------------------------------------------------------------------------- - -    @property -    def _socket_class(self): -        return Socket -     -    def socket(self, socket_type): -        """Create a Socket associated with this Context. - -        Parameters -        ---------- -        socket_type : int -            The socket type, which can be any of the 0MQ socket types: -            REQ, REP, PUB, SUB, PAIR, DEALER, ROUTER, PULL, PUSH, etc. -        """ -        if self.closed: -            raise ZMQError(ENOTSUP) -        s = self._socket_class(self, socket_type) -        for opt, value in self.sockopts.items(): -            try: -                s.setsockopt(opt, value) -            except ZMQError: -                # ignore ZMQErrors, which are likely for socket options -                # that do not apply to a particular socket type, e.g. -                # SUBSCRIBE for non-SUB sockets. -                pass -        return s -     -    def setsockopt(self, opt, value): -        """set default socket options for new sockets created by this Context -         -        .. versionadded:: 13.0 -        """ -        self.sockopts[opt] = value -     -    def getsockopt(self, opt): -        """get default socket options for new sockets created by this Context -         -        .. versionadded:: 13.0 -        """ -        return self.sockopts[opt] -     -    def _set_attr_opt(self, name, opt, value): -        """set default sockopts as attributes""" -        if name in constants.ctx_opt_names: -            return self.set(opt, value) -        else: -            self.sockopts[opt] = value -     -    def _get_attr_opt(self, name, opt): -        """get default sockopts as attributes""" -        if name in constants.ctx_opt_names: -            return self.get(opt) -        else: -            if opt not in self.sockopts: -                raise AttributeError(name) -            else: -                return self.sockopts[opt] -     -    def __delattr__(self, key): -        """delete default sockopts as attributes""" -        key = key.upper() -        try: -            opt = getattr(constants, key) -        except AttributeError: -            raise AttributeError("no such socket option: %s" % key) -        else: -            if opt not in self.sockopts: -                raise AttributeError(key) -            else: -                del self.sockopts[opt] - -__all__ = ['Context'] diff --git a/zmq/sugar/frame.py b/zmq/sugar/frame.py deleted file mode 100644 index cae4491..0000000 --- a/zmq/sugar/frame.py +++ /dev/null @@ -1,17 +0,0 @@ -# coding: utf-8 -"""0MQ Frame pure Python methods.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -from .attrsettr import AttributeSetter -from zmq.backend import Frame as FrameBase - - -class Frame(FrameBase, AttributeSetter): -    pass - -# keep deprecated alias -Message = Frame -__all__ = ['Frame', 'Message']
\ No newline at end of file diff --git a/zmq/sugar/poll.py b/zmq/sugar/poll.py deleted file mode 100644 index c7b1d1b..0000000 --- a/zmq/sugar/poll.py +++ /dev/null @@ -1,161 +0,0 @@ -"""0MQ polling related functions and classes.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import zmq -from zmq.backend import zmq_poll -from .constants import POLLIN, POLLOUT, POLLERR - -#----------------------------------------------------------------------------- -# Polling related methods -#----------------------------------------------------------------------------- - - -class Poller(object): -    """A stateful poll interface that mirrors Python's built-in poll.""" -    sockets = None -    _map = {} - -    def __init__(self): -        self.sockets = [] -        self._map = {} -     -    def __contains__(self, socket): -        return socket in self._map - -    def register(self, socket, flags=POLLIN|POLLOUT): -        """p.register(socket, flags=POLLIN|POLLOUT) - -        Register a 0MQ socket or native fd for I/O monitoring. -         -        register(s,0) is equivalent to unregister(s). - -        Parameters -        ---------- -        socket : zmq.Socket or native socket -            A zmq.Socket or any Python object having a ``fileno()``  -            method that returns a valid file descriptor. -        flags : int -            The events to watch for.  Can be POLLIN, POLLOUT or POLLIN|POLLOUT. -            If `flags=0`, socket will be unregistered. -        """ -        if flags: -            if socket in self._map: -                idx = self._map[socket] -                self.sockets[idx] = (socket, flags) -            else: -                idx = len(self.sockets) -                self.sockets.append((socket, flags)) -                self._map[socket] = idx -        elif socket in self._map: -            # uregister sockets registered with no events -            self.unregister(socket) -        else: -            # ignore new sockets with no events -            pass - -    def modify(self, socket, flags=POLLIN|POLLOUT): -        """Modify the flags for an already registered 0MQ socket or native fd.""" -        self.register(socket, flags) - -    def unregister(self, socket): -        """Remove a 0MQ socket or native fd for I/O monitoring. - -        Parameters -        ---------- -        socket : Socket -            The socket instance to stop polling. -        """ -        idx = self._map.pop(socket) -        self.sockets.pop(idx) -        # shift indices after deletion -        for socket, flags in self.sockets[idx:]: -            self._map[socket] -= 1 - -    def poll(self, timeout=None): -        """Poll the registered 0MQ or native fds for I/O. - -        Parameters -        ---------- -        timeout : float, int -            The timeout in milliseconds. If None, no `timeout` (infinite). This -            is in milliseconds to be compatible with ``select.poll()``. The -            underlying zmq_poll uses microseconds and we convert to that in -            this function. -         -        Returns -        ------- -        events : list of tuples -            The list of events that are ready to be processed. -            This is a list of tuples of the form ``(socket, event)``, where the 0MQ Socket -            or integer fd is the first element, and the poll event mask (POLLIN, POLLOUT) is the second. -            It is common to call ``events = dict(poller.poll())``, -            which turns the list of tuples into a mapping of ``socket : event``. -        """ -        if timeout is None or timeout < 0: -            timeout = -1 -        elif isinstance(timeout, float): -            timeout = int(timeout) -        return zmq_poll(self.sockets, timeout=timeout) - - -def select(rlist, wlist, xlist, timeout=None): -    """select(rlist, wlist, xlist, timeout=None) -> (rlist, wlist, xlist) - -    Return the result of poll as a lists of sockets ready for r/w/exception. - -    This has the same interface as Python's built-in ``select.select()`` function. - -    Parameters -    ---------- -    timeout : float, int, optional -        The timeout in seconds. If None, no timeout (infinite). This is in seconds to be -        compatible with ``select.select()``. The underlying zmq_poll uses microseconds -        and we convert to that in this function. -    rlist : list of sockets/FDs -        sockets/FDs to be polled for read events -    wlist : list of sockets/FDs -        sockets/FDs to be polled for write events -    xlist : list of sockets/FDs -        sockets/FDs to be polled for error events -     -    Returns -    ------- -    (rlist, wlist, xlist) : tuple of lists of sockets (length 3) -        Lists correspond to sockets available for read/write/error events respectively. -    """ -    if timeout is None: -        timeout = -1 -    # Convert from sec -> us for zmq_poll. -    # zmq_poll accepts 3.x style timeout in ms -    timeout = int(timeout*1000.0) -    if timeout < 0: -        timeout = -1 -    sockets = [] -    for s in set(rlist + wlist + xlist): -        flags = 0 -        if s in rlist: -            flags |= POLLIN -        if s in wlist: -            flags |= POLLOUT -        if s in xlist: -            flags |= POLLERR -        sockets.append((s, flags)) -    return_sockets = zmq_poll(sockets, timeout) -    rlist, wlist, xlist = [], [], [] -    for s, flags in return_sockets: -        if flags & POLLIN: -            rlist.append(s) -        if flags & POLLOUT: -            wlist.append(s) -        if flags & POLLERR: -            xlist.append(s) -    return rlist, wlist, xlist - -#----------------------------------------------------------------------------- -# Symbols to export -#----------------------------------------------------------------------------- - -__all__ = [ 'Poller', 'select' ] diff --git a/zmq/sugar/socket.py b/zmq/sugar/socket.py deleted file mode 100644 index c4d4df8..0000000 --- a/zmq/sugar/socket.py +++ /dev/null @@ -1,470 +0,0 @@ -# coding: utf-8 -"""0MQ Socket pure Python methods.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import codecs -import random -import warnings - -import zmq -from zmq.backend import Socket as SocketBase -from .poll import Poller -from . import constants -from .attrsettr import AttributeSetter -from zmq.error import ZMQError, ZMQBindError -from zmq.utils import jsonapi -from zmq.utils.strtypes import bytes,unicode,basestring -from zmq.utils.interop import cast_int_addr - -from .constants import ( -    SNDMORE, ENOTSUP, POLLIN, -    int64_sockopt_names, -    int_sockopt_names, -    bytes_sockopt_names, -) -try: -    import cPickle -    pickle = cPickle -except: -    cPickle = None -    import pickle - - -class Socket(SocketBase, AttributeSetter): -    """The ZMQ socket object -     -    To create a Socket, first create a Context:: -     -        ctx = zmq.Context.instance() -     -    then call ``ctx.socket(socket_type)``:: -     -        s = ctx.socket(zmq.ROUTER) -     -    """ -    _shadow = False -     -    def __del__(self): -        if not self._shadow: -            self.close() - -    #------------------------------------------------------------------------- -    # Socket creation -    #------------------------------------------------------------------------- -     -    @classmethod -    def shadow(cls, address): -        """Shadow an existing libzmq socket -         -        address is the integer address of the libzmq socket -        or an FFI pointer to it. -         -        .. versionadded:: 14.1 -        """ -        address = cast_int_addr(address) -        return cls(shadow=address) -     -    #------------------------------------------------------------------------- -    # Deprecated aliases -    #------------------------------------------------------------------------- -     -    @property -    def socket_type(self): -        warnings.warn("Socket.socket_type is deprecated, use Socket.type", -            DeprecationWarning -        ) -        return self.type -     -    #------------------------------------------------------------------------- -    # Hooks for sockopt completion -    #------------------------------------------------------------------------- -     -    def __dir__(self): -        keys = dir(self.__class__) -        for collection in ( -            bytes_sockopt_names, -            int_sockopt_names, -            int64_sockopt_names, -        ): -            keys.extend(collection) -        return keys -     -    #------------------------------------------------------------------------- -    # Getting/Setting options -    #------------------------------------------------------------------------- -    setsockopt = SocketBase.set -    getsockopt = SocketBase.get -     -    def set_string(self, option, optval, encoding='utf-8'): -        """set socket options with a unicode object -         -        This is simply a wrapper for setsockopt to protect from encoding ambiguity. - -        See the 0MQ documentation for details on specific options. -         -        Parameters -        ---------- -        option : int -            The name of the option to set. Can be any of: SUBSCRIBE,  -            UNSUBSCRIBE, IDENTITY -        optval : unicode string (unicode on py2, str on py3) -            The value of the option to set. -        encoding : str -            The encoding to be used, default is utf8 -        """ -        if not isinstance(optval, unicode): -            raise TypeError("unicode strings only") -        return self.set(option, optval.encode(encoding)) -     -    setsockopt_unicode = setsockopt_string = set_string -     -    def get_string(self, option, encoding='utf-8'): -        """get the value of a socket option - -        See the 0MQ documentation for details on specific options. - -        Parameters -        ---------- -        option : int -            The option to retrieve. - -        Returns -        ------- -        optval : unicode string (unicode on py2, str on py3) -            The value of the option as a unicode string. -        """ -     -        if option not in constants.bytes_sockopts: -            raise TypeError("option %i will not return a string to be decoded"%option) -        return self.getsockopt(option).decode(encoding) -     -    getsockopt_unicode = getsockopt_string = get_string -     -    def bind_to_random_port(self, addr, min_port=49152, max_port=65536, max_tries=100): -        """bind this socket to a random port in a range - -        Parameters -        ---------- -        addr : str -            The address string without the port to pass to ``Socket.bind()``. -        min_port : int, optional -            The minimum port in the range of ports to try (inclusive). -        max_port : int, optional -            The maximum port in the range of ports to try (exclusive). -        max_tries : int, optional -            The maximum number of bind attempts to make. - -        Returns -        ------- -        port : int -            The port the socket was bound to. -     -        Raises -        ------ -        ZMQBindError -            if `max_tries` reached before successful bind -        """ -        for i in range(max_tries): -            try: -                port = random.randrange(min_port, max_port) -                self.bind('%s:%s' % (addr, port)) -            except ZMQError as exception: -                if not exception.errno == zmq.EADDRINUSE: -                    raise -            else: -                return port -        raise ZMQBindError("Could not bind socket to random port.") -     -    def get_hwm(self): -        """get the High Water Mark -         -        On libzmq ≥ 3, this gets SNDHWM if available, otherwise RCVHWM -        """ -        major = zmq.zmq_version_info()[0] -        if major >= 3: -            # return sndhwm, fallback on rcvhwm -            try: -                return self.getsockopt(zmq.SNDHWM) -            except zmq.ZMQError as e: -                pass -             -            return self.getsockopt(zmq.RCVHWM) -        else: -            return self.getsockopt(zmq.HWM) -     -    def set_hwm(self, value): -        """set the High Water Mark -         -        On libzmq ≥ 3, this sets both SNDHWM and RCVHWM -        """ -        major = zmq.zmq_version_info()[0] -        if major >= 3: -            raised = None -            try: -                self.sndhwm = value -            except Exception as e: -                raised = e -            try: -                self.rcvhwm = value -            except Exception: -                raised = e -             -            if raised: -                raise raised -        else: -            return self.setsockopt(zmq.HWM, value) -     -    hwm = property(get_hwm, set_hwm, -        """property for High Water Mark -         -        Setting hwm sets both SNDHWM and RCVHWM as appropriate. -        It gets SNDHWM if available, otherwise RCVHWM. -        """ -    ) -     -    #------------------------------------------------------------------------- -    # Sending and receiving messages -    #------------------------------------------------------------------------- - -    def send_multipart(self, msg_parts, flags=0, copy=True, track=False): -        """send a sequence of buffers as a multipart message -         -        The zmq.SNDMORE flag is added to all msg parts before the last. - -        Parameters -        ---------- -        msg_parts : iterable -            A sequence of objects to send as a multipart message. Each element -            can be any sendable object (Frame, bytes, buffer-providers) -        flags : int, optional -            SNDMORE is handled automatically for frames before the last. -        copy : bool, optional -            Should the frame(s) be sent in a copying or non-copying manner. -        track : bool, optional -            Should the frame(s) be tracked for notification that ZMQ has -            finished with it (ignored if copy=True). -     -        Returns -        ------- -        None : if copy or not track -        MessageTracker : if track and not copy -            a MessageTracker object, whose `pending` property will -            be True until the last send is completed. -        """ -        for msg in msg_parts[:-1]: -            self.send(msg, SNDMORE|flags, copy=copy, track=track) -        # Send the last part without the extra SNDMORE flag. -        return self.send(msg_parts[-1], flags, copy=copy, track=track) - -    def recv_multipart(self, flags=0, copy=True, track=False): -        """receive a multipart message as a list of bytes or Frame objects - -        Parameters -        ---------- -        flags : int, optional -            Any supported flag: NOBLOCK. If NOBLOCK is set, this method -            will raise a ZMQError with EAGAIN if a message is not ready. -            If NOBLOCK is not set, then this method will block until a -            message arrives. -        copy : bool, optional -            Should the message frame(s) be received in a copying or non-copying manner? -            If False a Frame object is returned for each part, if True a copy of -            the bytes is made for each frame. -        track : bool, optional -            Should the message frame(s) be tracked for notification that ZMQ has -            finished with it? (ignored if copy=True) -         -        Returns -        ------- -        msg_parts : list -            A list of frames in the multipart message; either Frames or bytes, -            depending on `copy`. -     -        """ -        parts = [self.recv(flags, copy=copy, track=track)] -        # have first part already, only loop while more to receive -        while self.getsockopt(zmq.RCVMORE): -            part = self.recv(flags, copy=copy, track=track) -            parts.append(part) -     -        return parts - -    def send_string(self, u, flags=0, copy=True, encoding='utf-8'): -        """send a Python unicode string as a message with an encoding -     -        0MQ communicates with raw bytes, so you must encode/decode -        text (unicode on py2, str on py3) around 0MQ. -         -        Parameters -        ---------- -        u : Python unicode string (unicode on py2, str on py3) -            The unicode string to send. -        flags : int, optional -            Any valid send flag. -        encoding : str [default: 'utf-8'] -            The encoding to be used -        """ -        if not isinstance(u, basestring): -            raise TypeError("unicode/str objects only") -        return self.send(u.encode(encoding), flags=flags, copy=copy) -     -    send_unicode = send_string -     -    def recv_string(self, flags=0, encoding='utf-8'): -        """receive a unicode string, as sent by send_string -     -        Parameters -        ---------- -        flags : int -            Any valid recv flag. -        encoding : str [default: 'utf-8'] -            The encoding to be used - -        Returns -        ------- -        s : unicode string (unicode on py2, str on py3) -            The Python unicode string that arrives as encoded bytes. -        """ -        b = self.recv(flags=flags) -        return b.decode(encoding) -     -    recv_unicode = recv_string -     -    def send_pyobj(self, obj, flags=0, protocol=-1): -        """send a Python object as a message using pickle to serialize - -        Parameters -        ---------- -        obj : Python object -            The Python object to send. -        flags : int -            Any valid send flag. -        protocol : int -            The pickle protocol number to use. Default of -1 will select -            the highest supported number. Use 0 for multiple platform -            support. -        """ -        msg = pickle.dumps(obj, protocol) -        return self.send(msg, flags) - -    def recv_pyobj(self, flags=0): -        """receive a Python object as a message using pickle to serialize - -        Parameters -        ---------- -        flags : int -            Any valid recv flag. - -        Returns -        ------- -        obj : Python object -            The Python object that arrives as a message. -        """ -        s = self.recv(flags) -        return pickle.loads(s) - -    def send_json(self, obj, flags=0, **kwargs): -        """send a Python object as a message using json to serialize -         -        Keyword arguments are passed on to json.dumps -         -        Parameters -        ---------- -        obj : Python object -            The Python object to send -        flags : int -            Any valid send flag -        """ -        msg = jsonapi.dumps(obj, **kwargs) -        return self.send(msg, flags) - -    def recv_json(self, flags=0, **kwargs): -        """receive a Python object as a message using json to serialize - -        Keyword arguments are passed on to json.loads -         -        Parameters -        ---------- -        flags : int -            Any valid recv flag. - -        Returns -        ------- -        obj : Python object -            The Python object that arrives as a message. -        """ -        msg = self.recv(flags) -        return jsonapi.loads(msg, **kwargs) -     -    _poller_class = Poller - -    def poll(self, timeout=None, flags=POLLIN): -        """poll the socket for events -         -        The default is to poll forever for incoming -        events.  Timeout is in milliseconds, if specified. - -        Parameters -        ---------- -        timeout : int [default: None] -            The timeout (in milliseconds) to wait for an event. If unspecified -            (or specified None), will wait forever for an event. -        flags : bitfield (int) [default: POLLIN] -            The event flags to poll for (any combination of POLLIN|POLLOUT). -            The default is to check for incoming events (POLLIN). - -        Returns -        ------- -        events : bitfield (int) -            The events that are ready and waiting.  Will be 0 if no events were ready -            by the time timeout was reached. -        """ - -        if self.closed: -            raise ZMQError(ENOTSUP) - -        p = self._poller_class() -        p.register(self, flags) -        evts = dict(p.poll(timeout)) -        # return 0 if no events, otherwise return event bitfield -        return evts.get(self, 0) - -    def get_monitor_socket(self, events=None, addr=None): -        """Return a connected PAIR socket ready to receive the event notifications. -         -        .. versionadded:: libzmq-4.0 -        .. versionadded:: 14.0 -         -        Parameters -        ---------- -        events : bitfield (int) [default: ZMQ_EVENTS_ALL] -            The bitmask defining which events are wanted. -        addr :  string [default: None] -            The optional endpoint for the monitoring sockets. - -        Returns -        ------- -        socket :  (PAIR) -            The socket is already connected and ready to receive messages. -        """ -        # safe-guard, method only available on libzmq >= 4 -        if zmq.zmq_version_info() < (4,): -            raise NotImplementedError("get_monitor_socket requires libzmq >= 4, have %s" % zmq.zmq_version()) -        if addr is None: -            # create endpoint name from internal fd -            addr = "inproc://monitor.s-%d" % self.FD -        if events is None: -            # use all events -            events = zmq.EVENT_ALL -        # attach monitoring socket -        self.monitor(addr, events) -        # create new PAIR socket and connect it -        ret = self.context.socket(zmq.PAIR) -        ret.connect(addr) -        return ret - - -__all__ = ['Socket'] diff --git a/zmq/sugar/tracker.py b/zmq/sugar/tracker.py deleted file mode 100644 index fb8c007..0000000 --- a/zmq/sugar/tracker.py +++ /dev/null @@ -1,120 +0,0 @@ -"""Tracker for zero-copy messages with 0MQ.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import time - -try: -    # below 3.3 -    from threading import _Event as Event -except (ImportError, AttributeError): -    # python throws ImportError, cython throws AttributeError -    from threading import Event - -from zmq.error import NotDone -from zmq.backend import Frame - -class MessageTracker(object): -    """MessageTracker(*towatch) - -    A class for tracking if 0MQ is done using one or more messages. - -    When you send a 0MQ message, it is not sent immediately. The 0MQ IO thread -    sends the message at some later time. Often you want to know when 0MQ has -    actually sent the message though. This is complicated by the fact that -    a single 0MQ message can be sent multiple times using different sockets. -    This class allows you to track all of the 0MQ usages of a message. - -    Parameters -    ---------- -    *towatch : tuple of Event, MessageTracker, Message instances. -        This list of objects to track. This class can track the low-level -        Events used by the Message class, other MessageTrackers or -        actual Messages. -    """ -    events = None -    peers = None - -    def __init__(self, *towatch): -        """MessageTracker(*towatch) - -        Create a message tracker to track a set of mesages. - -        Parameters -        ---------- -        *towatch : tuple of Event, MessageTracker, Message instances. -            This list of objects to track. This class can track the low-level -            Events used by the Message class, other MessageTrackers or  -            actual Messages. -        """ -        self.events = set() -        self.peers = set() -        for obj in towatch: -            if isinstance(obj, Event): -                self.events.add(obj) -            elif isinstance(obj, MessageTracker): -                self.peers.add(obj) -            elif isinstance(obj, Frame): -                if not obj.tracker: -                    raise ValueError("Not a tracked message") -                self.peers.add(obj.tracker) -            else: -                raise TypeError("Require Events or Message Frames, not %s"%type(obj)) -     -    @property -    def done(self): -        """Is 0MQ completely done with the message(s) being tracked?""" -        for evt in self.events: -            if not evt.is_set(): -                return False -        for pm in self.peers: -            if not pm.done: -                return False -        return True -     -    def wait(self, timeout=-1): -        """mt.wait(timeout=-1) - -        Wait for 0MQ to be done with the message or until `timeout`. - -        Parameters -        ---------- -        timeout : float [default: -1, wait forever] -            Maximum time in (s) to wait before raising NotDone. - -        Returns -        ------- -        None -            if done before `timeout` -         -        Raises -        ------ -        NotDone -            if `timeout` reached before I am done. -        """ -        tic = time.time() -        if timeout is False or timeout < 0: -            remaining = 3600*24*7 # a week -        else: -            remaining = timeout -        done = False -        for evt in self.events: -            if remaining < 0: -                raise NotDone -            evt.wait(timeout=remaining) -            if not evt.is_set(): -                raise NotDone -            toc = time.time() -            remaining -= (toc-tic) -            tic = toc -         -        for peer in self.peers: -            if remaining < 0: -                raise NotDone -            peer.wait(timeout=remaining) -            toc = time.time() -            remaining -= (toc-tic) -            tic = toc - -__all__ = ['MessageTracker']
\ No newline at end of file diff --git a/zmq/sugar/version.py b/zmq/sugar/version.py deleted file mode 100644 index 3e2de6c..0000000 --- a/zmq/sugar/version.py +++ /dev/null @@ -1,48 +0,0 @@ -"""PyZMQ and 0MQ version functions.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -from zmq.backend import zmq_version_info - - -VERSION_MAJOR = 14 -VERSION_MINOR = 3 -VERSION_PATCH = 1 -VERSION_EXTRA = "" -__version__ = '%i.%i.%i' % (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH) - -if VERSION_EXTRA: -    __version__ = "%s-%s" % (__version__, VERSION_EXTRA) -    version_info = (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, float('inf')) -else: -    version_info = (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH) - -__revision__ = '' - -def pyzmq_version(): -    """return the version of pyzmq as a string""" -    if __revision__: -        return '@'.join([__version__,__revision__[:6]]) -    else: -        return __version__ - -def pyzmq_version_info(): -    """return the pyzmq version as a tuple of at least three numbers -     -    If pyzmq is a development version, `inf` will be appended after the third integer. -    """ -    return version_info - - -def zmq_version(): -    """return the version of libzmq as a string""" -    return "%i.%i.%i" % zmq_version_info() - - -__all__ = ['zmq_version', 'zmq_version_info', -           'pyzmq_version','pyzmq_version_info', -           '__version__', '__revision__' -] - diff --git a/zmq/tests/__init__.py b/zmq/tests/__init__.py deleted file mode 100644 index 09b3c89..0000000 --- a/zmq/tests/__init__.py +++ /dev/null @@ -1,211 +0,0 @@ -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import functools -import sys -import time -from threading import Thread - -from unittest import TestCase - -import zmq -from zmq.utils import jsonapi - -try: -    import gevent -    from zmq import green as gzmq -    have_gevent = True -except ImportError: -    have_gevent = False - -try: -    from unittest import SkipTest -except ImportError: -    try: -        from nose import SkipTest -    except ImportError: -        class SkipTest(Exception): -            pass - -PYPY = 'PyPy' in sys.version - -#----------------------------------------------------------------------------- -# skip decorators (directly from unittest) -#----------------------------------------------------------------------------- - -_id = lambda x: x - -def skip(reason): -    """ -    Unconditionally skip a test. -    """ -    def decorator(test_item): -        if not (isinstance(test_item, type) and issubclass(test_item, TestCase)): -            @functools.wraps(test_item) -            def skip_wrapper(*args, **kwargs): -                raise SkipTest(reason) -            test_item = skip_wrapper - -        test_item.__unittest_skip__ = True -        test_item.__unittest_skip_why__ = reason -        return test_item -    return decorator - -def skip_if(condition, reason="Skipped"): -    """ -    Skip a test if the condition is true. -    """ -    if condition: -        return skip(reason) -    return _id - -skip_pypy = skip_if(PYPY, "Doesn't work on PyPy") - -#----------------------------------------------------------------------------- -# Base test class -#----------------------------------------------------------------------------- - -class BaseZMQTestCase(TestCase): -    green = False -     -    @property -    def Context(self): -        if self.green: -            return gzmq.Context -        else: -            return zmq.Context -     -    def socket(self, socket_type): -        s = self.context.socket(socket_type) -        self.sockets.append(s) -        return s -     -    def setUp(self): -        if self.green and not have_gevent: -                raise SkipTest("requires gevent") -        self.context = self.Context.instance() -        self.sockets = [] -     -    def tearDown(self): -        contexts = set([self.context]) -        while self.sockets: -            sock = self.sockets.pop() -            contexts.add(sock.context) # in case additional contexts are created -            sock.close(0) -        for ctx in contexts: -            t = Thread(target=ctx.term) -            t.daemon = True -            t.start() -            t.join(timeout=2) -            if t.is_alive(): -                # reset Context.instance, so the failure to term doesn't corrupt subsequent tests -                zmq.sugar.context.Context._instance = None -                raise RuntimeError("context could not terminate, open sockets likely remain in test") - -    def create_bound_pair(self, type1=zmq.PAIR, type2=zmq.PAIR, interface='tcp://127.0.0.1'): -        """Create a bound socket pair using a random port.""" -        s1 = self.context.socket(type1) -        s1.setsockopt(zmq.LINGER, 0) -        port = s1.bind_to_random_port(interface) -        s2 = self.context.socket(type2) -        s2.setsockopt(zmq.LINGER, 0) -        s2.connect('%s:%s' % (interface, port)) -        self.sockets.extend([s1,s2]) -        return s1, s2 - -    def ping_pong(self, s1, s2, msg): -        s1.send(msg) -        msg2 = s2.recv() -        s2.send(msg2) -        msg3 = s1.recv() -        return msg3 - -    def ping_pong_json(self, s1, s2, o): -        if jsonapi.jsonmod is None: -            raise SkipTest("No json library") -        s1.send_json(o) -        o2 = s2.recv_json() -        s2.send_json(o2) -        o3 = s1.recv_json() -        return o3 - -    def ping_pong_pyobj(self, s1, s2, o): -        s1.send_pyobj(o) -        o2 = s2.recv_pyobj() -        s2.send_pyobj(o2) -        o3 = s1.recv_pyobj() -        return o3 - -    def assertRaisesErrno(self, errno, func, *args, **kwargs): -        try: -            func(*args, **kwargs) -        except zmq.ZMQError as e: -            self.assertEqual(e.errno, errno, "wrong error raised, expected '%s' \ -got '%s'" % (zmq.ZMQError(errno), zmq.ZMQError(e.errno))) -        else: -            self.fail("Function did not raise any error") -     -    def _select_recv(self, multipart, socket, **kwargs): -        """call recv[_multipart] in a way that raises if there is nothing to receive""" -        if zmq.zmq_version_info() >= (3,1,0): -            # zmq 3.1 has a bug, where poll can return false positives, -            # so we wait a little bit just in case -            # See LIBZMQ-280 on JIRA -            time.sleep(0.1) -         -        r,w,x = zmq.select([socket], [], [], timeout=5) -        assert len(r) > 0, "Should have received a message" -        kwargs['flags'] = zmq.DONTWAIT | kwargs.get('flags', 0) -         -        recv = socket.recv_multipart if multipart else socket.recv -        return recv(**kwargs) -         -    def recv(self, socket, **kwargs): -        """call recv in a way that raises if there is nothing to receive""" -        return self._select_recv(False, socket, **kwargs) - -    def recv_multipart(self, socket, **kwargs): -        """call recv_multipart in a way that raises if there is nothing to receive""" -        return self._select_recv(True, socket, **kwargs) -     - -class PollZMQTestCase(BaseZMQTestCase): -    pass - -class GreenTest: -    """Mixin for making green versions of test classes""" -    green = True -     -    def assertRaisesErrno(self, errno, func, *args, **kwargs): -        if errno == zmq.EAGAIN: -            raise SkipTest("Skipping because we're green.") -        try: -            func(*args, **kwargs) -        except zmq.ZMQError: -            e = sys.exc_info()[1] -            self.assertEqual(e.errno, errno, "wrong error raised, expected '%s' \ -got '%s'" % (zmq.ZMQError(errno), zmq.ZMQError(e.errno))) -        else: -            self.fail("Function did not raise any error") - -    def tearDown(self): -        contexts = set([self.context]) -        while self.sockets: -            sock = self.sockets.pop() -            contexts.add(sock.context) # in case additional contexts are created -            sock.close() -        try: -            gevent.joinall([gevent.spawn(ctx.term) for ctx in contexts], timeout=2, raise_error=True) -        except gevent.Timeout: -            raise RuntimeError("context could not terminate, open sockets likely remain in test") -     -    def skip_green(self): -        raise SkipTest("Skipping because we are green") - -def skip_green(f): -    def skipping_test(self, *args, **kwargs): -        if self.green: -            raise SkipTest("Skipping because we are green") -        else: -            return f(self, *args, **kwargs) -    return skipping_test diff --git a/zmq/tests/test_auth.py b/zmq/tests/test_auth.py deleted file mode 100644 index d350f61..0000000 --- a/zmq/tests/test_auth.py +++ /dev/null @@ -1,431 +0,0 @@ -# -*- coding: utf8 -*- - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import logging -import os -import shutil -import sys -import tempfile - -import zmq.auth -from zmq.auth.ioloop import IOLoopAuthenticator -from zmq.auth.thread import ThreadAuthenticator - -from zmq.eventloop import ioloop, zmqstream -from zmq.tests import (BaseZMQTestCase, SkipTest) - -class BaseAuthTestCase(BaseZMQTestCase): -    def setUp(self): -        if zmq.zmq_version_info() < (4,0): -            raise SkipTest("security is new in libzmq 4.0") -        try: -            zmq.curve_keypair() -        except zmq.ZMQError: -            raise SkipTest("security requires libzmq to be linked against libsodium") -        super(BaseAuthTestCase, self).setUp() -        # enable debug logging while we run tests -        logging.getLogger('zmq.auth').setLevel(logging.DEBUG) -        self.auth = self.make_auth() -        self.auth.start() -        self.base_dir, self.public_keys_dir, self.secret_keys_dir = self.create_certs() -     -    def make_auth(self): -        raise NotImplementedError() -     -    def tearDown(self): -        if self.auth: -            self.auth.stop() -            self.auth = None -        self.remove_certs(self.base_dir) -        super(BaseAuthTestCase, self).tearDown() -     -    def create_certs(self): -        """Create CURVE certificates for a test""" - -        # Create temporary CURVE keypairs for this test run. We create all keys in a -        # temp directory and then move them into the appropriate private or public -        # directory. - -        base_dir = tempfile.mkdtemp() -        keys_dir = os.path.join(base_dir, 'certificates') -        public_keys_dir = os.path.join(base_dir, 'public_keys') -        secret_keys_dir = os.path.join(base_dir, 'private_keys') - -        os.mkdir(keys_dir) -        os.mkdir(public_keys_dir) -        os.mkdir(secret_keys_dir) - -        server_public_file, server_secret_file = zmq.auth.create_certificates(keys_dir, "server") -        client_public_file, client_secret_file = zmq.auth.create_certificates(keys_dir, "client") - -        for key_file in os.listdir(keys_dir): -            if key_file.endswith(".key"): -                shutil.move(os.path.join(keys_dir, key_file), -                            os.path.join(public_keys_dir, '.')) - -        for key_file in os.listdir(keys_dir): -            if key_file.endswith(".key_secret"): -                shutil.move(os.path.join(keys_dir, key_file), -                            os.path.join(secret_keys_dir, '.')) - -        return (base_dir, public_keys_dir, secret_keys_dir) - -    def remove_certs(self, base_dir): -        """Remove certificates for a test""" -        shutil.rmtree(base_dir) - -    def load_certs(self, secret_keys_dir): -        """Return server and client certificate keys""" -        server_secret_file = os.path.join(secret_keys_dir, "server.key_secret") -        client_secret_file = os.path.join(secret_keys_dir, "client.key_secret") - -        server_public, server_secret = zmq.auth.load_certificate(server_secret_file) -        client_public, client_secret = zmq.auth.load_certificate(client_secret_file) - -        return server_public, server_secret, client_public, client_secret - - -class TestThreadAuthentication(BaseAuthTestCase): -    """Test authentication running in a thread""" - -    def make_auth(self): -        return ThreadAuthenticator(self.context) - -    def can_connect(self, server, client): -        """Check if client can connect to server using tcp transport""" -        result = False -        iface = 'tcp://127.0.0.1' -        port = server.bind_to_random_port(iface) -        client.connect("%s:%i" % (iface, port)) -        msg = [b"Hello World"] -        server.send_multipart(msg) -        if client.poll(1000): -            rcvd_msg = client.recv_multipart() -            self.assertEqual(rcvd_msg, msg) -            result = True -        return result - -    def test_null(self): -        """threaded auth - NULL""" -        # A default NULL connection should always succeed, and not -        # go through our authentication infrastructure at all. -        self.auth.stop() -        self.auth = None -         -        server = self.socket(zmq.PUSH) -        client = self.socket(zmq.PULL) -        self.assertTrue(self.can_connect(server, client)) - -        # By setting a domain we switch on authentication for NULL sockets, -        # though no policies are configured yet. The client connection -        # should still be allowed. -        server = self.socket(zmq.PUSH) -        server.zap_domain = b'global' -        client = self.socket(zmq.PULL) -        self.assertTrue(self.can_connect(server, client)) - -    def test_blacklist(self): -        """threaded auth - Blacklist""" -        # Blacklist 127.0.0.1, connection should fail -        self.auth.deny('127.0.0.1') -        server = self.socket(zmq.PUSH) -        # By setting a domain we switch on authentication for NULL sockets, -        # though no policies are configured yet. -        server.zap_domain = b'global' -        client = self.socket(zmq.PULL) -        self.assertFalse(self.can_connect(server, client)) - -    def test_whitelist(self): -        """threaded auth - Whitelist""" -        # Whitelist 127.0.0.1, connection should pass" -        self.auth.allow('127.0.0.1') -        server = self.socket(zmq.PUSH) -        # By setting a domain we switch on authentication for NULL sockets, -        # though no policies are configured yet. -        server.zap_domain = b'global' -        client = self.socket(zmq.PULL) -        self.assertTrue(self.can_connect(server, client)) - -    def test_plain(self): -        """threaded auth - PLAIN""" - -        # Try PLAIN authentication - without configuring server, connection should fail -        server = self.socket(zmq.PUSH) -        server.plain_server = True -        client = self.socket(zmq.PULL) -        client.plain_username = b'admin' -        client.plain_password = b'Password' -        self.assertFalse(self.can_connect(server, client)) - -        # Try PLAIN authentication - with server configured, connection should pass -        server = self.socket(zmq.PUSH) -        server.plain_server = True -        client = self.socket(zmq.PULL) -        client.plain_username = b'admin' -        client.plain_password = b'Password' -        self.auth.configure_plain(domain='*', passwords={'admin': 'Password'}) -        self.assertTrue(self.can_connect(server, client)) - -        # Try PLAIN authentication - with bogus credentials, connection should fail -        server = self.socket(zmq.PUSH) -        server.plain_server = True -        client = self.socket(zmq.PULL) -        client.plain_username = b'admin' -        client.plain_password = b'Bogus' -        self.assertFalse(self.can_connect(server, client)) - -        # Remove authenticator and check that a normal connection works -        self.auth.stop() -        self.auth = None - -        server = self.socket(zmq.PUSH) -        client = self.socket(zmq.PULL) -        self.assertTrue(self.can_connect(server, client)) -        client.close() -        server.close() - -    def test_curve(self): -        """threaded auth - CURVE""" -        self.auth.allow('127.0.0.1') -        certs = self.load_certs(self.secret_keys_dir) -        server_public, server_secret, client_public, client_secret = certs - -        #Try CURVE authentication - without configuring server, connection should fail -        server = self.socket(zmq.PUSH) -        server.curve_publickey = server_public -        server.curve_secretkey = server_secret -        server.curve_server = True -        client = self.socket(zmq.PULL) -        client.curve_publickey = client_public -        client.curve_secretkey = client_secret -        client.curve_serverkey = server_public -        self.assertFalse(self.can_connect(server, client)) - -        #Try CURVE authentication - with server configured to CURVE_ALLOW_ANY, connection should pass -        self.auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY) -        server = self.socket(zmq.PUSH) -        server.curve_publickey = server_public -        server.curve_secretkey = server_secret -        server.curve_server = True -        client = self.socket(zmq.PULL) -        client.curve_publickey = client_public -        client.curve_secretkey = client_secret -        client.curve_serverkey = server_public -        self.assertTrue(self.can_connect(server, client)) - -        # Try CURVE authentication - with server configured, connection should pass -        self.auth.configure_curve(domain='*', location=self.public_keys_dir) -        server = self.socket(zmq.PUSH) -        server.curve_publickey = server_public -        server.curve_secretkey = server_secret -        server.curve_server = True -        client = self.socket(zmq.PULL) -        client.curve_publickey = client_public -        client.curve_secretkey = client_secret -        client.curve_serverkey = server_public -        self.assertTrue(self.can_connect(server, client)) - -        # Remove authenticator and check that a normal connection works -        self.auth.stop() -        self.auth = None - -        # Try connecting using NULL and no authentication enabled, connection should pass -        server = self.socket(zmq.PUSH) -        client = self.socket(zmq.PULL) -        self.assertTrue(self.can_connect(server, client)) - - -def with_ioloop(method, expect_success=True): -    """decorator for running tests with an IOLoop""" -    def test_method(self): -        r = method(self) -         -        loop = self.io_loop -        if expect_success: -            self.pullstream.on_recv(self.on_message_succeed) -        else: -            self.pullstream.on_recv(self.on_message_fail) -         -        t = loop.time() -        loop.add_callback(self.attempt_connection) -        loop.add_callback(self.send_msg) -        if expect_success: -            loop.add_timeout(t + 1, self.on_test_timeout_fail) -        else: -            loop.add_timeout(t + 1, self.on_test_timeout_succeed) -         -        loop.start() -        if self.fail_msg: -            self.fail(self.fail_msg) -         -        return r -    return test_method - -def should_auth(method): -    return with_ioloop(method, True) - -def should_not_auth(method): -    return with_ioloop(method, False) - -class TestIOLoopAuthentication(BaseAuthTestCase): -    """Test authentication running in ioloop""" - -    def setUp(self): -        self.fail_msg = None -        self.io_loop = ioloop.IOLoop() -        super(TestIOLoopAuthentication, self).setUp() -        self.server = self.socket(zmq.PUSH) -        self.client = self.socket(zmq.PULL) -        self.pushstream = zmqstream.ZMQStream(self.server, self.io_loop) -        self.pullstream = zmqstream.ZMQStream(self.client, self.io_loop) -     -    def make_auth(self): -        return IOLoopAuthenticator(self.context, io_loop=self.io_loop) - -    def tearDown(self): -        if self.auth: -            self.auth.stop() -            self.auth = None -        self.io_loop.close(all_fds=True) -        super(TestIOLoopAuthentication, self).tearDown() - -    def attempt_connection(self): -        """Check if client can connect to server using tcp transport""" -        iface = 'tcp://127.0.0.1' -        port = self.server.bind_to_random_port(iface) -        self.client.connect("%s:%i" % (iface, port)) - -    def send_msg(self): -        """Send a message from server to a client""" -        msg = [b"Hello World"] -        self.pushstream.send_multipart(msg) -     -    def on_message_succeed(self, frames): -        """A message was received, as expected.""" -        if frames != [b"Hello World"]: -            self.fail_msg = "Unexpected message received" -        self.io_loop.stop() - -    def on_message_fail(self, frames): -        """A message was received, unexpectedly.""" -        self.fail_msg = 'Received messaged unexpectedly, security failed' -        self.io_loop.stop() - -    def on_test_timeout_succeed(self): -        """Test timer expired, indicates test success""" -        self.io_loop.stop() - -    def on_test_timeout_fail(self): -        """Test timer expired, indicates test failure""" -        self.fail_msg = 'Test timed out' -        self.io_loop.stop() - -    @should_auth -    def test_none(self): -        """ioloop auth - NONE""" -        # A default NULL connection should always succeed, and not -        # go through our authentication infrastructure at all. -        # no auth should be running -        self.auth.stop() -        self.auth = None - -    @should_auth -    def test_null(self): -        """ioloop auth - NULL""" -        # By setting a domain we switch on authentication for NULL sockets, -        # though no policies are configured yet. The client connection -        # should still be allowed. -        self.server.zap_domain = b'global' - -    @should_not_auth -    def test_blacklist(self): -        """ioloop auth - Blacklist""" -        # Blacklist 127.0.0.1, connection should fail -        self.auth.deny('127.0.0.1') -        self.server.zap_domain = b'global' - -    @should_auth -    def test_whitelist(self): -        """ioloop auth - Whitelist""" -        # Whitelist 127.0.0.1, which overrides the blacklist, connection should pass" -        self.auth.allow('127.0.0.1') - -        self.server.setsockopt(zmq.ZAP_DOMAIN, b'global') - -    @should_not_auth -    def test_plain_unconfigured_server(self): -        """ioloop auth - PLAIN, unconfigured server""" -        self.client.plain_username = b'admin' -        self.client.plain_password = b'Password' -        # Try PLAIN authentication - without configuring server, connection should fail -        self.server.plain_server = True - -    @should_auth -    def test_plain_configured_server(self): -        """ioloop auth - PLAIN, configured server""" -        self.client.plain_username = b'admin' -        self.client.plain_password = b'Password' -        # Try PLAIN authentication - with server configured, connection should pass -        self.server.plain_server = True -        self.auth.configure_plain(domain='*', passwords={'admin': 'Password'}) - -    @should_not_auth -    def test_plain_bogus_credentials(self): -        """ioloop auth - PLAIN, bogus credentials""" -        self.client.plain_username = b'admin' -        self.client.plain_password = b'Bogus' -        self.server.plain_server = True - -        self.auth.configure_plain(domain='*', passwords={'admin': 'Password'}) - -    @should_not_auth -    def test_curve_unconfigured_server(self): -        """ioloop auth - CURVE, unconfigured server""" -        certs = self.load_certs(self.secret_keys_dir) -        server_public, server_secret, client_public, client_secret = certs - -        self.auth.allow('127.0.0.1') - -        self.server.curve_publickey = server_public -        self.server.curve_secretkey = server_secret -        self.server.curve_server = True - -        self.client.curve_publickey = client_public -        self.client.curve_secretkey = client_secret -        self.client.curve_serverkey = server_public - -    @should_auth -    def test_curve_allow_any(self): -        """ioloop auth - CURVE, CURVE_ALLOW_ANY""" -        certs = self.load_certs(self.secret_keys_dir) -        server_public, server_secret, client_public, client_secret = certs - -        self.auth.allow('127.0.0.1') -        self.auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY) - -        self.server.curve_publickey = server_public -        self.server.curve_secretkey = server_secret -        self.server.curve_server = True - -        self.client.curve_publickey = client_public -        self.client.curve_secretkey = client_secret -        self.client.curve_serverkey = server_public - -    @should_auth -    def test_curve_configured_server(self): -        """ioloop auth - CURVE, configured server""" -        self.auth.allow('127.0.0.1') -        certs = self.load_certs(self.secret_keys_dir) -        server_public, server_secret, client_public, client_secret = certs - -        self.auth.configure_curve(domain='*', location=self.public_keys_dir) - -        self.server.curve_publickey = server_public -        self.server.curve_secretkey = server_secret -        self.server.curve_server = True - -        self.client.curve_publickey = client_public -        self.client.curve_secretkey = client_secret -        self.client.curve_serverkey = server_public diff --git a/zmq/tests/test_cffi_backend.py b/zmq/tests/test_cffi_backend.py deleted file mode 100644 index 1f85eeb..0000000 --- a/zmq/tests/test_cffi_backend.py +++ /dev/null @@ -1,310 +0,0 @@ -# -*- coding: utf8 -*- - -import sys -import time - -from unittest import TestCase - -from zmq.tests import BaseZMQTestCase, SkipTest - -try: -    from zmq.backend.cffi import ( -        zmq_version_info, -        PUSH, PULL, IDENTITY, -        REQ, REP, POLLIN, POLLOUT, -    ) -    from zmq.backend.cffi._cffi import ffi, C -    have_ffi_backend = True -except ImportError: -    have_ffi_backend = False - - -class TestCFFIBackend(TestCase): -     -    def setUp(self): -        if not have_ffi_backend or not 'PyPy' in sys.version: -            raise SkipTest('PyPy Tests Only') - -    def test_zmq_version_info(self): -        version = zmq_version_info() - -        assert version[0] in range(2,11) - -    def test_zmq_ctx_new_destroy(self): -        ctx = C.zmq_ctx_new() - -        assert ctx != ffi.NULL -        assert 0 == C.zmq_ctx_destroy(ctx) - -    def test_zmq_socket_open_close(self): -        ctx = C.zmq_ctx_new() -        socket = C.zmq_socket(ctx, PUSH) - -        assert ctx != ffi.NULL -        assert ffi.NULL != socket -        assert 0 == C.zmq_close(socket) -        assert 0 == C.zmq_ctx_destroy(ctx) - -    def test_zmq_setsockopt(self): -        ctx = C.zmq_ctx_new() -        socket = C.zmq_socket(ctx, PUSH) - -        identity = ffi.new('char[3]', 'zmq') -        ret = C.zmq_setsockopt(socket, IDENTITY, ffi.cast('void*', identity), 3) - -        assert ret == 0 -        assert ctx != ffi.NULL -        assert ffi.NULL != socket -        assert 0 == C.zmq_close(socket) -        assert 0 == C.zmq_ctx_destroy(ctx) - -    def test_zmq_getsockopt(self): -        ctx = C.zmq_ctx_new() -        socket = C.zmq_socket(ctx, PUSH) - -        identity = ffi.new('char[]', 'zmq') -        ret = C.zmq_setsockopt(socket, IDENTITY, ffi.cast('void*', identity), 3) -        assert ret == 0 - -        option_len = ffi.new('size_t*', 3) -        option = ffi.new('char*') -        ret = C.zmq_getsockopt(socket, -                            IDENTITY, -                            ffi.cast('void*', option), -                            option_len) - -        assert ret == 0 -        assert ffi.string(ffi.cast('char*', option))[0] == "z" -        assert ffi.string(ffi.cast('char*', option))[1] == "m" -        assert ffi.string(ffi.cast('char*', option))[2] == "q" -        assert ctx != ffi.NULL -        assert ffi.NULL != socket -        assert 0 == C.zmq_close(socket) -        assert 0 == C.zmq_ctx_destroy(ctx) - -    def test_zmq_bind(self): -        ctx = C.zmq_ctx_new() -        socket = C.zmq_socket(ctx, 8) - -        assert 0 == C.zmq_bind(socket, 'tcp://*:4444') -        assert ctx != ffi.NULL -        assert ffi.NULL != socket -        assert 0 == C.zmq_close(socket) -        assert 0 == C.zmq_ctx_destroy(ctx) - -    def test_zmq_bind_connect(self): -        ctx = C.zmq_ctx_new() - -        socket1 = C.zmq_socket(ctx, PUSH) -        socket2 = C.zmq_socket(ctx, PULL) - -        assert 0 == C.zmq_bind(socket1, 'tcp://*:4444') -        assert 0 == C.zmq_connect(socket2, 'tcp://127.0.0.1:4444') -        assert ctx != ffi.NULL -        assert ffi.NULL != socket1 -        assert ffi.NULL != socket2 -        assert 0 == C.zmq_close(socket1) -        assert 0 == C.zmq_close(socket2) -        assert 0 == C.zmq_ctx_destroy(ctx) - -    def test_zmq_msg_init_close(self): -        zmq_msg = ffi.new('zmq_msg_t*') - -        assert ffi.NULL != zmq_msg -        assert 0 == C.zmq_msg_init(zmq_msg) -        assert 0 == C.zmq_msg_close(zmq_msg) - -    def test_zmq_msg_init_size(self): -        zmq_msg = ffi.new('zmq_msg_t*') - -        assert ffi.NULL != zmq_msg -        assert 0 == C.zmq_msg_init_size(zmq_msg, 10) -        assert 0 == C.zmq_msg_close(zmq_msg) - -    def test_zmq_msg_init_data(self): -        zmq_msg = ffi.new('zmq_msg_t*') -        message = ffi.new('char[5]', 'Hello') - -        assert 0 == C.zmq_msg_init_data(zmq_msg, -                                        ffi.cast('void*', message), -                                        5, -                                        ffi.NULL, -                                        ffi.NULL) - -        assert ffi.NULL != zmq_msg -        assert 0 == C.zmq_msg_close(zmq_msg) - -    def test_zmq_msg_data(self): -        zmq_msg = ffi.new('zmq_msg_t*') -        message = ffi.new('char[]', 'Hello') -        assert 0 == C.zmq_msg_init_data(zmq_msg, -                                        ffi.cast('void*', message), -                                        5, -                                        ffi.NULL, -                                        ffi.NULL) - -        data = C.zmq_msg_data(zmq_msg) - -        assert ffi.NULL != zmq_msg -        assert ffi.string(ffi.cast("char*", data)) == 'Hello' -        assert 0 == C.zmq_msg_close(zmq_msg) - - -    def test_zmq_send(self): -        ctx = C.zmq_ctx_new() - -        sender = C.zmq_socket(ctx, REQ) -        receiver = C.zmq_socket(ctx, REP) - -        assert 0 == C.zmq_bind(receiver, 'tcp://*:7777') -        assert 0 == C.zmq_connect(sender, 'tcp://127.0.0.1:7777') - -        time.sleep(0.1) - -        zmq_msg = ffi.new('zmq_msg_t*') -        message = ffi.new('char[5]', 'Hello') - -        C.zmq_msg_init_data(zmq_msg, -                            ffi.cast('void*', message), -                            ffi.cast('size_t', 5), -                            ffi.NULL, -                            ffi.NULL) - -        assert 5 == C.zmq_msg_send(zmq_msg, sender, 0) -        assert 0 == C.zmq_msg_close(zmq_msg) -        assert C.zmq_close(sender) == 0 -        assert C.zmq_close(receiver) == 0 -        assert C.zmq_ctx_destroy(ctx) == 0 - -    def test_zmq_recv(self): -        ctx = C.zmq_ctx_new() - -        sender = C.zmq_socket(ctx, REQ) -        receiver = C.zmq_socket(ctx, REP) - -        assert 0 == C.zmq_bind(receiver, 'tcp://*:2222') -        assert 0 == C.zmq_connect(sender, 'tcp://127.0.0.1:2222') - -        time.sleep(0.1) - -        zmq_msg = ffi.new('zmq_msg_t*') -        message = ffi.new('char[5]', 'Hello') - -        C.zmq_msg_init_data(zmq_msg, -                            ffi.cast('void*', message), -                            ffi.cast('size_t', 5), -                            ffi.NULL, -                            ffi.NULL) - -        zmq_msg2 = ffi.new('zmq_msg_t*') -        C.zmq_msg_init(zmq_msg2) - -        assert 5 == C.zmq_msg_send(zmq_msg, sender, 0) -        assert 5 == C.zmq_msg_recv(zmq_msg2, receiver, 0) -        assert 5 == C.zmq_msg_size(zmq_msg2) -        assert b"Hello" == ffi.buffer(C.zmq_msg_data(zmq_msg2), -                                      C.zmq_msg_size(zmq_msg2))[:] -        assert C.zmq_close(sender) == 0 -        assert C.zmq_close(receiver) == 0 -        assert C.zmq_ctx_destroy(ctx) == 0 - -    def test_zmq_poll(self): -        ctx = C.zmq_ctx_new() - -        sender = C.zmq_socket(ctx, REQ) -        receiver = C.zmq_socket(ctx, REP) - -        r1 = C.zmq_bind(receiver, 'tcp://*:3333') -        r2 = C.zmq_connect(sender, 'tcp://127.0.0.1:3333') - -        zmq_msg = ffi.new('zmq_msg_t*') -        message = ffi.new('char[5]', 'Hello') - -        C.zmq_msg_init_data(zmq_msg, -                            ffi.cast('void*', message), -                            ffi.cast('size_t', 5), -                            ffi.NULL, -                            ffi.NULL) - -        receiver_pollitem = ffi.new('zmq_pollitem_t*') -        receiver_pollitem.socket = receiver -        receiver_pollitem.fd = 0 -        receiver_pollitem.events = POLLIN | POLLOUT -        receiver_pollitem.revents = 0 - -        ret = C.zmq_poll(ffi.NULL, 0, 0) -        assert ret == 0 - -        ret = C.zmq_poll(receiver_pollitem, 1, 0) -        assert ret == 0 - -        ret = C.zmq_msg_send(zmq_msg, sender, 0) -        print(ffi.string(C.zmq_strerror(C.zmq_errno()))) -        assert ret == 5 - -        time.sleep(0.2) - -        ret = C.zmq_poll(receiver_pollitem, 1, 0) -        assert ret == 1 - -        assert int(receiver_pollitem.revents) & POLLIN -        assert not int(receiver_pollitem.revents) & POLLOUT - -        zmq_msg2 = ffi.new('zmq_msg_t*') -        C.zmq_msg_init(zmq_msg2) - -        ret_recv = C.zmq_msg_recv(zmq_msg2, receiver, 0) -        assert ret_recv == 5 - -        assert 5 == C.zmq_msg_size(zmq_msg2) -        assert b"Hello" == ffi.buffer(C.zmq_msg_data(zmq_msg2), -                                    C.zmq_msg_size(zmq_msg2))[:] - -        sender_pollitem = ffi.new('zmq_pollitem_t*') -        sender_pollitem.socket = sender -        sender_pollitem.fd = 0 -        sender_pollitem.events = POLLIN | POLLOUT -        sender_pollitem.revents = 0 - -        ret = C.zmq_poll(sender_pollitem, 1, 0) -        assert ret == 0 - -        zmq_msg_again = ffi.new('zmq_msg_t*') -        message_again = ffi.new('char[11]', 'Hello Again') - -        C.zmq_msg_init_data(zmq_msg_again, -                            ffi.cast('void*', message_again), -                            ffi.cast('size_t', 11), -                            ffi.NULL, -                            ffi.NULL) - -        assert 11 == C.zmq_msg_send(zmq_msg_again, receiver, 0) - -        time.sleep(0.2) - -        assert 0 <= C.zmq_poll(sender_pollitem, 1, 0) -        assert int(sender_pollitem.revents) & POLLIN -        assert 11 == C.zmq_msg_recv(zmq_msg2, sender, 0) -        assert 11 == C.zmq_msg_size(zmq_msg2) -        assert b"Hello Again" == ffi.buffer(C.zmq_msg_data(zmq_msg2), -                                            int(C.zmq_msg_size(zmq_msg2)))[:] -        assert 0 == C.zmq_close(sender) -        assert 0 == C.zmq_close(receiver) -        assert 0 == C.zmq_ctx_destroy(ctx) -        assert 0 == C.zmq_msg_close(zmq_msg) -        assert 0 == C.zmq_msg_close(zmq_msg2) -        assert 0 == C.zmq_msg_close(zmq_msg_again) - -    def test_zmq_stopwatch_functions(self): -        stopwatch = C.zmq_stopwatch_start() -        ret = C.zmq_stopwatch_stop(stopwatch) - -        assert ffi.NULL != stopwatch -        assert 0 < int(ret) - -    def test_zmq_sleep(self): -        try: -            C.zmq_sleep(1) -        except Exception as e: -            raise AssertionError("Error executing zmq_sleep(int)") - diff --git a/zmq/tests/test_constants.py b/zmq/tests/test_constants.py deleted file mode 100644 index 183bced..0000000 --- a/zmq/tests/test_constants.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import json -from unittest import TestCase - -import zmq - -from zmq.utils import constant_names -from zmq.sugar import constants as sugar_constants -from zmq.backend import constants as backend_constants - -all_set = set(constant_names.all_names) - -class TestConstants(TestCase): -     -    def _duplicate_test(self, namelist, listname): -        """test that a given list has no duplicates""" -        dupes = {} -        for name in set(namelist): -            cnt = namelist.count(name) -            if cnt > 1: -                dupes[name] = cnt -        if dupes: -            self.fail("The following names occur more than once in %s: %s" % (listname, json.dumps(dupes, indent=2))) -     -    def test_duplicate_all(self): -        return self._duplicate_test(constant_names.all_names, "all_names") -     -    def _change_key(self, change, version): -        """return changed-in key""" -        return "%s-in %d.%d.%d" % tuple([change] + list(version)) - -    def test_duplicate_changed(self): -        all_changed = [] -        for change in ("new", "removed"): -            d = getattr(constant_names, change + "_in") -            for version, namelist in d.items(): -                all_changed.extend(namelist) -                self._duplicate_test(namelist, self._change_key(change, version)) -         -        self._duplicate_test(all_changed, "all-changed") -     -    def test_changed_in_all(self): -        missing = {} -        for change in ("new", "removed"): -            d = getattr(constant_names, change + "_in") -            for version, namelist in d.items(): -                key = self._change_key(change, version) -                for name in namelist: -                    if name not in all_set: -                        if key not in missing: -                            missing[key] = [] -                        missing[key].append(name) -         -        if missing: -            self.fail( -                "The following names are missing in `all_names`: %s" % json.dumps(missing, indent=2) -            ) -     -    def test_no_negative_constants(self): -        for name in sugar_constants.__all__: -            self.assertNotEqual(getattr(zmq, name), -1) -     -    def test_undefined_constants(self): -        all_aliases = [] -        for alias_group in sugar_constants.aliases: -            all_aliases.extend(alias_group) -         -        for name in all_set.difference(all_aliases): -            raw = getattr(backend_constants, name) -            if raw == -1: -                self.assertRaises(AttributeError, getattr, zmq, name) -            else: -                self.assertEqual(getattr(zmq, name), raw) -     -    def test_new(self): -        zmq_version = zmq.zmq_version_info() -        for version, new_names in constant_names.new_in.items(): -            should_have = zmq_version >= version -            for name in new_names: -                try: -                    value = getattr(zmq, name) -                except AttributeError: -                    if should_have: -                        self.fail("AttributeError: zmq.%s" % name) -                else: -                    if not should_have: -                        self.fail("Shouldn't have: zmq.%s=%s" % (name, value)) - -    def test_removed(self): -        zmq_version = zmq.zmq_version_info() -        for version, new_names in constant_names.removed_in.items(): -            should_have = zmq_version < version -            for name in new_names: -                try: -                    value = getattr(zmq, name) -                except AttributeError: -                    if should_have: -                        self.fail("AttributeError: zmq.%s" % name) -                else: -                    if not should_have: -                        self.fail("Shouldn't have: zmq.%s=%s" % (name, value)) - diff --git a/zmq/tests/test_context.py b/zmq/tests/test_context.py deleted file mode 100644 index e328077..0000000 --- a/zmq/tests/test_context.py +++ /dev/null @@ -1,257 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import gc -import sys -import time -from threading import Thread, Event - -import zmq -from zmq.tests import ( -    BaseZMQTestCase, have_gevent, GreenTest, skip_green, PYPY, SkipTest, -) - - -class TestContext(BaseZMQTestCase): - -    def test_init(self): -        c1 = self.Context() -        self.assert_(isinstance(c1, self.Context)) -        del c1 -        c2 = self.Context() -        self.assert_(isinstance(c2, self.Context)) -        del c2 -        c3 = self.Context() -        self.assert_(isinstance(c3, self.Context)) -        del c3 - -    def test_dir(self): -        ctx = self.Context() -        self.assertTrue('socket' in dir(ctx)) -        if zmq.zmq_version_info() > (3,): -            self.assertTrue('IO_THREADS' in dir(ctx)) -        ctx.term() - -    def test_term(self): -        c = self.Context() -        c.term() -        self.assert_(c.closed) -     -    def test_context_manager(self): -        with self.Context() as c: -            pass -        self.assert_(c.closed) -     -    def test_fail_init(self): -        self.assertRaisesErrno(zmq.EINVAL, self.Context, -1) -     -    def test_term_hang(self): -        rep,req = self.create_bound_pair(zmq.ROUTER, zmq.DEALER) -        req.setsockopt(zmq.LINGER, 0) -        req.send(b'hello', copy=False) -        req.close() -        rep.close() -        self.context.term() -     -    def test_instance(self): -        ctx = self.Context.instance() -        c2 = self.Context.instance(io_threads=2) -        self.assertTrue(c2 is ctx) -        c2.term() -        c3 = self.Context.instance() -        c4 = self.Context.instance() -        self.assertFalse(c3 is c2) -        self.assertFalse(c3.closed) -        self.assertTrue(c3 is c4) -     -    def test_many_sockets(self): -        """opening and closing many sockets shouldn't cause problems""" -        ctx = self.Context() -        for i in range(16): -            sockets = [ ctx.socket(zmq.REP) for i in range(65) ] -            [ s.close() for s in sockets ] -            # give the reaper a chance -            time.sleep(1e-2) -        ctx.term() -     -    def test_sockopts(self): -        """setting socket options with ctx attributes""" -        ctx = self.Context() -        ctx.linger = 5 -        self.assertEqual(ctx.linger, 5) -        s = ctx.socket(zmq.REQ) -        self.assertEqual(s.linger, 5) -        self.assertEqual(s.getsockopt(zmq.LINGER), 5) -        s.close() -        # check that subscribe doesn't get set on sockets that don't subscribe: -        ctx.subscribe = b'' -        s = ctx.socket(zmq.REQ) -        s.close() -         -        ctx.term() - -     -    def test_destroy(self): -        """Context.destroy should close sockets""" -        ctx = self.Context() -        sockets = [ ctx.socket(zmq.REP) for i in range(65) ] -         -        # close half of the sockets -        [ s.close() for s in sockets[::2] ] -         -        ctx.destroy() -        # reaper is not instantaneous -        time.sleep(1e-2) -        for s in sockets: -            self.assertTrue(s.closed) -         -    def test_destroy_linger(self): -        """Context.destroy should set linger on closing sockets""" -        req,rep = self.create_bound_pair(zmq.REQ, zmq.REP) -        req.send(b'hi') -        time.sleep(1e-2) -        self.context.destroy(linger=0) -        # reaper is not instantaneous -        time.sleep(1e-2) -        for s in (req,rep): -            self.assertTrue(s.closed) -         -    def test_term_noclose(self): -        """Context.term won't close sockets""" -        ctx = self.Context() -        s = ctx.socket(zmq.REQ) -        self.assertFalse(s.closed) -        t = Thread(target=ctx.term) -        t.start() -        t.join(timeout=0.1) -        self.assertTrue(t.is_alive(), "Context should be waiting") -        s.close() -        t.join(timeout=0.1) -        self.assertFalse(t.is_alive(), "Context should have closed") -     -    def test_gc(self): -        """test close&term by garbage collection alone""" -        if PYPY: -            raise SkipTest("GC doesn't work ") -             -        # test credit @dln (GH #137): -        def gcf(): -            def inner(): -                ctx = self.Context() -                s = ctx.socket(zmq.PUSH) -            inner() -            gc.collect() -        t = Thread(target=gcf) -        t.start() -        t.join(timeout=1) -        self.assertFalse(t.is_alive(), "Garbage collection should have cleaned up context") -     -    def test_cyclic_destroy(self): -        """ctx.destroy should succeed when cyclic ref prevents gc""" -        # test credit @dln (GH #137): -        class CyclicReference(object): -            def __init__(self, parent=None): -                self.parent = parent -             -            def crash(self, sock): -                self.sock = sock -                self.child = CyclicReference(self) -         -        def crash_zmq(): -            ctx = self.Context() -            sock = ctx.socket(zmq.PULL) -            c = CyclicReference() -            c.crash(sock) -            ctx.destroy() -         -        crash_zmq() -     -    def test_term_thread(self): -        """ctx.term should not crash active threads (#139)""" -        ctx = self.Context() -        evt = Event() -        evt.clear() - -        def block(): -            s = ctx.socket(zmq.REP) -            s.bind_to_random_port('tcp://127.0.0.1') -            evt.set() -            try: -                s.recv() -            except zmq.ZMQError as e: -                self.assertEqual(e.errno, zmq.ETERM) -                return -            finally: -                s.close() -            self.fail("recv should have been interrupted with ETERM") -        t = Thread(target=block) -        t.start() -         -        evt.wait(1) -        self.assertTrue(evt.is_set(), "sync event never fired") -        time.sleep(0.01) -        ctx.term() -        t.join(timeout=1) -        self.assertFalse(t.is_alive(), "term should have interrupted s.recv()") -     -    def test_destroy_no_sockets(self): -        ctx = self.Context() -        s = ctx.socket(zmq.PUB) -        s.bind_to_random_port('tcp://127.0.0.1') -        s.close() -        ctx.destroy() -        assert s.closed -        assert ctx.closed -     -    def test_ctx_opts(self): -        if zmq.zmq_version_info() < (3,): -            raise SkipTest("context options require libzmq 3") -        ctx = self.Context() -        ctx.set(zmq.MAX_SOCKETS, 2) -        self.assertEqual(ctx.get(zmq.MAX_SOCKETS), 2) -        ctx.max_sockets = 100 -        self.assertEqual(ctx.max_sockets, 100) -        self.assertEqual(ctx.get(zmq.MAX_SOCKETS), 100) -     -    def test_shadow(self): -        ctx = self.Context() -        ctx2 = self.Context.shadow(ctx.underlying) -        self.assertEqual(ctx.underlying, ctx2.underlying) -        s = ctx.socket(zmq.PUB) -        s.close() -        del ctx2 -        self.assertFalse(ctx.closed) -        s = ctx.socket(zmq.PUB) -        ctx2 = self.Context.shadow(ctx.underlying) -        s2 = ctx2.socket(zmq.PUB) -        s.close() -        s2.close() -        ctx.term() -        self.assertRaisesErrno(zmq.EFAULT, ctx2.socket, zmq.PUB) -        del ctx2 -     -    def test_shadow_pyczmq(self): -        try: -            from pyczmq import zctx, zsocket, zstr -        except Exception: -            raise SkipTest("Requires pyczmq") -         -        ctx = zctx.new() -        a = zsocket.new(ctx, zmq.PUSH) -        zsocket.bind(a, "inproc://a") -        ctx2 = self.Context.shadow_pyczmq(ctx) -        b = ctx2.socket(zmq.PULL) -        b.connect("inproc://a") -        zstr.send(a, b'hi') -        rcvd = self.recv(b) -        self.assertEqual(rcvd, b'hi') -        b.close() - - -if False: # disable green context tests -    class TestContextGreen(GreenTest, TestContext): -        """gevent subclass of context tests""" -        # skip tests that use real threads: -        test_gc = GreenTest.skip_green -        test_term_thread = GreenTest.skip_green -        test_destroy_linger = GreenTest.skip_green diff --git a/zmq/tests/test_device.py b/zmq/tests/test_device.py deleted file mode 100644 index f830507..0000000 --- a/zmq/tests/test_device.py +++ /dev/null @@ -1,146 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import time - -import zmq -from zmq import devices -from zmq.tests import BaseZMQTestCase, SkipTest, have_gevent, GreenTest, PYPY -from zmq.utils.strtypes import (bytes,unicode,basestring) - -if PYPY: -    # cleanup of shared Context doesn't work on PyPy -    devices.Device.context_factory = zmq.Context - -class TestDevice(BaseZMQTestCase): -     -    def test_device_types(self): -        for devtype in (zmq.STREAMER, zmq.FORWARDER, zmq.QUEUE): -            dev = devices.Device(devtype, zmq.PAIR, zmq.PAIR) -            self.assertEqual(dev.device_type, devtype) -            del dev -     -    def test_device_attributes(self): -        dev = devices.Device(zmq.QUEUE, zmq.SUB, zmq.PUB) -        self.assertEqual(dev.in_type, zmq.SUB) -        self.assertEqual(dev.out_type, zmq.PUB) -        self.assertEqual(dev.device_type, zmq.QUEUE) -        self.assertEqual(dev.daemon, True) -        del dev -     -    def test_tsdevice_attributes(self): -        dev = devices.Device(zmq.QUEUE, zmq.SUB, zmq.PUB) -        self.assertEqual(dev.in_type, zmq.SUB) -        self.assertEqual(dev.out_type, zmq.PUB) -        self.assertEqual(dev.device_type, zmq.QUEUE) -        self.assertEqual(dev.daemon, True) -        del dev -         -     -    def test_single_socket_forwarder_connect(self): -        dev = devices.ThreadDevice(zmq.QUEUE, zmq.REP, -1) -        req = self.context.socket(zmq.REQ) -        port = req.bind_to_random_port('tcp://127.0.0.1') -        dev.connect_in('tcp://127.0.0.1:%i'%port) -        dev.start() -        time.sleep(.25) -        msg = b'hello' -        req.send(msg) -        self.assertEqual(msg, self.recv(req)) -        del dev -        req.close() -        dev = devices.ThreadDevice(zmq.QUEUE, zmq.REP, -1) -        req = self.context.socket(zmq.REQ) -        port = req.bind_to_random_port('tcp://127.0.0.1') -        dev.connect_out('tcp://127.0.0.1:%i'%port) -        dev.start() -        time.sleep(.25) -        msg = b'hello again' -        req.send(msg) -        self.assertEqual(msg, self.recv(req)) -        del dev -        req.close() -         -    def test_single_socket_forwarder_bind(self): -        dev = devices.ThreadDevice(zmq.QUEUE, zmq.REP, -1) -        # select random port: -        binder = self.context.socket(zmq.REQ) -        port = binder.bind_to_random_port('tcp://127.0.0.1') -        binder.close() -        time.sleep(0.1) -        req = self.context.socket(zmq.REQ) -        req.connect('tcp://127.0.0.1:%i'%port) -        dev.bind_in('tcp://127.0.0.1:%i'%port) -        dev.start() -        time.sleep(.25) -        msg = b'hello' -        req.send(msg) -        self.assertEqual(msg, self.recv(req)) -        del dev -        req.close() -        dev = devices.ThreadDevice(zmq.QUEUE, zmq.REP, -1) -        # select random port: -        binder = self.context.socket(zmq.REQ) -        port = binder.bind_to_random_port('tcp://127.0.0.1') -        binder.close() -        time.sleep(0.1) -        req = self.context.socket(zmq.REQ) -        req.connect('tcp://127.0.0.1:%i'%port) -        dev.bind_in('tcp://127.0.0.1:%i'%port) -        dev.start() -        time.sleep(.25) -        msg = b'hello again' -        req.send(msg) -        self.assertEqual(msg, self.recv(req)) -        del dev -        req.close() -     -    def test_proxy(self): -        if zmq.zmq_version_info() < (3,2): -            raise SkipTest("Proxies only in libzmq >= 3") -        dev = devices.ThreadProxy(zmq.PULL, zmq.PUSH, zmq.PUSH) -        binder = self.context.socket(zmq.REQ) -        iface = 'tcp://127.0.0.1' -        port = binder.bind_to_random_port(iface) -        port2 = binder.bind_to_random_port(iface) -        port3 = binder.bind_to_random_port(iface) -        binder.close() -        time.sleep(0.1) -        dev.bind_in("%s:%i" % (iface, port)) -        dev.bind_out("%s:%i" % (iface, port2)) -        dev.bind_mon("%s:%i" % (iface, port3)) -        dev.start() -        time.sleep(0.25) -        msg = b'hello' -        push = self.context.socket(zmq.PUSH) -        push.connect("%s:%i" % (iface, port)) -        pull = self.context.socket(zmq.PULL) -        pull.connect("%s:%i" % (iface, port2)) -        mon = self.context.socket(zmq.PULL) -        mon.connect("%s:%i" % (iface, port3)) -        push.send(msg) -        self.sockets.extend([push, pull, mon]) -        self.assertEqual(msg, self.recv(pull)) -        self.assertEqual(msg, self.recv(mon)) - -if have_gevent: -    import gevent -    import zmq.green -     -    class TestDeviceGreen(GreenTest, BaseZMQTestCase): -         -        def test_green_device(self): -            rep = self.context.socket(zmq.REP) -            req = self.context.socket(zmq.REQ) -            self.sockets.extend([req, rep]) -            port = rep.bind_to_random_port('tcp://127.0.0.1') -            g = gevent.spawn(zmq.green.device, zmq.QUEUE, rep, rep) -            req.connect('tcp://127.0.0.1:%i' % port) -            req.send(b'hi') -            timeout = gevent.Timeout(3) -            timeout.start() -            receiver = gevent.spawn(req.recv) -            self.assertEqual(receiver.get(2), b'hi') -            timeout.cancel() -            g.kill(block=True) -             diff --git a/zmq/tests/test_error.py b/zmq/tests/test_error.py deleted file mode 100644 index a2eee14..0000000 --- a/zmq/tests/test_error.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf8 -*- -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import sys -import time - -import zmq -from zmq import ZMQError, strerror, Again, ContextTerminated -from zmq.tests import BaseZMQTestCase - -if sys.version_info[0] >= 3: -    long = int - -class TestZMQError(BaseZMQTestCase): -     -    def test_strerror(self): -        """test that strerror gets the right type.""" -        for i in range(10): -            e = strerror(i) -            self.assertTrue(isinstance(e, str)) -     -    def test_zmqerror(self): -        for errno in range(10): -            e = ZMQError(errno) -            self.assertEqual(e.errno, errno) -            self.assertEqual(str(e), strerror(errno)) -     -    def test_again(self): -        s = self.context.socket(zmq.REP) -        self.assertRaises(Again, s.recv, zmq.NOBLOCK) -        self.assertRaisesErrno(zmq.EAGAIN, s.recv, zmq.NOBLOCK) -        s.close() -     -    def atest_ctxterm(self): -        s = self.context.socket(zmq.REP) -        t = Thread(target=self.context.term) -        t.start() -        self.assertRaises(ContextTerminated, s.recv, zmq.NOBLOCK) -        self.assertRaisesErrno(zmq.TERM, s.recv, zmq.NOBLOCK) -        s.close() -        t.join() - diff --git a/zmq/tests/test_imports.py b/zmq/tests/test_imports.py deleted file mode 100644 index f1a93d9..0000000 --- a/zmq/tests/test_imports.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import sys -from unittest import TestCase - -class TestImports(TestCase): -    """Test Imports - the quickest test to ensure that we haven't -    introduced version-incompatible syntax errors.""" -     -    def test_toplevel(self): -        """test toplevel import""" -        import zmq -         -    def test_core(self): -        """test core imports""" -        from zmq import Context -        from zmq import Socket -        from zmq import Poller -        from zmq import Frame -        from zmq import constants -        from zmq import device, proxy -        from zmq import Stopwatch -        from zmq import (  -            zmq_version, -            zmq_version_info, -            pyzmq_version, -            pyzmq_version_info, -        ) -     -    def test_devices(self): -        """test device imports""" -        import zmq.devices -        from zmq.devices import basedevice -        from zmq.devices import monitoredqueue -        from zmq.devices import monitoredqueuedevice -     -    def test_log(self): -        """test log imports""" -        import zmq.log -        from zmq.log import handlers -     -    def test_eventloop(self): -        """test eventloop imports""" -        import zmq.eventloop -        from zmq.eventloop import ioloop -        from zmq.eventloop import zmqstream -        from zmq.eventloop.minitornado.platform import auto -        from zmq.eventloop.minitornado import ioloop -     -    def test_utils(self): -        """test util imports""" -        import zmq.utils -        from zmq.utils import strtypes -        from zmq.utils import jsonapi -     - - diff --git a/zmq/tests/test_ioloop.py b/zmq/tests/test_ioloop.py deleted file mode 100644 index 2a8b115..0000000 --- a/zmq/tests/test_ioloop.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import time -import os -import threading - -import zmq -from zmq.tests import BaseZMQTestCase -from zmq.eventloop import ioloop -from zmq.eventloop.minitornado.ioloop import _Timeout -try: -    from tornado.ioloop import PollIOLoop, IOLoop as BaseIOLoop -except ImportError: -    from zmq.eventloop.minitornado.ioloop import IOLoop as BaseIOLoop - - -def printer(): -    os.system("say hello") -    raise Exception -    print (time.time()) - - -class Delay(threading.Thread): -    def __init__(self, f, delay=1): -        self.f=f -        self.delay=delay -        self.aborted=False -        self.cond=threading.Condition() -        super(Delay, self).__init__() -     -    def run(self): -        self.cond.acquire() -        self.cond.wait(self.delay) -        self.cond.release() -        if not self.aborted: -            self.f() -     -    def abort(self): -        self.aborted=True -        self.cond.acquire() -        self.cond.notify() -        self.cond.release() - - -class TestIOLoop(BaseZMQTestCase): - -    def test_simple(self): -        """simple IOLoop creation test""" -        loop = ioloop.IOLoop() -        dc = ioloop.PeriodicCallback(loop.stop, 200, loop) -        pc = ioloop.PeriodicCallback(lambda : None, 10, loop) -        pc.start() -        dc.start() -        t = Delay(loop.stop,1) -        t.start() -        loop.start() -        if t.isAlive(): -            t.abort() -        else: -            self.fail("IOLoop failed to exit") -     -    def test_timeout_compare(self): -        """test timeout comparisons""" -        loop = ioloop.IOLoop() -        t = _Timeout(1, 2, loop) -        t2 = _Timeout(1, 3, loop) -        self.assertEqual(t < t2, id(t) < id(t2)) -        t2 = _Timeout(2,1, loop) -        self.assertTrue(t < t2) - -    def test_poller_events(self): -        """Tornado poller implementation maps events correctly""" -        req,rep = self.create_bound_pair(zmq.REQ, zmq.REP) -        poller = ioloop.ZMQPoller() -        poller.register(req, ioloop.IOLoop.READ) -        poller.register(rep, ioloop.IOLoop.READ) -        events = dict(poller.poll(0)) -        self.assertEqual(events.get(rep), None) -        self.assertEqual(events.get(req), None) -         -        poller.register(req, ioloop.IOLoop.WRITE) -        poller.register(rep, ioloop.IOLoop.WRITE) -        events = dict(poller.poll(1)) -        self.assertEqual(events.get(req), ioloop.IOLoop.WRITE) -        self.assertEqual(events.get(rep), None) -         -        poller.register(rep, ioloop.IOLoop.READ) -        req.send(b'hi') -        events = dict(poller.poll(1)) -        self.assertEqual(events.get(rep), ioloop.IOLoop.READ) -        self.assertEqual(events.get(req), None) -     -    def test_instance(self): -        """Test IOLoop.instance returns the right object""" -        loop = ioloop.IOLoop.instance() -        self.assertEqual(loop.__class__, ioloop.IOLoop) -        loop = BaseIOLoop.instance() -        self.assertEqual(loop.__class__, ioloop.IOLoop) -     -    def test_close_all(self): -        """Test close(all_fds=True)""" -        loop = ioloop.IOLoop.instance() -        req,rep = self.create_bound_pair(zmq.REQ, zmq.REP) -        loop.add_handler(req, lambda msg: msg, ioloop.IOLoop.READ) -        loop.add_handler(rep, lambda msg: msg, ioloop.IOLoop.READ) -        self.assertEqual(req.closed, False) -        self.assertEqual(rep.closed, False) -        loop.close(all_fds=True) -        self.assertEqual(req.closed, True) -        self.assertEqual(rep.closed, True) -         - diff --git a/zmq/tests/test_log.py b/zmq/tests/test_log.py deleted file mode 100644 index 9206f09..0000000 --- a/zmq/tests/test_log.py +++ /dev/null @@ -1,116 +0,0 @@ -# encoding: utf-8 - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import logging -import time -from unittest import TestCase - -import zmq -from zmq.log import handlers -from zmq.utils.strtypes import b, u -from zmq.tests import BaseZMQTestCase - - -class TestPubLog(BaseZMQTestCase): -     -    iface = 'inproc://zmqlog' -    topic= 'zmq' -     -    @property -    def logger(self): -        # print dir(self) -        logger = logging.getLogger('zmqtest') -        logger.setLevel(logging.DEBUG) -        return logger -     -    def connect_handler(self, topic=None): -        topic = self.topic if topic is None else topic -        logger = self.logger -        pub,sub = self.create_bound_pair(zmq.PUB, zmq.SUB) -        handler = handlers.PUBHandler(pub) -        handler.setLevel(logging.DEBUG) -        handler.root_topic = topic -        logger.addHandler(handler) -        sub.setsockopt(zmq.SUBSCRIBE, b(topic)) -        time.sleep(0.1) -        return logger, handler, sub -     -    def test_init_iface(self): -        logger = self.logger -        ctx = self.context -        handler = handlers.PUBHandler(self.iface) -        self.assertFalse(handler.ctx is ctx) -        self.sockets.append(handler.socket) -        # handler.ctx.term() -        handler = handlers.PUBHandler(self.iface, self.context) -        self.sockets.append(handler.socket) -        self.assertTrue(handler.ctx is ctx) -        handler.setLevel(logging.DEBUG) -        handler.root_topic = self.topic -        logger.addHandler(handler) -        sub = ctx.socket(zmq.SUB) -        self.sockets.append(sub) -        sub.setsockopt(zmq.SUBSCRIBE, b(self.topic)) -        sub.connect(self.iface) -        import time; time.sleep(0.25) -        msg1 = 'message' -        logger.info(msg1) -         -        (topic, msg2) = sub.recv_multipart() -        self.assertEqual(topic, b'zmq.INFO') -        self.assertEqual(msg2, b(msg1)+b'\n') -        logger.removeHandler(handler) -     -    def test_init_socket(self): -        pub,sub = self.create_bound_pair(zmq.PUB, zmq.SUB) -        logger = self.logger -        handler = handlers.PUBHandler(pub) -        handler.setLevel(logging.DEBUG) -        handler.root_topic = self.topic -        logger.addHandler(handler) -         -        self.assertTrue(handler.socket is pub) -        self.assertTrue(handler.ctx is pub.context) -        self.assertTrue(handler.ctx is self.context) -        sub.setsockopt(zmq.SUBSCRIBE, b(self.topic)) -        import time; time.sleep(0.1) -        msg1 = 'message' -        logger.info(msg1) -         -        (topic, msg2) = sub.recv_multipart() -        self.assertEqual(topic, b'zmq.INFO') -        self.assertEqual(msg2, b(msg1)+b'\n') -        logger.removeHandler(handler) -     -    def test_root_topic(self): -        logger, handler, sub = self.connect_handler() -        handler.socket.bind(self.iface) -        sub2 = sub.context.socket(zmq.SUB) -        self.sockets.append(sub2) -        sub2.connect(self.iface) -        sub2.setsockopt(zmq.SUBSCRIBE, b'') -        handler.root_topic = b'twoonly' -        msg1 = 'ignored' -        logger.info(msg1) -        self.assertRaisesErrno(zmq.EAGAIN, sub.recv, zmq.NOBLOCK) -        topic,msg2 = sub2.recv_multipart() -        self.assertEqual(topic, b'twoonly.INFO') -        self.assertEqual(msg2, b(msg1)+b'\n') -         -        logger.removeHandler(handler) -     -    def test_unicode_message(self): -        logger, handler, sub = self.connect_handler() -        base_topic = b(self.topic + '.INFO') -        for msg, expected in [ -            (u('hello'), [base_topic, b('hello\n')]), -            (u('héllo'), [base_topic, b('héllo\n')]), -            (u('tøpic::héllo'), [base_topic + b('.tøpic'), b('héllo\n')]), -        ]: -            logger.info(msg) -            received = sub.recv_multipart() -            self.assertEqual(received, expected) - diff --git a/zmq/tests/test_message.py b/zmq/tests/test_message.py deleted file mode 100644 index 5e9b58c..0000000 --- a/zmq/tests/test_message.py +++ /dev/null @@ -1,360 +0,0 @@ -# -*- coding: utf8 -*- -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import copy -import sys -try: -    from sys import getrefcount as grc -except ImportError: -    grc = None - -import time -from pprint import pprint -from unittest import TestCase - -import zmq -from zmq.tests import BaseZMQTestCase, SkipTest, skip_pypy, PYPY -from zmq.utils.strtypes import unicode, bytes, b, u - - -# some useful constants: - -x = b'x' - -try: -    view = memoryview -except NameError: -    view = buffer - -if grc: -    rc0 = grc(x) -    v = view(x) -    view_rc = grc(x) - rc0 - -def await_gc(obj, rc): -    """wait for refcount on an object to drop to an expected value -     -    Necessary because of the zero-copy gc thread, -    which can take some time to receive its DECREF message. -    """ -    for i in range(50): -        # rc + 2 because of the refs in this function -        if grc(obj) <= rc + 2: -            return -        time.sleep(0.05) -     -class TestFrame(BaseZMQTestCase): - -    @skip_pypy -    def test_above_30(self): -        """Message above 30 bytes are never copied by 0MQ.""" -        for i in range(5, 16):  # 32, 64,..., 65536 -            s = (2**i)*x -            self.assertEqual(grc(s), 2) -            m = zmq.Frame(s) -            self.assertEqual(grc(s), 4) -            del m -            await_gc(s, 2) -            self.assertEqual(grc(s), 2) -            del s - -    def test_str(self): -        """Test the str representations of the Frames.""" -        for i in range(16): -            s = (2**i)*x -            m = zmq.Frame(s) -            m_str = str(m) -            m_str_b = b(m_str) # py3compat -            self.assertEqual(s, m_str_b) - -    def test_bytes(self): -        """Test the Frame.bytes property.""" -        for i in range(1,16): -            s = (2**i)*x -            m = zmq.Frame(s) -            b = m.bytes -            self.assertEqual(s, m.bytes) -            if not PYPY: -                # check that it copies -                self.assert_(b is not s) -            # check that it copies only once -            self.assert_(b is m.bytes) - -    def test_unicode(self): -        """Test the unicode representations of the Frames.""" -        s = u('asdf') -        self.assertRaises(TypeError, zmq.Frame, s) -        for i in range(16): -            s = (2**i)*u('§') -            m = zmq.Frame(s.encode('utf8')) -            self.assertEqual(s, unicode(m.bytes,'utf8')) - -    def test_len(self): -        """Test the len of the Frames.""" -        for i in range(16): -            s = (2**i)*x -            m = zmq.Frame(s) -            self.assertEqual(len(s), len(m)) - -    @skip_pypy -    def test_lifecycle1(self): -        """Run through a ref counting cycle with a copy.""" -        for i in range(5, 16):  # 32, 64,..., 65536 -            s = (2**i)*x -            rc = 2 -            self.assertEqual(grc(s), rc) -            m = zmq.Frame(s) -            rc += 2 -            self.assertEqual(grc(s), rc) -            m2 = copy.copy(m) -            rc += 1 -            self.assertEqual(grc(s), rc) -            buf = m2.buffer - -            rc += view_rc -            self.assertEqual(grc(s), rc) - -            self.assertEqual(s, b(str(m))) -            self.assertEqual(s, bytes(m2)) -            self.assertEqual(s, m.bytes) -            # self.assert_(s is str(m)) -            # self.assert_(s is str(m2)) -            del m2 -            rc -= 1 -            self.assertEqual(grc(s), rc) -            rc -= view_rc -            del buf -            self.assertEqual(grc(s), rc) -            del m -            rc -= 2 -            await_gc(s, rc) -            self.assertEqual(grc(s), rc) -            self.assertEqual(rc, 2) -            del s - -    @skip_pypy -    def test_lifecycle2(self): -        """Run through a different ref counting cycle with a copy.""" -        for i in range(5, 16):  # 32, 64,..., 65536 -            s = (2**i)*x -            rc = 2 -            self.assertEqual(grc(s), rc) -            m = zmq.Frame(s) -            rc += 2 -            self.assertEqual(grc(s), rc) -            m2 = copy.copy(m) -            rc += 1 -            self.assertEqual(grc(s), rc) -            buf = m.buffer -            rc += view_rc -            self.assertEqual(grc(s), rc) -            self.assertEqual(s, b(str(m))) -            self.assertEqual(s, bytes(m2)) -            self.assertEqual(s, m2.bytes) -            self.assertEqual(s, m.bytes) -            # self.assert_(s is str(m)) -            # self.assert_(s is str(m2)) -            del buf -            self.assertEqual(grc(s), rc) -            del m -            # m.buffer is kept until m is del'd -            rc -= view_rc -            rc -= 1 -            self.assertEqual(grc(s), rc) -            del m2 -            rc -= 2 -            await_gc(s, rc) -            self.assertEqual(grc(s), rc) -            self.assertEqual(rc, 2) -            del s -     -    @skip_pypy -    def test_tracker(self): -        m = zmq.Frame(b'asdf', track=True) -        self.assertFalse(m.tracker.done) -        pm = zmq.MessageTracker(m) -        self.assertFalse(pm.done) -        del m -        for i in range(10): -            if pm.done: -                break -            time.sleep(0.1) -        self.assertTrue(pm.done) -     -    def test_no_tracker(self): -        m = zmq.Frame(b'asdf', track=False) -        self.assertEqual(m.tracker, None) -        m2 = copy.copy(m) -        self.assertEqual(m2.tracker, None) -        self.assertRaises(ValueError, zmq.MessageTracker, m) -     -    @skip_pypy -    def test_multi_tracker(self): -        m = zmq.Frame(b'asdf', track=True) -        m2 = zmq.Frame(b'whoda', track=True) -        mt = zmq.MessageTracker(m,m2) -        self.assertFalse(m.tracker.done) -        self.assertFalse(mt.done) -        self.assertRaises(zmq.NotDone, mt.wait, 0.1) -        del m -        time.sleep(0.1) -        self.assertRaises(zmq.NotDone, mt.wait, 0.1) -        self.assertFalse(mt.done) -        del m2 -        self.assertTrue(mt.wait() is None) -        self.assertTrue(mt.done) -         -     -    def test_buffer_in(self): -        """test using a buffer as input""" -        ins = b("§§¶•ªº˜µ¬˚…∆˙åß∂©œ∑´†≈ç√") -        m = zmq.Frame(view(ins)) -     -    def test_bad_buffer_in(self): -        """test using a bad object""" -        self.assertRaises(TypeError, zmq.Frame, 5) -        self.assertRaises(TypeError, zmq.Frame, object()) -         -    def test_buffer_out(self): -        """receiving buffered output""" -        ins = b("§§¶•ªº˜µ¬˚…∆˙åß∂©œ∑´†≈ç√") -        m = zmq.Frame(ins) -        outb = m.buffer -        self.assertTrue(isinstance(outb, view)) -        self.assert_(outb is m.buffer) -        self.assert_(m.buffer is m.buffer) -     -    def test_multisend(self): -        """ensure that a message remains intact after multiple sends""" -        a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        s = b"message" -        m = zmq.Frame(s) -        self.assertEqual(s, m.bytes) -         -        a.send(m, copy=False) -        time.sleep(0.1) -        self.assertEqual(s, m.bytes) -        a.send(m, copy=False) -        time.sleep(0.1) -        self.assertEqual(s, m.bytes) -        a.send(m, copy=True) -        time.sleep(0.1) -        self.assertEqual(s, m.bytes) -        a.send(m, copy=True) -        time.sleep(0.1) -        self.assertEqual(s, m.bytes) -        for i in range(4): -            r = b.recv() -            self.assertEqual(s,r) -        self.assertEqual(s, m.bytes) -     -    def test_buffer_numpy(self): -        """test non-copying numpy array messages""" -        try: -            import numpy -        except ImportError: -            raise SkipTest("numpy required") -        rand = numpy.random.randint -        shapes = [ rand(2,16) for i in range(5) ] -        for i in range(1,len(shapes)+1): -            shape = shapes[:i] -            A = numpy.random.random(shape) -            m = zmq.Frame(A) -            if view.__name__ == 'buffer': -                self.assertEqual(A.data, m.buffer) -                B = numpy.frombuffer(m.buffer,dtype=A.dtype).reshape(A.shape) -            else: -                self.assertEqual(memoryview(A), m.buffer) -                B = numpy.array(m.buffer,dtype=A.dtype).reshape(A.shape) -            self.assertEqual((A==B).all(), True) -     -    def test_memoryview(self): -        """test messages from memoryview""" -        major,minor = sys.version_info[:2] -        if not (major >= 3 or (major == 2 and minor >= 7)): -            raise SkipTest("memoryviews only in python >= 2.7") - -        s = b'carrotjuice' -        v = memoryview(s) -        m = zmq.Frame(s) -        buf = m.buffer -        s2 = buf.tobytes() -        self.assertEqual(s2,s) -        self.assertEqual(m.bytes,s) -     -    def test_noncopying_recv(self): -        """check for clobbering message buffers""" -        null = b'\0'*64 -        sa,sb = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        for i in range(32): -            # try a few times -            sb.send(null, copy=False) -            m = sa.recv(copy=False) -            mb = m.bytes -            # buf = view(m) -            buf = m.buffer -            del m -            for i in range(5): -                ff=b'\xff'*(40 + i*10) -                sb.send(ff, copy=False) -                m2 = sa.recv(copy=False) -                if view.__name__ == 'buffer': -                    b = bytes(buf) -                else: -                    b = buf.tobytes() -                self.assertEqual(b, null) -                self.assertEqual(mb, null) -                self.assertEqual(m2.bytes, ff) - -    @skip_pypy -    def test_buffer_numpy(self): -        """test non-copying numpy array messages""" -        try: -            import numpy -        except ImportError: -            raise SkipTest("requires numpy") -        if sys.version_info < (2,7): -            raise SkipTest("requires new-style buffer interface (py >= 2.7)") -        rand = numpy.random.randint -        shapes = [ rand(2,5) for i in range(5) ] -        a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        dtypes = [int, float, '>i4', 'B'] -        for i in range(1,len(shapes)+1): -            shape = shapes[:i] -            for dt in dtypes: -                A = numpy.random.uniform(-10000000, -                                         1000000, size=shape).astype(dt) -                a.send(A, copy=False) -                msg = b.recv(copy=False) -                 -                B = numpy.frombuffer(msg, A.dtype).reshape(A.shape) -                self.assertEqual(A.shape, B.shape) -                self.assertTrue((A==B).all()) -            A = numpy.empty(shape, dtype=[('a', int), ('b', float), ('c', 'a32')]) -            A['a'] = 1024 -            A['b'] = 1e9 -            A['c'] = 'hello there' -            a.send(A, copy=False) -            msg = b.recv(copy=False) -             -            B = numpy.frombuffer(msg, A.dtype).reshape(A.shape) -            self.assertEqual(A.shape, B.shape) -            self.assertTrue((A==B).all()) -     -    def test_frame_more(self): -        """test Frame.more attribute""" -        frame = zmq.Frame(b"hello") -        self.assertFalse(frame.more) -        sa,sb = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        sa.send_multipart([b'hi', b'there']) -        frame = self.recv(sb, copy=False) -        self.assertTrue(frame.more) -        if zmq.zmq_version_info()[0] >= 3 and not PYPY: -            self.assertTrue(frame.get(zmq.MORE)) -        frame = self.recv(sb, copy=False) -        self.assertFalse(frame.more) -        if zmq.zmq_version_info()[0] >= 3 and not PYPY: -            self.assertFalse(frame.get(zmq.MORE)) - diff --git a/zmq/tests/test_monitor.py b/zmq/tests/test_monitor.py deleted file mode 100644 index ab02b68..0000000 --- a/zmq/tests/test_monitor.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import sys -import time -import struct - -from unittest import TestCase - -import zmq -from zmq.tests import BaseZMQTestCase, skip_if, skip_pypy -from zmq.utils.monitor import recv_monitor_message - -skip_lt_4 = skip_if(zmq.zmq_version_info() < (4,), "requires zmq >= 4") - -class TestSocketMonitor(BaseZMQTestCase): - -    @skip_lt_4 -    def test_monitor(self): -        """Test monitoring interface for sockets.""" -        s_rep = self.context.socket(zmq.REP) -        s_req = self.context.socket(zmq.REQ) -        self.sockets.extend([s_rep, s_req]) -        s_req.bind("tcp://127.0.0.1:6666") -        # try monitoring the REP socket -         -        s_rep.monitor("inproc://monitor.rep", zmq.EVENT_ALL) -        # create listening socket for monitor -        s_event = self.context.socket(zmq.PAIR) -        self.sockets.append(s_event) -        s_event.connect("inproc://monitor.rep") -        s_event.linger = 0 -        # test receive event for connect event -        s_rep.connect("tcp://127.0.0.1:6666") -        m = recv_monitor_message(s_event) -        if m['event'] == zmq.EVENT_CONNECT_DELAYED: -            self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6666") -            # test receive event for connected event -            m = recv_monitor_message(s_event) -        self.assertEqual(m['event'], zmq.EVENT_CONNECTED) -        self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6666") - - -    @skip_lt_4 -    def test_monitor_connected(self): -        """Test connected monitoring socket.""" -        s_rep = self.context.socket(zmq.REP) -        s_req = self.context.socket(zmq.REQ) -        self.sockets.extend([s_rep, s_req]) -        s_req.bind("tcp://127.0.0.1:6667") -        # try monitoring the REP socket -        # create listening socket for monitor -        s_event = s_rep.get_monitor_socket() -        s_event.linger = 0 -        self.sockets.append(s_event) -        # test receive event for connect event -        s_rep.connect("tcp://127.0.0.1:6667") -        m = recv_monitor_message(s_event) -        if m['event'] == zmq.EVENT_CONNECT_DELAYED: -            self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6667") -            # test receive event for connected event -            m = recv_monitor_message(s_event) -        self.assertEqual(m['event'], zmq.EVENT_CONNECTED) -        self.assertEqual(m['endpoint'], b"tcp://127.0.0.1:6667") diff --git a/zmq/tests/test_monqueue.py b/zmq/tests/test_monqueue.py deleted file mode 100644 index e855602..0000000 --- a/zmq/tests/test_monqueue.py +++ /dev/null @@ -1,227 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import time -from unittest import TestCase - -import zmq -from zmq import devices - -from zmq.tests import BaseZMQTestCase, SkipTest, PYPY -from zmq.utils.strtypes import unicode - - -if PYPY or zmq.zmq_version_info() >= (4,1): -    # cleanup of shared Context doesn't work on PyPy -    # there also seems to be a bug in cleanup in libzmq-4.1 (zeromq/libzmq#1052) -    devices.Device.context_factory = zmq.Context - - -class TestMonitoredQueue(BaseZMQTestCase): -     -    sockets = [] -     -    def build_device(self, mon_sub=b"", in_prefix=b'in', out_prefix=b'out'): -        self.device = devices.ThreadMonitoredQueue(zmq.PAIR, zmq.PAIR, zmq.PUB, -                                            in_prefix, out_prefix) -        alice = self.context.socket(zmq.PAIR) -        bob = self.context.socket(zmq.PAIR) -        mon = self.context.socket(zmq.SUB) -         -        aport = alice.bind_to_random_port('tcp://127.0.0.1') -        bport = bob.bind_to_random_port('tcp://127.0.0.1') -        mport = mon.bind_to_random_port('tcp://127.0.0.1') -        mon.setsockopt(zmq.SUBSCRIBE, mon_sub) -         -        self.device.connect_in("tcp://127.0.0.1:%i"%aport) -        self.device.connect_out("tcp://127.0.0.1:%i"%bport) -        self.device.connect_mon("tcp://127.0.0.1:%i"%mport) -        self.device.start() -        time.sleep(.2) -        try: -            # this is currenlty necessary to ensure no dropped monitor messages -            # see LIBZMQ-248 for more info -            mon.recv_multipart(zmq.NOBLOCK) -        except zmq.ZMQError: -            pass -        self.sockets.extend([alice, bob, mon]) -        return alice, bob, mon -         -     -    def teardown_device(self): -        for socket in self.sockets: -            socket.close() -            del socket -        del self.device -         -    def test_reply(self): -        alice, bob, mon = self.build_device() -        alices = b"hello bob".split() -        alice.send_multipart(alices) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices, bobs) -        bobs = b"hello alice".split() -        bob.send_multipart(bobs) -        alices = self.recv_multipart(alice) -        self.assertEqual(alices, bobs) -        self.teardown_device() -     -    def test_queue(self): -        alice, bob, mon = self.build_device() -        alices = b"hello bob".split() -        alice.send_multipart(alices) -        alices2 = b"hello again".split() -        alice.send_multipart(alices2) -        alices3 = b"hello again and again".split() -        alice.send_multipart(alices3) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices, bobs) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices2, bobs) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices3, bobs) -        bobs = b"hello alice".split() -        bob.send_multipart(bobs) -        alices = self.recv_multipart(alice) -        self.assertEqual(alices, bobs) -        self.teardown_device() -     -    def test_monitor(self): -        alice, bob, mon = self.build_device() -        alices = b"hello bob".split() -        alice.send_multipart(alices) -        alices2 = b"hello again".split() -        alice.send_multipart(alices2) -        alices3 = b"hello again and again".split() -        alice.send_multipart(alices3) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices, bobs) -        mons = self.recv_multipart(mon) -        self.assertEqual([b'in']+bobs, mons) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices2, bobs) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices3, bobs) -        mons = self.recv_multipart(mon) -        self.assertEqual([b'in']+alices2, mons) -        bobs = b"hello alice".split() -        bob.send_multipart(bobs) -        alices = self.recv_multipart(alice) -        self.assertEqual(alices, bobs) -        mons = self.recv_multipart(mon) -        self.assertEqual([b'in']+alices3, mons) -        mons = self.recv_multipart(mon) -        self.assertEqual([b'out']+bobs, mons) -        self.teardown_device() -     -    def test_prefix(self): -        alice, bob, mon = self.build_device(b"", b'foo', b'bar') -        alices = b"hello bob".split() -        alice.send_multipart(alices) -        alices2 = b"hello again".split() -        alice.send_multipart(alices2) -        alices3 = b"hello again and again".split() -        alice.send_multipart(alices3) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices, bobs) -        mons = self.recv_multipart(mon) -        self.assertEqual([b'foo']+bobs, mons) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices2, bobs) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices3, bobs) -        mons = self.recv_multipart(mon) -        self.assertEqual([b'foo']+alices2, mons) -        bobs = b"hello alice".split() -        bob.send_multipart(bobs) -        alices = self.recv_multipart(alice) -        self.assertEqual(alices, bobs) -        mons = self.recv_multipart(mon) -        self.assertEqual([b'foo']+alices3, mons) -        mons = self.recv_multipart(mon) -        self.assertEqual([b'bar']+bobs, mons) -        self.teardown_device() -     -    def test_monitor_subscribe(self): -        alice, bob, mon = self.build_device(b"out") -        alices = b"hello bob".split() -        alice.send_multipart(alices) -        alices2 = b"hello again".split() -        alice.send_multipart(alices2) -        alices3 = b"hello again and again".split() -        alice.send_multipart(alices3) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices, bobs) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices2, bobs) -        bobs = self.recv_multipart(bob) -        self.assertEqual(alices3, bobs) -        bobs = b"hello alice".split() -        bob.send_multipart(bobs) -        alices = self.recv_multipart(alice) -        self.assertEqual(alices, bobs) -        mons = self.recv_multipart(mon) -        self.assertEqual([b'out']+bobs, mons) -        self.teardown_device() -     -    def test_router_router(self): -        """test router-router MQ devices""" -        dev = devices.ThreadMonitoredQueue(zmq.ROUTER, zmq.ROUTER, zmq.PUB, b'in', b'out') -        self.device = dev -        dev.setsockopt_in(zmq.LINGER, 0) -        dev.setsockopt_out(zmq.LINGER, 0) -        dev.setsockopt_mon(zmq.LINGER, 0) -         -        binder = self.context.socket(zmq.DEALER) -        porta = binder.bind_to_random_port('tcp://127.0.0.1') -        portb = binder.bind_to_random_port('tcp://127.0.0.1') -        binder.close() -        time.sleep(0.1) -        a = self.context.socket(zmq.DEALER) -        a.identity = b'a' -        b = self.context.socket(zmq.DEALER) -        b.identity = b'b' -        self.sockets.extend([a, b]) -         -        a.connect('tcp://127.0.0.1:%i'%porta) -        dev.bind_in('tcp://127.0.0.1:%i'%porta) -        b.connect('tcp://127.0.0.1:%i'%portb) -        dev.bind_out('tcp://127.0.0.1:%i'%portb) -        dev.start() -        time.sleep(0.2) -        if zmq.zmq_version_info() >= (3,1,0): -            # flush erroneous poll state, due to LIBZMQ-280 -            ping_msg = [ b'ping', b'pong' ] -            for s in (a,b): -                s.send_multipart(ping_msg) -                try: -                    s.recv(zmq.NOBLOCK) -                except zmq.ZMQError: -                    pass -        msg = [ b'hello', b'there' ] -        a.send_multipart([b'b']+msg) -        bmsg = self.recv_multipart(b) -        self.assertEqual(bmsg, [b'a']+msg) -        b.send_multipart(bmsg) -        amsg = self.recv_multipart(a) -        self.assertEqual(amsg, [b'b']+msg) -        self.teardown_device() -     -    def test_default_mq_args(self): -        self.device = dev = devices.ThreadMonitoredQueue(zmq.ROUTER, zmq.DEALER, zmq.PUB) -        dev.setsockopt_in(zmq.LINGER, 0) -        dev.setsockopt_out(zmq.LINGER, 0) -        dev.setsockopt_mon(zmq.LINGER, 0) -        # this will raise if default args are wrong -        dev.start() -        self.teardown_device() -     -    def test_mq_check_prefix(self): -        ins = self.context.socket(zmq.ROUTER) -        outs = self.context.socket(zmq.DEALER) -        mons = self.context.socket(zmq.PUB) -        self.sockets.extend([ins, outs, mons]) -         -        ins = unicode('in') -        outs = unicode('out') -        self.assertRaises(TypeError, devices.monitoredqueue, ins, outs, mons) diff --git a/zmq/tests/test_multipart.py b/zmq/tests/test_multipart.py deleted file mode 100644 index 24d41be..0000000 --- a/zmq/tests/test_multipart.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import zmq - - -from zmq.tests import BaseZMQTestCase, SkipTest, have_gevent, GreenTest - - -class TestMultipart(BaseZMQTestCase): - -    def test_router_dealer(self): -        router, dealer = self.create_bound_pair(zmq.ROUTER, zmq.DEALER) - -        msg1 = b'message1' -        dealer.send(msg1) -        ident = self.recv(router) -        more = router.rcvmore -        self.assertEqual(more, True) -        msg2 = self.recv(router) -        self.assertEqual(msg1, msg2) -        more = router.rcvmore -        self.assertEqual(more, False) -     -    def test_basic_multipart(self): -        a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        msg = [ b'hi', b'there', b'b'] -        a.send_multipart(msg) -        recvd = b.recv_multipart() -        self.assertEqual(msg, recvd) - -if have_gevent: -    class TestMultipartGreen(GreenTest, TestMultipart): -        pass diff --git a/zmq/tests/test_pair.py b/zmq/tests/test_pair.py deleted file mode 100644 index e88c1e8..0000000 --- a/zmq/tests/test_pair.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import zmq - - -from zmq.tests import BaseZMQTestCase, have_gevent, GreenTest - - -x = b' ' -class TestPair(BaseZMQTestCase): - -    def test_basic(self): -        s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) - -        msg1 = b'message1' -        msg2 = self.ping_pong(s1, s2, msg1) -        self.assertEqual(msg1, msg2) - -    def test_multiple(self): -        s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) - -        for i in range(10): -            msg = i*x -            s1.send(msg) - -        for i in range(10): -            msg = i*x -            s2.send(msg) - -        for i in range(10): -            msg = s1.recv() -            self.assertEqual(msg, i*x) - -        for i in range(10): -            msg = s2.recv() -            self.assertEqual(msg, i*x) - -    def test_json(self): -        s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        o = dict(a=10,b=list(range(10))) -        o2 = self.ping_pong_json(s1, s2, o) - -    def test_pyobj(self): -        s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        o = dict(a=10,b=range(10)) -        o2 = self.ping_pong_pyobj(s1, s2, o) - -if have_gevent: -    class TestReqRepGreen(GreenTest, TestPair): -        pass - diff --git a/zmq/tests/test_poll.py b/zmq/tests/test_poll.py deleted file mode 100644 index 57346c8..0000000 --- a/zmq/tests/test_poll.py +++ /dev/null @@ -1,229 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import time -from unittest import TestCase - -import zmq - -from zmq.tests import PollZMQTestCase, have_gevent, GreenTest - -def wait(): -    time.sleep(.25) - - -class TestPoll(PollZMQTestCase): - -    Poller = zmq.Poller - -    # This test is failing due to this issue: -    # http://github.com/sustrik/zeromq2/issues#issue/26 -    def test_pair(self): -        s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) - -        # Sleep to allow sockets to connect. -        wait() - -        poller = self.Poller() -        poller.register(s1, zmq.POLLIN|zmq.POLLOUT) -        poller.register(s2, zmq.POLLIN|zmq.POLLOUT) -        # Poll result should contain both sockets -        socks = dict(poller.poll()) -        # Now make sure that both are send ready. -        self.assertEqual(socks[s1], zmq.POLLOUT) -        self.assertEqual(socks[s2], zmq.POLLOUT) -        # Now do a send on both, wait and test for zmq.POLLOUT|zmq.POLLIN -        s1.send(b'msg1') -        s2.send(b'msg2') -        wait() -        socks = dict(poller.poll()) -        self.assertEqual(socks[s1], zmq.POLLOUT|zmq.POLLIN) -        self.assertEqual(socks[s2], zmq.POLLOUT|zmq.POLLIN) -        # Make sure that both are in POLLOUT after recv. -        s1.recv() -        s2.recv() -        socks = dict(poller.poll()) -        self.assertEqual(socks[s1], zmq.POLLOUT) -        self.assertEqual(socks[s2], zmq.POLLOUT) - -        poller.unregister(s1) -        poller.unregister(s2) - -        # Wait for everything to finish. -        wait() - -    def test_reqrep(self): -        s1, s2 = self.create_bound_pair(zmq.REP, zmq.REQ) - -        # Sleep to allow sockets to connect. -        wait() - -        poller = self.Poller() -        poller.register(s1, zmq.POLLIN|zmq.POLLOUT) -        poller.register(s2, zmq.POLLIN|zmq.POLLOUT) - -        # Make sure that s1 is in state 0 and s2 is in POLLOUT -        socks = dict(poller.poll()) -        self.assertEqual(s1 in socks, 0) -        self.assertEqual(socks[s2], zmq.POLLOUT) - -        # Make sure that s2 goes immediately into state 0 after send. -        s2.send(b'msg1') -        socks = dict(poller.poll()) -        self.assertEqual(s2 in socks, 0) - -        # Make sure that s1 goes into POLLIN state after a time.sleep(). -        time.sleep(0.5) -        socks = dict(poller.poll()) -        self.assertEqual(socks[s1], zmq.POLLIN) - -        # Make sure that s1 goes into POLLOUT after recv. -        s1.recv() -        socks = dict(poller.poll()) -        self.assertEqual(socks[s1], zmq.POLLOUT) - -        # Make sure s1 goes into state 0 after send. -        s1.send(b'msg2') -        socks = dict(poller.poll()) -        self.assertEqual(s1 in socks, 0) - -        # Wait and then see that s2 is in POLLIN. -        time.sleep(0.5) -        socks = dict(poller.poll()) -        self.assertEqual(socks[s2], zmq.POLLIN) - -        # Make sure that s2 is in POLLOUT after recv. -        s2.recv() -        socks = dict(poller.poll()) -        self.assertEqual(socks[s2], zmq.POLLOUT) - -        poller.unregister(s1) -        poller.unregister(s2) - -        # Wait for everything to finish. -        wait() -     -    def test_no_events(self): -        s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        poller = self.Poller() -        poller.register(s1, zmq.POLLIN|zmq.POLLOUT) -        poller.register(s2, 0) -        self.assertTrue(s1 in poller) -        self.assertFalse(s2 in poller) -        poller.register(s1, 0) -        self.assertFalse(s1 in poller) - -    def test_pubsub(self): -        s1, s2 = self.create_bound_pair(zmq.PUB, zmq.SUB) -        s2.setsockopt(zmq.SUBSCRIBE, b'') - -        # Sleep to allow sockets to connect. -        wait() - -        poller = self.Poller() -        poller.register(s1, zmq.POLLIN|zmq.POLLOUT) -        poller.register(s2, zmq.POLLIN) - -        # Now make sure that both are send ready. -        socks = dict(poller.poll()) -        self.assertEqual(socks[s1], zmq.POLLOUT) -        self.assertEqual(s2 in socks, 0) -        # Make sure that s1 stays in POLLOUT after a send. -        s1.send(b'msg1') -        socks = dict(poller.poll()) -        self.assertEqual(socks[s1], zmq.POLLOUT) - -        # Make sure that s2 is POLLIN after waiting. -        wait() -        socks = dict(poller.poll()) -        self.assertEqual(socks[s2], zmq.POLLIN) - -        # Make sure that s2 goes into 0 after recv. -        s2.recv() -        socks = dict(poller.poll()) -        self.assertEqual(s2 in socks, 0) - -        poller.unregister(s1) -        poller.unregister(s2) - -        # Wait for everything to finish. -        wait() -    def test_timeout(self): -        """make sure Poller.poll timeout has the right units (milliseconds).""" -        s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        poller = self.Poller() -        poller.register(s1, zmq.POLLIN) -        tic = time.time() -        evt = poller.poll(.005) -        toc = time.time() -        self.assertTrue(toc-tic < 0.1) -        tic = time.time() -        evt = poller.poll(5) -        toc = time.time() -        self.assertTrue(toc-tic < 0.1) -        self.assertTrue(toc-tic > .001) -        tic = time.time() -        evt = poller.poll(500) -        toc = time.time() -        self.assertTrue(toc-tic < 1) -        self.assertTrue(toc-tic > 0.1) - -class TestSelect(PollZMQTestCase): - -    def test_pair(self): -        s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) - -        # Sleep to allow sockets to connect. -        wait() - -        rlist, wlist, xlist = zmq.select([s1, s2], [s1, s2], [s1, s2]) -        self.assert_(s1 in wlist) -        self.assert_(s2 in wlist) -        self.assert_(s1 not in rlist) -        self.assert_(s2 not in rlist) - -    def test_timeout(self): -        """make sure select timeout has the right units (seconds).""" -        s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        tic = time.time() -        r,w,x = zmq.select([s1,s2],[],[],.005) -        toc = time.time() -        self.assertTrue(toc-tic < 1) -        self.assertTrue(toc-tic > 0.001) -        tic = time.time() -        r,w,x = zmq.select([s1,s2],[],[],.25) -        toc = time.time() -        self.assertTrue(toc-tic < 1) -        self.assertTrue(toc-tic > 0.1) - - -if have_gevent: -    import gevent -    from zmq import green as gzmq - -    class TestPollGreen(GreenTest, TestPoll): -        Poller = gzmq.Poller - -        def test_wakeup(self): -            s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -            poller = self.Poller() -            poller.register(s2, zmq.POLLIN) - -            tic = time.time() -            r = gevent.spawn(lambda: poller.poll(10000)) -            s = gevent.spawn(lambda: s1.send(b'msg1')) -            r.join() -            toc = time.time() -            self.assertTrue(toc-tic < 1) -         -        def test_socket_poll(self): -            s1, s2 = self.create_bound_pair(zmq.PAIR, zmq.PAIR) - -            tic = time.time() -            r = gevent.spawn(lambda: s2.poll(10000)) -            s = gevent.spawn(lambda: s1.send(b'msg1')) -            r.join() -            toc = time.time() -            self.assertTrue(toc-tic < 1) - diff --git a/zmq/tests/test_pubsub.py b/zmq/tests/test_pubsub.py deleted file mode 100644 index a3ee22a..0000000 --- a/zmq/tests/test_pubsub.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import time -from unittest import TestCase - -import zmq - -from zmq.tests import BaseZMQTestCase, have_gevent, GreenTest - - -class TestPubSub(BaseZMQTestCase): - -    pass - -    # We are disabling this test while an issue is being resolved. -    def test_basic(self): -        s1, s2 = self.create_bound_pair(zmq.PUB, zmq.SUB) -        s2.setsockopt(zmq.SUBSCRIBE,b'') -        time.sleep(0.1) -        msg1 = b'message' -        s1.send(msg1) -        msg2 = s2.recv()  # This is blocking! -        self.assertEqual(msg1, msg2) - -    def test_topic(self): -        s1, s2 = self.create_bound_pair(zmq.PUB, zmq.SUB) -        s2.setsockopt(zmq.SUBSCRIBE, b'x') -        time.sleep(0.1) -        msg1 = b'message' -        s1.send(msg1) -        self.assertRaisesErrno(zmq.EAGAIN, s2.recv, zmq.NOBLOCK) -        msg1 = b'xmessage' -        s1.send(msg1) -        msg2 = s2.recv() -        self.assertEqual(msg1, msg2) - -if have_gevent: -    class TestPubSubGreen(GreenTest, TestPubSub): -        pass diff --git a/zmq/tests/test_reqrep.py b/zmq/tests/test_reqrep.py deleted file mode 100644 index de17f2b..0000000 --- a/zmq/tests/test_reqrep.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -from unittest import TestCase - -import zmq -from zmq.tests import BaseZMQTestCase, have_gevent, GreenTest - - -class TestReqRep(BaseZMQTestCase): - -    def test_basic(self): -        s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) - -        msg1 = b'message 1' -        msg2 = self.ping_pong(s1, s2, msg1) -        self.assertEqual(msg1, msg2) - -    def test_multiple(self): -        s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) - -        for i in range(10): -            msg1 = i*b' ' -            msg2 = self.ping_pong(s1, s2, msg1) -            self.assertEqual(msg1, msg2) - -    def test_bad_send_recv(self): -        s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) -         -        if zmq.zmq_version() != '2.1.8': -            # this doesn't work on 2.1.8 -            for copy in (True,False): -                self.assertRaisesErrno(zmq.EFSM, s1.recv, copy=copy) -                self.assertRaisesErrno(zmq.EFSM, s2.send, b'asdf', copy=copy) - -        # I have to have this or we die on an Abort trap. -        msg1 = b'asdf' -        msg2 = self.ping_pong(s1, s2, msg1) -        self.assertEqual(msg1, msg2) - -    def test_json(self): -        s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) -        o = dict(a=10,b=list(range(10))) -        o2 = self.ping_pong_json(s1, s2, o) - -    def test_pyobj(self): -        s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) -        o = dict(a=10,b=range(10)) -        o2 = self.ping_pong_pyobj(s1, s2, o) - -    def test_large_msg(self): -        s1, s2 = self.create_bound_pair(zmq.REQ, zmq.REP) -        msg1 = 10000*b'X' - -        for i in range(10): -            msg2 = self.ping_pong(s1, s2, msg1) -            self.assertEqual(msg1, msg2) - -if have_gevent: -    class TestReqRepGreen(GreenTest, TestReqRep): -        pass diff --git a/zmq/tests/test_security.py b/zmq/tests/test_security.py deleted file mode 100644 index 7d74c10..0000000 --- a/zmq/tests/test_security.py +++ /dev/null @@ -1,201 +0,0 @@ -"""Test libzmq security (libzmq >= 3.3.0)""" -# -*- coding: utf8 -*- - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import os -from threading import Thread - -import zmq -from zmq.tests import ( -    BaseZMQTestCase, SkipTest -) -from zmq.utils import z85 - - -USER = b"admin" -PASS = b"password" - -class TestSecurity(BaseZMQTestCase): -     -    def setUp(self): -        if zmq.zmq_version_info() < (4,0): -            raise SkipTest("security is new in libzmq 4.0") -        try: -            zmq.curve_keypair() -        except zmq.ZMQError: -            raise SkipTest("security requires libzmq to be linked against libsodium") -        super(TestSecurity, self).setUp() -     -     -    def zap_handler(self): -        socket = self.context.socket(zmq.REP) -        socket.bind("inproc://zeromq.zap.01") -        try: -            msg = self.recv_multipart(socket) - -            version, sequence, domain, address, identity, mechanism = msg[:6] -            if mechanism == b'PLAIN': -                username, password = msg[6:] -            elif mechanism == b'CURVE': -                key = msg[6] - -            self.assertEqual(version, b"1.0") -            self.assertEqual(identity, b"IDENT") -            reply = [version, sequence] -            if mechanism == b'CURVE' or \ -                (mechanism == b'PLAIN' and username == USER and password == PASS) or \ -                (mechanism == b'NULL'): -                reply.extend([ -                    b"200", -                    b"OK", -                    b"anonymous", -                    b"", -                ]) -            else: -                reply.extend([ -                    b"400", -                    b"Invalid username or password", -                    b"", -                    b"", -                ]) -            socket.send_multipart(reply) -        finally: -            socket.close() -     -    def start_zap(self): -        self.zap_thread = Thread(target=self.zap_handler) -        self.zap_thread.start() -     -    def stop_zap(self): -        self.zap_thread.join() - -    def bounce(self, server, client): -        msg = [os.urandom(64), os.urandom(64)] -        client.send_multipart(msg) -        recvd = self.recv_multipart(server) -        self.assertEqual(recvd, msg) -        server.send_multipart(recvd) -        msg2 = self.recv_multipart(client) -        self.assertEqual(msg2, msg) -     -    def test_null(self): -        """test NULL (default) security""" -        server = self.socket(zmq.DEALER) -        client = self.socket(zmq.DEALER) -        self.assertEqual(client.MECHANISM, zmq.NULL) -        self.assertEqual(server.mechanism, zmq.NULL) -        self.assertEqual(client.plain_server, 0) -        self.assertEqual(server.plain_server, 0) -        iface = 'tcp://127.0.0.1' -        port = server.bind_to_random_port(iface) -        client.connect("%s:%i" % (iface, port)) -        self.bounce(server, client) - -    def test_plain(self): -        """test PLAIN authentication""" -        server = self.socket(zmq.DEALER) -        server.identity = b'IDENT' -        client = self.socket(zmq.DEALER) -        self.assertEqual(client.plain_username, b'') -        self.assertEqual(client.plain_password, b'') -        client.plain_username = USER -        client.plain_password = PASS -        self.assertEqual(client.getsockopt(zmq.PLAIN_USERNAME), USER) -        self.assertEqual(client.getsockopt(zmq.PLAIN_PASSWORD), PASS) -        self.assertEqual(client.plain_server, 0) -        self.assertEqual(server.plain_server, 0) -        server.plain_server = True -        self.assertEqual(server.mechanism, zmq.PLAIN) -        self.assertEqual(client.mechanism, zmq.PLAIN) -         -        assert not client.plain_server -        assert server.plain_server -         -        self.start_zap() -         -        iface = 'tcp://127.0.0.1' -        port = server.bind_to_random_port(iface) -        client.connect("%s:%i" % (iface, port)) -        self.bounce(server, client) -        self.stop_zap() - -    def skip_plain_inauth(self): -        """test PLAIN failed authentication""" -        server = self.socket(zmq.DEALER) -        server.identity = b'IDENT' -        client = self.socket(zmq.DEALER) -        self.sockets.extend([server, client]) -        client.plain_username = USER -        client.plain_password = b'incorrect' -        server.plain_server = True -        self.assertEqual(server.mechanism, zmq.PLAIN) -        self.assertEqual(client.mechanism, zmq.PLAIN) -         -        self.start_zap() -         -        iface = 'tcp://127.0.0.1' -        port = server.bind_to_random_port(iface) -        client.connect("%s:%i" % (iface, port)) -        client.send(b'ping') -        server.rcvtimeo = 250 -        self.assertRaisesErrno(zmq.EAGAIN, server.recv) -        self.stop_zap() -     -    def test_keypair(self): -        """test curve_keypair""" -        try: -            public, secret = zmq.curve_keypair() -        except zmq.ZMQError: -            raise SkipTest("CURVE unsupported") -         -        self.assertEqual(type(secret), bytes) -        self.assertEqual(type(public), bytes) -        self.assertEqual(len(secret), 40) -        self.assertEqual(len(public), 40) -         -        # verify that it is indeed Z85 -        bsecret, bpublic = [ z85.decode(key) for key in (public, secret) ] -        self.assertEqual(type(bsecret), bytes) -        self.assertEqual(type(bpublic), bytes) -        self.assertEqual(len(bsecret), 32) -        self.assertEqual(len(bpublic), 32) -         -     -    def test_curve(self): -        """test CURVE encryption""" -        server = self.socket(zmq.DEALER) -        server.identity = b'IDENT' -        client = self.socket(zmq.DEALER) -        self.sockets.extend([server, client]) -        try: -            server.curve_server = True -        except zmq.ZMQError as e: -            # will raise EINVAL if not linked against libsodium -            if e.errno == zmq.EINVAL: -                raise SkipTest("CURVE unsupported") -         -        server_public, server_secret = zmq.curve_keypair() -        client_public, client_secret = zmq.curve_keypair() -         -        server.curve_secretkey = server_secret -        server.curve_publickey = server_public -        client.curve_serverkey = server_public -        client.curve_publickey = client_public -        client.curve_secretkey = client_secret -         -        self.assertEqual(server.mechanism, zmq.CURVE) -        self.assertEqual(client.mechanism, zmq.CURVE) -         -        self.assertEqual(server.get(zmq.CURVE_SERVER), True) -        self.assertEqual(client.get(zmq.CURVE_SERVER), False) -         -        self.start_zap() -         -        iface = 'tcp://127.0.0.1' -        port = server.bind_to_random_port(iface) -        client.connect("%s:%i" % (iface, port)) -        self.bounce(server, client) -        self.stop_zap() -         diff --git a/zmq/tests/test_socket.py b/zmq/tests/test_socket.py deleted file mode 100644 index d572949..0000000 --- a/zmq/tests/test_socket.py +++ /dev/null @@ -1,461 +0,0 @@ -# -*- coding: utf8 -*- -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import sys -import time -import errno -import warnings - -import zmq -from zmq.tests import ( -    BaseZMQTestCase, SkipTest, have_gevent, GreenTest, skip_pypy, skip_if -) -from zmq.utils.strtypes import bytes, unicode - -try: -    from queue import Queue -except: -    from Queue import Queue - - -class TestSocket(BaseZMQTestCase): - -    def test_create(self): -        ctx = self.Context() -        s = ctx.socket(zmq.PUB) -        # Superluminal protocol not yet implemented -        self.assertRaisesErrno(zmq.EPROTONOSUPPORT, s.bind, 'ftl://a') -        self.assertRaisesErrno(zmq.EPROTONOSUPPORT, s.connect, 'ftl://a') -        self.assertRaisesErrno(zmq.EINVAL, s.bind, 'tcp://') -        s.close() -        del ctx -     -    def test_dir(self): -        ctx = self.Context() -        s = ctx.socket(zmq.PUB) -        self.assertTrue('send' in dir(s)) -        self.assertTrue('IDENTITY' in dir(s)) -        self.assertTrue('AFFINITY' in dir(s)) -        self.assertTrue('FD' in dir(s)) -        s.close() -        ctx.term() - -    def test_bind_unicode(self): -        s = self.socket(zmq.PUB) -        p = s.bind_to_random_port(unicode("tcp://*")) - -    def test_connect_unicode(self): -        s = self.socket(zmq.PUB) -        s.connect(unicode("tcp://127.0.0.1:5555")) - -    def test_bind_to_random_port(self): -        # Check that bind_to_random_port do not hide usefull exception -        ctx = self.Context() -        c = ctx.socket(zmq.PUB) -        # Invalid format -        try: -            c.bind_to_random_port('tcp:*') -        except zmq.ZMQError as e: -            self.assertEqual(e.errno, zmq.EINVAL) -        # Invalid protocol -        try: -            c.bind_to_random_port('rand://*') -        except zmq.ZMQError as e: -            self.assertEqual(e.errno, zmq.EPROTONOSUPPORT) - -    def test_identity(self): -        s = self.context.socket(zmq.PULL) -        self.sockets.append(s) -        ident = b'identity\0\0' -        s.identity = ident -        self.assertEqual(s.get(zmq.IDENTITY), ident) - -    def test_unicode_sockopts(self): -        """test setting/getting sockopts with unicode strings""" -        topic = "tést" -        if str is not unicode: -            topic = topic.decode('utf8') -        p,s = self.create_bound_pair(zmq.PUB, zmq.SUB) -        self.assertEqual(s.send_unicode, s.send_unicode) -        self.assertEqual(p.recv_unicode, p.recv_unicode) -        self.assertRaises(TypeError, s.setsockopt, zmq.SUBSCRIBE, topic) -        self.assertRaises(TypeError, s.setsockopt, zmq.IDENTITY, topic) -        s.setsockopt_unicode(zmq.IDENTITY, topic, 'utf16') -        self.assertRaises(TypeError, s.setsockopt, zmq.AFFINITY, topic) -        s.setsockopt_unicode(zmq.SUBSCRIBE, topic) -        self.assertRaises(TypeError, s.getsockopt_unicode, zmq.AFFINITY) -        self.assertRaisesErrno(zmq.EINVAL, s.getsockopt_unicode, zmq.SUBSCRIBE) -         -        identb = s.getsockopt(zmq.IDENTITY) -        identu = identb.decode('utf16') -        identu2 = s.getsockopt_unicode(zmq.IDENTITY, 'utf16') -        self.assertEqual(identu, identu2) -        time.sleep(0.1) # wait for connection/subscription -        p.send_unicode(topic,zmq.SNDMORE) -        p.send_unicode(topic*2, encoding='latin-1') -        self.assertEqual(topic, s.recv_unicode()) -        self.assertEqual(topic*2, s.recv_unicode(encoding='latin-1')) -     -    def test_int_sockopts(self): -        "test integer sockopts" -        v = zmq.zmq_version_info() -        if v < (3,0): -            default_hwm = 0 -        else: -            default_hwm = 1000 -        p,s = self.create_bound_pair(zmq.PUB, zmq.SUB) -        p.setsockopt(zmq.LINGER, 0) -        self.assertEqual(p.getsockopt(zmq.LINGER), 0) -        p.setsockopt(zmq.LINGER, -1) -        self.assertEqual(p.getsockopt(zmq.LINGER), -1) -        self.assertEqual(p.hwm, default_hwm) -        p.hwm = 11 -        self.assertEqual(p.hwm, 11) -        # p.setsockopt(zmq.EVENTS, zmq.POLLIN) -        self.assertEqual(p.getsockopt(zmq.EVENTS), zmq.POLLOUT) -        self.assertRaisesErrno(zmq.EINVAL, p.setsockopt,zmq.EVENTS, 2**7-1) -        self.assertEqual(p.getsockopt(zmq.TYPE), p.socket_type) -        self.assertEqual(p.getsockopt(zmq.TYPE), zmq.PUB) -        self.assertEqual(s.getsockopt(zmq.TYPE), s.socket_type) -        self.assertEqual(s.getsockopt(zmq.TYPE), zmq.SUB) -         -        # check for overflow / wrong type: -        errors = [] -        backref = {} -        constants = zmq.constants -        for name in constants.__all__: -            value = getattr(constants, name) -            if isinstance(value, int): -                backref[value] = name -        for opt in zmq.constants.int_sockopts.union(zmq.constants.int64_sockopts): -            sopt = backref[opt] -            if sopt.startswith(( -                'ROUTER', 'XPUB', 'TCP', 'FAIL', -                'REQ_', 'CURVE_', 'PROBE_ROUTER', -                'IPC_FILTER', -                )): -                # some sockopts are write-only -                continue -            try: -                n = p.getsockopt(opt) -            except zmq.ZMQError as e: -                errors.append("getsockopt(zmq.%s) raised '%s'."%(sopt, e)) -            else: -                if n > 2**31: -                    errors.append("getsockopt(zmq.%s) returned a ridiculous value." -                                    " It is probably the wrong type."%sopt) -        if errors: -            self.fail('\n'.join([''] + errors)) -     -    def test_bad_sockopts(self): -        """Test that appropriate errors are raised on bad socket options""" -        s = self.context.socket(zmq.PUB) -        self.sockets.append(s) -        s.setsockopt(zmq.LINGER, 0) -        # unrecognized int sockopts pass through to libzmq, and should raise EINVAL -        self.assertRaisesErrno(zmq.EINVAL, s.setsockopt, 9999, 5) -        self.assertRaisesErrno(zmq.EINVAL, s.getsockopt, 9999) -        # but only int sockopts are allowed through this way, otherwise raise a TypeError -        self.assertRaises(TypeError, s.setsockopt, 9999, b"5") -        # some sockopts are valid in general, but not on every socket: -        self.assertRaisesErrno(zmq.EINVAL, s.setsockopt, zmq.SUBSCRIBE, b'hi') -     -    def test_sockopt_roundtrip(self): -        "test set/getsockopt roundtrip." -        p = self.context.socket(zmq.PUB) -        self.sockets.append(p) -        self.assertEqual(p.getsockopt(zmq.LINGER), -1) -        p.setsockopt(zmq.LINGER, 11) -        self.assertEqual(p.getsockopt(zmq.LINGER), 11) -     -    def test_poll(self): -        """test Socket.poll()""" -        req, rep = self.create_bound_pair(zmq.REQ, zmq.REP) -        # default flag is POLLIN, nobody has anything to recv: -        self.assertEqual(req.poll(0), 0) -        self.assertEqual(rep.poll(0), 0) -        self.assertEqual(req.poll(0, zmq.POLLOUT), zmq.POLLOUT) -        self.assertEqual(rep.poll(0, zmq.POLLOUT), 0) -        self.assertEqual(req.poll(0, zmq.POLLOUT|zmq.POLLIN), zmq.POLLOUT) -        self.assertEqual(rep.poll(0, zmq.POLLOUT), 0) -        req.send('hi') -        self.assertEqual(req.poll(0), 0) -        self.assertEqual(rep.poll(1), zmq.POLLIN) -        self.assertEqual(req.poll(0, zmq.POLLOUT), 0) -        self.assertEqual(rep.poll(0, zmq.POLLOUT), 0) -        self.assertEqual(req.poll(0, zmq.POLLOUT|zmq.POLLIN), 0) -        self.assertEqual(rep.poll(0, zmq.POLLOUT), zmq.POLLIN) -     -    def test_send_unicode(self): -        "test sending unicode objects" -        a,b = self.create_bound_pair(zmq.PAIR, zmq.PAIR) -        self.sockets.extend([a,b]) -        u = "çπ§" -        if str is not unicode: -            u = u.decode('utf8') -        self.assertRaises(TypeError, a.send, u,copy=False) -        self.assertRaises(TypeError, a.send, u,copy=True) -        a.send_unicode(u) -        s = b.recv() -        self.assertEqual(s,u.encode('utf8')) -        self.assertEqual(s.decode('utf8'),u) -        a.send_unicode(u,encoding='utf16') -        s = b.recv_unicode(encoding='utf16') -        self.assertEqual(s,u) -     -    @skip_pypy -    def test_tracker(self): -        "test the MessageTracker object for tracking when zmq is done with a buffer" -        addr = 'tcp://127.0.0.1' -        a = self.context.socket(zmq.PUB) -        port = a.bind_to_random_port(addr) -        a.close() -        iface = "%s:%i"%(addr,port) -        a = self.context.socket(zmq.PAIR) -        # a.setsockopt(zmq.IDENTITY, b"a") -        b = self.context.socket(zmq.PAIR) -        self.sockets.extend([a,b]) -        a.connect(iface) -        time.sleep(0.1) -        p1 = a.send(b'something', copy=False, track=True) -        self.assertTrue(isinstance(p1, zmq.MessageTracker)) -        self.assertFalse(p1.done) -        p2 = a.send_multipart([b'something', b'else'], copy=False, track=True) -        self.assert_(isinstance(p2, zmq.MessageTracker)) -        self.assertEqual(p2.done, False) -        self.assertEqual(p1.done, False) - -        b.bind(iface) -        msg = b.recv_multipart() -        for i in range(10): -            if p1.done: -                break -            time.sleep(0.1) -        self.assertEqual(p1.done, True) -        self.assertEqual(msg, [b'something']) -        msg = b.recv_multipart() -        for i in range(10): -            if p2.done: -                break -            time.sleep(0.1) -        self.assertEqual(p2.done, True) -        self.assertEqual(msg, [b'something', b'else']) -        m = zmq.Frame(b"again", track=True) -        self.assertEqual(m.tracker.done, False) -        p1 = a.send(m, copy=False) -        p2 = a.send(m, copy=False) -        self.assertEqual(m.tracker.done, False) -        self.assertEqual(p1.done, False) -        self.assertEqual(p2.done, False) -        msg = b.recv_multipart() -        self.assertEqual(m.tracker.done, False) -        self.assertEqual(msg, [b'again']) -        msg = b.recv_multipart() -        self.assertEqual(m.tracker.done, False) -        self.assertEqual(msg, [b'again']) -        self.assertEqual(p1.done, False) -        self.assertEqual(p2.done, False) -        pm = m.tracker -        del m -        for i in range(10): -            if p1.done: -                break -            time.sleep(0.1) -        self.assertEqual(p1.done, True) -        self.assertEqual(p2.done, True) -        m = zmq.Frame(b'something', track=False) -        self.assertRaises(ValueError, a.send, m, copy=False, track=True) -         - -    def test_close(self): -        ctx = self.Context() -        s = ctx.socket(zmq.PUB) -        s.close() -        self.assertRaisesErrno(zmq.ENOTSOCK, s.bind, b'') -        self.assertRaisesErrno(zmq.ENOTSOCK, s.connect, b'') -        self.assertRaisesErrno(zmq.ENOTSOCK, s.setsockopt, zmq.SUBSCRIBE, b'') -        self.assertRaisesErrno(zmq.ENOTSOCK, s.send, b'asdf') -        self.assertRaisesErrno(zmq.ENOTSOCK, s.recv) -        del ctx -     -    def test_attr(self): -        """set setting/getting sockopts as attributes""" -        s = self.context.socket(zmq.DEALER) -        self.sockets.append(s) -        linger = 10 -        s.linger = linger -        self.assertEqual(linger, s.linger) -        self.assertEqual(linger, s.getsockopt(zmq.LINGER)) -        self.assertEqual(s.fd, s.getsockopt(zmq.FD)) -     -    def test_bad_attr(self): -        s = self.context.socket(zmq.DEALER) -        self.sockets.append(s) -        try: -            s.apple='foo' -        except AttributeError: -            pass -        else: -            self.fail("bad setattr should have raised AttributeError") -        try: -            s.apple -        except AttributeError: -            pass -        else: -            self.fail("bad getattr should have raised AttributeError") - -    def test_subclass(self): -        """subclasses can assign attributes""" -        class S(zmq.Socket): -            a = None -            def __init__(self, *a, **kw): -                self.a=-1 -                super(S, self).__init__(*a, **kw) -         -        s = S(self.context, zmq.REP) -        self.sockets.append(s) -        self.assertEqual(s.a, -1) -        s.a=1 -        self.assertEqual(s.a, 1) -        a=s.a -        self.assertEqual(a, 1) -     -    def test_recv_multipart(self): -        a,b = self.create_bound_pair() -        msg = b'hi' -        for i in range(3): -            a.send(msg) -        time.sleep(0.1) -        for i in range(3): -            self.assertEqual(b.recv_multipart(), [msg]) -     -    def test_close_after_destroy(self): -        """s.close() after ctx.destroy() should be fine""" -        ctx = self.Context() -        s = ctx.socket(zmq.REP) -        ctx.destroy() -        # reaper is not instantaneous -        time.sleep(1e-2) -        s.close() -        self.assertTrue(s.closed) -     -    def test_poll(self): -        a,b = self.create_bound_pair() -        tic = time.time() -        evt = a.poll(50) -        self.assertEqual(evt, 0) -        evt = a.poll(50, zmq.POLLOUT) -        self.assertEqual(evt, zmq.POLLOUT) -        msg = b'hi' -        a.send(msg) -        evt = b.poll(50) -        self.assertEqual(evt, zmq.POLLIN) -        msg2 = self.recv(b) -        evt = b.poll(50) -        self.assertEqual(evt, 0) -        self.assertEqual(msg2, msg) -     -    def test_ipc_path_max_length(self): -        """IPC_PATH_MAX_LEN is a sensible value""" -        if zmq.IPC_PATH_MAX_LEN == 0: -            raise SkipTest("IPC_PATH_MAX_LEN undefined") -         -        msg = "Surprising value for IPC_PATH_MAX_LEN: %s" % zmq.IPC_PATH_MAX_LEN -        self.assertTrue(zmq.IPC_PATH_MAX_LEN > 30, msg) -        self.assertTrue(zmq.IPC_PATH_MAX_LEN < 1025, msg) - -    def test_ipc_path_max_length_msg(self): -        if zmq.IPC_PATH_MAX_LEN == 0: -            raise SkipTest("IPC_PATH_MAX_LEN undefined") -         -        s = self.context.socket(zmq.PUB) -        self.sockets.append(s) -        try: -            s.bind('ipc://{0}'.format('a' * (zmq.IPC_PATH_MAX_LEN + 1))) -        except zmq.ZMQError as e: -            self.assertTrue(str(zmq.IPC_PATH_MAX_LEN) in e.strerror) -     -    def test_hwm(self): -        zmq3 = zmq.zmq_version_info()[0] >= 3 -        for stype in (zmq.PUB, zmq.ROUTER, zmq.SUB, zmq.REQ, zmq.DEALER): -            s = self.context.socket(stype) -            s.hwm = 100 -            self.assertEqual(s.hwm, 100) -            if zmq3: -                try: -                    self.assertEqual(s.sndhwm, 100) -                except AttributeError: -                    pass -                try: -                    self.assertEqual(s.rcvhwm, 100) -                except AttributeError: -                    pass -            s.close() -     -    def test_shadow(self): -        p = self.socket(zmq.PUSH) -        p.bind("tcp://127.0.0.1:5555") -        p2 = zmq.Socket.shadow(p.underlying) -        self.assertEqual(p.underlying, p2.underlying) -        s = self.socket(zmq.PULL) -        s2 = zmq.Socket.shadow(s.underlying) -        self.assertNotEqual(s.underlying, p.underlying) -        self.assertEqual(s.underlying, s2.underlying) -        s2.connect("tcp://127.0.0.1:5555") -        sent = b'hi' -        p2.send(sent) -        rcvd = self.recv(s2) -        self.assertEqual(rcvd, sent) -     -    def test_shadow_pyczmq(self): -        try: -            from pyczmq import zctx, zsocket, zstr -        except Exception: -            raise SkipTest("Requires pyczmq") -         -        ctx = zctx.new() -        ca = zsocket.new(ctx, zmq.PUSH) -        cb = zsocket.new(ctx, zmq.PULL) -        a = zmq.Socket.shadow(ca) -        b = zmq.Socket.shadow(cb) -        a.bind("inproc://a") -        b.connect("inproc://a") -        a.send(b'hi') -        rcvd = self.recv(b) -        self.assertEqual(rcvd, b'hi') - - -if have_gevent: -    import gevent -     -    class TestSocketGreen(GreenTest, TestSocket): -        test_bad_attr = GreenTest.skip_green -        test_close_after_destroy = GreenTest.skip_green -         -        def test_timeout(self): -            a,b = self.create_bound_pair() -            g = gevent.spawn_later(0.5, lambda: a.send(b'hi')) -            timeout = gevent.Timeout(0.1) -            timeout.start() -            self.assertRaises(gevent.Timeout, b.recv) -            g.kill() -         -        @skip_if(not hasattr(zmq, 'RCVTIMEO')) -        def test_warn_set_timeo(self): -            s = self.context.socket(zmq.REQ) -            with warnings.catch_warnings(record=True) as w: -                s.rcvtimeo = 5 -            s.close() -            self.assertEqual(len(w), 1) -            self.assertEqual(w[0].category, UserWarning) -             - -        @skip_if(not hasattr(zmq, 'SNDTIMEO')) -        def test_warn_get_timeo(self): -            s = self.context.socket(zmq.REQ) -            with warnings.catch_warnings(record=True) as w: -                s.sndtimeo -            s.close() -            self.assertEqual(len(w), 1) -            self.assertEqual(w[0].category, UserWarning) diff --git a/zmq/tests/test_stopwatch.py b/zmq/tests/test_stopwatch.py deleted file mode 100644 index 49fb79f..0000000 --- a/zmq/tests/test_stopwatch.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf8 -*- -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import sys -import time - -from unittest import TestCase - -from zmq import Stopwatch, ZMQError - -if sys.version_info[0] >= 3: -    long = int - -class TestStopWatch(TestCase): -     -    def test_stop_long(self): -        """Ensure stop returns a long int.""" -        watch = Stopwatch() -        watch.start() -        us = watch.stop() -        self.assertTrue(isinstance(us, long)) -         -    def test_stop_microseconds(self): -        """Test that stop/sleep have right units.""" -        watch = Stopwatch() -        watch.start() -        tic = time.time() -        watch.sleep(1) -        us = watch.stop() -        toc = time.time() -        self.assertAlmostEqual(us/1e6,(toc-tic),places=0) -     -    def test_double_stop(self): -        """Test error raised on multiple calls to stop.""" -        watch = Stopwatch() -        watch.start() -        watch.stop() -        self.assertRaises(ZMQError, watch.stop) -        self.assertRaises(ZMQError, watch.stop) -     diff --git a/zmq/tests/test_version.py b/zmq/tests/test_version.py deleted file mode 100644 index 6ebebf3..0000000 --- a/zmq/tests/test_version.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -from unittest import TestCase -import zmq -from zmq.sugar import version - - -class TestVersion(TestCase): - -    def test_pyzmq_version(self): -        vs = zmq.pyzmq_version() -        vs2 = zmq.__version__ -        self.assertTrue(isinstance(vs, str)) -        if zmq.__revision__: -            self.assertEqual(vs, '@'.join(vs2, zmq.__revision__)) -        else: -            self.assertEqual(vs, vs2) -        if version.VERSION_EXTRA: -            self.assertTrue(version.VERSION_EXTRA in vs) -            self.assertTrue(version.VERSION_EXTRA in vs2) - -    def test_pyzmq_version_info(self): -        info = zmq.pyzmq_version_info() -        self.assertTrue(isinstance(info, tuple)) -        for n in info[:3]: -            self.assertTrue(isinstance(n, int)) -        if version.VERSION_EXTRA: -            self.assertEqual(len(info), 4) -            self.assertEqual(info[-1], float('inf')) -        else: -            self.assertEqual(len(info), 3) - -    def test_zmq_version_info(self): -        info = zmq.zmq_version_info() -        self.assertTrue(isinstance(info, tuple)) -        for n in info[:3]: -            self.assertTrue(isinstance(n, int)) - -    def test_zmq_version(self): -        v = zmq.zmq_version() -        self.assertTrue(isinstance(v, str)) - diff --git a/zmq/tests/test_z85.py b/zmq/tests/test_z85.py deleted file mode 100644 index 8a73cb4..0000000 --- a/zmq/tests/test_z85.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf8 -*- -"""Test Z85 encoding - -confirm values and roundtrip with test values from the reference implementation. -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from unittest import TestCase -from zmq.utils import z85 - - -class TestZ85(TestCase): -     -    def test_client_public(self): -        client_public = \ -            b"\xBB\x88\x47\x1D\x65\xE2\x65\x9B" \ -            b"\x30\xC5\x5A\x53\x21\xCE\xBB\x5A" \ -            b"\xAB\x2B\x70\xA3\x98\x64\x5C\x26" \ -            b"\xDC\xA2\xB2\xFC\xB4\x3F\xC5\x18" -        encoded = z85.encode(client_public) -         -        self.assertEqual(encoded, b"Yne@$w-vo<fVvi]a<NY6T1ed:M$fCG*[IaLV{hID") -        decoded = z85.decode(encoded) -        self.assertEqual(decoded, client_public) -     -    def test_client_secret(self): -        client_secret = \ -            b"\x7B\xB8\x64\xB4\x89\xAF\xA3\x67" \ -            b"\x1F\xBE\x69\x10\x1F\x94\xB3\x89" \ -            b"\x72\xF2\x48\x16\xDF\xB0\x1B\x51" \ -            b"\x65\x6B\x3F\xEC\x8D\xFD\x08\x88" -        encoded = z85.encode(client_secret) -         -        self.assertEqual(encoded, b"D:)Q[IlAW!ahhC2ac:9*A}h:p?([4%wOTJ%JR%cs") -        decoded = z85.decode(encoded) -        self.assertEqual(decoded, client_secret) - -    def test_server_public(self): -        server_public = \ -            b"\x54\xFC\xBA\x24\xE9\x32\x49\x96" \ -            b"\x93\x16\xFB\x61\x7C\x87\x2B\xB0" \ -            b"\xC1\xD1\xFF\x14\x80\x04\x27\xC5" \ -            b"\x94\xCB\xFA\xCF\x1B\xC2\xD6\x52" -        encoded = z85.encode(server_public) -         -        self.assertEqual(encoded, b"rq:rM>}U?@Lns47E1%kR.o@n%FcmmsL/@{H8]yf7") -        decoded = z85.decode(encoded) -        self.assertEqual(decoded, server_public) -     -    def test_server_secret(self): -        server_secret = \ -            b"\x8E\x0B\xDD\x69\x76\x28\xB9\x1D" \ -            b"\x8F\x24\x55\x87\xEE\x95\xC5\xB0" \ -            b"\x4D\x48\x96\x3F\x79\x25\x98\x77" \ -            b"\xB4\x9C\xD9\x06\x3A\xEA\xD3\xB7" -        encoded = z85.encode(server_secret) -         -        self.assertEqual(encoded, b"JTKVSB%%)wK0E.X)V>+}o?pNmC{O&4W4b!Ni{Lh6") -        decoded = z85.decode(encoded) -        self.assertEqual(decoded, server_secret) - diff --git a/zmq/tests/test_zmqstream.py b/zmq/tests/test_zmqstream.py deleted file mode 100644 index cdb3a17..0000000 --- a/zmq/tests/test_zmqstream.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf8 -*- -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import sys -import time - -from unittest import TestCase - -import zmq -from zmq.eventloop import ioloop, zmqstream - -class TestZMQStream(TestCase): -     -    def setUp(self): -        self.context = zmq.Context() -        self.socket = self.context.socket(zmq.REP) -        self.loop = ioloop.IOLoop.instance() -        self.stream = zmqstream.ZMQStream(self.socket) -     -    def tearDown(self): -        self.socket.close() -        self.context.term() -     -    def test_callable_check(self): -        """Ensure callable check works (py3k).""" -         -        self.stream.on_send(lambda *args: None) -        self.stream.on_recv(lambda *args: None) -        self.assertRaises(AssertionError, self.stream.on_recv, 1) -        self.assertRaises(AssertionError, self.stream.on_send, 1) -        self.assertRaises(AssertionError, self.stream.on_recv, zmq) -         diff --git a/zmq/utils/__init__.py b/zmq/utils/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/zmq/utils/__init__.py +++ /dev/null diff --git a/zmq/utils/buffers.pxd b/zmq/utils/buffers.pxd deleted file mode 100644 index 998aa55..0000000 --- a/zmq/utils/buffers.pxd +++ /dev/null @@ -1,313 +0,0 @@ -"""Python version-independent methods for C/Python buffers. - -This file was copied and adapted from mpi4py. - -Authors -------- -* MinRK -""" - -#----------------------------------------------------------------------------- -#  Copyright (c) 2010 Lisandro Dalcin -#  All rights reserved. -#  Used under BSD License: http://www.opensource.org/licenses/bsd-license.php -# -#  Retrieval: -#  Jul 23, 2010 18:00 PST (r539) -#  http://code.google.com/p/mpi4py/source/browse/trunk/src/MPI/asbuffer.pxi -# -#  Modifications from original: -#  Copyright (c) 2010-2012 Brian Granger, Min Ragan-Kelley -# -#  Distributed under the terms of the New BSD License.  The full license is in -#  the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - - -#----------------------------------------------------------------------------- -# Python includes. -#----------------------------------------------------------------------------- - -# get version-independent aliases: -cdef extern from "pyversion_compat.h": -    pass - -# Python 3 buffer interface (PEP 3118) -cdef extern from "Python.h": -    int PY_MAJOR_VERSION -    int PY_MINOR_VERSION -    ctypedef int Py_ssize_t -    ctypedef struct PyMemoryViewObject: -        pass -    ctypedef struct Py_buffer: -        void *buf -        Py_ssize_t len -        int readonly -        char *format -        int ndim -        Py_ssize_t *shape -        Py_ssize_t *strides -        Py_ssize_t *suboffsets -        Py_ssize_t itemsize -        void *internal -    cdef enum: -        PyBUF_SIMPLE -        PyBUF_WRITABLE -        PyBUF_FORMAT -        PyBUF_ANY_CONTIGUOUS -    int  PyObject_CheckBuffer(object) -    int  PyObject_GetBuffer(object, Py_buffer *, int) except -1 -    void PyBuffer_Release(Py_buffer *) -     -    int PyBuffer_FillInfo(Py_buffer *view, object obj, void *buf, -                Py_ssize_t len, int readonly, int infoflags) except -1 -    object PyMemoryView_FromBuffer(Py_buffer *info) -     -    object PyMemoryView_FromObject(object) - -# Python 2 buffer interface (legacy) -cdef extern from "Python.h": -    ctypedef void const_void "const void" -    Py_ssize_t Py_END_OF_BUFFER -    int PyObject_CheckReadBuffer(object) -    int PyObject_AsReadBuffer (object, const_void **, Py_ssize_t *) except -1 -    int PyObject_AsWriteBuffer(object, void **, Py_ssize_t *) except -1 -     -    object PyBuffer_FromMemory(void *ptr, Py_ssize_t s) -    object PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t s) - -    object PyBuffer_FromObject(object, Py_ssize_t offset, Py_ssize_t size) -    object PyBuffer_FromReadWriteObject(object, Py_ssize_t offset, Py_ssize_t size) - - -#----------------------------------------------------------------------------- -# asbuffer: C buffer from python object -#----------------------------------------------------------------------------- - - -cdef inline int memoryview_available(): -    return PY_MAJOR_VERSION >= 3 or (PY_MAJOR_VERSION >=2 and PY_MINOR_VERSION >= 7) - -cdef inline int oldstyle_available(): -    return PY_MAJOR_VERSION < 3 - - -cdef inline int check_buffer(object ob): -    """Version independent check for whether an object is a buffer. -     -    Parameters -    ---------- -    object : object -        Any Python object - -    Returns -    ------- -    int : 0 if no buffer interface, 3 if newstyle buffer interface, 2 if oldstyle. -    """ -    if PyObject_CheckBuffer(ob): -        return 3 -    if oldstyle_available(): -        return PyObject_CheckReadBuffer(ob) and 2 -    return 0 - - -cdef inline object asbuffer(object ob, int writable, int format, -                            void **base, Py_ssize_t *size, -                            Py_ssize_t *itemsize): -    """Turn an object into a C buffer in a Python version-independent way. -     -    Parameters -    ---------- -    ob : object -        The object to be turned into a buffer. -        Must provide a Python Buffer interface -    writable : int -        Whether the resulting buffer should be allowed to write -        to the object. -    format : int -        The format of the buffer.  See Python buffer docs. -    base : void ** -        The pointer that will be used to store the resulting C buffer. -    size : Py_ssize_t * -        The size of the buffer(s). -    itemsize : Py_ssize_t * -        The size of an item, if the buffer is non-contiguous. -     -    Returns -    ------- -    An object describing the buffer format. Generally a str, such as 'B'. -    """ - -    cdef void *bptr = NULL -    cdef Py_ssize_t blen = 0, bitemlen = 0 -    cdef Py_buffer view -    cdef int flags = PyBUF_SIMPLE -    cdef int mode = 0 -     -    bfmt = None - -    mode = check_buffer(ob) -    if mode == 0: -        raise TypeError("%r does not provide a buffer interface."%ob) - -    if mode == 3: -        flags = PyBUF_ANY_CONTIGUOUS -        if writable: -            flags |= PyBUF_WRITABLE -        if format: -            flags |= PyBUF_FORMAT -        PyObject_GetBuffer(ob, &view, flags) -        bptr = view.buf -        blen = view.len -        if format: -            if view.format != NULL: -                bfmt = view.format -                bitemlen = view.itemsize -        PyBuffer_Release(&view) -    else: # oldstyle -        if writable: -            PyObject_AsWriteBuffer(ob, &bptr, &blen) -        else: -            PyObject_AsReadBuffer(ob, <const_void **>&bptr, &blen) -        if format: -            try: # numpy.ndarray -                dtype = ob.dtype -                bfmt = dtype.char -                bitemlen = dtype.itemsize -            except AttributeError: -                try: # array.array -                    bfmt = ob.typecode -                    bitemlen = ob.itemsize -                except AttributeError: -                    if isinstance(ob, bytes): -                        bfmt = b"B" -                        bitemlen = 1 -                    else: -                        # nothing found -                        bfmt = None -                        bitemlen = 0 -    if base: base[0] = <void *>bptr -    if size: size[0] = <Py_ssize_t>blen -    if itemsize: itemsize[0] = <Py_ssize_t>bitemlen -     -    if PY_MAJOR_VERSION >= 3 and bfmt is not None: -        return bfmt.decode('ascii') -    return bfmt - - -cdef inline object asbuffer_r(object ob, void **base, Py_ssize_t *size): -    """Wrapper for standard calls to asbuffer with a readonly buffer.""" -    asbuffer(ob, 0, 0, base, size, NULL) -    return ob - - -cdef inline object asbuffer_w(object ob, void **base, Py_ssize_t *size): -    """Wrapper for standard calls to asbuffer with a writable buffer.""" -    asbuffer(ob, 1, 0, base, size, NULL) -    return ob - -#------------------------------------------------------------------------------ -# frombuffer: python buffer/view from C buffer -#------------------------------------------------------------------------------ - - -cdef inline object frombuffer_3(void *ptr, Py_ssize_t s, int readonly): -    """Python 3 version of frombuffer. - -    This is the Python 3 model, but will work on Python >= 2.6. Currently, -    we use it only on >= 3.0. -    """ -    cdef Py_buffer pybuf -    cdef Py_ssize_t *shape = [s] -    cdef str astr="" -    PyBuffer_FillInfo(&pybuf, astr, ptr, s, readonly, PyBUF_SIMPLE) -    pybuf.format = "B" -    pybuf.shape = shape -    return PyMemoryView_FromBuffer(&pybuf) - - -cdef inline object frombuffer_2(void *ptr, Py_ssize_t s, int readonly): -    """Python 2 version of frombuffer.  - -    This must be used for Python <= 2.6, but we use it for all Python < 3. -    """ -     -    if oldstyle_available(): -        if readonly: -            return PyBuffer_FromMemory(ptr, s) -        else: -            return PyBuffer_FromReadWriteMemory(ptr, s) -    else: -        raise NotImplementedError("Old style buffers not available.") - - -cdef inline object frombuffer(void *ptr, Py_ssize_t s, int readonly): -    """Create a Python Buffer/View of a C array.  -     -    Parameters -    ---------- -    ptr : void * -        Pointer to the array to be copied. -    s : size_t -        Length of the buffer. -    readonly : int -        whether the resulting object should be allowed to write to the buffer. -     -    Returns -    ------- -    Python Buffer/View of the C buffer. -    """ -    # oldstyle first priority for now -    if oldstyle_available(): -        return frombuffer_2(ptr, s, readonly) -    else: -        return frombuffer_3(ptr, s, readonly) - - -cdef inline object frombuffer_r(void *ptr, Py_ssize_t s): -    """Wrapper for readonly view frombuffer.""" -    return frombuffer(ptr, s, 1) - - -cdef inline object frombuffer_w(void *ptr, Py_ssize_t s): -    """Wrapper for writable view frombuffer.""" -    return frombuffer(ptr, s, 0) - -#------------------------------------------------------------------------------ -# viewfromobject: python buffer/view from python object, refcounts intact -# frombuffer(asbuffer(obj)) would lose track of refs -#------------------------------------------------------------------------------ - -cdef inline object viewfromobject(object obj, int readonly): -    """Construct a Python Buffer/View object from another Python object. - -    This work in a Python version independent manner. -     -    Parameters -    ---------- -    obj : object -        The input object to be cast as a buffer -    readonly : int -        Whether the result should be prevented from overwriting the original. -     -    Returns -    ------- -    Buffer/View of the original object. -    """ -    if not memoryview_available(): -        if readonly: -            return PyBuffer_FromObject(obj, 0, Py_END_OF_BUFFER) -        else: -            return PyBuffer_FromReadWriteObject(obj, 0, Py_END_OF_BUFFER) -    else: -        return PyMemoryView_FromObject(obj) - - -cdef inline object viewfromobject_r(object obj): -    """Wrapper for readonly viewfromobject.""" -    return viewfromobject(obj, 1) - - -cdef inline object viewfromobject_w(object obj): -    """Wrapper for writable viewfromobject.""" -    return viewfromobject(obj, 0) diff --git a/zmq/utils/constant_names.py b/zmq/utils/constant_names.py deleted file mode 100644 index fe3bdbc..0000000 --- a/zmq/utils/constant_names.py +++ /dev/null @@ -1,309 +0,0 @@ -"""0MQ Constant names""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -#----------------------------------------------------------------------------- -# Python module level constants -#----------------------------------------------------------------------------- - -# dictionaries of constants new or removed in particular versions - -new_in = { -    (2,2,0) : [ -        'RCVTIMEO', -        'SNDTIMEO', -    ], -    (3,2,2) : [ -        # errnos -        'EMSGSIZE', -        'EAFNOSUPPORT', -        'ENETUNREACH', -        'ECONNABORTED', -        'ECONNRESET', -        'ENOTCONN', -        'ETIMEDOUT', -        'EHOSTUNREACH', -        'ENETRESET', -         -        'IO_THREADS', -        'MAX_SOCKETS', -        'IO_THREADS_DFLT', -        'MAX_SOCKETS_DFLT', -         -        'ROUTER_BEHAVIOR', -        'ROUTER_MANDATORY', -        'FAIL_UNROUTABLE', -        'TCP_KEEPALIVE', -        'TCP_KEEPALIVE_CNT', -        'TCP_KEEPALIVE_IDLE', -        'TCP_KEEPALIVE_INTVL', -        'DELAY_ATTACH_ON_CONNECT', -        'XPUB_VERBOSE', -         -        'EVENT_CONNECTED', -        'EVENT_CONNECT_DELAYED', -        'EVENT_CONNECT_RETRIED', -        'EVENT_LISTENING', -        'EVENT_BIND_FAILED', -        'EVENT_ACCEPTED', -        'EVENT_ACCEPT_FAILED', -        'EVENT_CLOSED', -        'EVENT_CLOSE_FAILED', -        'EVENT_DISCONNECTED', -        'EVENT_ALL', -    ], -    (4,0,0) : [ -        # socket types -        'STREAM', -         -        # socket opts -        'IMMEDIATE', -        'ROUTER_RAW', -        'IPV6', -        'MECHANISM', -        'PLAIN_SERVER', -        'PLAIN_USERNAME', -        'PLAIN_PASSWORD', -        'CURVE_SERVER', -        'CURVE_PUBLICKEY', -        'CURVE_SECRETKEY', -        'CURVE_SERVERKEY', -        'PROBE_ROUTER', -        'REQ_RELAXED', -        'REQ_CORRELATE', -        'CONFLATE', -        'ZAP_DOMAIN', -         -        # security -        'NULL', -        'PLAIN', -        'CURVE', -         -        # events -        'EVENT_MONITOR_STOPPED', -    ], -    (4,1,0) : [ -        # socket opts -        'ROUTER_HANDOVER', -        'TOS', -        'IPC_FILTER_PID', -        'IPC_FILTER_UID', -        'IPC_FILTER_GID', -        'CONNECT_RID', -    ], -} - - -removed_in = { -    (3,2,2) : [ -        'UPSTREAM', -        'DOWNSTREAM', -         -        'HWM', -        'SWAP', -        'MCAST_LOOP', -        'RECOVERY_IVL_MSEC', -    ] -} - -# collections of zmq constant names based on their role -# base names have no specific use -# opt names are validated in get/set methods of various objects - -base_names = [ -    # base -    'VERSION', -    'VERSION_MAJOR', -    'VERSION_MINOR', -    'VERSION_PATCH', -    'NOBLOCK', -    'DONTWAIT', - -    'POLLIN', -    'POLLOUT', -    'POLLERR', -     -    'SNDMORE', - -    'STREAMER', -    'FORWARDER', -    'QUEUE', - -    'IO_THREADS_DFLT', -    'MAX_SOCKETS_DFLT', - -    # socktypes -    'PAIR', -    'PUB', -    'SUB', -    'REQ', -    'REP', -    'DEALER', -    'ROUTER', -    'PULL', -    'PUSH', -    'XPUB', -    'XSUB', -    'UPSTREAM', -    'DOWNSTREAM', -    'STREAM', - -    # events -    'EVENT_CONNECTED', -    'EVENT_CONNECT_DELAYED', -    'EVENT_CONNECT_RETRIED', -    'EVENT_LISTENING', -    'EVENT_BIND_FAILED', -    'EVENT_ACCEPTED', -    'EVENT_ACCEPT_FAILED', -    'EVENT_CLOSED', -    'EVENT_CLOSE_FAILED', -    'EVENT_DISCONNECTED', -    'EVENT_ALL', -    'EVENT_MONITOR_STOPPED', - -    # security -    'NULL', -    'PLAIN', -    'CURVE', - -    ## ERRNO -    # Often used (these are alse in errno.) -    'EAGAIN', -    'EINVAL', -    'EFAULT', -    'ENOMEM', -    'ENODEV', -    'EMSGSIZE', -    'EAFNOSUPPORT', -    'ENETUNREACH', -    'ECONNABORTED', -    'ECONNRESET', -    'ENOTCONN', -    'ETIMEDOUT', -    'EHOSTUNREACH', -    'ENETRESET', - -    # For Windows compatability -    'HAUSNUMERO', -    'ENOTSUP', -    'EPROTONOSUPPORT', -    'ENOBUFS', -    'ENETDOWN', -    'EADDRINUSE', -    'EADDRNOTAVAIL', -    'ECONNREFUSED', -    'EINPROGRESS', -    'ENOTSOCK', - -    # 0MQ Native -    'EFSM', -    'ENOCOMPATPROTO', -    'ETERM', -    'EMTHREAD', -] - -int64_sockopt_names = [ -    'AFFINITY', -    'MAXMSGSIZE', - -    # sockopts removed in 3.0.0 -    'HWM', -    'SWAP', -    'MCAST_LOOP', -    'RECOVERY_IVL_MSEC', -] - -bytes_sockopt_names = [ -    'IDENTITY', -    'SUBSCRIBE', -    'UNSUBSCRIBE', -    'LAST_ENDPOINT', -    'TCP_ACCEPT_FILTER', - -    'PLAIN_USERNAME', -    'PLAIN_PASSWORD', - -    'CURVE_PUBLICKEY', -    'CURVE_SECRETKEY', -    'CURVE_SERVERKEY', -    'ZAP_DOMAIN', -    'CONNECT_RID', -] - -int_sockopt_names = [ -    # sockopts -    'RECONNECT_IVL_MAX', - -    # sockopts new in 2.2.0 -    'SNDTIMEO', -    'RCVTIMEO', - -    # new in 3.x -    'SNDHWM', -    'RCVHWM', -    'MULTICAST_HOPS', -    'IPV4ONLY', - -    'ROUTER_BEHAVIOR', -    'TCP_KEEPALIVE', -    'TCP_KEEPALIVE_CNT', -    'TCP_KEEPALIVE_IDLE', -    'TCP_KEEPALIVE_INTVL', -    'DELAY_ATTACH_ON_CONNECT', -    'XPUB_VERBOSE', - -    'FD', -    'EVENTS', -    'TYPE', -    'LINGER', -    'RECONNECT_IVL', -    'BACKLOG', -     -    'ROUTER_MANDATORY', -    'FAIL_UNROUTABLE', - -    'ROUTER_RAW', -    'IMMEDIATE', -    'IPV6', -    'MECHANISM', -    'PLAIN_SERVER', -    'CURVE_SERVER', -    'PROBE_ROUTER', -    'REQ_RELAXED', -    'REQ_CORRELATE', -    'CONFLATE', -    'ROUTER_HANDOVER', -    'TOS', -    'IPC_FILTER_PID', -    'IPC_FILTER_UID', -    'IPC_FILTER_GID', -] - -switched_sockopt_names = [ -    'RATE', -    'RECOVERY_IVL', -    'SNDBUF', -    'RCVBUF', -    'RCVMORE', -] - -ctx_opt_names = [ -    'IO_THREADS', -    'MAX_SOCKETS', -] - -msg_opt_names = [ -    'MORE', -] - -all_names = ( -    base_names + ctx_opt_names + msg_opt_names + -    bytes_sockopt_names + int_sockopt_names + int64_sockopt_names + switched_sockopt_names -) - -def no_prefix(name): -    """does the given constant have a ZMQ_ prefix?""" -    return name.startswith('E') and not name.startswith('EVENT') - diff --git a/zmq/utils/garbage.py b/zmq/utils/garbage.py deleted file mode 100644 index e77cb00..0000000 --- a/zmq/utils/garbage.py +++ /dev/null @@ -1,166 +0,0 @@ -"""Garbage collection thread for representing zmq refcount of Python objects -used in zero-copy sends. -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -import atexit -import struct - -from os import getpid -from collections import namedtuple -from threading import Thread, Event, Lock -import warnings - -import zmq - - -gcref = namedtuple('gcref', ['obj', 'event']) - -class GarbageCollectorThread(Thread): -    """Thread in which garbage collection actually happens.""" -    def __init__(self, gc): -        super(GarbageCollectorThread, self).__init__() -        self.gc = gc -        self.daemon = True -        self.pid = getpid() -        self.ready = Event() -     -    def run(self): -        s = self.gc.context.socket(zmq.PULL) -        s.linger = 0 -        s.bind(self.gc.url) -        self.ready.set() -         -        while True: -            # detect fork -            if getpid is None or getpid() != self.pid: -                return -            msg = s.recv() -            if msg == b'DIE': -                break -            fmt = 'L' if len(msg) == 4 else 'Q' -            key = struct.unpack(fmt, msg)[0] -            tup = self.gc.refs.pop(key, None) -            if tup and tup.event: -                tup.event.set() -            del tup -        s.close() - - -class GarbageCollector(object): -    """PyZMQ Garbage Collector -     -    Used for representing the reference held by libzmq during zero-copy sends. -    This object holds a dictionary, keyed by Python id, -    of the Python objects whose memory are currently in use by zeromq. -     -    When zeromq is done with the memory, it sends a message on an inproc PUSH socket -    containing the packed size_t (32 or 64-bit unsigned int), -    which is the key in the dict. -    When the PULL socket in the gc thread receives that message, -    the reference is popped from the dict, -    and any tracker events that should be signaled fire. -    """ -     -    refs = None -    _context = None -    _lock = None -    url = "inproc://pyzmq.gc.01" -     -    def __init__(self, context=None): -        super(GarbageCollector, self).__init__() -        self.refs = {} -        self.pid = None -        self.thread = None -        self._context = context -        self._lock = Lock() -        self._stay_down = False -        atexit.register(self._atexit) -     -    @property -    def context(self): -        if self._context is None: -            self._context = zmq.Context() -        return self._context -     -    @context.setter -    def context(self, ctx): -        if self.is_alive(): -            if self.refs: -                warnings.warn("Replacing gc context while gc is running", RuntimeWarning) -            self.stop() -        self._context = ctx -     -    def _atexit(self): -        """atexit callback -         -        sets _stay_down flag so that gc doesn't try to start up again in other atexit handlers -        """ -        self._stay_down = True -        self.stop() -     -    def stop(self): -        """stop the garbage-collection thread""" -        if not self.is_alive(): -            return -        push = self.context.socket(zmq.PUSH) -        push.connect(self.url) -        push.send(b'DIE') -        push.close() -        self.thread.join() -        self.context.term() -        self.refs.clear() -     -    def start(self): -        """Start a new garbage collection thread. -         -        Creates a new zmq Context used for garbage collection. -        Under most circumstances, this will only be called once per process. -        """ -        self.pid = getpid() -        self.refs = {} -        self.thread = GarbageCollectorThread(self) -        self.thread.start() -        self.thread.ready.wait() -     -    def is_alive(self): -        """Is the garbage collection thread currently running? -         -        Includes checks for process shutdown or fork. -        """ -        if (getpid is None or -            getpid() != self.pid or -            self.thread is None or -            not self.thread.is_alive() -            ): -            return False -        return True -     -    def store(self, obj, event=None): -        """store an object and (optionally) event for zero-copy""" -        if not self.is_alive(): -            if self._stay_down: -                return 0 -            # safely start the gc thread -            # use lock and double check, -            # so we don't start multiple threads -            with self._lock: -                if not self.is_alive(): -                    self.start() -        tup = gcref(obj, event) -        theid = id(tup) -        self.refs[theid] = tup -        return theid -     -    def __del__(self): -        if not self.is_alive(): -            return -        try: -            self.stop() -        except Exception as e: -            raise (e) - -gc = GarbageCollector() diff --git a/zmq/utils/getpid_compat.h b/zmq/utils/getpid_compat.h deleted file mode 100644 index 47ce90f..0000000 --- a/zmq/utils/getpid_compat.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifdef _WIN32 -    #include <process.h> -    #define getpid _getpid -#else -    #include <unistd.h> -#endif diff --git a/zmq/utils/interop.py b/zmq/utils/interop.py deleted file mode 100644 index 26c0196..0000000 --- a/zmq/utils/interop.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Utils for interoperability with other libraries. - -Just CFFI pointer casting for now. -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - - -try: -    long -except NameError: -    long = int # Python 3 - - -def cast_int_addr(n): -    """Cast an address to a Python int -     -    This could be a Python integer or a CFFI pointer -    """ -    if isinstance(n, (int, long)): -        return n -    try: -        import cffi -    except ImportError: -        pass -    else: -        # from pyzmq, this is an FFI void * -        ffi = cffi.FFI() -        if isinstance(n, ffi.CData): -            return int(ffi.cast("size_t", n)) -     -    raise ValueError("Cannot cast %r to int" % n) diff --git a/zmq/utils/ipcmaxlen.h b/zmq/utils/ipcmaxlen.h deleted file mode 100644 index 7218db7..0000000 --- a/zmq/utils/ipcmaxlen.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - -Platform-independant detection of IPC path max length - -Copyright (c) 2012 Godefroid Chapelle - -Distributed under the terms of the New BSD License.  The full license is in -the file COPYING.BSD, distributed as part of this software. - */ - -#if defined(HAVE_SYS_UN_H) -#include "sys/un.h" -int get_ipc_path_max_len(void) { -    struct sockaddr_un *dummy; -    return sizeof(dummy->sun_path) - 1; -} -#else -int get_ipc_path_max_len(void) { -    return 0; -} -#endif diff --git a/zmq/utils/jsonapi.py b/zmq/utils/jsonapi.py deleted file mode 100644 index 865ca6d..0000000 --- a/zmq/utils/jsonapi.py +++ /dev/null @@ -1,59 +0,0 @@ -"""Priority based json library imports. - -Always serializes to bytes instead of unicode for zeromq compatibility -on Python 2 and 3. - -Use ``jsonapi.loads()`` and ``jsonapi.dumps()`` for guaranteed symmetry. - -Priority: ``simplejson`` > ``jsonlib2`` > stdlib ``json`` - -``jsonapi.loads/dumps`` provide kwarg-compatibility with stdlib json. - -``jsonapi.jsonmod`` will be the module of the actual underlying implementation. -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from zmq.utils.strtypes import bytes, unicode - -jsonmod = None - -priority = ['simplejson', 'jsonlib2', 'json'] -for mod in priority: -    try: -        jsonmod = __import__(mod) -    except ImportError: -        pass -    else: -        break - -def dumps(o, **kwargs): -    """Serialize object to JSON bytes (utf-8). -     -    See jsonapi.jsonmod.dumps for details on kwargs. -    """ -     -    if 'separators' not in kwargs: -        kwargs['separators'] = (',', ':') -     -    s = jsonmod.dumps(o, **kwargs) -     -    if isinstance(s, unicode): -        s = s.encode('utf8') -     -    return s - -def loads(s, **kwargs): -    """Load object from JSON bytes (utf-8). -     -    See jsonapi.jsonmod.loads for details on kwargs. -    """ -     -    if str is unicode and isinstance(s, bytes): -        s = s.decode('utf8') -     -    return jsonmod.loads(s, **kwargs) - -__all__ = ['jsonmod', 'dumps', 'loads'] - diff --git a/zmq/utils/monitor.py b/zmq/utils/monitor.py deleted file mode 100644 index 734d54b..0000000 --- a/zmq/utils/monitor.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -"""Module holding utility and convenience functions for zmq event monitoring.""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import struct -import zmq -from zmq.error import _check_version - -def parse_monitor_message(msg): -    """decode zmq_monitor event messages. -     -    Parameters -    ---------- -    msg : list(bytes) -        zmq multipart message that has arrived on a monitor PAIR socket. -         -        First frame is:: -         -            16 bit event id -            32 bit event value -            no padding - -        Second frame is the endpoint as a bytestring - -    Returns -    ------- -    event : dict -        event description as dict with the keys `event`, `value`, and `endpoint`. -    """ -     -    if len(msg) != 2 or len(msg[0]) != 6: -        raise RuntimeError("Invalid event message format: %s" % msg) -    event = {} -    event['event'], event['value'] = struct.unpack("=hi", msg[0]) -    event['endpoint'] = msg[1] -    return event - -def recv_monitor_message(socket, flags=0): -    """Receive and decode the given raw message from the monitoring socket and return a dict. - -    Requires libzmq ≥ 4.0 - -    The returned dict will have the following entries: -      event     : int, the event id as described in libzmq.zmq_socket_monitor -      value     : int, the event value associated with the event, see libzmq.zmq_socket_monitor -      endpoint  : string, the affected endpoint -     -    Parameters -    ---------- -    socket : zmq PAIR socket -        The PAIR socket (created by other.get_monitor_socket()) on which to recv the message -    flags : bitfield (int) -        standard zmq recv flags - -    Returns -    ------- -    event : dict -        event description as dict with the keys `event`, `value`, and `endpoint`. -    """ -    _check_version((4,0), 'libzmq event API') -    # will always return a list -    msg = socket.recv_multipart(flags) -    # 4.0-style event API -    return parse_monitor_message(msg) - -__all__ = ['parse_monitor_message', 'recv_monitor_message'] diff --git a/zmq/utils/pyversion_compat.h b/zmq/utils/pyversion_compat.h deleted file mode 100644 index fac0904..0000000 --- a/zmq/utils/pyversion_compat.h +++ /dev/null @@ -1,25 +0,0 @@ -#include "Python.h" - -#if PY_VERSION_HEX < 0x02070000 -    #define PyMemoryView_FromBuffer(info) (PyErr_SetString(PyExc_NotImplementedError, \ -                    "new buffer interface is not available"), (PyObject *)NULL) -    #define PyMemoryView_FromObject(object)     (PyErr_SetString(PyExc_NotImplementedError, \ -                                        "new buffer interface is not available"), (PyObject *)NULL) -#endif - -#if PY_VERSION_HEX >= 0x03000000 -    // for buffers -    #define Py_END_OF_BUFFER ((Py_ssize_t) 0) - -    #define PyObject_CheckReadBuffer(object) (0) - -    #define PyBuffer_FromMemory(ptr, s) (PyErr_SetString(PyExc_NotImplementedError, \ -                            "old buffer interface is not available"), (PyObject *)NULL) -    #define PyBuffer_FromReadWriteMemory(ptr, s) (PyErr_SetString(PyExc_NotImplementedError, \ -                            "old buffer interface is not available"), (PyObject *)NULL) -    #define PyBuffer_FromObject(object, offset, size)  (PyErr_SetString(PyExc_NotImplementedError, \ -                            "old buffer interface is not available"), (PyObject *)NULL) -    #define PyBuffer_FromReadWriteObject(object, offset, size)  (PyErr_SetString(PyExc_NotImplementedError, \ -                            "old buffer interface is not available"), (PyObject *)NULL) - -#endif diff --git a/zmq/utils/sixcerpt.py b/zmq/utils/sixcerpt.py deleted file mode 100644 index 5492fd5..0000000 --- a/zmq/utils/sixcerpt.py +++ /dev/null @@ -1,52 +0,0 @@ -"""Excerpts of six.py""" - -# Copyright (C) 2010-2014 Benjamin Peterson -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import sys - -# Useful for very coarse version differentiation. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 - -if PY3: - -    def reraise(tp, value, tb=None): -        if value.__traceback__ is not tb: -            raise value.with_traceback(tb) -        raise value - -else: -    def exec_(_code_, _globs_=None, _locs_=None): -        """Execute code in a namespace.""" -        if _globs_ is None: -            frame = sys._getframe(1) -            _globs_ = frame.f_globals -            if _locs_ is None: -                _locs_ = frame.f_locals -            del frame -        elif _locs_ is None: -            _locs_ = _globs_ -        exec("""exec _code_ in _globs_, _locs_""") - - -    exec_("""def reraise(tp, value, tb=None): -    raise tp, value, tb -""") diff --git a/zmq/utils/strtypes.py b/zmq/utils/strtypes.py deleted file mode 100644 index 548410d..0000000 --- a/zmq/utils/strtypes.py +++ /dev/null @@ -1,45 +0,0 @@ -"""Declare basic string types unambiguously for various Python versions. - -Authors -------- -* MinRK -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import sys - -if sys.version_info[0] >= 3: -    bytes = bytes -    unicode = str -    basestring = (bytes, unicode) -else: -    unicode = unicode -    bytes = str -    basestring = basestring - -def cast_bytes(s, encoding='utf8', errors='strict'): -    """cast unicode or bytes to bytes""" -    if isinstance(s, bytes): -        return s -    elif isinstance(s, unicode): -        return s.encode(encoding, errors) -    else: -        raise TypeError("Expected unicode or bytes, got %r" % s) - -def cast_unicode(s, encoding='utf8', errors='strict'): -    """cast bytes or unicode to unicode""" -    if isinstance(s, bytes): -        return s.decode(encoding, errors) -    elif isinstance(s, unicode): -        return s -    else: -        raise TypeError("Expected unicode or bytes, got %r" % s) - -# give short 'b' alias for cast_bytes, so that we can use fake b('stuff') -# to simulate b'stuff' -b = asbytes = cast_bytes -u = cast_unicode - -__all__ = ['asbytes', 'bytes', 'unicode', 'basestring', 'b', 'u', 'cast_bytes', 'cast_unicode'] diff --git a/zmq/utils/z85.py b/zmq/utils/z85.py deleted file mode 100644 index 1bb1784..0000000 --- a/zmq/utils/z85.py +++ /dev/null @@ -1,56 +0,0 @@ -"""Python implementation of Z85 85-bit encoding - -Z85 encoding is a plaintext encoding for a bytestring interpreted as 32bit integers. -Since the chunks are 32bit, a bytestring must be a multiple of 4 bytes. -See ZMQ RFC 32 for details. - - -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import sys -import struct - -PY3 = sys.version_info[0] >= 3 -# Z85CHARS is the base 85 symbol table -Z85CHARS = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#" -# Z85MAP maps integers in [0,84] to the appropriate character in Z85CHARS -Z85MAP = dict([(c, idx) for idx, c in enumerate(Z85CHARS)]) - -_85s = [ 85**i for i in range(5) ][::-1] - -def encode(rawbytes): -    """encode raw bytes into Z85""" -    # Accepts only byte arrays bounded to 4 bytes -    if len(rawbytes) % 4: -        raise ValueError("length must be multiple of 4, not %i" % len(rawbytes)) -     -    nvalues = len(rawbytes) / 4 -     -    values = struct.unpack('>%dI' % nvalues, rawbytes) -    encoded = [] -    for v in values: -        for offset in _85s: -            encoded.append(Z85CHARS[(v // offset) % 85]) -     -    # In Python 3, encoded is a list of integers (obviously?!) -    if PY3: -        return bytes(encoded) -    else: -        return b''.join(encoded) - -def decode(z85bytes): -    """decode Z85 bytes to raw bytes""" -    if len(z85bytes) % 5: -        raise ValueError("Z85 length must be multiple of 5, not %i" % len(z85bytes)) -     -    nvalues = len(z85bytes) / 5 -    values = [] -    for i in range(0, len(z85bytes), 5): -        value = 0 -        for j, offset in enumerate(_85s): -            value += Z85MAP[z85bytes[i+j]] * offset -        values.append(value) -    return struct.pack('>%dI' % nvalues, *values) diff --git a/zmq/utils/zmq_compat.h b/zmq/utils/zmq_compat.h deleted file mode 100644 index a949e95..0000000 --- a/zmq/utils/zmq_compat.h +++ /dev/null @@ -1,73 +0,0 @@ -//----------------------------------------------------------------------------- -//  Copyright (c) 2010 Brian Granger, Min Ragan-Kelley -// -//  Distributed under the terms of the New BSD License.  The full license is in -//  the file COPYING.BSD, distributed as part of this software. -//----------------------------------------------------------------------------- - -#if defined(_MSC_VER) -#define pyzmq_int64_t __int64 -#else -#include <stdint.h> -#define pyzmq_int64_t int64_t -#endif - - -#include "zmq.h" -// version compatibility for constants: -#include "zmq_constants.h" - -#define _missing (-1) - - -// define fd type (from libzmq's fd.hpp) -#ifdef _WIN32 -  #ifdef _MSC_VER && _MSC_VER <= 1400 -    #define ZMQ_FD_T UINT_PTR -  #else -    #define ZMQ_FD_T SOCKET -  #endif -#else -    #define ZMQ_FD_T int -#endif - -// use unambiguous aliases for zmq_send/recv functions - -#if ZMQ_VERSION_MAJOR >= 4 -// nothing to remove -#else -    #define zmq_curve_keypair(z85_public_key, z85_secret_key) _missing -#endif - -#if ZMQ_VERSION_MAJOR >= 3 -    #define zmq_sendbuf zmq_send -    #define zmq_recvbuf zmq_recv - -    // 3.x deprecations - these symbols haven't been removed, -    // but let's protect against their planned removal -    #define zmq_device(device_type, isocket, osocket) _missing -    #define zmq_init(io_threads) ((void*)NULL) -    #define zmq_term zmq_ctx_destroy -#else -    #define zmq_ctx_set(ctx, opt, val) _missing -    #define zmq_ctx_get(ctx, opt) _missing -    #define zmq_ctx_destroy zmq_term -    #define zmq_ctx_new() ((void*)NULL) - -    #define zmq_proxy(a,b,c) _missing - -    #define zmq_disconnect(s, addr) _missing -    #define zmq_unbind(s, addr) _missing -     -    #define zmq_msg_more(msg) _missing -    #define zmq_msg_get(msg, opt) _missing -    #define zmq_msg_set(msg, opt, val) _missing -    #define zmq_msg_send(msg, s, flags) zmq_send(s, msg, flags) -    #define zmq_msg_recv(msg, s, flags) zmq_recv(s, msg, flags) -     -    #define zmq_sendbuf(s, buf, len, flags) _missing -    #define zmq_recvbuf(s, buf, len, flags) _missing - -    #define zmq_socket_monitor(s, addr, flags) _missing - -#endif diff --git a/zmq/utils/zmq_constants.h b/zmq/utils/zmq_constants.h deleted file mode 100644 index 830ac58..0000000 --- a/zmq/utils/zmq_constants.h +++ /dev/null @@ -1,545 +0,0 @@ -#ifndef _PYZMQ_CONSTANT_DEFS -#define _PYZMQ_CONSTANT_DEFS - -#ifndef ZMQ_VERSION -    #define ZMQ_VERSION (-1) -#endif - -#ifndef ZMQ_VERSION_MAJOR -    #define ZMQ_VERSION_MAJOR (-1) -#endif - -#ifndef ZMQ_VERSION_MINOR -    #define ZMQ_VERSION_MINOR (-1) -#endif - -#ifndef ZMQ_VERSION_PATCH -    #define ZMQ_VERSION_PATCH (-1) -#endif - -#ifndef ZMQ_NOBLOCK -    #define ZMQ_NOBLOCK (-1) -#endif - -#ifndef ZMQ_DONTWAIT -    #define ZMQ_DONTWAIT (-1) -#endif - -#ifndef ZMQ_POLLIN -    #define ZMQ_POLLIN (-1) -#endif - -#ifndef ZMQ_POLLOUT -    #define ZMQ_POLLOUT (-1) -#endif - -#ifndef ZMQ_POLLERR -    #define ZMQ_POLLERR (-1) -#endif - -#ifndef ZMQ_SNDMORE -    #define ZMQ_SNDMORE (-1) -#endif - -#ifndef ZMQ_STREAMER -    #define ZMQ_STREAMER (-1) -#endif - -#ifndef ZMQ_FORWARDER -    #define ZMQ_FORWARDER (-1) -#endif - -#ifndef ZMQ_QUEUE -    #define ZMQ_QUEUE (-1) -#endif - -#ifndef ZMQ_IO_THREADS_DFLT -    #define ZMQ_IO_THREADS_DFLT (-1) -#endif - -#ifndef ZMQ_MAX_SOCKETS_DFLT -    #define ZMQ_MAX_SOCKETS_DFLT (-1) -#endif - -#ifndef ZMQ_PAIR -    #define ZMQ_PAIR (-1) -#endif - -#ifndef ZMQ_PUB -    #define ZMQ_PUB (-1) -#endif - -#ifndef ZMQ_SUB -    #define ZMQ_SUB (-1) -#endif - -#ifndef ZMQ_REQ -    #define ZMQ_REQ (-1) -#endif - -#ifndef ZMQ_REP -    #define ZMQ_REP (-1) -#endif - -#ifndef ZMQ_DEALER -    #define ZMQ_DEALER (-1) -#endif - -#ifndef ZMQ_ROUTER -    #define ZMQ_ROUTER (-1) -#endif - -#ifndef ZMQ_PULL -    #define ZMQ_PULL (-1) -#endif - -#ifndef ZMQ_PUSH -    #define ZMQ_PUSH (-1) -#endif - -#ifndef ZMQ_XPUB -    #define ZMQ_XPUB (-1) -#endif - -#ifndef ZMQ_XSUB -    #define ZMQ_XSUB (-1) -#endif - -#ifndef ZMQ_UPSTREAM -    #define ZMQ_UPSTREAM (-1) -#endif - -#ifndef ZMQ_DOWNSTREAM -    #define ZMQ_DOWNSTREAM (-1) -#endif - -#ifndef ZMQ_STREAM -    #define ZMQ_STREAM (-1) -#endif - -#ifndef ZMQ_EVENT_CONNECTED -    #define ZMQ_EVENT_CONNECTED (-1) -#endif - -#ifndef ZMQ_EVENT_CONNECT_DELAYED -    #define ZMQ_EVENT_CONNECT_DELAYED (-1) -#endif - -#ifndef ZMQ_EVENT_CONNECT_RETRIED -    #define ZMQ_EVENT_CONNECT_RETRIED (-1) -#endif - -#ifndef ZMQ_EVENT_LISTENING -    #define ZMQ_EVENT_LISTENING (-1) -#endif - -#ifndef ZMQ_EVENT_BIND_FAILED -    #define ZMQ_EVENT_BIND_FAILED (-1) -#endif - -#ifndef ZMQ_EVENT_ACCEPTED -    #define ZMQ_EVENT_ACCEPTED (-1) -#endif - -#ifndef ZMQ_EVENT_ACCEPT_FAILED -    #define ZMQ_EVENT_ACCEPT_FAILED (-1) -#endif - -#ifndef ZMQ_EVENT_CLOSED -    #define ZMQ_EVENT_CLOSED (-1) -#endif - -#ifndef ZMQ_EVENT_CLOSE_FAILED -    #define ZMQ_EVENT_CLOSE_FAILED (-1) -#endif - -#ifndef ZMQ_EVENT_DISCONNECTED -    #define ZMQ_EVENT_DISCONNECTED (-1) -#endif - -#ifndef ZMQ_EVENT_ALL -    #define ZMQ_EVENT_ALL (-1) -#endif - -#ifndef ZMQ_EVENT_MONITOR_STOPPED -    #define ZMQ_EVENT_MONITOR_STOPPED (-1) -#endif - -#ifndef ZMQ_NULL -    #define ZMQ_NULL (-1) -#endif - -#ifndef ZMQ_PLAIN -    #define ZMQ_PLAIN (-1) -#endif - -#ifndef ZMQ_CURVE -    #define ZMQ_CURVE (-1) -#endif - -#ifndef EAGAIN -    #define EAGAIN (-1) -#endif - -#ifndef EINVAL -    #define EINVAL (-1) -#endif - -#ifndef EFAULT -    #define EFAULT (-1) -#endif - -#ifndef ENOMEM -    #define ENOMEM (-1) -#endif - -#ifndef ENODEV -    #define ENODEV (-1) -#endif - -#ifndef EMSGSIZE -    #define EMSGSIZE (-1) -#endif - -#ifndef EAFNOSUPPORT -    #define EAFNOSUPPORT (-1) -#endif - -#ifndef ENETUNREACH -    #define ENETUNREACH (-1) -#endif - -#ifndef ECONNABORTED -    #define ECONNABORTED (-1) -#endif - -#ifndef ECONNRESET -    #define ECONNRESET (-1) -#endif - -#ifndef ENOTCONN -    #define ENOTCONN (-1) -#endif - -#ifndef ETIMEDOUT -    #define ETIMEDOUT (-1) -#endif - -#ifndef EHOSTUNREACH -    #define EHOSTUNREACH (-1) -#endif - -#ifndef ENETRESET -    #define ENETRESET (-1) -#endif - -#ifndef ZMQ_HAUSNUMERO -    #define ZMQ_HAUSNUMERO (-1) -#endif - -#ifndef ENOTSUP -    #define ENOTSUP (-1) -#endif - -#ifndef EPROTONOSUPPORT -    #define EPROTONOSUPPORT (-1) -#endif - -#ifndef ENOBUFS -    #define ENOBUFS (-1) -#endif - -#ifndef ENETDOWN -    #define ENETDOWN (-1) -#endif - -#ifndef EADDRINUSE -    #define EADDRINUSE (-1) -#endif - -#ifndef EADDRNOTAVAIL -    #define EADDRNOTAVAIL (-1) -#endif - -#ifndef ECONNREFUSED -    #define ECONNREFUSED (-1) -#endif - -#ifndef EINPROGRESS -    #define EINPROGRESS (-1) -#endif - -#ifndef ENOTSOCK -    #define ENOTSOCK (-1) -#endif - -#ifndef EFSM -    #define EFSM (-1) -#endif - -#ifndef ENOCOMPATPROTO -    #define ENOCOMPATPROTO (-1) -#endif - -#ifndef ETERM -    #define ETERM (-1) -#endif - -#ifndef EMTHREAD -    #define EMTHREAD (-1) -#endif - -#ifndef ZMQ_IO_THREADS -    #define ZMQ_IO_THREADS (-1) -#endif - -#ifndef ZMQ_MAX_SOCKETS -    #define ZMQ_MAX_SOCKETS (-1) -#endif - -#ifndef ZMQ_MORE -    #define ZMQ_MORE (-1) -#endif - -#ifndef ZMQ_IDENTITY -    #define ZMQ_IDENTITY (-1) -#endif - -#ifndef ZMQ_SUBSCRIBE -    #define ZMQ_SUBSCRIBE (-1) -#endif - -#ifndef ZMQ_UNSUBSCRIBE -    #define ZMQ_UNSUBSCRIBE (-1) -#endif - -#ifndef ZMQ_LAST_ENDPOINT -    #define ZMQ_LAST_ENDPOINT (-1) -#endif - -#ifndef ZMQ_TCP_ACCEPT_FILTER -    #define ZMQ_TCP_ACCEPT_FILTER (-1) -#endif - -#ifndef ZMQ_PLAIN_USERNAME -    #define ZMQ_PLAIN_USERNAME (-1) -#endif - -#ifndef ZMQ_PLAIN_PASSWORD -    #define ZMQ_PLAIN_PASSWORD (-1) -#endif - -#ifndef ZMQ_CURVE_PUBLICKEY -    #define ZMQ_CURVE_PUBLICKEY (-1) -#endif - -#ifndef ZMQ_CURVE_SECRETKEY -    #define ZMQ_CURVE_SECRETKEY (-1) -#endif - -#ifndef ZMQ_CURVE_SERVERKEY -    #define ZMQ_CURVE_SERVERKEY (-1) -#endif - -#ifndef ZMQ_ZAP_DOMAIN -    #define ZMQ_ZAP_DOMAIN (-1) -#endif - -#ifndef ZMQ_CONNECT_RID -    #define ZMQ_CONNECT_RID (-1) -#endif - -#ifndef ZMQ_RECONNECT_IVL_MAX -    #define ZMQ_RECONNECT_IVL_MAX (-1) -#endif - -#ifndef ZMQ_SNDTIMEO -    #define ZMQ_SNDTIMEO (-1) -#endif - -#ifndef ZMQ_RCVTIMEO -    #define ZMQ_RCVTIMEO (-1) -#endif - -#ifndef ZMQ_SNDHWM -    #define ZMQ_SNDHWM (-1) -#endif - -#ifndef ZMQ_RCVHWM -    #define ZMQ_RCVHWM (-1) -#endif - -#ifndef ZMQ_MULTICAST_HOPS -    #define ZMQ_MULTICAST_HOPS (-1) -#endif - -#ifndef ZMQ_IPV4ONLY -    #define ZMQ_IPV4ONLY (-1) -#endif - -#ifndef ZMQ_ROUTER_BEHAVIOR -    #define ZMQ_ROUTER_BEHAVIOR (-1) -#endif - -#ifndef ZMQ_TCP_KEEPALIVE -    #define ZMQ_TCP_KEEPALIVE (-1) -#endif - -#ifndef ZMQ_TCP_KEEPALIVE_CNT -    #define ZMQ_TCP_KEEPALIVE_CNT (-1) -#endif - -#ifndef ZMQ_TCP_KEEPALIVE_IDLE -    #define ZMQ_TCP_KEEPALIVE_IDLE (-1) -#endif - -#ifndef ZMQ_TCP_KEEPALIVE_INTVL -    #define ZMQ_TCP_KEEPALIVE_INTVL (-1) -#endif - -#ifndef ZMQ_DELAY_ATTACH_ON_CONNECT -    #define ZMQ_DELAY_ATTACH_ON_CONNECT (-1) -#endif - -#ifndef ZMQ_XPUB_VERBOSE -    #define ZMQ_XPUB_VERBOSE (-1) -#endif - -#ifndef ZMQ_FD -    #define ZMQ_FD (-1) -#endif - -#ifndef ZMQ_EVENTS -    #define ZMQ_EVENTS (-1) -#endif - -#ifndef ZMQ_TYPE -    #define ZMQ_TYPE (-1) -#endif - -#ifndef ZMQ_LINGER -    #define ZMQ_LINGER (-1) -#endif - -#ifndef ZMQ_RECONNECT_IVL -    #define ZMQ_RECONNECT_IVL (-1) -#endif - -#ifndef ZMQ_BACKLOG -    #define ZMQ_BACKLOG (-1) -#endif - -#ifndef ZMQ_ROUTER_MANDATORY -    #define ZMQ_ROUTER_MANDATORY (-1) -#endif - -#ifndef ZMQ_FAIL_UNROUTABLE -    #define ZMQ_FAIL_UNROUTABLE (-1) -#endif - -#ifndef ZMQ_ROUTER_RAW -    #define ZMQ_ROUTER_RAW (-1) -#endif - -#ifndef ZMQ_IMMEDIATE -    #define ZMQ_IMMEDIATE (-1) -#endif - -#ifndef ZMQ_IPV6 -    #define ZMQ_IPV6 (-1) -#endif - -#ifndef ZMQ_MECHANISM -    #define ZMQ_MECHANISM (-1) -#endif - -#ifndef ZMQ_PLAIN_SERVER -    #define ZMQ_PLAIN_SERVER (-1) -#endif - -#ifndef ZMQ_CURVE_SERVER -    #define ZMQ_CURVE_SERVER (-1) -#endif - -#ifndef ZMQ_PROBE_ROUTER -    #define ZMQ_PROBE_ROUTER (-1) -#endif - -#ifndef ZMQ_REQ_RELAXED -    #define ZMQ_REQ_RELAXED (-1) -#endif - -#ifndef ZMQ_REQ_CORRELATE -    #define ZMQ_REQ_CORRELATE (-1) -#endif - -#ifndef ZMQ_CONFLATE -    #define ZMQ_CONFLATE (-1) -#endif - -#ifndef ZMQ_ROUTER_HANDOVER -    #define ZMQ_ROUTER_HANDOVER (-1) -#endif - -#ifndef ZMQ_TOS -    #define ZMQ_TOS (-1) -#endif - -#ifndef ZMQ_IPC_FILTER_PID -    #define ZMQ_IPC_FILTER_PID (-1) -#endif - -#ifndef ZMQ_IPC_FILTER_UID -    #define ZMQ_IPC_FILTER_UID (-1) -#endif - -#ifndef ZMQ_IPC_FILTER_GID -    #define ZMQ_IPC_FILTER_GID (-1) -#endif - -#ifndef ZMQ_AFFINITY -    #define ZMQ_AFFINITY (-1) -#endif - -#ifndef ZMQ_MAXMSGSIZE -    #define ZMQ_MAXMSGSIZE (-1) -#endif - -#ifndef ZMQ_HWM -    #define ZMQ_HWM (-1) -#endif - -#ifndef ZMQ_SWAP -    #define ZMQ_SWAP (-1) -#endif - -#ifndef ZMQ_MCAST_LOOP -    #define ZMQ_MCAST_LOOP (-1) -#endif - -#ifndef ZMQ_RECOVERY_IVL_MSEC -    #define ZMQ_RECOVERY_IVL_MSEC (-1) -#endif - -#ifndef ZMQ_RATE -    #define ZMQ_RATE (-1) -#endif - -#ifndef ZMQ_RECOVERY_IVL -    #define ZMQ_RECOVERY_IVL (-1) -#endif - -#ifndef ZMQ_SNDBUF -    #define ZMQ_SNDBUF (-1) -#endif - -#ifndef ZMQ_RCVBUF -    #define ZMQ_RCVBUF (-1) -#endif - -#ifndef ZMQ_RCVMORE -    #define ZMQ_RCVMORE (-1) -#endif - - -#endif // ifndef _PYZMQ_CONSTANT_DEFS diff --git a/zmqversion.py b/zmqversion.py deleted file mode 100644 index 0b98ca1..0000000 --- a/zmqversion.py +++ /dev/null @@ -1,119 +0,0 @@ -"""A simply script to scrape zmq.h for the zeromq version. -This is similar to the version.sh script in a zeromq source dir, but -it searches for an installed header, rather than in the current dir. -""" - -# Copyright (c) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -from __future__ import with_statement - -import os -import sys -import re -import traceback - -from warnings import warn -try: -    from configparser import ConfigParser -except: -    from ConfigParser import ConfigParser - -pjoin = os.path.join - -MAJOR_PAT='^#define +ZMQ_VERSION_MAJOR +[0-9]+$' -MINOR_PAT='^#define +ZMQ_VERSION_MINOR +[0-9]+$' -PATCH_PAT='^#define +ZMQ_VERSION_PATCH +[0-9]+$' - -def include_dirs_from_path(): -    """Check the exec path for include dirs.""" -    include_dirs = [] -    for p in os.environ['PATH'].split(os.path.pathsep): -        if p.endswith('/'): -            p = p[:-1] -        if p.endswith('bin'): -            include_dirs.append(p[:-3]+'include') -    return include_dirs - -def default_include_dirs(): -    """Default to just /usr/local/include:/usr/include""" -    return ['/usr/local/include', '/usr/include'] - -def find_zmq_version(): -    """check setup.cfg, then /usr/local/include, then /usr/include for zmq.h. -    Then scrape zmq.h for the version tuple. -     -    Returns -    ------- -        ((major,minor,patch), "/path/to/zmq.h")""" -    include_dirs = [] - -    if os.path.exists('setup.cfg'): -        cfg = ConfigParser() -        cfg.read('setup.cfg') -        if 'build_ext' in cfg.sections(): -            items = cfg.items('build_ext') -            for name,val in items: -                if name == 'include_dirs': -                    include_dirs = val.split(os.path.pathsep) - -    if not include_dirs: -        include_dirs = default_include_dirs() -     -    for include in include_dirs: -        zmq_h = pjoin(include, 'zmq.h') -        if os.path.isfile(zmq_h): -            with open(zmq_h) as f: -                contents = f.read() -        else: -            continue -     -        line = re.findall(MAJOR_PAT, contents, re.MULTILINE)[0] -        major = int(re.findall('[0-9]+',line)[0]) -        line = re.findall(MINOR_PAT, contents, re.MULTILINE)[0] -        minor = int(re.findall('[0-9]+',line)[0]) -        line = re.findall(PATCH_PAT, contents, re.MULTILINE)[0] -        patch = int(re.findall('[0-9]+',line)[0]) -        return ((major,minor,patch), zmq_h) -     -    raise IOError("Couldn't find zmq.h") - -def ver_str(version): -    """version tuple as string""" -    return '.'.join(map(str, version)) - -def check_zmq_version(min_version): -    """Check that zmq.h has an appropriate version.""" -    sv = ver_str(min_version) -    try: -        found, zmq_h = find_zmq_version() -        sf = ver_str(found) -        if found < min_version: -            print ("This pyzmq requires zeromq >= %s"%sv) -            print ("but it appears you are building against %s"%zmq_h) -            print ("which has zeromq %s"%sf) -            sys.exit(1) -    except IOError: -        msg = '\n'.join(["Couldn't find zmq.h to check for version compatibility.", -        "If you see 'undeclared identifier' errors, your ZeroMQ is likely too old.", -        "This pyzmq requires zeromq >= %s"%sv]) -        warn(msg) -    except IndexError: -        msg = '\n'.join(["Couldn't find ZMQ_VERSION macros in zmq.h to check for version compatibility.", -        "This probably means that you have ZeroMQ <= 2.0.9", -        "If you see 'undeclared identifier' errors, your ZeroMQ is likely too old.", -        "This pyzmq requires zeromq >= %s"%sv]) -        warn(msg) -    except Exception: -        traceback.print_exc() -        msg = '\n'.join(["Unexpected Error checking for zmq version.", -        "If you see 'undeclared identifier' errors, your ZeroMQ is likely too old.", -        "This pyzmq requires zeromq >= %s"%sv]) -        warn(msg) - -if __name__ == '__main__': -    v,h = find_zmq_version() -    print (h) -    print (ver_str(v)) - -  | 
