From d3907f0dcac6c6e0d7b3c3abe69c64fe4e9dcaa6 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Tue, 28 Feb 2017 14:21:30 +0200 Subject: [PATCH] PyZMQ restore removed by accident version of Python3/32 bits Change-Id: Ie8a54015a02bdcc5cd0a50faff7b82cf0ad8de93 Signed-off-by: Yaroslav Brustinov --- .../fedora18/64bit/zmq/sugar/.version.py.swp | Bin 12288 -> 0 bytes .../python3/ucs4/32bit/zmq/__init__.py | 64 ++ .../python3/ucs4/32bit/zmq/auth/__init__.py | 10 + .../python3/ucs4/32bit/zmq/auth/base.py | 272 +++++++ .../python3/ucs4/32bit/zmq/auth/certs.py | 119 +++ .../python3/ucs4/32bit/zmq/auth/ioloop.py | 34 + .../python3/ucs4/32bit/zmq/auth/thread.py | 184 +++++ .../python3/ucs4/32bit/zmq/backend/__init__.py | 45 ++ .../ucs4/32bit/zmq/backend/cffi/__init__.py | 22 + .../python3/ucs4/32bit/zmq/backend/cffi/_cdefs.h | 68 ++ .../python3/ucs4/32bit/zmq/backend/cffi/_cffi.py | 127 ++++ .../python3/ucs4/32bit/zmq/backend/cffi/_poll.py | 56 ++ .../python3/ucs4/32bit/zmq/backend/cffi/_verify.c | 12 + .../ucs4/32bit/zmq/backend/cffi/constants.py | 15 + .../python3/ucs4/32bit/zmq/backend/cffi/context.py | 100 +++ .../python3/ucs4/32bit/zmq/backend/cffi/devices.py | 24 + .../python3/ucs4/32bit/zmq/backend/cffi/error.py | 13 + .../python3/ucs4/32bit/zmq/backend/cffi/message.py | 69 ++ .../python3/ucs4/32bit/zmq/backend/cffi/socket.py | 244 ++++++ .../python3/ucs4/32bit/zmq/backend/cffi/utils.py | 62 ++ .../ucs4/32bit/zmq/backend/cython/__init__.py | 23 + .../zmq/backend/cython/_device.cpython-34m.so | Bin 0 -> 24068 bytes .../32bit/zmq/backend/cython/_poll.cpython-34m.so | Bin 0 -> 32624 bytes .../zmq/backend/cython/_version.cpython-34m.so | Bin 0 -> 9340 bytes .../ucs4/32bit/zmq/backend/cython/checkrc.pxd | 23 + .../zmq/backend/cython/constants.cpython-34m.so | Bin 0 -> 40588 bytes .../zmq/backend/cython/context.cpython-34m.so | Bin 0 -> 33628 bytes .../ucs4/32bit/zmq/backend/cython/context.pxd | 41 + .../32bit/zmq/backend/cython/error.cpython-34m.so | Bin 0 -> 12280 bytes .../ucs4/32bit/zmq/backend/cython/libzmq.pxd | 110 +++ .../zmq/backend/cython/message.cpython-34m.so | Bin 0 -> 51204 bytes .../ucs4/32bit/zmq/backend/cython/message.pxd | 63 ++ .../32bit/zmq/backend/cython/socket.cpython-34m.so | Bin 0 -> 90224 bytes .../ucs4/32bit/zmq/backend/cython/socket.pxd | 47 ++ .../32bit/zmq/backend/cython/utils.cpython-34m.so | Bin 0 -> 24532 bytes .../ucs4/32bit/zmq/backend/cython/utils.pxd | 29 + .../python3/ucs4/32bit/zmq/backend/select.py | 39 + .../python3/ucs4/32bit/zmq/devices/__init__.py | 16 + .../python3/ucs4/32bit/zmq/devices/basedevice.py | 229 ++++++ .../zmq/devices/monitoredqueue.cpython-34m.so | Bin 0 -> 33368 bytes .../ucs4/32bit/zmq/devices/monitoredqueue.pxd | 177 +++++ .../ucs4/32bit/zmq/devices/monitoredqueue.py | 37 + .../ucs4/32bit/zmq/devices/monitoredqueuedevice.py | 66 ++ .../python3/ucs4/32bit/zmq/devices/proxydevice.py | 90 +++ .../pyzmq-14.5.0/python3/ucs4/32bit/zmq/error.py | 164 ++++ .../python3/ucs4/32bit/zmq/eventloop/__init__.py | 5 + .../python3/ucs4/32bit/zmq/eventloop/ioloop.py | 193 +++++ .../32bit/zmq/eventloop/minitornado/__init__.py | 0 .../32bit/zmq/eventloop/minitornado/concurrent.py | 11 + .../ucs4/32bit/zmq/eventloop/minitornado/ioloop.py | 829 +++++++++++++++++++++ .../ucs4/32bit/zmq/eventloop/minitornado/log.py | 6 + .../zmq/eventloop/minitornado/platform/__init__.py | 0 .../zmq/eventloop/minitornado/platform/auto.py | 45 ++ .../zmq/eventloop/minitornado/platform/common.py | 91 +++ .../eventloop/minitornado/platform/interface.py | 63 ++ .../zmq/eventloop/minitornado/platform/posix.py | 70 ++ .../zmq/eventloop/minitornado/platform/windows.py | 20 + .../zmq/eventloop/minitornado/stack_context.py | 376 ++++++++++ .../ucs4/32bit/zmq/eventloop/minitornado/util.py | 184 +++++ .../python3/ucs4/32bit/zmq/eventloop/zmqstream.py | 529 +++++++++++++ .../python3/ucs4/32bit/zmq/green/__init__.py | 40 + .../python3/ucs4/32bit/zmq/green/core.py | 287 +++++++ .../python3/ucs4/32bit/zmq/green/device.py | 32 + .../ucs4/32bit/zmq/green/eventloop/__init__.py | 3 + .../ucs4/32bit/zmq/green/eventloop/ioloop.py | 33 + .../ucs4/32bit/zmq/green/eventloop/zmqstream.py | 11 + .../python3/ucs4/32bit/zmq/green/poll.py | 95 +++ .../python3/ucs4/32bit/zmq/libzmq.so.3 | Bin 0 -> 414996 bytes .../python3/ucs4/32bit/zmq/log/__init__.py | 0 .../python3/ucs4/32bit/zmq/log/handlers.py | 146 ++++ .../python3/ucs4/32bit/zmq/ssh/__init__.py | 1 + .../python3/ucs4/32bit/zmq/ssh/forward.py | 91 +++ .../python3/ucs4/32bit/zmq/ssh/tunnel.py | 376 ++++++++++ .../python3/ucs4/32bit/zmq/sugar/__init__.py | 27 + .../python3/ucs4/32bit/zmq/sugar/attrsettr.py | 52 ++ .../python3/ucs4/32bit/zmq/sugar/constants.py | 98 +++ .../python3/ucs4/32bit/zmq/sugar/context.py | 192 +++++ .../python3/ucs4/32bit/zmq/sugar/frame.py | 19 + .../python3/ucs4/32bit/zmq/sugar/poll.py | 161 ++++ .../python3/ucs4/32bit/zmq/sugar/socket.py | 495 ++++++++++++ .../python3/ucs4/32bit/zmq/sugar/tracker.py | 120 +++ .../python3/ucs4/32bit/zmq/sugar/version.py | 48 ++ .../python3/ucs4/32bit/zmq/tests/__init__.py | 211 ++++++ .../python3/ucs4/32bit/zmq/tests/test_auth.py | 431 +++++++++++ .../ucs4/32bit/zmq/tests/test_cffi_backend.py | 310 ++++++++ .../python3/ucs4/32bit/zmq/tests/test_constants.py | 104 +++ .../python3/ucs4/32bit/zmq/tests/test_context.py | 257 +++++++ .../python3/ucs4/32bit/zmq/tests/test_device.py | 146 ++++ .../python3/ucs4/32bit/zmq/tests/test_error.py | 43 ++ .../python3/ucs4/32bit/zmq/tests/test_etc.py | 15 + .../python3/ucs4/32bit/zmq/tests/test_imports.py | 62 ++ .../python3/ucs4/32bit/zmq/tests/test_ioloop.py | 113 +++ .../python3/ucs4/32bit/zmq/tests/test_log.py | 116 +++ .../python3/ucs4/32bit/zmq/tests/test_message.py | 362 +++++++++ .../python3/ucs4/32bit/zmq/tests/test_monitor.py | 71 ++ .../python3/ucs4/32bit/zmq/tests/test_monqueue.py | 227 ++++++ .../python3/ucs4/32bit/zmq/tests/test_multipart.py | 35 + .../python3/ucs4/32bit/zmq/tests/test_pair.py | 53 ++ .../python3/ucs4/32bit/zmq/tests/test_poll.py | 229 ++++++ .../python3/ucs4/32bit/zmq/tests/test_pubsub.py | 41 + .../python3/ucs4/32bit/zmq/tests/test_reqrep.py | 62 ++ .../python3/ucs4/32bit/zmq/tests/test_security.py | 212 ++++++ .../python3/ucs4/32bit/zmq/tests/test_socket.py | 450 +++++++++++ .../python3/ucs4/32bit/zmq/tests/test_stopwatch.py | 42 ++ .../python3/ucs4/32bit/zmq/tests/test_version.py | 44 ++ .../ucs4/32bit/zmq/tests/test_win32_shim.py | 56 ++ .../python3/ucs4/32bit/zmq/tests/test_z85.py | 63 ++ .../python3/ucs4/32bit/zmq/tests/test_zmqstream.py | 34 + .../python3/ucs4/32bit/zmq/utils/__init__.py | 0 .../python3/ucs4/32bit/zmq/utils/buffers.pxd | 313 ++++++++ .../python3/ucs4/32bit/zmq/utils/compiler.json | 19 + .../python3/ucs4/32bit/zmq/utils/config.json | 13 + .../python3/ucs4/32bit/zmq/utils/constant_names.py | 365 +++++++++ .../python3/ucs4/32bit/zmq/utils/garbage.py | 180 +++++ .../python3/ucs4/32bit/zmq/utils/getpid_compat.h | 6 + .../python3/ucs4/32bit/zmq/utils/interop.py | 33 + .../python3/ucs4/32bit/zmq/utils/ipcmaxlen.h | 21 + .../python3/ucs4/32bit/zmq/utils/jsonapi.py | 59 ++ .../python3/ucs4/32bit/zmq/utils/monitor.py | 68 ++ .../ucs4/32bit/zmq/utils/pyversion_compat.h | 25 + .../python3/ucs4/32bit/zmq/utils/sixcerpt.py | 52 ++ .../python3/ucs4/32bit/zmq/utils/strtypes.py | 45 ++ .../python3/ucs4/32bit/zmq/utils/win32.py | 132 ++++ .../python3/ucs4/32bit/zmq/utils/z85.py | 56 ++ .../python3/ucs4/32bit/zmq/utils/zmq_compat.h | 80 ++ .../python3/ucs4/32bit/zmq/utils/zmq_constants.h | 622 ++++++++++++++++ 126 files changed, 13321 insertions(+) delete mode 100644 scripts/external_libs/pyzmq-14.5.0/python2/fedora18/64bit/zmq/sugar/.version.py.swp create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/auth/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/auth/base.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/auth/certs.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/auth/ioloop.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/auth/thread.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_cdefs.h create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_cffi.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_poll.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_verify.c create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/constants.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/context.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/devices.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/error.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/message.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/socket.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/utils.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/_device.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/_poll.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/_version.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/checkrc.pxd create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/constants.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/context.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/context.pxd create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/error.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/libzmq.pxd create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/message.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/message.pxd create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/socket.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/socket.pxd create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/utils.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/utils.pxd create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/select.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/basedevice.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.cpython-34m.so create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.pxd create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueuedevice.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/proxydevice.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/error.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/ioloop.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/concurrent.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/ioloop.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/log.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/auto.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/common.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/interface.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/posix.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/windows.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/stack_context.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/util.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/zmqstream.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/core.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/device.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/ioloop.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/zmqstream.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/poll.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/libzmq.so.3 create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/log/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/log/handlers.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/forward.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/tunnel.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/attrsettr.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/constants.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/context.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/frame.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/poll.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/socket.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/tracker.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/version.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_auth.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_cffi_backend.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_constants.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_context.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_device.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_error.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_etc.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_imports.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_ioloop.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_log.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_message.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_monitor.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_monqueue.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_multipart.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_pair.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_poll.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_pubsub.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_reqrep.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_security.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_socket.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_stopwatch.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_version.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_win32_shim.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_z85.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_zmqstream.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/__init__.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/buffers.pxd create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/compiler.json create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/config.json create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/constant_names.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/garbage.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/getpid_compat.h create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/interop.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/ipcmaxlen.h create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/jsonapi.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/monitor.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/pyversion_compat.h create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/sixcerpt.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/strtypes.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/win32.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/z85.py create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/zmq_compat.h create mode 100644 scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/zmq_constants.h diff --git a/scripts/external_libs/pyzmq-14.5.0/python2/fedora18/64bit/zmq/sugar/.version.py.swp b/scripts/external_libs/pyzmq-14.5.0/python2/fedora18/64bit/zmq/sugar/.version.py.swp deleted file mode 100644 index 803e504940f5c4ce7004fe5ded3a946bc72b8cdc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2&u<$=6vw9sF3U8QR{=JQi>X?xXjqVIDe{`~~ALcgojh;B` zj@eg9q{B{bv@fSaKQ~evf3~JSQFcGo_k646gU%?`(l;ZmGHZPKz)GEjaS*Ga@gGj_ z`zD`++TX+5DowiC!N~#e3==rj1m?uW#f75OFEq~6+iz{1Y8sq86JP>NfC(@GCcp%k z024TE1Z;Lj93ttL%EXHw2l#xZ>{rjS%MT{N1egF5U;<2l2`~XBzyz286JP>N;D1OU z91F4ast^mWA$a`%zxw_E>`-p$%vqT7#}Y??dlEuRxDq7vcx#5tKpa zp?9HQ=7e|#J%N6PzJm^-yU-%kgyx{L&>v@o_!jyG+JO4d0@Q4 z2e_+R8GCK-SU{O)ZM~uwMH$6 z*)mloMf^6;V(F3!EycK$Y~e~vNl88(;*M~U)!*S4$x+$L1!{X+EG=Urmx@o$t~ByK z@w#_Yl{B|&=I#19*k1ZzXJ@tnDx&(#%-M;%GE43sHsx6OMdWp_I6a;>+o<{uVYqqg z>gJ99+Vx-FyX^39dcTH+|(7jV<2C{9D$^swJvYeu043PCmIO=sS? zQ`@Xf90hmv_RY=ZmH@gc++qZ0v1aaat_r|&t}5IAlxbyLICdd5L^V{fz)jz&9HfVKLY3`H@oT}Mih!}d9 RtcoPclaa+2l= 3.2.2," + " but found %i.%i.%i" % _version_info + ) + +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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_poll.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_poll.py new file mode 100644 index 00000000..9bca34ca --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_poll.py @@ -0,0 +1,56 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_verify.c b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_verify.c new file mode 100644 index 00000000..547840eb --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/_verify.c @@ -0,0 +1,12 @@ +#include +#include +#include + +#include +#include +#include "zmq_compat.h" + +int get_ipc_path_max_len(void) { + struct sockaddr_un *dummy; + return sizeof(dummy->sun_path) - 1; +} diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/constants.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/constants.py new file mode 100644 index 00000000..ee293e74 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/constants.py @@ -0,0 +1,15 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/context.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/context.py new file mode 100644 index 00000000..16a7b257 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/context.py @@ -0,0 +1,100 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/devices.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/devices.py new file mode 100644 index 00000000..c7a514a8 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/devices.py @@ -0,0 +1,24 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/error.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/error.py new file mode 100644 index 00000000..3bb64de0 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/error.py @@ -0,0 +1,13 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/message.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/message.py new file mode 100644 index 00000000..c35decb6 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/message.py @@ -0,0 +1,69 @@ +"""Dummy Frame object""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +from ._cffi import ffi, C + +import zmq +from zmq.utils.strtypes import unicode + +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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/socket.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/socket.py new file mode 100644 index 00000000..3c427739 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/socket.py @@ -0,0 +1,244 @@ +# 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 ( + int64_sockopts, bytes_sockopts, + ) + if option in int64_sockopts: + return new_int64_pointer() + elif option in bytes_sockopts: + return new_binary_data(length) + else: + # default + return new_int_pointer() + +def value_from_opt_pointer(option, opt_pointer, length=0): + from zmq.sugar.constants import ( + int64_sockopts, bytes_sockopts, + ) + if option in int64_sockopts: + return int(opt_pointer[0]) + elif option in bytes_sockopts: + return ffi.buffer(opt_pointer, length)[:] + else: + return int(opt_pointer[0]) + +def initialize_opt_pointer(option, value, length=0): + from zmq.sugar.constants import ( + int64_sockopts, bytes_sockopts, + ) + if option in int64_sockopts: + return value_int64_pointer(value) + elif option in bytes_sockopts: + return value_binary_data(value, length) + else: + return value_int_pointer(value) + + +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. Passing None as + the addr will cause an existing socket monitor to be + deregistered. + 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 + if addr is None: + addr = ffi.NULL + rc = C.zmq_socket_monitor(self._zmq_socket, addr, events) + + +__all__ = ['Socket', 'IPC_PATH_MAX_LEN'] diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/utils.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/utils.py new file mode 100644 index 00000000..fde7827b --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cffi/utils.py @@ -0,0 +1,62 @@ +# 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 +from zmq.utils.strtypes import unicode + +def has(capability): + """Check for zmq capability by name (e.g. 'ipc', 'curve') + + .. versionadded:: libzmq-4.1 + .. versionadded:: 14.1 + """ + _check_version((4,1), 'zmq.has') + if isinstance(capability, unicode): + capability = capability.encode('utf8') + return bool(C.zmq_has(capability)) + +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__ = ['has', 'curve_keypair', 'Stopwatch'] diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/__init__.py new file mode 100644 index 00000000..e5358185 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/__init__.py @@ -0,0 +1,23 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/_device.cpython-34m.so b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/_device.cpython-34m.so new file mode 100644 index 0000000000000000000000000000000000000000..c3124e03c9c149dad452b770f59c4455f6a04a08 GIT binary patch literal 24068 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

G5@r5^@;|JdsO*+ulhxfIt@f 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 Oy31fA-%4pm@IL_Q0M@7g literal 0 HcmV?d00001 diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/_poll.cpython-34m.so b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/_poll.cpython-34m.so new file mode 100644 index 0000000000000000000000000000000000000000..0e6a778b394c108f64ac47ed4fd4dde75d5e8105 GIT binary patch literal 32624 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 FKLM(HH;VuO literal 0 HcmV?d00001 diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/_version.cpython-34m.so b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/_version.cpython-34m.so new file mode 100644 index 0000000000000000000000000000000000000000..22192ec99707a1aef9775ac01eef3cba9b95d23f GIT binary patch literal 9340 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 SfVQ0S3+TxkMw>w$mj4DGwPT9_ literal 0 HcmV?d00001 diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/checkrc.pxd b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/checkrc.pxd new file mode 100644 index 00000000..3bf69fc3 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/checkrc.pxd @@ -0,0 +1,23 @@ +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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/constants.cpython-34m.so b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/constants.cpython-34m.so new file mode 100644 index 0000000000000000000000000000000000000000..e10468be9c96f46bfbc167b94667f84e117f5a9f GIT binary patch literal 40588 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

g3M486qQtwYdg;P?zz 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 iQs@!&04_$mx. +# + +#----------------------------------------------------------------------------- +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/error.cpython-34m.so b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/error.cpython-34m.so new file mode 100644 index 0000000000000000000000000000000000000000..973a73fc8cc3c3f6dec22b9ef9c93f8e6be668fa GIT binary patch literal 12280 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 literal 0 HcmV?d00001 diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/libzmq.pxd b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/libzmq.pxd new file mode 100644 index 00000000..e42f6d6b --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/libzmq.pxd @@ -0,0 +1,110 @@ +"""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 . +# + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Import the C header files +#----------------------------------------------------------------------------- + +cdef extern from *: + ctypedef void* const_void_ptr "const void *" + ctypedef char* const_char_ptr "const char *" + +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) + const_char_ptr zmq_msg_gets (zmq_msg_t *msg, const_char_ptr property) + int zmq_has (const_char_ptr capability) + + 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/message.cpython-34m.so b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/message.cpython-34m.so new file mode 100644 index 0000000000000000000000000000000000000000..d7f21128a7347cf188c443efb70b42eb9b58ed6e GIT binary patch literal 51204 zcmeHweSB5Lwe}9C7&Y|-8X+7>MpY7wXg!X;>_MnvU$X`5QK`xsi$T1ATHeV#S5_u1zp=zZ_+ z{p0=P9^K4dGizqnthHv%nzd)|++I4XEGsL^aDJy4rx=7bU0@i+NZ;*JCB=r{_>?i) z_?+=sDR=Oh-uMf3eTqPyp~^SmUSCJgGK|iA!x*Z|haeq+GUw_A%!}pO`Z|Erxkloi zms57#>ycW31AgB6=nf+>jOnv0jk&)XHuJ3aTZcECc5eLPmyZ7OoOS>4J(k^qi?p!b z>a+Yar|l^@jd@{Qt+=-R<(?H&OJ6#&_?@1<>(9EU``|4LN8I_{-<3bv@%EWNSvc$R zH(z|~%$w)z!RXR|M@~(_EWC!D=^xl*tQAJ648m{dGA4w-oq=CTBK42uQ*#_h;jhXl zzdED+Uwi0b{bQ->(%*|2^;6nlK=z-ba4iC)oEDBQpSbmoS zASK+LG5$|wj5nCk|LBbNf0|K$lqja^g#Ev&ZslM0SLG=uygj4*h^Kv)KbBE`Lk4|S z8RgU|=g0axGU$88DMZTh8#Bsp&nSP~Ll4LEXa*e1kpFiwP^Is<++ z1HL4q{yCohDX$-S#>4*241Sbkz~PMXo|yr6X7v9-#`vDgD8D76|3C)+?#n3e$$+oP zz<)8Lza|gN@vg|IAIcctc;Glc;(yJ9Px!$M`Y+9ZKc7L*qZ#~Joq@k81OE36dChQ$ zLCXGHGw?6YXg{1$e|E}nuQU4Fkiq{~JuvmHAVVK- z&!GRM4EP*Re;49@wMRZ|FV_Q;U!V8DEdR0xX8Cy;?f)F~bnZq0etE{*{oe(AbXN*~ z1pH_~`3PhUGtM<$z<7_LoNOWdgADvJ81DuT{yzZk_`GWGEaNnz2=zPX!!BQ77-t!0 zh>YtVa>{d!H__i}Pkp1RYDr^rQ&l(;2t}%@jH<=;P4&pEX$|l;&``fTXjEOZv}#Up zNqsmH3{7nagu}tGQB~1aHM_YfI5!fC)eC z+C|?8)W}m)!eiMP-!Ssb!|-z@oNdT)(9T5n?t&IZZLvg>Rt4* z=1^mRZL^80$zk1+?qzx~GC2}q-D&mcbat?nsFh9iHO;jkthuoz5F!~)&g8JZb84Ww znUP?lvApq?s>bk=s@gy#-~wUt!|l1UDO|s#DOl@_1;k&wG#Fak(7a3yz-a?ajZ{fp z=7gJTZVpDI&6?(>Ch#WJez2+51!@|a!$E~6cZ)+o1qMT*re-M!M?wI=s&J$hH^$-? zFe|~Yu}B?;F}pc}ku(GwF^Pk<&Tyu*MS|g~l%OX!)y`G(LD=NI2M1*m zRkVSW=1|-G`rtCDnZ~Wz7_iegyXC~KUlfg`GNCCVxw)8UpqdQhq$dq}(v=4zbplvsp5Qvb%AYf1IL=GJY&#A zVkC-4ukve2x@4;9SfM6AO*+-Cwk5BPB^a6(4A+DlF-;A$ggMca?n*1@ zxqflIECNcKlm_X3)v%VSrWRpMsk(xLy2=^Um3mNDX~9%|S1i`NVaSLOss>J?RrFb+mJhKT)Zc~j{&U$^+>H#)Ri7s9oq>)fJU^I*dR)myl zXiMNMGd0aEZ3b*NZMl;tU8k*K%yEmCh)#26PY#6wFcoT%7Lm*h&y6mMFasqJvT`)hLnUUbv&c5oF9Kx+;pT!X4BWRw#A_g2NVtY~R~l78p%_XV z4lCaTSy&lIUOQ*z^qI3SFDNjk&zd=9YSq|+A~fXO7b-{R|KYzL_tn#?lk23OqCszo z_us`GtO1WxiHOp`{}^W)VsyY)qz}qp`270Q81>nv^YZHJKTR6;0Ol`$lVR|7xK8iI zMxXFHovzpEKAj%a>4+T)&#%)Pb-GcfTXlLsrw4U9j$o5uLW`bd^ryI$f{R4LaST)2%w)tJ8ftJ*3lKogUTcyE@H&O3|64)8RTD zq0=!sE!1g=PN(T~o=z9)v`(iDI$fdDRXSax(|dKgL8p)CbgNEx=yab>dvw~X)5AJ_ zSEt8xn)9?8Pp(c!=+v*%LY)@tbec|Q=yah@Z`5gnPFr-kN~dw1-mBAfI(HJ&`3`gJ-|r^PxQr_&iaou$(oby}^{7M(_P8rSJ+ zovzdA13KNP(@i?<)ah=W9?vg(Gr(1NoTc>+U6zMH|X>coo>0X`g(`k=RPrxn?9by>9 zuaF`Lp3M{nGKXm{;sQ)zQS+Fd346*Ef%f4{&%u74=>>=xGaZANJ<}q?7|nF7VT@sV zg<%vjEynW&rV+y!$8@=2Ok!GU7$r<+8pbrH*BQnPrgIEq7SjcWQNi?j!JD zVirt4XBfMge%>(lG96(U`vX&5%s zQHF7Z=|zaSFufShaF~upjD_hXhH--FmmufIkzNWpGrbIQW?BF_Grb&gW?Be2GyO8; z%=Ajgndw!KGt+U9GgAcpMl+oNIWwIIIWwIEIWxT)a%TD!$eHO^A!nu~kTcWCkTcUM zkTcV%kTcV1kTcUV$eHPM$eHO3$eHOikTcV-8Act`S%@t$EjNr7rn4b`rq@FLOe-LN zrgI^Grt=_wrj?LC)A^7;(}j>f)2~DROmBqzncf8XGyONnpJ^53&$JryXSxXTXIcyS zGYvxiOcz7`OqW3ZOzR+jruC3N({DijOrfv)m^MKEOdBD8rcIDP(`Lw@X^UZ0ny=4| z9m%#KN#ln0uJ!jBhP8G>e}8{sf8(v3U;mFV zsSOZf7|C8#>;Dmy*{EZ2vPWP{ZljKw$xeZxyha`WNp2Dt%4*d439lEJw{@cluMv18 z;X=Zz1ZGhkG{#7_2n-`()Rhpf7MQ4YGYD4*3?pIGRS+%_m{sc*5-t=N%4O756ZQ*S zLb#4_p1{)xw-7c2X47@8gpYoNj2}T+jJj2Xdj)1!b*l;Y2n^*g>edkM6qsGtts}fi zU?_!Ax1R8NfvX8WLU@h9Py(ZF6X8_?leD_6gj)n|Alyl~T40h|x0i5*z!Abdgi8b_ z>2(JQ7Ye+Ba4%uMz^e$`g!2TB6Fy4V5O_7=V}y@>$noDv7=ARyFYp?|IfQ!zzL#(w z;ZA|q5gtx>lfVxU_7h$&@Or|09G6@p@CL$#gjWgt2;p&rTLj)nxP)-Ez?%rqAY38v z7Qz*TO9b9Zcp>3Jfp-wDChQlulW-m3Jb`x;ZXs+4OxD)55kQ>D+DekTtT=*;BkZ(5-t>Y65(pXet}B}*AdPWcpBjr!iK;z2)7bG zdR*o|;Z=lt1+E~xnsAT6^9ZjY+$r!v!s`fc68J{K>j|$HxSH@Igx3gMOL!CERRY%$ z-b%Pd;0D5-gsTN^A-tDxg}@QQJ%mdDL)f(W^XJ-+;;y~xvAYc;b|i1r_SM4xM{lxX z6mp_7a%M+t6Xv^_J<_g2jupET2pyX@Ag^QXdi;CI%R4_B68n4B_@iNe#}jNf)|q7r zTK~NHc!*KHpmV2=KAwoNdJ(QT?CMA$ey0 z$o`(#?))2W>as?R>{`Pg>c@@@H>1a_XpXt^gtao)D$4=Mc~)f}=r!k!%4D8qePfO@oFdss}@MLUb1{vG+R$1X7*;B2u;z6>< zSY?w2$p(W;1~Ldz`nRf^x;mB`UV7%*D9BcX*%^YxMjKi5>?&y7S z#6Apir%r zjx_k+)8XV2hD`oaD6aPH^XRAaS8|g6{(>pn-gOw<^!8VB(*7XxPwFpr zWCllKO3UA7%cY0alrSp~Se1vZn9W&XSTiP>6_YIFwU$^d(-O~^6(v?>j#)7+a)y-^ zvpHL`B4vqwfTt?()X2qPNWL{xfkVNHvTU<>WPb%GNs0^L|MYBg67&0>Q}UUdZRQI6 z%gp%#A2uI6vJb*Uw|D*Lw+-XHlKFYjf^JNCPAN{pHS|0%3qE75l_`C?Sph^eK zr)vwdb~nrvaIM%D3=fraq%sZ48u}@Hozxq#Kd=|a%;*W|h+QL{*0R$n3$mhx)|^5Z zo$=P35+q~MoW1lt+EjB-WF+v36#1HU6U>(~LlA2Uf|}Xi67)!RQD@)5j+p=NFvA#! z727C0XM@2H`ukD3P4Q()F3R&dVj~nLp`4D`v9|`+`~5#5HJ9@bxtuTROx{c#7dxIg zz8Kbx_O7_8#uqt@1k|!2cL;V8w!z#J+uIM(+U8OFNm6=_GLh#*U$*9Fo2Bnk$gqT^ z@Am!2pz@oMZ4Z~OK8vobnKKg4M0_;n=&%0;B_R#krRcuzNXmXMm=6t@WtR59(sz^} zvU|Xv_O2IJLz=1J z(%n|&K6BQ{T&ui??39jkN7}RAr6hgv%~(~f(gRjb;u&B3Y^<(U^zis1^PT8f$u1O$ zT*hDJi+2Kub!J=R68+J)!0z`-7UcQjJRQY~)JQ9Opl`UAqknvNq&&7K+d30tzm@YW zYkW^+fi)wa*mt5W-xD+PVt=k)^+B~SPS3?^^;=W&Nf9C66I1eHz15SdqnoWMIpe#d zn@P7d)S^<`E${UA$Br4kJ0ApUbln=OJl8yGRrX$5+PU-C5Hr7>-TD$Aa_Np9#^}bE zqTO!+*?ikt3H9w8qv)*gTa(deq|EokWYr&Noa`UJE3zQgojv{|Uz|>mb*g2I-x*nC zRpcl3`{JJx`YQ5buT`%)ULDR;XluZ1*f#4%9eWa}@6q zyQ#kUBkjk~G`ODJLKZ+*wupZK{(wv1mf}+K5bQhc0Et<_8bhr-m-BF8miyU8P_fZ` zC;2JfEze;lw`8nV%4!&o?+J$?k(n0QT7EeBL!j6R5KN&SMOTv1Aq&lAOqbj@Su^c>F8oZQ0#r zdAK#qvfWHu)7}C0%$|)gws&0{r?@7 z+#cf^8mZty> zD6H`t4xo6XeLI+$#tJ0{djVHI;9aiPL#&0Lfx%Tn-t7)Kiw$}`4*Psv@BP0CgHW$< zkb2Lc_vAN336y;RzqtI+U$+-v{Ow%}@4&#zvaMCS!2#?<>PYQ((5l*~oMq*8mytP! zvx$I%o(qF21-agWFKXGXSx;=We{%iOzGt*O7JZ&Gyl?+|Whb(t_prAY(HmO)Cgj=I ztra-kpWg`Pws$?+P7R%emC>y1(QaKKHWzUCu$M4lYRbl$rH4974|SInlCtiyVwH?z z0;c9*Jtc2D;39(Q*Hb9B6(;(9i9Z6tDm?@;E)eDe4+t~CKNzdkoo?wV^nl6_!?v9g z%gTbSh2L}v?1r`Sfa$YV_L%3ws+gx*w@or3Jnz)Y+>VBI#&ESnZN z(*pfNlv6n*aszx)w1Uh7smv?W{ZL;~XKeQ*&wAj@XXNT_gW~U$Y;Hs0hd!MF-*3U= z00osf-KSzSMmPU4x}h{2_+bou@XcUp@5zh6u4oQTZ8bI3*=9!n=1SdN58g|c=OOU5 zz3UIRV_ScOX3$LJp#}54T>RS+yNYumkCMI&i$T7QJ-!QTq0*v2` zLQ6FRlud4>`&kJh=e*q3hl;yW73)*xw2bTi#cX3rwpB6@LN{eyNRTA+G)b^rTzdkA0D=vtKTHFRgja`HXf8VYXy8#U8-;`hEi57QLtRGx=+* z&Ytxw`WUuQC=|9O*P&4KSFhhUy$f@0cGJ#d#rXmBqrK~)l@!*zpJCu7k*}H`6?K}g zaO+231G1h?%0;gyn|oZ5M~hvFrP)*PYYbK!mtI+yMA?2qo_bBM(DmN*1tpQ^9KO#1 z4ra+gS0+l|K#lzhRE{pgo)qu$vGI5mWWc{J!4BnUvJA`tYxKnZGdKoe*QU{8u5i4Y zC$O7MjzJC0pBETm8iyS)SL8kPYD%*06|ks?f2;t9DzLNj#a{rIw8b1}P0wTaYkHow zeJ|RXc&hJi1WFA0t?mGzrTZ<5#h7Sn1D$8VVYjo)DS6hg*zwxi$Lu^lq$7XM_#VWx z)`F;hYsj9Gd;@mtT=Q5O$6(iEZ;tJI$-W+FFd4lau^bq5r5Wp4Q#d^dtiqZv`?`*p zjqw-t(-DLB1x@^j^29Eq9QG*sgXC;fbEyU8Tt{vOirL-QPKP($-ZVf!?Olzxa{U-% zt%bVxkFUt~C9n?$hjOe?&ii}l9z<4H*JKy%kGM*jnhX&_uFRJy$bo__$5-3Vhzda8uZ||za!)U|@p+BX)zW4{^No*^k z3z&|ThsgVT(7xW8g85%dUz*08G(>`B**kGaUn)+b`~kD{pq(v}J)}FZ$`4BT;eJ{= zY#+dAJbW zVI*>##{T&Rw5IfM@*>n&w7`@Bc-yn z81@(4`ioYym%NxN{J~!FAgv$5N8mH#0aSvHSP2~h5O6)JnY-XCt+rwee_`VBUxe1@ zjVwg84}TjQn*+M%7HK%-g__*?ttMaLMzv?0WI>wBJ%5*Q{Fo< zx5sxkA9qpYWymXf#*7~78)_bhyvsU@hnep~-dXRz(BDz~A;~wR2f@0D#m81a#Lpw6 zc%;Fw%MNc+{0F8SS&6>}{7w*VDX0~8M zg>_dRuu!+5ZOIPo^U@R!&F`6V6YtCW5Cq@mG~=&8zQ)V%zh6owRgQA zp|noGKUh97)(KjC_wJe)V~EH1#5>V*XcbzfaTo6dSvhYK??vC37&`={$RDZs{$8-+ z7`D#Q=k0uq9pPrt@F1T>3VWNj>; zg^o+C32WvS=lK$2(H)4Nqn1er# zb5*iCm#1I16;IsGF`36A=P-PdwmK-QdRs1?w--3k;Q+&dn*S$I3-wda#Ox)GUGihg z=gKp3s(D*6A_hNqMcVgw&7Qye9QMQ&dvG$xu%{t-+Y#GB{_Q!#K{%igra;8@7l8m( z{5q)3u=jYLN0~`T-TsV>G9ROa8v#M}pCyYIgOw?Hs(vm!&FSZa>WA~#-j0As-wUQ^ ze-t~i5bHBk$bJG`Xz%(>NV70cLK-Sk1$$zxr3kRd_!1AHC95?j)<0y~IbbT3$$fCB zlESWbl57tyHr&?gI{G-dc zENmo|=GCGqG;b$IlspE3-Sn>LRf-NFFUuGIJy1ZWFa8v6xba@ZLBM%C?@!QbSS?@T zL6&s-?iz~{D>myabb_g0OiP|^p9?gZ`jIo?tw>D5cUO*Ju1?4N8whnVX>4g){|Hm# zjyczf2CN;9_0K#?C)+XqbH!ElnU6{ZQIvOZxG0&6u44UJ(Z~C~X;tKb`&LOV2uY4d zzKTaJm~ZZxYahoXZSVS5i}E;Q;&GP2<6MowS+fyN&Uqv!a+@_X8>Xu0nMXd(-}K#m zKPt&;h(}83@njC?g##T<#KciI<#f{D{1g4n+3+{vb`();G->u-!dUF+&7G0w83?V& zHFtq0h=G0=(uF0&P9RIgEV81HTJ8g`hf}`#A?>TrQEj0PP4pD7CfSC6?CUZ4k&|cu zFu0#O4mFeIEOzaYiZ{|K{RBp^z3ZpVV1|0+-8x3ulgJEM6WWc_{vdt@Vg(z>=W|8s z=DBzV?lm>;Qp8#6d5j0X(AMr2Dx>>4HaB7hY};@)7S~velL5XF*mXJW!zlfo2e#1;4u#SHH1aC<-oRVEdYpiJ7Q}%!O(`i2W2oWOE}Jt>*NQ(>xi*^>56sJ zJ6Q&jtkLoUt*wr#`C~;?XQE=?OoS52{ZNSgxd-~$v$(Y)?rGBYd8wA zx0DIaHE%0~3GPD%75tr7G& zTmM)m)?Zk7Yt9V#fahVl(i`aCZ|=bsQZ~pe}d_I`u@-n+e|sh3U~yJ=VVtF ztri%4I~AK`{U(3d=__2h5N{|DQZ5H6|5rWF(mh)-EE0Ofoq;^8r@!xr?Q^N&<|ReV z%LhTtqaJ>=AEC{l$bJIthW8QaOuOI{9oc8_~KcgqE&6p%XliVCic-8zW6`j z-n4)8;nj0a^Tl_9`_9z=j3~Tp{vL)eZ0@vTqhU*}>vFNcn?tPFdRo?J?WeINhv2cP zh+hXhK4@|RLU4xRJzHy~Ug;s5Po;?3i>(iv+-1?E$LA2K{E%x$eDOl$P^q4NRVkG( z9>F@vreg=d7Z{@PQ?h;WKe9i>WRKhTV`0`r%wp!b$kx-`7pDvFYNRjTbqZ@8vY$XW zB)!}FS;9cXVJIVf?b3a)grzgjA2jtrDHB37Bk@ms}5 zMKum0F6B5CgHFvFKOI`mST(o6$LuZdyEIG^B|hkK#60GUmlM%p5rS4AWj~`RcqHvC z(UGrfPlAPDmix=WRuv%%(8E#U|Z)TftJd_ch4{&_lP2#cPt65q5|J+(~q>rL1rVO~=L$xGORLl_h*`8zg&y|L4Zc}$Ksrvk+Y4mFU*1-XclRUSZaiKD>@ zyCGSOr8r(jbSPX9JbHnsAz8zo^s;Z1i#jTo=hi9K9keKLMWEzYUmak#T zjt%oAgz3&G5h3RB<_=42)q6PmQABa}sWFK-D^sIJ+@M$H0#Hs#NxZxC0BC}C^~$3r zJS%h6X9126U`;v`Nh-4laWlp*{snUj6Y3WD5=rJjSzr^f_~MXE`QGG91M~Wx%0TK{ zr$!+33z4Ak!_*+0_+M#C)uU%wh@|0&i=&%z+y&37eDN!&Y>1{gqwpmzU`_^IpGIC9 z-^`UbPt)^(w^ung`I$!IAL;u{4FK z&mtukWauN7P#}&{h_I<(ke98=gxfw;6Z)(0g9<+%_!1%-IByrFFdUXoU{h=LRH(#M zkip!PLQKxU;*utGkoE^9ar~P>nlqvwbAls+@TxdDAyI|j+EFdzd- zy--mw$l$LTl;SU>@RR=zYp>M^i%veFkX9qumy@Z{p%;`ILG$htH9BmzYBf4)|3#u$ z@YSeBsTpM+^(FobTbDF@cQm;dSz3)?J?IXBXJJJlouTBrL{J8(Ur*oz@SlKXrLf$S zYKKw9NRB0+q)vK`1ZrR&Qf}gDX<3BABP|(R)nEGzKLw` z+1OB+O5)R1sapOoD6tW27HWbs(y}$ z6OPu5!tN4bhKUmtGm5)QWbn`=YsR?l5;@S(5gP+f92~|HVL$aO>f>Z&w>1P9Rz;y% zj`g<3tlVN%6vtL>G0Yi-R{1`2MlluSu=Nb3E#a13LGLB_b z;-SYaj5PS59PZBBmw1EJyH3T>JdQhR)89cK7p{i^Cu2l+%y{2--P<*N z57D{7Fl52Nc#?JClO>U0s?xgO0U9c=8wtNvyjcY!&6mM#yB*5e-gO7w*HfF-5=ITU zQtyX8}_ZrSfA$^7dL$A6t2Vo`nDq z=XuyHE1GA&2Q@5 zV&D%w12*mf-+b{TohdB+4$4me6J-TZprUvx$_$x>a`I3gXS)o=HqVm@jvVz6wqmf( zQA=wRs6al za~#(J-ToKi@d#yY1D<{BUJ$zrdtN$@x29^2Le1m{#AsAYR(Iq@dkT!N>pJ@qQ&DU! zz;5^eooINKr3aFiv&uzi6b6)2=hRe_d|;XU3Clm{H2ISK7H+-I>k_}mTytk-@@YWi za^mygiI%fG(8UveKA08tOWq}&Xh}9H_)*5>B=21uxVm9m|3;w0HzW6P$wfRn4R<4Q5iIn%kFkC6 zpE0W+S*ho|^I2DpKv3;^;YwKBX(xg9CF?%Y))DK$h^-D%C844FNGYGazWFEQOI?>l z&l@z|Qi5R^MV;-tDLPqz*MPCFPAGlZm-s0fbXfB*VT~z|x)IERBi0eSMhTH}6Qj34 zJXgnuhU58i!{(U=e`BT*?zhLKXmD{7rb_u!Q>X9g5G}t%@0Q z#j1s3O0*+(7Gg*=XKIXWXbTh-d|G`FBw5?XL03CA^IyD1P?@}yVqI#iy6r3jt0Xaa zdekQm{Gkp&Qw`&^DIF*_j3WbR^)8TybCh@=03sY0+mmm7g$F4vMSH7m8)ifwU3FWY z5&h|adS#%-sTbYbv6eA;Q)FhY?ZH^OWBc$gHK{xH2<|Qt?V|LWafh7=w9e7B%WvW;Uj2W-_%{7kA?C@KtXM7A z4UxPYIZl)OHqjB^>MJ2eyHPcS;NQPK2bpgd^gwjKTI)$WN;f%N)aJrNR-ZFcPR*e4G~cZ+EH*xdr*Y z_(qJzijB#@`JTqvDmX8I9vr1nI524>YyLO6;}Ox)41}4J>~4RE^gu zc%!6MhC#g4ov(3r3(m_JhZQT%!1-6F8o^${xm(&9o`Lg<#@Q!06M)mPc_Hi>7pd<* zr3}sactU{3)oF&PI~D;Je-Ig;#M@ukrLe~fb`RP!V+X+5j@WSSbvED2`_1F{SSrTS zj@XPf$d4T$CVIO}_jZZY=VS8j*gQrM*#`tdoHiLXmI!?A#M+MNcmMd-Y+w98K?*FX zCXk2~8nGUTf>I$UU-h6|rcu7&p!D%UNNfkXb*vOXeqj3IESbDkE)A`Cqa zbvRqqDrLo5I2e6&qCqnRpOD21PwGkTsaP{)eACmo>G1GBMH;@94*);}9LK7*;R4PLz_Ewv()Ch$6-KoU<`Sj#Ed7Ua+hQA}^r+}U9K;sw zw-@RV`C-KVkuSrEv5Z{T8x{=uLB+4t`#BtMBru+2j+}6FVv2nE)2b-3aG2#8vx8er z^S*caZ{jHaRY&=M%M7gWr&%4mdzG5<8Nmt4eysuea1?+K z&hc(H9(=4qhTZY92!@V$%K$Pfn4>E4Ex*H*tbHr?1rij-ad$MV27dxfN+0}s^zU8U zl&6#ggSiraZa`nJK;7UYIs9;=rtwWI5RPcK5l^trRvDhn@vFoVj$w;@wz~5?6tP$= zEW%oi+GLxj_MI$_J)oq!{3SI&M8$7&rOUGP0X{7%?OXj<8Hy+V94|m?PIytTZd(8O zVDe^Kp0(4`q;W_+!L<7ixV$}|Xx^}P{8SRDDwZDB?c0C*vrFuMDiU$DkBz4jdzL2l z#SCISjvq8sH#(?WsH6|=qH}KF@svxb#gVKnNgEHeYYj8z$n)7LcrJ;Yah@E$zlX0A zAjdvKj~T4_HZeRC#Y>&)0WZ#IHGH?%rJw-Slp2zX^nrg?2=%RAIY8lVV$ND2Gu7%3 zQmqD+N`sxmNpH35x9r@v`lvkg^~Ct&8>LklYO2*4saE&HeNnU$C%x51-Rf5d(8~1$ z$}n(p93ue|B+#-`ZQnSc?P0oYe#+ZgI|=33aASlvPg-$0gZ(k&I_Beo9WHyP6B&;d z_*}>mZ^ThPe~(*tC>DW}iOwZl5y#Hez)66$Dh`F>8qp+O`d0r^nChKS-PxvrmV7V}%1+KfaCQ_O1S22DzS@=LoxBP(@LCJ}nZ&)L1c~#Yc3DG2nRZ zSM+P}j4>cYPWno)-|Dc6vG2i7x`Vq_XD9tlcfWEW2AcfUQFp&$KmCM|8lQ0yP`& zg&b6Da2~W$-f(hzPOiWc3cNXQtzAc~@n%K7Il*enHkW5xZ8;|1$8O6tm*-k-dFJvw zt1aJLo^Q<@ZeBCI!#W5Knb+hcU*t)!ihRrJVGC!O!wAgDHm}Q;b|rUaj(JTE!I`<{ zHMuG5IeF%Fd4ivBUYF0CYld5ESw*_wp>=ctqLSA*y&M~~7s(x@7s(&I7Zyn`41MZe zcD@VN$;LfXk-A+TUrNO|3Y+BWeeyIi(U}FwhXE-;sX3rLq{C7Q<5BxI}}}A=+2A%JM9xiXqzu*66g=BS8_T|qaIfIb+NF2~>_S+_l6S~M zVQp{I!ov5s?OcI5lsud~+2HD3qrthB+)l(n2e2d^@g5=$%Gbr|i1jD!`r35Fl9P5l zJ00;{w`&y&M}&gzSw`q`G%6)aT%}QV&a?(Yy_l$H6Lrv$|I+0p-)Ty&vprHsR-IJ8 zHoDcuvswVv2AbTTrXg_(Bxe(GP(mJbk%bUn8X*f#Iv4MDtBoZg2meaR&A|$sIU|1K z@);)7NdA(DgA($L+u};L_)TeXFg4tnj(8Ih2lWrOxrmI3CyRmTYI<@qhNfeUcK)NV z1vgMunMalp*-|dVuQocpbc@NsSd4+<=i_q~;q?w`Mr>U$j;PCiCE zanioO%)W(Z-Lfi5-va{dslI=QzWeS_H3kOaf8^5mXP3tIfiw;UjVCAR;a{+nr}foD zQM0x?#y~26YT~>tcZ~V>per@8l6-LQF#h{!CK>(M!H;84BHr#8|+}iGw=NNnwlmT^;0x8SAd+8iM+u@Jvk_nM|z)!5(hQARq2R6bm`2_ z4}S`+e(iOqc@UenxBW4OulOSSw3iUM8=UFiPeODBpZz~IYl|xuJ1c8 zqICOj1G-i1wYq4c5?2Y@Eoy;E8^)6^qL0EklZb1p6=K?+daH|wfR2%T9YL^xqW-qa zPFWXk$8KwIm0jf`iZk_Hwl;t%(_AFcha$E%=u-F9bi|oxEw$9Wg^hX&+Utejk3U4% z*^vWY33wnS-*7t+rTZ!L+&!+HoQNul>z{GaWUjPhUztLC7JK-?nQ?_%O|~50{*!~K zX1;3sui$^On;{ZWWMxHE(VtkvZ;8nF7UaC)B%U{X<7Ygz@z-(K5X~QBSqyS9mZXkg z;n+XlZZ1E-?L*N|Kq-!-m*ZeIH+=jPng}@YNe=K3{jkr+YygIwWwN1D*6Hd~WO#}D z81x}^vPM4rfh}#LwR8+mt8bT>tm;!go$dOu+RXCcBSLEUJZ$RuKo=UD7(?t3&)%QM zJ(@7z$0LzJKZ=Qu5$TUxfXzA@tQQWOI!#J**`G+YbPN59$)@3C_R~Z=AB_ zZ3z$NQWl7$J1@`hjO}6bSqRVm7k2lq*uKXK2o@ez58JXLg>DsJBK;lspOH|!e+c=5 z_ysssf1vN@c>d4RfPAN)pB$|`*!Q&7SRB#CDSvS7X2rGh*pov})W;pLY6;b#MCr#{ zVvwVZ2Ysd<(LJGYCzE7cD2vU=uV_%r&AX0rOsr*2)9#yS8S%|f&*rz>=*7hWMj?3H92G!CR z*-{V6OdRt(Xy+l203Ini*P;UtuR!G%Po)>!QV0jbKrsWzP(Nw&aTY%TE~)R!wesb= zOE4wdyS@a=r(ZtBm-$}drye#RBHc49Ff+*1Z=;rV8t+!&uA_X1S-FYNZ`T1b%eOe6 zFu41NBzBX`->*`5_=>0Cnxz}8(k*8BM%say8^A{5S>+oeLrfo@zJ1Cn-(a4OFFYUR zM0LJf>f;|tF$TUrreco~>NuMF#zT&hZz44yOh@s*^CO`~85OG~o!fRfn=4h#_5IR4uPI%{bs1lX?^{bd;e>+ZRSmQcovYlW zb*^$#@@mS?r&?aT?aE2g~UsF6`8KZRDD^SV60cL@B(_s_<{p5l8%_;$AXoXK`R?U190*?3ybQ|iUT2-??R&^Mx5f1%m7lyAbqB#ujy*{}^~nxD$O#jvSN3Pye1sZ= zm$4Dpg`q z7Fs2#?}_03G8UB|n7Fx<6t@-o5|fy-St9dkhvpLxIOg#T%w7^=iSuwxwl6-0^BER$ zhaKKbvF;#0_WI%>o<+kqAU&Uf#CqY7yw{pCiN{YIJ@>^ch0whq$lCk>jrrtB=_mIM zMMP;2jsT&YRN%FVwRyP5l5UlV6ZRMmvci?nPS{SaQNQBZ)-)iEeR0qack^NUbDpOMf8{%{d_S$kL;7pX#A`y(l*uL5W{>x&j@H?w z-xvPv^u?1|W<&;k7iE2bD47gG0GLs+(iz~&ptt2D{};(k?kD<5HG_{E<` zo$<$f@$aKUOlj`H>{~Gs)sF00@hN8297a(sP2uEz{P$=~v=t6=E4x&(c@tBCvcaIm zM;12YST1LX`(9}L515K#e2*+lnT~AZDc?cRGY{R=-l{+-&c95LP9VvnB1%Gk8 z2QMl0m^1LTaJ<^y!f=-q9fHZU3let*Ltdw4F5h6a=EdH^WXppLkJb9_;-9*Y*<;6d;~Rpi zk5lDCdFb~SY!y1361Ja%cYIuY>VTkpMG>ZB3&ndIKee{{v$%y1VLyoBi+jZn@1)+l zkN@fvfR&xrb_$%&@6+}|zgZ{R2vxfjGNqunlbMkc)Kp|sMCbxL8GMY)7v~@4^h|>_ z>;UarccyAx#ahB3s&+qSK3GEbvcNN_2G(^3MZX%~iorZxeJATBA69>5KR={B4WHmNX=qnGmcpdF97a*EC^=aoUrP+y33oi~}Cou)PQZ!My7cS?+x8W&kr=6iKc>Cj!*@Ne;c<&LrM0|RzsB`>tzI$orU`CSPV)SRrMPv{@tKN}alKk3-+Mjd% zisaouLVJ#%k+yckccXCpN6~s%N4^+5Ws=7f4Z|D&HuEQ!VDa=6y@8nxrgoR^W#49N zNpkyf?T)?Ow;C@%t^ZiTr#}8%f;G9$W6Hn-Tx4pN4iE(qkEcLlx-jUqr)CaxDM}3ulG#oFB8Q>?h@~OL)dH!=c0FUoJd4j~*re3{?Z{PTecN0}u1{CpA%DO%e4| zm#8-&X!+{*Vt&t(tAkzm@6ICoG*^_hve-f4v9QXC)z}6a!)NV7cs!vN3|PQXv_C2P zy9N!>8j9i6%NA`v=NviPV~R_02W!Q|xZ;!iT#IOW+?DVRPGb5HIEuywo%Zn&1os?5 z;^$bk(Up={@&Q7g_uiA^Qv7uFevz8b4&3)ErQd6}&*-2ZsE$j(ww{07d)Pq=r$9;Mf_dX0PM| z@khwewOYQ!^8{VR-AO22ZSk6Ay1w>3slE+Mzvd)=?*)E(axP+I9)EfZL@)mI!?>ZF zv>0=Ye_u*@RvV#7iT5B2esql=wSr9Ux}B@4{^*)G60&aaZ&le30N?Q^`1Q4e@(#1_ zu31uLH5CX`Ov@X+ph~@`iZA{l7qL=)>J&`5`z@|uG_{D?IM$ZF^1kG`7=~u_!-~-i zb?w_qd8~mv5UxA$Ypu_T=V0~Ik%7vML$XfhhQtMys&k>3l%2voi@lG2C!iC((zDm1E1aWWTebI+3CMlksvi8@9*U{6$p?eQhL5R_I8 zKh3FcO6%WX>(9d|X&1u2_-@?qO8y$i?ph=_Sd0!PuVuro+h8BROC*4Z*iJUCjFB`h z#;BQ%-wAa}k5N<_Kaz)So72QfzHlPbQ%1P~&@UK(X> z{4XMLGI*TkFNFjDTS!Jo6g{b6<2SSMbdQwbCcfeU9mWm@5_*uTqnOC?p(&|<1M0&w z=FWhBb`VQx@(W0vT{>4ayTxe-ekfY$+X~gUZ|%^HM}Ic>j{JI6tMA(>Pv5?Xm9Vm& zNu^gDf6v45$sEl0p)fiIeJ6%$RY(jPj}FGco5n{I$NAzv!~mY=9$+hc9OEg>W+VCb zKZL=LJWdAt64#)rR>)tWSSe&4+y4qybx7j*`y5GJ1--NL9zd@tNhC1NOiA2=JX9=` z9{67JD0Hd&5SEJ4f0cc_3L_5A36085^v@rjA{H#*di@pD=Qm&Abww$8>{RG$gX14r zsJ}Bg{cUuh9v$NA)SXZBW09g#O&DFW6m;XOSNu#5HmK8pYu(~}rpH-meDO!=2I`OW zd>7gZZ9v?gU-h?2vB#D@(3CuyV4RXHDdBb(x-gXGDz27g;V&EQ%ra--L@)x~{S)zF zXKaKvlB*=wvkk(!h`olYhP~KnbSV+X!>f*n;~|oZO(M5Kw|#}%pwdq4gLD_%2ZVX)OoOjGI?Dl7sIL$;lwG`;K65263s+P*6J92eHPRQbPoFH3hXR z{hRk{+jObB>iZHGas;jelMg6OPEXm_nldTl{{`yxgb}usD+4*(!x;YUP%SF8aQ_2S zLAg-z=@iw|j+gf=3ZSh!BaiYi-7d2Qo4_8d$o5MQNezxCH4XSgBDQj`ftT;mihRBc zB3u5LE3zm5hK`l-76$RplkIDu7JQoXKA#WSlFgWMTCU<1iK={&GyZik(}R8Ke-7wO z4n?PsWb*e%up;aAMNIdzR0PM5OI{B&m`fE@V~11377y0!zm(!9Psak~{pjM0-{O!W z=bikciveJ0DaatS6fWX0#(*5{;@WM%gAqELrZ6x07Wk7Meo5X&NsBijUZk?IyUDUw zX&GaB_lxfe98^2<-5qOl5fP%>q~2SEe`ddobyNx1e3eX88{%KV&q|))loyzb1c`-A z&Lf>|>_C+~hq9vmVjEGqg556$$*L4zU_wn%w#ptco!1fJbQpxx^J;t_C)d6bVruWY z3UB5@m7!7igB4kkMmXj6uy4x#gO8>w>HXn*$k+tv;6natu%+9c{HWTa#76*wJE}v- zr&0Pdx^qJpcvi`+9Y0_pt2_RHs`@64-Y;#JSGm$cH2ES*!%VNo~Rzn(agr+RMb&teaek zkha)v&8+FpLnf8|am@MxDDJ9p#i2sSUJr&bp%pURO?K~%u9;7=fAvOvcz{C0ElV&4SbEsmY zaO)JdpOOWivyxkHu^(~^t5ZMzXdy#P;$s|-D-Gord*#nx;aOa?7S{I&x>qi8{4UEz8H_ z^84&@G1iUTsp@Uzmuyh65Eb=&z}H^*{4_!XOo#SXxXXBqw2?*;`wu?v`VO5SOe%cr zNKGo-JSTrA&>L4+3hDs!c^5;sa$ce*c^zqHJcFNN>2X}{p5%9({0w~gJT~z82eqIa z`h(gu5r14ITv*MM76?Tqzkn3|p0{S$xn0j5FTyiAB)CV_rMw^&nCae+@YlL z1FnAxXNkhuL7cZy6(0>(2H4URU9)0VnN#t9Kr%H;5+6VmT09<3Vxdp|i6wIE!)wy0 zCD%c%WMsZX^#CsQq91F5+DT0CCBDa2mW%k&J~RV|QQ$&BShu4D9AEeohvNxqosvw8 zqB)ntTmU?ky?ARq6~Bjan9N-5af-nk;}R7QBQTL%455>i#gL9Bb}q68-%9yZWqAsp z)tPJnC76qt?;=qq_5-)0(eMBg&m@Vt?5oG_kdsd^xQTl}K|1@7kmx&6-To08qTTo& zTGcpm+_m(;3F0h-e9{Is7mBL}5bs8_eZNbubexs0K*NxgYd;V)q@W&Y7v5qgb(l53 zqYb!ifCT*cnX6J%YQ4IEqj_0aJD5vkqrKz|3|5n%YmHznIe4q2r?WrD?C(KAtlZS! zFUN6(%fRgRF1`qiw<$4N7}v;WJ2vxH$HilR=R=L5D2Tr6{N41}k!+iSxS_p^pYE^= z!IrPz@Jv^IQ^W`~`H=*d1VjG%us;;MC0ZW})*6eV^$n5wrm!(8>>oWUJYiJrB}P?M zZLp!L3Tb^)eFQgwh`+Hpj5Z?vhF}0U%NuXGJQ}HQ2w%P^x_EIg6fS6KWn1cgX?<|n z;!tyA^P+DAYa%Dft_m4VfySW!;!%|slcJ{Ph`%p3`;8)##8{+WetB# zU7%@6uy%~UG0+BOudS~MM1uZB^-X~gVG0Z#Evj#*kF@D=Ic?Vk!v08I(7!Cy+_Xem z8{?0lRw&3?sL`|pC;iKkI4xvDOI5@!{bjtiS4S{fqu>pTLx=3YZwqh9mWp(usoI^^$Um;rW zcla^8a@H(R6o!QT%jz*9q7i>E6oP>3n}B<*%*m>$7>V(5ipcr=F_Wu6=1Bo{u%N06 zGZG5>vG}6YQ2eUK@RBN}+8^J4TkFTRr~20oo!kg$I^9X-=oIuh61W+fKdN9H{#jn@ zZ)pzKQ%->fcLt0qD56nB;S#84(df0VL?J(Hs$K-?(H#XNsp|ux- zr7%Vp`)ixQd)oNMK%}P5ABr|*R5EBj{U;~%lWBrlibenLjCU~>HL<(@E#5e${gY{+ z_5S$&GnS)I?w{?6@{g_!L;_dOZf*+FRADu{x-8HT4qkHl>3;kslXrf-toWsZwlcK! zTp~Cl{b8(|m&3>{4Hu|-^Xjk`E8Byc=B9==*yms^ta<%ne_M0Zzbt^I0XDj}*=>a; zkq!9+xO8KrVL@H6N$RxFy1}Z+g2BoWx0f;ghWeX>{_1Kqrtl@z)ff&ev5X=VTnsv) z9Mqxea5dKe81fLD5Ky$J%^z9TJONa~-YyE(1ft=f)K$X`!#0Pd7L2U z#R5U91JK1fxJFJZ0sr;o*SYK?OVB6Rv`AebB5k!a!=1vS!NH(+aeXwE1%BaT7;A?x z#2JG_Ih3BJCman0r75;4bT+`ugt3Ccv+`s5IsJ2K0tQEiIU!5Vq99lco<|D&*K+iQ z<=0756a!d|x}-{r9~qznRXOXp@=~H1WQWJF4XhZb%C$vWtFEqStD06ibxvv7Xi7%w zNJW57QUnuRur70dN`@Dnlb)nS^fg5MXE)hsZAHEakYe+m)6%};2uWORShi; zU}QoOybX*VG&f6+Yz4f9K1FMwj2J0tca)v|7YLqA3y?zJ&3^;D%K%oz34WO;H@Ph> zs|%uu5EL|hGFCZ@JbHJ<4{>v@p;Jx|8KUZoG|giXXG6dxhK@x5#KL8Q2&EZu1{_6$ zR8-qUi_}5OYQurWN-x-CDSf`Qj)ZPnf&cyeF9-gY1OLl`|GznaNC=-78cxdl&-~CZ zhU0}8M6iroa43c8N}cj(rw=f{n)L;pB79@)_`G2tSYp)SO_P6q)Zcsz_lS`j?*b1G zV~lBN1ZRwl9>6$oW#r*H1y>!Oyd!*Q9K=6318yKLVw{VM-=*RG5yV*Vzi|wW;mnGG z>IR}L%{!0@nwv=*o&YuP1~Otn%^Lv!|M(jLemcJ)BQPdh7vdU=YYMJ8xEA3G;kpCY zJ-8mm^*F9wxc1|E4c9xkhJf*B;kpplSX@(Z&B3(@R|wY~xbDIAFs{dO?ZUMm*K4@m z!8PPO)W>xpuCchL;F^PL5v~xfJ8<2D>tS4v z*CJdYTzBBQ2iL>69>=u{*M3~D;d%$x5I^eUx)9e`TvKq(!L6?VbN80em(rdPy!i%kdu2xu3>O%amjvpY zjLDAkT*}CTF|`@)T5DupFw}@(3*2Nw+!musCE|`7GbNg*D(L2obcf5B-5dc{Ly+O8 zV68&E7EzXPqz#)#9Z8dIV_+$U5?Is_EHLJ_g(Ja6g**=dFLmcKu(GMXrnwgJ81dEA zrjuLSWx-nd&JAr7xG%X}L@>tj<6ZX?BgRG`qe-`I-UMoD5K*Ml$4ynRwI0;KW78Xg zaBv9+gD4&P#AZ4WuBop#7Ge9MHbaKq*{eVX0$7Mhs-3#tKLb?EHR#qFwb)bC28~(? zPzDjw0^r8m(Bv3~_aNYqv80BvLubzg?Px))tsW6Y#3)1(pr#&-W8@5ZjSwqxl(TMV z^fnZw&Aj&H{Q+nAE*}ewaD?&7swxCE87xw+F4$&pzwfY)4lE=HmJg$yU*1h_D&l@ocbCgCH9xgMdKoWzxD+nZ4Ace-5G-kK zBxjqzD5T(C7~9=JTd7w&V7B7~fz!F8V>JZ`kd0PzYmADyU*e9$y_t*Y8qlE{g_~;2 zgQP+nl*iH=giZ0z+%&!ebU^A%){xAac^^5Ck^xhn?AC7=O z_okr0iQoll5&fAk0dbl|X!^1%3dVj6QqdI!g>JFTGMNblFhzR&IzGkDrVkjfA9OlW z^h~9}T;U>+7vM4iLM`&Z%PU0= zz&~0)t_wRtC@v^UDUipQ4RV_`NM2|?{GQFqCokDO2!bceTR$6bJkYO}-{sED{~(Z1Q?%~U<__zE$;8BS4!b2CV~%P>aca(*p%R^j}LnUC?!Lt7PJ zG>l$cnZFWUcfF?#FV6a}XsF$r`|e z-f76=eouaAFM_R*` zk;na`{Lt^6$XkWH$!?xutU=yRTU#H5%Rpe+Jw9k zkPbu$a@NTUcMYcUN7=SyYvA@ zUJhRB@Q(K|^3Ft_mlhj&=OWLmLr0Kz0rI@^IEuWBGTN)7+%npG7kFPro|gy5kXM2{ zuMV9+-VEe<`=A{tN1m7FY~;;FUbZ{7EF%Yb3y|lfITv{W`%)ss?qgWXM^I(347^z_-4m-ved ziVLptk1Z@3TX;p$75>q4@C0K9+)2s5tmw*145J`i$3045kx>A@K3K4%DO$i&E47!^ z*BS!h0YaToP}|lNZfjI&B&1559ipIV0H;d|uxBT}x@l>M7zKQmY7}sbZWQ2zO+AX5 zWjk3AtgBiqCteC_us;i<1C@NE1`WxB6t)&>mYxHR^)=|a8Li--0%=+`vnY(Jc={`Q z-NCprcpi0|^OS4K0ew*v&W|$Z49`Q-WO}L0R1sCI#ycoYE-r2Yuyv4XDt(@nKkMd%_&X0Kf1#mfd zM}Wht6a6|r;_+(0<=}0)0KCJsb)|!q^8G>{JjP>rA#CXWoPJw1-dLn@;P5)&8nhID zR%tx)W#KQ><+On;p^fRcagjdZ*CyQH@`%mF`;G@Mhd3v}Tj#;c0}ijj`hC!Ymk%6X zgZ2A!;87N&kMUSuy|{PUWXgJQh1_wR01hwm-uV%a*H&E4cp1m$#jmzIKL>B82e0>W z^oc7k&%rVbzrO88%Kk~;(Ov42Z@uVpw#VN-TvnsJsnm&ih};FER1Z`Aip Ih{NCi0fp5b0RR91 literal 0 HcmV?d00001 diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/message.pxd b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/message.pxd new file mode 100644 index 00000000..4781195f --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/message.pxd @@ -0,0 +1,63 @@ +"""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 . +# + +#----------------------------------------------------------------------------- +# 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 = zmq_msg_data(zmq_msg) + data_len_c = zmq_msg_size(zmq_msg) + return PyBytes_FromStringAndSize(data_c, data_len_c) + + diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/socket.cpython-34m.so b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/socket.cpython-34m.so new file mode 100644 index 0000000000000000000000000000000000000000..f524bd39b225f93bf7f77a18450e9544271f7dc6 GIT binary patch literal 90224 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 JCNGa3{|g6(|LFh# literal 0 HcmV?d00001 diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/socket.pxd b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/socket.pxd new file mode 100644 index 00000000..b8a331e2 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/socket.pxd @@ -0,0 +1,47 @@ +"""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 . +# + +#----------------------------------------------------------------------------- +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/utils.cpython-34m.so b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/utils.cpython-34m.so new file mode 100644 index 0000000000000000000000000000000000000000..2834d64592aad3f8f837d94279a1dced17babd02 GIT binary patch literal 24532 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 L1Kr6KI->s@*ybE& literal 0 HcmV?d00001 diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/utils.pxd b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/utils.pxd new file mode 100644 index 00000000..1d7117f1 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/cython/utils.pxd @@ -0,0 +1,29 @@ +"""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 . +# + +#----------------------------------------------------------------------------- +# Code +#----------------------------------------------------------------------------- + + +cdef class Stopwatch: + cdef void *watch # The C handle for the underlying zmq object + diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/select.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/select.py new file mode 100644 index 00000000..0a2e09a2 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/backend/select.py @@ -0,0 +1,39 @@ +"""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', + 'has', + '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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/__init__.py new file mode 100644 index 00000000..23715963 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/__init__.py @@ -0,0 +1,16 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/basedevice.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/basedevice.py new file mode 100644 index 00000000..7ba1b7ac --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/basedevice.py @@ -0,0 +1,229 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.cpython-34m.so b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.cpython-34m.so new file mode 100644 index 0000000000000000000000000000000000000000..049ee6902ea4ca1cd322924e5fa53fb25fea9deb GIT binary patch literal 33368 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 JuVv5?{of&%S#SUV literal 0 HcmV?d00001 diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.pxd b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.pxd new file mode 100644 index 00000000..1e26ed86 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.pxd @@ -0,0 +1,177 @@ +"""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 . +# + +#----------------------------------------------------------------------------- +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.py new file mode 100644 index 00000000..c6d91429 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueue.py @@ -0,0 +1,37 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueuedevice.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueuedevice.py new file mode 100644 index 00000000..9723f866 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/monitoredqueuedevice.py @@ -0,0 +1,66 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/proxydevice.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/proxydevice.py new file mode 100644 index 00000000..68be3f15 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/devices/proxydevice.py @@ -0,0 +1,90 @@ +"""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 + _mon version of each _{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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/error.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/error.py new file mode 100644 index 00000000..48cdaafa --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/error.py @@ -0,0 +1,164 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/__init__.py new file mode 100644 index 00000000..568e8e8d --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/__init__.py @@ -0,0 +1,5 @@ +"""A Tornado based event loop for PyZMQ.""" + +from zmq.eventloop.ioloop import IOLoop + +__all__ = ['IOLoop'] \ No newline at end of file diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/ioloop.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/ioloop.py new file mode 100644 index 00000000..35f4c418 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/ioloop.py @@ -0,0 +1,193 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/concurrent.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/concurrent.py new file mode 100644 index 00000000..519b23d5 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/concurrent.py @@ -0,0 +1,11 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/ioloop.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/ioloop.py new file mode 100644 index 00000000..710a3ecb --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/ioloop.py @@ -0,0 +1,829 @@ +#!/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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/log.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/log.py new file mode 100644 index 00000000..49051e89 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/log.py @@ -0,0 +1,6 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/auto.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/auto.py new file mode 100644 index 00000000..b40ccd94 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/auto.py @@ -0,0 +1,45 @@ +#!/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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/common.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/common.py new file mode 100644 index 00000000..2d75dc1e --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/common.py @@ -0,0 +1,91 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/interface.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/interface.py new file mode 100644 index 00000000..07da6bab --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/interface.py @@ -0,0 +1,63 @@ +#!/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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/posix.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/posix.py new file mode 100644 index 00000000..ccffbb66 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/posix.py @@ -0,0 +1,70 @@ +#!/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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/windows.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/windows.py new file mode 100644 index 00000000..817bdca1 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/platform/windows.py @@ -0,0 +1,20 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/stack_context.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/stack_context.py new file mode 100644 index 00000000..226d8042 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/stack_context.py @@ -0,0 +1,376 @@ +#!/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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/util.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/util.py new file mode 100644 index 00000000..c1e2eb95 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/minitornado/util.py @@ -0,0 +1,184 @@ +"""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, '', '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, '', '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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/zmqstream.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/zmqstream.py new file mode 100644 index 00000000..86a97e44 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/eventloop/zmqstream.py @@ -0,0 +1,529 @@ +# +# 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_(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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/__init__.py new file mode 100644 index 00000000..ff7e5965 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/__init__.py @@ -0,0 +1,40 @@ +# -*- 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/core.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/core.py new file mode 100644 index 00000000..9fc73e32 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/core.py @@ -0,0 +1,287 @@ +#----------------------------------------------------------------------------- +# 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 ` 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/device.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/device.py new file mode 100644 index 00000000..4b070237 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/device.py @@ -0,0 +1,32 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/__init__.py new file mode 100644 index 00000000..c5150efe --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/__init__.py @@ -0,0 +1,3 @@ +from zmq.green.eventloop.ioloop import IOLoop + +__all__ = ['IOLoop'] \ No newline at end of file diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/ioloop.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/ioloop.py new file mode 100644 index 00000000..e12fd5e9 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/ioloop.py @@ -0,0 +1,33 @@ +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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/zmqstream.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/zmqstream.py new file mode 100644 index 00000000..90fbd1f5 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/eventloop/zmqstream.py @@ -0,0 +1,11 @@ +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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/poll.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/poll.py new file mode 100644 index 00000000..8f016129 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/green/poll.py @@ -0,0 +1,95 @@ +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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/libzmq.so.3 b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/libzmq.so.3 new file mode 100644 index 0000000000000000000000000000000000000000..3d94abe0eedae33d942a7e56754aaec22ca37f22 GIT binary patch literal 414996 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�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 literal 0 HcmV?d00001 diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/log/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/log/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/log/handlers.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/log/handlers.py new file mode 100644 index 00000000..5ff21bf3 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/log/handlers.py @@ -0,0 +1,146 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/__init__.py new file mode 100644 index 00000000..57f09568 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/__init__.py @@ -0,0 +1 @@ +from zmq.ssh.tunnel import * diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/forward.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/forward.py new file mode 100644 index 00000000..2d619462 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/forward.py @@ -0,0 +1,91 @@ +# +# This file is adapted from a paramiko demo, and thus licensed under LGPL 2.1. +# Original Copyright (C) 2003-2007 Robey Pointer +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/tunnel.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/tunnel.py new file mode 100644 index 00000000..5a0c5433 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/ssh/tunnel.py @@ -0,0 +1,376 @@ +"""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 + SSHException = paramiko.ssh_exception.SSHException +except ImportError: + paramiko = None + class SSHException(Exception): + pass +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' + + # pop SSH_ASKPASS from env + env = os.environ.copy() + env.pop('SSH_ASKPASS', None) + + ssh_newkey = 'Are you sure you want to continue connecting' + p = pexpect.spawn(cmd, env=env) + while True: + try: + i = p.expect([ssh_newkey, '[Pp]assword:'], timeout=.1) + if i==0: + raise SSHException('The authenticity of the host can\'t be established.') + 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) + + # pop SSH_ASKPASS from env + env = os.environ.copy() + env.pop('SSH_ASKPASS', None) + + ssh_newkey = 'Are you sure you want to continue connecting' + tunnel = pexpect.spawn(cmd, env=env) + failed = False + while True: + try: + i = tunnel.expect([ssh_newkey, '[Pp]assword:'], timeout=.1) + if i==0: + raise SSHException('The authenticity of the host can\'t be established.') + 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/__init__.py new file mode 100644 index 00000000..d0510a44 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/__init__.py @@ -0,0 +1,27 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/attrsettr.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/attrsettr.py new file mode 100644 index 00000000..4bbd36d6 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/attrsettr.py @@ -0,0 +1,52 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/constants.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/constants.py new file mode 100644 index 00000000..88281176 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/constants.py @@ -0,0 +1,98 @@ +"""0MQ Constants.""" + +# Copyright (c) PyZMQ Developers. +# 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, + fd_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() +fd_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) + +_UNDEFINED = -9999 + +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, _UNDEFINED) + if c == _UNDEFINED: + 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 fd_sockopt_names: + _add_constant(name, fd_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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/context.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/context.py new file mode 100644 index 00000000..86a9c5dc --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/context.py @@ -0,0 +1,192 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/frame.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/frame.py new file mode 100644 index 00000000..9f556c86 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/frame.py @@ -0,0 +1,19 @@ +# 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): + def __getitem__(self, key): + # map Frame['User-Id'] to Frame.get('User-Id') + return self.get(key) + +# keep deprecated alias +Message = Frame +__all__ = ['Frame', 'Message'] \ No newline at end of file diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/poll.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/poll.py new file mode 100644 index 00000000..c7b1d1bb --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/poll.py @@ -0,0 +1,161 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/socket.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/socket.py new file mode 100644 index 00000000..c91589d7 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/socket.py @@ -0,0 +1,495 @@ +# 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, + fd_sockopt_names, +) +try: + import cPickle + pickle = cPickle +except: + cPickle = None + import pickle + +try: + DEFAULT_PROTOCOL = pickle.DEFAULT_PROTOCOL +except AttributeError: + DEFAULT_PROTOCOL = pickle.HIGHEST_PROTOCOL + + +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 as context manager: + def __enter__(self): + """Sockets are context managers + + .. versionadded:: 14.4 + """ + return self + + def __exit__(self, *args, **kwargs): + 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, + fd_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=DEFAULT_PROTOCOL): + """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. The default is pickle.DEFAULT_PROTOCOl + where defined, and pickle.HIGHEST_PROTOCOL elsewhere. + """ + 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 + + def disable_monitor(self): + """Shutdown the PAIR socket (created using get_monitor_socket) + that is serving socket events. + + .. versionadded:: 14.4 + """ + self.monitor(None, 0) + + +__all__ = ['Socket'] diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/tracker.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/tracker.py new file mode 100644 index 00000000..fb8c007f --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/tracker.py @@ -0,0 +1,120 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/version.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/version.py new file mode 100644 index 00000000..ea8fbbc4 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/sugar/version.py @@ -0,0 +1,48 @@ +"""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 = 5 +VERSION_PATCH = 0 +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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/__init__.py new file mode 100644 index 00000000..325a3f19 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/__init__.py @@ -0,0 +1,211 @@ +# Copyright (c) PyZMQ Developers. +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_auth.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_auth.py new file mode 100644 index 00000000..d350f61f --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_auth.py @@ -0,0 +1,431 @@ +# -*- 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_cffi_backend.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_cffi_backend.py new file mode 100644 index 00000000..1f85eebf --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_cffi_backend.py @@ -0,0 +1,310 @@ +# -*- 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_constants.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_constants.py new file mode 100644 index 00000000..d32b2b48 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_constants.py @@ -0,0 +1,104 @@ +# 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), sugar_constants._UNDEFINED) + + 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 == sugar_constants._UNDEFINED: + 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_context.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_context.py new file mode 100644 index 00000000..e3280778 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_context.py @@ -0,0 +1,257 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_device.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_device.py new file mode 100644 index 00000000..f8305074 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_device.py @@ -0,0 +1,146 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_error.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_error.py new file mode 100644 index 00000000..a2eee14a --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_error.py @@ -0,0 +1,43 @@ +# -*- 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_etc.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_etc.py new file mode 100644 index 00000000..ad224064 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_etc.py @@ -0,0 +1,15 @@ +# Copyright (c) PyZMQ Developers. +# Distributed under the terms of the Modified BSD License. + +import sys + +import zmq + +from . import skip_if + +@skip_if(zmq.zmq_version_info() < (4,1), "libzmq < 4.1") +def test_has(): + assert not zmq.has('something weird') + has_ipc = zmq.has('ipc') + not_windows = not sys.platform.startswith('win') + assert has_ipc == not_windows diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_imports.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_imports.py new file mode 100644 index 00000000..c0ddfaac --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_imports.py @@ -0,0 +1,62 @@ +# 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 + + def test_ssh(self): + """test ssh imports""" + from zmq.ssh import tunnel + + + diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_ioloop.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_ioloop.py new file mode 100644 index 00000000..2a8b1153 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_ioloop.py @@ -0,0 +1,113 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_log.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_log.py new file mode 100644 index 00000000..9206f095 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_log.py @@ -0,0 +1,116 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_message.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_message.py new file mode 100644 index 00000000..d8770bdf --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_message.py @@ -0,0 +1,362 @@ +# -*- 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_monitor.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_monitor.py new file mode 100644 index 00000000..4f035388 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_monitor.py @@ -0,0 +1,71 @@ +# -*- 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") + + # test monitor can be disabled. + s_rep.disable_monitor() + m = recv_monitor_message(s_event) + self.assertEqual(m['event'], zmq.EVENT_MONITOR_STOPPED) + + + @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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_monqueue.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_monqueue.py new file mode 100644 index 00000000..e855602e --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_monqueue.py @@ -0,0 +1,227 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_multipart.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_multipart.py new file mode 100644 index 00000000..24d41be0 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_multipart.py @@ -0,0 +1,35 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_pair.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_pair.py new file mode 100644 index 00000000..e88c1e8b --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_pair.py @@ -0,0 +1,53 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_poll.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_poll.py new file mode 100644 index 00000000..57346c89 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_poll.py @@ -0,0 +1,229 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_pubsub.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_pubsub.py new file mode 100644 index 00000000..a3ee22aa --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_pubsub.py @@ -0,0 +1,41 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_reqrep.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_reqrep.py new file mode 100644 index 00000000..de17f2b3 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_reqrep.py @@ -0,0 +1,62 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_security.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_security.py new file mode 100644 index 00000000..687b7e0f --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_security.py @@ -0,0 +1,212 @@ +"""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, PYPY +) +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"\5Hello\0\0\0\5World", + ]) + 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, test_metadata=True): + msg = [os.urandom(64), os.urandom(64)] + client.send_multipart(msg) + frames = self.recv_multipart(server, copy=False) + recvd = list(map(lambda x: x.bytes, frames)) + + try: + if test_metadata and not PYPY: + for frame in frames: + self.assertEqual(frame.get('User-Id'), 'anonymous') + self.assertEqual(frame.get('Hello'), 'World') + self.assertEqual(frame['Socket-Type'], 'DEALER') + except zmq.ZMQVersionError: + pass + + 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, False) + + 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_socket.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_socket.py new file mode 100644 index 00000000..5c842edc --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_socket.py @@ -0,0 +1,450 @@ +# -*- coding: utf8 -*- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +import time +import warnings + +import zmq +from zmq.tests import ( + BaseZMQTestCase, SkipTest, have_gevent, GreenTest, skip_pypy, skip_if +) +from zmq.utils.strtypes import bytes, unicode + + +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_context_manager(self): + url = 'inproc://a' + with self.Context() as ctx: + with ctx.socket(zmq.PUSH) as a: + a.bind(url) + with ctx.socket(zmq.PULL) as b: + b.connect(url) + msg = b'hi' + a.send(msg) + rcvd = self.recv(b) + self.assertEqual(rcvd, msg) + self.assertEqual(b.closed, True) + self.assertEqual(a.closed, True) + self.assertEqual(ctx.closed, True) + + 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', 'GSSAPI', + )): + # 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) + p.setsockopt(zmq.LINGER, 11) + self.assertEqual(p.getsockopt(zmq.LINGER), 11) + + 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 + 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_stopwatch.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_stopwatch.py new file mode 100644 index 00000000..49fb79f2 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_stopwatch.py @@ -0,0 +1,42 @@ +# -*- 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_version.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_version.py new file mode 100644 index 00000000..6ebebf30 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_version.py @@ -0,0 +1,44 @@ +# 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_win32_shim.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_win32_shim.py new file mode 100644 index 00000000..55657bda --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_win32_shim.py @@ -0,0 +1,56 @@ +from __future__ import print_function + +import os + +from functools import wraps +from zmq.tests import BaseZMQTestCase +from zmq.utils.win32 import allow_interrupt + + +def count_calls(f): + @wraps(f) + def _(*args, **kwds): + try: + return f(*args, **kwds) + finally: + _.__calls__ += 1 + _.__calls__ = 0 + return _ + + +class TestWindowsConsoleControlHandler(BaseZMQTestCase): + + def test_handler(self): + @count_calls + def interrupt_polling(): + print('Caught CTRL-C!') + + if os.name == 'nt': + from ctypes import windll + from ctypes.wintypes import BOOL, DWORD + + kernel32 = windll.LoadLibrary('kernel32') + + # + GenerateConsoleCtrlEvent = kernel32.GenerateConsoleCtrlEvent + GenerateConsoleCtrlEvent.argtypes = (DWORD, DWORD) + GenerateConsoleCtrlEvent.restype = BOOL + + try: + # Simulate CTRL-C event while handler is active. + with allow_interrupt(interrupt_polling): + result = GenerateConsoleCtrlEvent(0, 0) + if result == 0: + raise WindowsError + except KeyboardInterrupt: + pass + else: + self.fail('Expecting `KeyboardInterrupt` exception!') + + # Make sure our handler was called. + self.assertEqual(interrupt_polling.__calls__, 1) + else: + # On non-Windows systems, this utility is just a no-op! + with allow_interrupt(interrupt_polling): + pass + self.assertEqual(interrupt_polling.__calls__, 0) diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_z85.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_z85.py new file mode 100644 index 00000000..8a73cb4d --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_z85.py @@ -0,0 +1,63 @@ +# -*- 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}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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_zmqstream.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_zmqstream.py new file mode 100644 index 00000000..cdb3a171 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/tests/test_zmqstream.py @@ -0,0 +1,34 @@ +# -*- 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/__init__.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/buffers.pxd b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/buffers.pxd new file mode 100644 index 00000000..998aa551 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/buffers.pxd @@ -0,0 +1,313 @@ +"""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, &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] = bptr + if size: size[0] = blen + if itemsize: itemsize[0] = 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/compiler.json b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/compiler.json new file mode 100644 index 00000000..d95952e3 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/compiler.json @@ -0,0 +1,19 @@ +{ + "runtime_library_dirs": [ + "$ORIGIN/.." + ], + "library_dirs": [ + "zmq" + ], + "include_dirs": [ + "/tmp/zmq/zmq-bin/include", + "zmq/utils", + "zmq/backend/cython", + "zmq/devices" + ], + "extra_link_args": [], + "libraries": [ + "zmq" + ], + "define_macros": [] +} \ No newline at end of file diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/config.json b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/config.json new file mode 100644 index 00000000..544b389d --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/config.json @@ -0,0 +1,13 @@ +{ + "zmq_prefix": "/tmp/zmq/zmq-bin", + "build_ext": { + "library_dirs": "/tmp/zmq/zmq-bin/lib" + }, + "skip_check_zmq": false, + "no_libzmq_extension": true, + "have_sys_un_h": false, + "bdist_egg": { + "plat-name": "linux-i686" + }, + "libzmq_extension": false +} \ No newline at end of file diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/constant_names.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/constant_names.py new file mode 100644 index 00000000..47da9dc2 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/constant_names.py @@ -0,0 +1,365 @@ +"""0MQ Constant names""" + +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. + +# 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', + + # ctx opts + 'IO_THREADS', + 'MAX_SOCKETS', + 'IO_THREADS_DFLT', + 'MAX_SOCKETS_DFLT', + + # socket opts + 'ROUTER_BEHAVIOR', + 'ROUTER_MANDATORY', + 'FAIL_UNROUTABLE', + 'TCP_KEEPALIVE', + 'TCP_KEEPALIVE_CNT', + 'TCP_KEEPALIVE_IDLE', + 'TCP_KEEPALIVE_INTVL', + 'DELAY_ATTACH_ON_CONNECT', + 'XPUB_VERBOSE', + + # msg opts + 'MORE', + + '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) : [ + # ctx opts + 'SOCKET_LIMIT', + 'THREAD_PRIORITY', + 'THREAD_PRIORITY_DFLT', + 'THREAD_SCHED_POLICY', + 'THREAD_SCHED_POLICY_DFLT', + + # socket opts + 'ROUTER_HANDOVER', + 'TOS', + 'IPC_FILTER_PID', + 'IPC_FILTER_UID', + 'IPC_FILTER_GID', + 'CONNECT_RID', + 'GSSAPI_SERVER', + 'GSSAPI_PRINCIPAL', + 'GSSAPI_SERVICE_PRINCIPAL', + 'GSSAPI_PLAINTEXT', + 'HANDSHAKE_IVL', + 'IDENTITY_FD', + 'XPUB_NODROP', + 'SOCKS_PROXY', + + # msg opts + 'SRCFD', + 'SHARED', + + # security + 'GSSAPI', + + ], +} + + +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', + 'POLLITEMS_DFLT', + 'THREAD_PRIORITY_DFLT', + 'THREAD_SCHED_POLICY_DFLT', + + # socktypes + 'PAIR', + 'PUB', + 'SUB', + 'REQ', + 'REP', + 'DEALER', + 'ROUTER', + 'XREQ', + 'XREP', + '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', + 'GSSAPI', + + ## 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', + 'GSSAPI_PRINCIPAL', + 'GSSAPI_SERVICE_PRINCIPAL', + 'SOCKS_PROXY', +] + +fd_sockopt_names = [ + 'FD', + 'IDENTITY_FD', +] + +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', + + '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', + 'GSSAPI_SERVER', + 'GSSAPI_PLAINTEXT', + 'HANDSHAKE_IVL', + 'XPUB_NODROP', +] + +switched_sockopt_names = [ + 'RATE', + 'RECOVERY_IVL', + 'SNDBUF', + 'RCVBUF', + 'RCVMORE', +] + +ctx_opt_names = [ + 'IO_THREADS', + 'MAX_SOCKETS', + 'SOCKET_LIMIT', + 'THREAD_PRIORITY', + 'THREAD_SCHED_POLICY', +] + +msg_opt_names = [ + 'MORE', + 'SRCFD', + 'SHARED', +] + +from itertools import chain + +all_names = list(chain( + base_names, + ctx_opt_names, + bytes_sockopt_names, + fd_sockopt_names, + int_sockopt_names, + int64_sockopt_names, + switched_sockopt_names, + msg_opt_names, +)) + +del chain + +def no_prefix(name): + """does the given constant have a ZMQ_ prefix?""" + return name.startswith('E') and not name.startswith('EVENT') + diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/garbage.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/garbage.py new file mode 100644 index 00000000..80a8725a --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/garbage.py @@ -0,0 +1,180 @@ +"""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): + # detect fork at begining of the thread + if getpid is None or getpid() != self.pid: + self.ready.set() + return + try: + s = self.gc.context.socket(zmq.PULL) + s.linger = 0 + s.bind(self.gc.url) + finally: + 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 + self._stop() + + def _stop(self): + 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() + self.context = None + + 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. + """ + if self.thread is not None and self.pid != getpid(): + # It's re-starting, must free earlier thread's context + # since a fork probably broke it + self._stop() + 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/getpid_compat.h b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/getpid_compat.h new file mode 100644 index 00000000..47ce90fa --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/getpid_compat.h @@ -0,0 +1,6 @@ +#ifdef _WIN32 + #include + #define getpid _getpid +#else + #include +#endif diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/interop.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/interop.py new file mode 100644 index 00000000..26c01969 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/interop.py @@ -0,0 +1,33 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/ipcmaxlen.h b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/ipcmaxlen.h new file mode 100644 index 00000000..7218db78 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/ipcmaxlen.h @@ -0,0 +1,21 @@ +/* + +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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/jsonapi.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/jsonapi.py new file mode 100644 index 00000000..865ca6d5 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/jsonapi.py @@ -0,0 +1,59 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/monitor.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/monitor.py new file mode 100644 index 00000000..734d54b1 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/monitor.py @@ -0,0 +1,68 @@ +# -*- 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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/pyversion_compat.h b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/pyversion_compat.h new file mode 100644 index 00000000..fac09046 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/pyversion_compat.h @@ -0,0 +1,25 @@ +#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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/sixcerpt.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/sixcerpt.py new file mode 100644 index 00000000..5492fd59 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/sixcerpt.py @@ -0,0 +1,52 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/strtypes.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/strtypes.py new file mode 100644 index 00000000..548410dc --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/strtypes.py @@ -0,0 +1,45 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/win32.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/win32.py new file mode 100644 index 00000000..ea758299 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/win32.py @@ -0,0 +1,132 @@ +"""Win32 compatibility utilities.""" + +#----------------------------------------------------------------------------- +# Copyright (C) PyZMQ Developers +# Distributed under the terms of the Modified BSD License. +#----------------------------------------------------------------------------- + +import os + +# No-op implementation for other platforms. +class _allow_interrupt(object): + """Utility for fixing CTRL-C events on Windows. + + On Windows, the Python interpreter intercepts CTRL-C events in order to + translate them into ``KeyboardInterrupt`` exceptions. It (presumably) + does this by setting a flag in its "control control handler" and + checking it later at a convenient location in the interpreter. + + However, when the Python interpreter is blocked waiting for the ZMQ + poll operation to complete, it must wait for ZMQ's ``select()`` + operation to complete before translating the CTRL-C event into the + ``KeyboardInterrupt`` exception. + + The only way to fix this seems to be to add our own "console control + handler" and perform some application-defined operation that will + unblock the ZMQ polling operation in order to force ZMQ to pass control + back to the Python interpreter. + + This context manager performs all that Windows-y stuff, providing you + with a hook that is called when a CTRL-C event is intercepted. This + hook allows you to unblock your ZMQ poll operation immediately, which + will then result in the expected ``KeyboardInterrupt`` exception. + + Without this context manager, your ZMQ-based application will not + respond normally to CTRL-C events on Windows. If a CTRL-C event occurs + while blocked on ZMQ socket polling, the translation to a + ``KeyboardInterrupt`` exception will be delayed until the I/O completes + and control returns to the Python interpreter (this may never happen if + you use an infinite timeout). + + A no-op implementation is provided on non-Win32 systems to avoid the + application from having to conditionally use it. + + Example usage: + + .. sourcecode:: python + + def stop_my_application(): + # ... + + with allow_interrupt(stop_my_application): + # main polling loop. + + In a typical ZMQ application, you would use the "self pipe trick" to + send message to a ``PAIR`` socket in order to interrupt your blocking + socket polling operation. + + In a Tornado event loop, you can use the ``IOLoop.stop`` method to + unblock your I/O loop. + """ + + def __init__(self, action=None): + """Translate ``action`` into a CTRL-C handler. + + ``action`` is a callable that takes no arguments and returns no + value (returned value is ignored). It must *NEVER* raise an + exception. + + If unspecified, a no-op will be used. + """ + self._init_action(action) + + def _init_action(self, action): + pass + + def __enter__(self): + return self + + def __exit__(self, *args): + return + +if os.name == 'nt': + from ctypes import WINFUNCTYPE, windll + from ctypes.wintypes import BOOL, DWORD + + kernel32 = windll.LoadLibrary('kernel32') + + # + PHANDLER_ROUTINE = WINFUNCTYPE(BOOL, DWORD) + SetConsoleCtrlHandler = kernel32.SetConsoleCtrlHandler + SetConsoleCtrlHandler.argtypes = (PHANDLER_ROUTINE, BOOL) + SetConsoleCtrlHandler.restype = BOOL + + class allow_interrupt(_allow_interrupt): + __doc__ = _allow_interrupt.__doc__ + + def _init_action(self, action): + if action is None: + action = lambda: None + self.action = action + @PHANDLER_ROUTINE + def handle(event): + if event == 0: # CTRL_C_EVENT + action() + # Typical C implementations would return 1 to indicate that + # the event was processed and other control handlers in the + # stack should not be executed. However, that would + # prevent the Python interpreter's handler from translating + # CTRL-C to a `KeyboardInterrupt` exception, so we pretend + # that we didn't handle it. + return 0 + self.handle = handle + + def __enter__(self): + """Install the custom CTRL-C handler.""" + result = SetConsoleCtrlHandler(self.handle, 1) + if result == 0: + # Have standard library automatically call `GetLastError()` and + # `FormatMessage()` into a nice exception object :-) + raise WindowsError() + + def __exit__(self, *args): + """Remove the custom CTRL-C handler.""" + result = SetConsoleCtrlHandler(self.handle, 0) + if result == 0: + # Have standard library automatically call `GetLastError()` and + # `FormatMessage()` into a nice exception object :-) + raise WindowsError() +else: + class allow_interrupt(_allow_interrupt): + __doc__ = _allow_interrupt.__doc__ + pass diff --git a/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/z85.py b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/z85.py new file mode 100644 index 00000000..1bb1784e --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/z85.py @@ -0,0 +1,56 @@ +"""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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/zmq_compat.h b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/zmq_compat.h new file mode 100644 index 00000000..81c57b69 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/zmq_compat.h @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------- +// 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 +#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 >= 4 && ZMQ_VERSION_MINOR >= 1 +// nothing to remove +#else + #define zmq_msg_gets(msg, prop) _missing + #define zmq_has(capability) _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/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/zmq_constants.h b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/zmq_constants.h new file mode 100644 index 00000000..97683022 --- /dev/null +++ b/scripts/external_libs/pyzmq-14.5.0/python3/ucs4/32bit/zmq/utils/zmq_constants.h @@ -0,0 +1,622 @@ +#ifndef _PYZMQ_CONSTANT_DEFS +#define _PYZMQ_CONSTANT_DEFS + +#define _PYZMQ_UNDEFINED (-9999) +#ifndef ZMQ_VERSION + #define ZMQ_VERSION (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VERSION_MAJOR + #define ZMQ_VERSION_MAJOR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VERSION_MINOR + #define ZMQ_VERSION_MINOR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_VERSION_PATCH + #define ZMQ_VERSION_PATCH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_NOBLOCK + #define ZMQ_NOBLOCK (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DONTWAIT + #define ZMQ_DONTWAIT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_POLLIN + #define ZMQ_POLLIN (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_POLLOUT + #define ZMQ_POLLOUT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_POLLERR + #define ZMQ_POLLERR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SNDMORE + #define ZMQ_SNDMORE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_STREAMER + #define ZMQ_STREAMER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_FORWARDER + #define ZMQ_FORWARDER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_QUEUE + #define ZMQ_QUEUE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IO_THREADS_DFLT + #define ZMQ_IO_THREADS_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MAX_SOCKETS_DFLT + #define ZMQ_MAX_SOCKETS_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_POLLITEMS_DFLT + #define ZMQ_POLLITEMS_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_PRIORITY_DFLT + #define ZMQ_THREAD_PRIORITY_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_SCHED_POLICY_DFLT + #define ZMQ_THREAD_SCHED_POLICY_DFLT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PAIR + #define ZMQ_PAIR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PUB + #define ZMQ_PUB (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SUB + #define ZMQ_SUB (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_REQ + #define ZMQ_REQ (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_REP + #define ZMQ_REP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DEALER + #define ZMQ_DEALER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER + #define ZMQ_ROUTER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XREQ + #define ZMQ_XREQ (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XREP + #define ZMQ_XREP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PULL + #define ZMQ_PULL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PUSH + #define ZMQ_PUSH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XPUB + #define ZMQ_XPUB (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XSUB + #define ZMQ_XSUB (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_UPSTREAM + #define ZMQ_UPSTREAM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DOWNSTREAM + #define ZMQ_DOWNSTREAM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_STREAM + #define ZMQ_STREAM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CONNECTED + #define ZMQ_EVENT_CONNECTED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CONNECT_DELAYED + #define ZMQ_EVENT_CONNECT_DELAYED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CONNECT_RETRIED + #define ZMQ_EVENT_CONNECT_RETRIED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_LISTENING + #define ZMQ_EVENT_LISTENING (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_BIND_FAILED + #define ZMQ_EVENT_BIND_FAILED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_ACCEPTED + #define ZMQ_EVENT_ACCEPTED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_ACCEPT_FAILED + #define ZMQ_EVENT_ACCEPT_FAILED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CLOSED + #define ZMQ_EVENT_CLOSED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_CLOSE_FAILED + #define ZMQ_EVENT_CLOSE_FAILED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_DISCONNECTED + #define ZMQ_EVENT_DISCONNECTED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_ALL + #define ZMQ_EVENT_ALL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENT_MONITOR_STOPPED + #define ZMQ_EVENT_MONITOR_STOPPED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_NULL + #define ZMQ_NULL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PLAIN + #define ZMQ_PLAIN (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE + #define ZMQ_CURVE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI + #define ZMQ_GSSAPI (_PYZMQ_UNDEFINED) +#endif + +#ifndef EAGAIN + #define EAGAIN (_PYZMQ_UNDEFINED) +#endif + +#ifndef EINVAL + #define EINVAL (_PYZMQ_UNDEFINED) +#endif + +#ifndef EFAULT + #define EFAULT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOMEM + #define ENOMEM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENODEV + #define ENODEV (_PYZMQ_UNDEFINED) +#endif + +#ifndef EMSGSIZE + #define EMSGSIZE (_PYZMQ_UNDEFINED) +#endif + +#ifndef EAFNOSUPPORT + #define EAFNOSUPPORT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENETUNREACH + #define ENETUNREACH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ECONNABORTED + #define ECONNABORTED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ECONNRESET + #define ECONNRESET (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOTCONN + #define ENOTCONN (_PYZMQ_UNDEFINED) +#endif + +#ifndef ETIMEDOUT + #define ETIMEDOUT (_PYZMQ_UNDEFINED) +#endif + +#ifndef EHOSTUNREACH + #define EHOSTUNREACH (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENETRESET + #define ENETRESET (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_HAUSNUMERO + #define ZMQ_HAUSNUMERO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOTSUP + #define ENOTSUP (_PYZMQ_UNDEFINED) +#endif + +#ifndef EPROTONOSUPPORT + #define EPROTONOSUPPORT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOBUFS + #define ENOBUFS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENETDOWN + #define ENETDOWN (_PYZMQ_UNDEFINED) +#endif + +#ifndef EADDRINUSE + #define EADDRINUSE (_PYZMQ_UNDEFINED) +#endif + +#ifndef EADDRNOTAVAIL + #define EADDRNOTAVAIL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ECONNREFUSED + #define ECONNREFUSED (_PYZMQ_UNDEFINED) +#endif + +#ifndef EINPROGRESS + #define EINPROGRESS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOTSOCK + #define ENOTSOCK (_PYZMQ_UNDEFINED) +#endif + +#ifndef EFSM + #define EFSM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ENOCOMPATPROTO + #define ENOCOMPATPROTO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ETERM + #define ETERM (_PYZMQ_UNDEFINED) +#endif + +#ifndef EMTHREAD + #define EMTHREAD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IO_THREADS + #define ZMQ_IO_THREADS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MAX_SOCKETS + #define ZMQ_MAX_SOCKETS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SOCKET_LIMIT + #define ZMQ_SOCKET_LIMIT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_PRIORITY + #define ZMQ_THREAD_PRIORITY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_THREAD_SCHED_POLICY + #define ZMQ_THREAD_SCHED_POLICY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IDENTITY + #define ZMQ_IDENTITY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SUBSCRIBE + #define ZMQ_SUBSCRIBE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_UNSUBSCRIBE + #define ZMQ_UNSUBSCRIBE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_LAST_ENDPOINT + #define ZMQ_LAST_ENDPOINT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_ACCEPT_FILTER + #define ZMQ_TCP_ACCEPT_FILTER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PLAIN_USERNAME + #define ZMQ_PLAIN_USERNAME (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PLAIN_PASSWORD + #define ZMQ_PLAIN_PASSWORD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE_PUBLICKEY + #define ZMQ_CURVE_PUBLICKEY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE_SECRETKEY + #define ZMQ_CURVE_SECRETKEY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE_SERVERKEY + #define ZMQ_CURVE_SERVERKEY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ZAP_DOMAIN + #define ZMQ_ZAP_DOMAIN (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CONNECT_RID + #define ZMQ_CONNECT_RID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_PRINCIPAL + #define ZMQ_GSSAPI_PRINCIPAL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_SERVICE_PRINCIPAL + #define ZMQ_GSSAPI_SERVICE_PRINCIPAL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SOCKS_PROXY + #define ZMQ_SOCKS_PROXY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_FD + #define ZMQ_FD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IDENTITY_FD + #define ZMQ_IDENTITY_FD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RECONNECT_IVL_MAX + #define ZMQ_RECONNECT_IVL_MAX (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SNDTIMEO + #define ZMQ_SNDTIMEO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RCVTIMEO + #define ZMQ_RCVTIMEO (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SNDHWM + #define ZMQ_SNDHWM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RCVHWM + #define ZMQ_RCVHWM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MULTICAST_HOPS + #define ZMQ_MULTICAST_HOPS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPV4ONLY + #define ZMQ_IPV4ONLY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER_BEHAVIOR + #define ZMQ_ROUTER_BEHAVIOR (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_KEEPALIVE + #define ZMQ_TCP_KEEPALIVE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_KEEPALIVE_CNT + #define ZMQ_TCP_KEEPALIVE_CNT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_KEEPALIVE_IDLE + #define ZMQ_TCP_KEEPALIVE_IDLE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TCP_KEEPALIVE_INTVL + #define ZMQ_TCP_KEEPALIVE_INTVL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_DELAY_ATTACH_ON_CONNECT + #define ZMQ_DELAY_ATTACH_ON_CONNECT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XPUB_VERBOSE + #define ZMQ_XPUB_VERBOSE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_EVENTS + #define ZMQ_EVENTS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TYPE + #define ZMQ_TYPE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_LINGER + #define ZMQ_LINGER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RECONNECT_IVL + #define ZMQ_RECONNECT_IVL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_BACKLOG + #define ZMQ_BACKLOG (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER_MANDATORY + #define ZMQ_ROUTER_MANDATORY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_FAIL_UNROUTABLE + #define ZMQ_FAIL_UNROUTABLE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER_RAW + #define ZMQ_ROUTER_RAW (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IMMEDIATE + #define ZMQ_IMMEDIATE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPV6 + #define ZMQ_IPV6 (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MECHANISM + #define ZMQ_MECHANISM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PLAIN_SERVER + #define ZMQ_PLAIN_SERVER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CURVE_SERVER + #define ZMQ_CURVE_SERVER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_PROBE_ROUTER + #define ZMQ_PROBE_ROUTER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_REQ_RELAXED + #define ZMQ_REQ_RELAXED (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_REQ_CORRELATE + #define ZMQ_REQ_CORRELATE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_CONFLATE + #define ZMQ_CONFLATE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_ROUTER_HANDOVER + #define ZMQ_ROUTER_HANDOVER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_TOS + #define ZMQ_TOS (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPC_FILTER_PID + #define ZMQ_IPC_FILTER_PID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPC_FILTER_UID + #define ZMQ_IPC_FILTER_UID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_IPC_FILTER_GID + #define ZMQ_IPC_FILTER_GID (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_SERVER + #define ZMQ_GSSAPI_SERVER (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_GSSAPI_PLAINTEXT + #define ZMQ_GSSAPI_PLAINTEXT (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_HANDSHAKE_IVL + #define ZMQ_HANDSHAKE_IVL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_XPUB_NODROP + #define ZMQ_XPUB_NODROP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_AFFINITY + #define ZMQ_AFFINITY (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MAXMSGSIZE + #define ZMQ_MAXMSGSIZE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_HWM + #define ZMQ_HWM (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SWAP + #define ZMQ_SWAP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MCAST_LOOP + #define ZMQ_MCAST_LOOP (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RECOVERY_IVL_MSEC + #define ZMQ_RECOVERY_IVL_MSEC (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RATE + #define ZMQ_RATE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RECOVERY_IVL + #define ZMQ_RECOVERY_IVL (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SNDBUF + #define ZMQ_SNDBUF (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RCVBUF + #define ZMQ_RCVBUF (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_RCVMORE + #define ZMQ_RCVMORE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_MORE + #define ZMQ_MORE (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SRCFD + #define ZMQ_SRCFD (_PYZMQ_UNDEFINED) +#endif + +#ifndef ZMQ_SHARED + #define ZMQ_SHARED (_PYZMQ_UNDEFINED) +#endif + + +#endif // ifndef _PYZMQ_CONSTANT_DEFS -- 2.16.6

T(eTpD);5f8V^K=H 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%0Acx*MegfpbjFV^uf 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⋙F{Ty7{yaso8w0c`*l{E<=LNrxzf9-lYVUFK6>9 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