Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
4
venv/Lib/site-packages/zmq/__init__.pxd
Normal file
4
venv/Lib/site-packages/zmq/__init__.pxd
Normal file
|
@ -0,0 +1,4 @@
|
|||
from zmq.backend.cython.context cimport Context
|
||||
from zmq.backend.cython.socket cimport Socket
|
||||
from zmq.backend.cython.message cimport Frame
|
||||
from zmq.backend.cython cimport libzmq
|
73
venv/Lib/site-packages/zmq/__init__.py
Normal file
73
venv/Lib/site-packages/zmq/__init__.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
"""Python bindings for 0MQ."""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
# load bundled libzmq, if there is one:
|
||||
def _load_libzmq():
|
||||
"""load bundled libzmq if there is one"""
|
||||
import sys, platform, os
|
||||
dlopen = hasattr(sys, 'getdlopenflags') # unix-only
|
||||
# RTLD flags are added to os in Python 3
|
||||
# get values from os because ctypes values are WRONG on pypy
|
||||
PYPY = platform.python_implementation().lower() == 'pypy'
|
||||
|
||||
if dlopen:
|
||||
import ctypes
|
||||
dlflags = sys.getdlopenflags()
|
||||
# set RTLD_GLOBAL, unset RTLD_LOCAL
|
||||
flags = ctypes.RTLD_GLOBAL | dlflags
|
||||
# ctypes.RTLD_LOCAL is 0 on pypy, which is *wrong*
|
||||
flags &= ~ getattr(os, 'RTLD_LOCAL', 4)
|
||||
# pypy on darwin needs RTLD_LAZY for some reason
|
||||
if PYPY and sys.platform == 'darwin':
|
||||
flags |= getattr(os, 'RTLD_LAZY', 1)
|
||||
flags &= ~ getattr(os, 'RTLD_NOW', 2)
|
||||
sys.setdlopenflags(flags)
|
||||
try:
|
||||
from . import libzmq
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
# store libzmq as zmq._libzmq for backward-compat
|
||||
globals()['_libzmq'] = libzmq
|
||||
if PYPY:
|
||||
# should already have been imported above, so reimporting is as cheap as checking
|
||||
import ctypes
|
||||
# some versions of pypy (5.3 < ? < 5.8) needs explicit CDLL load for some reason,
|
||||
# otherwise symbols won't be globally available
|
||||
# do this unconditionally because it should be harmless (?)
|
||||
ctypes.CDLL(libzmq.__file__, ctypes.RTLD_GLOBAL)
|
||||
finally:
|
||||
if dlopen:
|
||||
sys.setdlopenflags(dlflags)
|
||||
|
||||
_load_libzmq()
|
||||
|
||||
|
||||
# zmq top-level imports
|
||||
|
||||
from zmq import backend
|
||||
from zmq.backend import *
|
||||
from zmq import sugar
|
||||
from zmq.sugar import *
|
||||
|
||||
def get_includes():
|
||||
"""Return a list of directories to include for linking against pyzmq with cython."""
|
||||
from os.path import join, dirname, abspath, pardir, exists
|
||||
base = dirname(__file__)
|
||||
parent = abspath(join(base, pardir))
|
||||
includes = [ parent ] + [ join(parent, base, subdir) for subdir in ('utils',) ]
|
||||
if exists(join(parent, base, 'include')):
|
||||
includes.append(join(parent, base, 'include'))
|
||||
return includes
|
||||
|
||||
def get_library_dirs():
|
||||
"""Return a list of directories used to link against pyzmq's bundled libzmq."""
|
||||
from os.path import join, dirname, abspath, pardir
|
||||
base = dirname(__file__)
|
||||
parent = abspath(join(base, pardir))
|
||||
return [ join(parent, base) ]
|
||||
|
||||
COPY_THRESHOLD = 65536
|
||||
__all__ = ['get_includes', 'COPY_THRESHOLD'] + sugar.__all__ + backend.__all__
|
BIN
venv/Lib/site-packages/zmq/__pycache__/__init__.cpython-36.pyc
Normal file
BIN
venv/Lib/site-packages/zmq/__pycache__/__init__.cpython-36.pyc
Normal file
Binary file not shown.
BIN
venv/Lib/site-packages/zmq/__pycache__/_future.cpython-36.pyc
Normal file
BIN
venv/Lib/site-packages/zmq/__pycache__/_future.cpython-36.pyc
Normal file
Binary file not shown.
BIN
venv/Lib/site-packages/zmq/__pycache__/decorators.cpython-36.pyc
Normal file
BIN
venv/Lib/site-packages/zmq/__pycache__/decorators.cpython-36.pyc
Normal file
Binary file not shown.
BIN
venv/Lib/site-packages/zmq/__pycache__/error.cpython-36.pyc
Normal file
BIN
venv/Lib/site-packages/zmq/__pycache__/error.cpython-36.pyc
Normal file
Binary file not shown.
545
venv/Lib/site-packages/zmq/_future.py
Normal file
545
venv/Lib/site-packages/zmq/_future.py
Normal file
|
@ -0,0 +1,545 @@
|
|||
"""Future-returning APIs for coroutines."""
|
||||
|
||||
# Copyright (c) PyZMQ Developers.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from collections import namedtuple, deque
|
||||
from itertools import chain
|
||||
|
||||
from zmq import EVENTS, POLLOUT, POLLIN
|
||||
import zmq as _zmq
|
||||
|
||||
_FutureEvent = namedtuple('_FutureEvent', ('future', 'kind', 'kwargs', 'msg'))
|
||||
|
||||
# These are incomplete classes and need a Mixin for compatibility with an eventloop
|
||||
# defining the followig attributes:
|
||||
#
|
||||
# _Future
|
||||
# _READ
|
||||
# _WRITE
|
||||
# _default_loop()
|
||||
|
||||
|
||||
class _AsyncPoller(_zmq.Poller):
|
||||
"""Poller that returns a Future on poll, instead of blocking."""
|
||||
|
||||
def poll(self, timeout=-1):
|
||||
"""Return a Future for a poll event"""
|
||||
future = self._Future()
|
||||
if timeout == 0:
|
||||
try:
|
||||
result = super(_AsyncPoller, self).poll(0)
|
||||
except Exception as e:
|
||||
future.set_exception(e)
|
||||
else:
|
||||
future.set_result(result)
|
||||
return future
|
||||
|
||||
loop = self._default_loop()
|
||||
|
||||
# register Future to be called as soon as any event is available on any socket
|
||||
watcher = self._Future()
|
||||
|
||||
# watch raw sockets:
|
||||
raw_sockets = []
|
||||
def wake_raw(*args):
|
||||
if not watcher.done():
|
||||
watcher.set_result(None)
|
||||
|
||||
watcher.add_done_callback(lambda f: self._unwatch_raw_sockets(loop, *raw_sockets))
|
||||
|
||||
for socket, mask in self.sockets:
|
||||
if isinstance(socket, _zmq.Socket):
|
||||
if not isinstance(socket, self._socket_class):
|
||||
# it's a blocking zmq.Socket, wrap it in async
|
||||
socket = self._socket_class.from_socket(socket)
|
||||
if mask & _zmq.POLLIN:
|
||||
socket._add_recv_event('poll', future=watcher)
|
||||
if mask & _zmq.POLLOUT:
|
||||
socket._add_send_event('poll', future=watcher)
|
||||
else:
|
||||
raw_sockets.append(socket)
|
||||
evt = 0
|
||||
if mask & _zmq.POLLIN:
|
||||
evt |= self._READ
|
||||
if mask & _zmq.POLLOUT:
|
||||
evt |= self._WRITE
|
||||
self._watch_raw_socket(loop, socket, evt, wake_raw)
|
||||
|
||||
def on_poll_ready(f):
|
||||
if future.done():
|
||||
return
|
||||
if watcher.cancelled():
|
||||
try:
|
||||
future.cancel()
|
||||
except RuntimeError:
|
||||
# RuntimeError may be called during teardown
|
||||
pass
|
||||
return
|
||||
if watcher.exception():
|
||||
future.set_exception(watcher.exception())
|
||||
else:
|
||||
try:
|
||||
result = super(_AsyncPoller, self).poll(0)
|
||||
except Exception as e:
|
||||
future.set_exception(e)
|
||||
else:
|
||||
future.set_result(result)
|
||||
watcher.add_done_callback(on_poll_ready)
|
||||
|
||||
if timeout is not None and timeout > 0:
|
||||
# schedule cancel to fire on poll timeout, if any
|
||||
def trigger_timeout():
|
||||
if not watcher.done():
|
||||
watcher.set_result(None)
|
||||
|
||||
timeout_handle = loop.call_later(
|
||||
1e-3 * timeout,
|
||||
trigger_timeout
|
||||
)
|
||||
def cancel_timeout(f):
|
||||
if hasattr(timeout_handle, 'cancel'):
|
||||
timeout_handle.cancel()
|
||||
else:
|
||||
loop.remove_timeout(timeout_handle)
|
||||
future.add_done_callback(cancel_timeout)
|
||||
|
||||
def cancel_watcher(f):
|
||||
if not watcher.done():
|
||||
watcher.cancel()
|
||||
future.add_done_callback(cancel_watcher)
|
||||
|
||||
return future
|
||||
|
||||
|
||||
class _AsyncSocket(_zmq.Socket):
|
||||
|
||||
|
||||
# Warning : these class variables are only here to allow to call super().__setattr__.
|
||||
# They be overridden at instance initialization and not shared in the whole class
|
||||
_recv_futures = None
|
||||
_send_futures = None
|
||||
_state = 0
|
||||
_shadow_sock = None
|
||||
_poller_class = _AsyncPoller
|
||||
io_loop = None
|
||||
_fd = None
|
||||
|
||||
def __init__(self, context=None, socket_type=-1, io_loop=None, **kwargs):
|
||||
if isinstance(context, _zmq.Socket):
|
||||
context, from_socket = (None, context)
|
||||
else:
|
||||
from_socket = kwargs.pop('_from_socket', None)
|
||||
if from_socket is not None:
|
||||
super(_AsyncSocket, self).__init__(shadow=from_socket.underlying)
|
||||
self._shadow_sock = from_socket
|
||||
else:
|
||||
super(_AsyncSocket, self).__init__(context, socket_type, **kwargs)
|
||||
self._shadow_sock = _zmq.Socket.shadow(self.underlying)
|
||||
self.io_loop = io_loop or self._default_loop()
|
||||
self._recv_futures = deque()
|
||||
self._send_futures = deque()
|
||||
self._state = 0
|
||||
self._fd = self._shadow_sock.FD
|
||||
self._init_io_state()
|
||||
|
||||
@classmethod
|
||||
def from_socket(cls, socket, io_loop=None):
|
||||
"""Create an async socket from an existing Socket"""
|
||||
return cls(_from_socket=socket, io_loop=io_loop)
|
||||
|
||||
def close(self, linger=None):
|
||||
if not self.closed:
|
||||
for event in list(chain(self._recv_futures, self._send_futures)):
|
||||
if not event.future.done():
|
||||
try:
|
||||
event.future.cancel()
|
||||
except RuntimeError:
|
||||
# RuntimeError may be called during teardown
|
||||
pass
|
||||
self._clear_io_state()
|
||||
super(_AsyncSocket, self).close(linger=linger)
|
||||
close.__doc__ = _zmq.Socket.close.__doc__
|
||||
|
||||
def get(self, key):
|
||||
result = super(_AsyncSocket, self).get(key)
|
||||
if key == EVENTS:
|
||||
self._schedule_remaining_events(result)
|
||||
return result
|
||||
get.__doc__ = _zmq.Socket.get.__doc__
|
||||
|
||||
def recv_multipart(self, flags=0, copy=True, track=False):
|
||||
"""Receive a complete multipart zmq message.
|
||||
|
||||
Returns a Future whose result will be a multipart message.
|
||||
"""
|
||||
return self._add_recv_event('recv_multipart',
|
||||
dict(flags=flags, copy=copy, track=track)
|
||||
)
|
||||
|
||||
def recv(self, flags=0, copy=True, track=False):
|
||||
"""Receive a single zmq frame.
|
||||
|
||||
Returns a Future, whose result will be the received frame.
|
||||
|
||||
Recommend using recv_multipart instead.
|
||||
"""
|
||||
return self._add_recv_event('recv',
|
||||
dict(flags=flags, copy=copy, track=track)
|
||||
)
|
||||
|
||||
def send_multipart(self, msg, flags=0, copy=True, track=False, **kwargs):
|
||||
"""Send a complete multipart zmq message.
|
||||
|
||||
Returns a Future that resolves when sending is complete.
|
||||
"""
|
||||
kwargs['flags'] = flags
|
||||
kwargs['copy'] = copy
|
||||
kwargs['track'] = track
|
||||
return self._add_send_event('send_multipart', msg=msg, kwargs=kwargs)
|
||||
|
||||
def send(self, msg, flags=0, copy=True, track=False, **kwargs):
|
||||
"""Send a single zmq frame.
|
||||
|
||||
Returns a Future that resolves when sending is complete.
|
||||
|
||||
Recommend using send_multipart instead.
|
||||
"""
|
||||
kwargs['flags'] = flags
|
||||
kwargs['copy'] = copy
|
||||
kwargs['track'] = track
|
||||
kwargs.update(dict(flags=flags, copy=copy, track=track))
|
||||
return self._add_send_event('send', msg=msg, kwargs=kwargs)
|
||||
|
||||
def _deserialize(self, recvd, load):
|
||||
"""Deserialize with Futures"""
|
||||
f = self._Future()
|
||||
def _chain(_):
|
||||
"""Chain result through serialization to recvd"""
|
||||
if f.done():
|
||||
return
|
||||
if recvd.exception():
|
||||
f.set_exception(recvd.exception())
|
||||
else:
|
||||
buf = recvd.result()
|
||||
try:
|
||||
loaded = load(buf)
|
||||
except Exception as e:
|
||||
f.set_exception(e)
|
||||
else:
|
||||
f.set_result(loaded)
|
||||
recvd.add_done_callback(_chain)
|
||||
|
||||
def _chain_cancel(_):
|
||||
"""Chain cancellation from f to recvd"""
|
||||
if recvd.done():
|
||||
return
|
||||
if f.cancelled():
|
||||
recvd.cancel()
|
||||
f.add_done_callback(_chain_cancel)
|
||||
|
||||
return f
|
||||
|
||||
def poll(self, timeout=None, flags=_zmq.POLLIN):
|
||||
"""poll the socket for events
|
||||
|
||||
returns a Future for the poll results.
|
||||
"""
|
||||
|
||||
if self.closed:
|
||||
raise _zmq.ZMQError(_zmq.ENOTSUP)
|
||||
|
||||
p = self._poller_class()
|
||||
p.register(self, flags)
|
||||
f = p.poll(timeout)
|
||||
|
||||
future = self._Future()
|
||||
def unwrap_result(f):
|
||||
if future.done():
|
||||
return
|
||||
if f.cancelled():
|
||||
try:
|
||||
future.cancel()
|
||||
except RuntimeError:
|
||||
# RuntimeError may be called during teardown
|
||||
pass
|
||||
return
|
||||
if f.exception():
|
||||
future.set_exception(f.exception())
|
||||
else:
|
||||
evts = dict(f.result())
|
||||
future.set_result(evts.get(self, 0))
|
||||
|
||||
if f.done():
|
||||
# hook up result if
|
||||
unwrap_result(f)
|
||||
else:
|
||||
f.add_done_callback(unwrap_result)
|
||||
return future
|
||||
|
||||
def _add_timeout(self, future, timeout):
|
||||
"""Add a timeout for a send or recv Future"""
|
||||
def future_timeout():
|
||||
if future.done():
|
||||
# future already resolved, do nothing
|
||||
return
|
||||
|
||||
# raise EAGAIN
|
||||
future.set_exception(_zmq.Again())
|
||||
self._call_later(timeout, future_timeout)
|
||||
|
||||
def _call_later(self, delay, callback):
|
||||
"""Schedule a function to be called later
|
||||
|
||||
Override for different IOLoop implementations
|
||||
|
||||
Tornado and asyncio happen to both have ioloop.call_later
|
||||
with the same signature.
|
||||
"""
|
||||
self.io_loop.call_later(delay, callback)
|
||||
|
||||
@staticmethod
|
||||
def _remove_finished_future(future, event_list):
|
||||
"""Make sure that futures are removed from the event list when they resolve
|
||||
|
||||
Avoids delaying cleanup until the next send/recv event,
|
||||
which may never come.
|
||||
"""
|
||||
for f_idx, (f, kind, kwargs, _) in enumerate(event_list):
|
||||
if f is future:
|
||||
break
|
||||
else:
|
||||
return
|
||||
|
||||
# "future" instance is shared between sockets, but each socket has its own event list.
|
||||
event_list.remove(event_list[f_idx])
|
||||
|
||||
def _add_recv_event(self, kind, kwargs=None, future=None):
|
||||
"""Add a recv event, returning the corresponding Future"""
|
||||
f = future or self._Future()
|
||||
if kind.startswith('recv') and kwargs.get('flags', 0) & _zmq.DONTWAIT:
|
||||
# short-circuit non-blocking calls
|
||||
recv = getattr(self._shadow_sock, kind)
|
||||
try:
|
||||
r = recv(**kwargs)
|
||||
except Exception as e:
|
||||
f.set_exception(e)
|
||||
else:
|
||||
f.set_result(r)
|
||||
return f
|
||||
|
||||
# we add it to the list of futures before we add the timeout as the
|
||||
# timeout will remove the future from recv_futures to avoid leaks
|
||||
self._recv_futures.append(
|
||||
_FutureEvent(f, kind, kwargs, msg=None)
|
||||
)
|
||||
|
||||
# Don't let the Future sit in _recv_events after it's done
|
||||
f.add_done_callback(lambda f: self._remove_finished_future(f, self._recv_futures))
|
||||
|
||||
if hasattr(_zmq, 'RCVTIMEO'):
|
||||
timeout_ms = self._shadow_sock.rcvtimeo
|
||||
if timeout_ms >= 0:
|
||||
self._add_timeout(f, timeout_ms * 1e-3)
|
||||
|
||||
if self._shadow_sock.get(EVENTS) & POLLIN:
|
||||
# recv immediately, if we can
|
||||
self._handle_recv()
|
||||
if self._recv_futures:
|
||||
self._add_io_state(POLLIN)
|
||||
return f
|
||||
|
||||
def _add_send_event(self, kind, msg=None, kwargs=None, future=None):
|
||||
"""Add a send event, returning the corresponding Future"""
|
||||
f = future or self._Future()
|
||||
# attempt send with DONTWAIT if no futures are waiting
|
||||
# short-circuit for sends that will resolve immediately
|
||||
# only call if no send Futures are waiting
|
||||
if (
|
||||
kind in ('send', 'send_multipart')
|
||||
and not self._send_futures
|
||||
):
|
||||
flags = kwargs.get('flags', 0)
|
||||
nowait_kwargs = kwargs.copy()
|
||||
nowait_kwargs['flags'] = flags | _zmq.DONTWAIT
|
||||
|
||||
# short-circuit non-blocking calls
|
||||
send = getattr(self._shadow_sock, kind)
|
||||
# track if the send resolved or not
|
||||
# (EAGAIN if DONTWAIT is not set should proceed with)
|
||||
finish_early = True
|
||||
try:
|
||||
r = send(msg, **nowait_kwargs)
|
||||
except _zmq.Again as e:
|
||||
if flags & _zmq.DONTWAIT:
|
||||
f.set_exception(e)
|
||||
else:
|
||||
# EAGAIN raised and DONTWAIT not requested,
|
||||
# proceed with async send
|
||||
finish_early = False
|
||||
except Exception as e:
|
||||
f.set_exception(e)
|
||||
else:
|
||||
f.set_result(r)
|
||||
|
||||
if finish_early:
|
||||
# short-circuit resolved, return finished Future
|
||||
# schedule wake for recv if there are any receivers waiting
|
||||
if self._recv_futures:
|
||||
self._schedule_remaining_events()
|
||||
return f
|
||||
|
||||
# we add it to the list of futures before we add the timeout as the
|
||||
# timeout will remove the future from recv_futures to avoid leaks
|
||||
self._send_futures.append(
|
||||
_FutureEvent(f, kind, kwargs=kwargs, msg=msg)
|
||||
)
|
||||
# Don't let the Future sit in _send_futures after it's done
|
||||
f.add_done_callback(lambda f: self._remove_finished_future(f, self._send_futures))
|
||||
|
||||
if hasattr(_zmq, 'SNDTIMEO'):
|
||||
timeout_ms = self._shadow_sock.get(_zmq.SNDTIMEO)
|
||||
if timeout_ms >= 0:
|
||||
self._add_timeout(f, timeout_ms * 1e-3)
|
||||
|
||||
self._add_io_state(POLLOUT)
|
||||
return f
|
||||
|
||||
def _handle_recv(self):
|
||||
"""Handle recv events"""
|
||||
if not self._shadow_sock.get(EVENTS) & POLLIN:
|
||||
# event triggered, but state may have been changed between trigger and callback
|
||||
return
|
||||
f = None
|
||||
while self._recv_futures:
|
||||
f, kind, kwargs, _ = self._recv_futures.popleft()
|
||||
# skip any cancelled futures
|
||||
if f.done():
|
||||
f = None
|
||||
else:
|
||||
break
|
||||
|
||||
if not self._recv_futures:
|
||||
self._drop_io_state(POLLIN)
|
||||
|
||||
if f is None:
|
||||
return
|
||||
|
||||
if kind == 'poll':
|
||||
# on poll event, just signal ready, nothing else.
|
||||
f.set_result(None)
|
||||
return
|
||||
elif kind == 'recv_multipart':
|
||||
recv = self._shadow_sock.recv_multipart
|
||||
elif kind == 'recv':
|
||||
recv = self._shadow_sock.recv
|
||||
else:
|
||||
raise ValueError("Unhandled recv event type: %r" % kind)
|
||||
|
||||
kwargs['flags'] |= _zmq.DONTWAIT
|
||||
try:
|
||||
result = recv(**kwargs)
|
||||
except Exception as e:
|
||||
f.set_exception(e)
|
||||
else:
|
||||
f.set_result(result)
|
||||
|
||||
def _handle_send(self):
|
||||
if not self._shadow_sock.get(EVENTS) & POLLOUT:
|
||||
# event triggered, but state may have been changed between trigger and callback
|
||||
return
|
||||
f = None
|
||||
while self._send_futures:
|
||||
f, kind, kwargs, msg = self._send_futures.popleft()
|
||||
# skip any cancelled futures
|
||||
if f.done():
|
||||
f = None
|
||||
else:
|
||||
break
|
||||
|
||||
if not self._send_futures:
|
||||
self._drop_io_state(POLLOUT)
|
||||
|
||||
if f is None:
|
||||
return
|
||||
|
||||
if kind == 'poll':
|
||||
# on poll event, just signal ready, nothing else.
|
||||
f.set_result(None)
|
||||
return
|
||||
elif kind == 'send_multipart':
|
||||
send = self._shadow_sock.send_multipart
|
||||
elif kind == 'send':
|
||||
send = self._shadow_sock.send
|
||||
else:
|
||||
raise ValueError("Unhandled send event type: %r" % kind)
|
||||
|
||||
kwargs['flags'] |= _zmq.DONTWAIT
|
||||
try:
|
||||
result = send(msg, **kwargs)
|
||||
except Exception as e:
|
||||
f.set_exception(e)
|
||||
else:
|
||||
f.set_result(result)
|
||||
|
||||
# event masking from ZMQStream
|
||||
def _handle_events(self, fd=0, events=0):
|
||||
"""Dispatch IO events to _handle_recv, etc."""
|
||||
zmq_events = self._shadow_sock.get(EVENTS)
|
||||
if zmq_events & _zmq.POLLIN:
|
||||
self._handle_recv()
|
||||
if zmq_events & _zmq.POLLOUT:
|
||||
self._handle_send()
|
||||
self._schedule_remaining_events()
|
||||
|
||||
def _schedule_remaining_events(self, events=None):
|
||||
"""Schedule a call to handle_events next loop iteration
|
||||
|
||||
If there are still events to handle.
|
||||
"""
|
||||
# edge-triggered handling
|
||||
# allow passing events in, in case this is triggered by retrieving events,
|
||||
# so we don't have to retrieve it twice.
|
||||
if self._state == 0:
|
||||
# not watching for anything, nothing to schedule
|
||||
return
|
||||
if events is None:
|
||||
events = self._shadow_sock.get(EVENTS)
|
||||
if events & self._state:
|
||||
self._call_later(0, self._handle_events)
|
||||
|
||||
def _add_io_state(self, state):
|
||||
"""Add io_state to poller."""
|
||||
if self._state != 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.
|
||||
|
||||
zmq FD is always read-only.
|
||||
"""
|
||||
self._schedule_remaining_events()
|
||||
|
||||
def _init_io_state(self):
|
||||
"""initialize the ioloop event handler"""
|
||||
self.io_loop.add_handler(self._shadow_sock, self._handle_events, self._READ)
|
||||
self._call_later(0, self._handle_events)
|
||||
|
||||
def _clear_io_state(self):
|
||||
"""unregister the ioloop event handler
|
||||
|
||||
called once during close
|
||||
"""
|
||||
fd = self._shadow_sock
|
||||
if self._shadow_sock.closed:
|
||||
fd = self._fd
|
||||
self.io_loop.remove_handler(fd)
|
||||
|
||||
|
105
venv/Lib/site-packages/zmq/asyncio/__init__.py
Normal file
105
venv/Lib/site-packages/zmq/asyncio/__init__.py
Normal file
|
@ -0,0 +1,105 @@
|
|||
"""AsyncIO support for zmq
|
||||
|
||||
Requires asyncio and Python 3.
|
||||
"""
|
||||
|
||||
# Copyright (c) PyZMQ Developers.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import zmq as _zmq
|
||||
from zmq import _future
|
||||
|
||||
# TODO: support trollius for Legacy Python? (probably not)
|
||||
|
||||
import asyncio
|
||||
from asyncio import SelectorEventLoop, Future
|
||||
try:
|
||||
import selectors
|
||||
except ImportError:
|
||||
from asyncio import selectors # py33
|
||||
|
||||
|
||||
class _AsyncIO(object):
|
||||
_Future = Future
|
||||
_WRITE = selectors.EVENT_WRITE
|
||||
_READ = selectors.EVENT_READ
|
||||
|
||||
def _default_loop(self):
|
||||
return asyncio.get_event_loop()
|
||||
|
||||
class Poller(_AsyncIO, _future._AsyncPoller):
|
||||
"""Poller returning asyncio.Future for poll results."""
|
||||
def _watch_raw_socket(self, loop, socket, evt, f):
|
||||
"""Schedule callback for a raw socket"""
|
||||
if evt & self._READ:
|
||||
loop.add_reader(socket, lambda *args: f())
|
||||
if evt & self._WRITE:
|
||||
loop.add_writer(socket, lambda *args: f())
|
||||
|
||||
def _unwatch_raw_sockets(self, loop, *sockets):
|
||||
"""Unschedule callback for a raw socket"""
|
||||
for socket in sockets:
|
||||
loop.remove_reader(socket)
|
||||
loop.remove_writer(socket)
|
||||
|
||||
|
||||
class Socket(_AsyncIO, _future._AsyncSocket):
|
||||
"""Socket returning asyncio Futures for send/recv/poll methods."""
|
||||
|
||||
_poller_class = Poller
|
||||
|
||||
def _init_io_state(self):
|
||||
"""initialize the ioloop event handler"""
|
||||
self.io_loop.add_reader(self._fd, lambda : self._handle_events(0, 0))
|
||||
|
||||
def _clear_io_state(self):
|
||||
"""clear any ioloop event handler
|
||||
|
||||
called once at close
|
||||
"""
|
||||
self.io_loop.remove_reader(self._fd)
|
||||
|
||||
Poller._socket_class = Socket
|
||||
|
||||
class Context(_zmq.Context):
|
||||
"""Context for creating asyncio-compatible Sockets"""
|
||||
_socket_class = Socket
|
||||
|
||||
# avoid sharing instance with base Context class
|
||||
_instance = None
|
||||
|
||||
|
||||
class ZMQEventLoop(SelectorEventLoop):
|
||||
"""DEPRECATED: AsyncIO eventloop using zmq_poll.
|
||||
|
||||
pyzmq sockets should work with any asyncio event loop as of pyzmq 17.
|
||||
"""
|
||||
def __init__(self, selector=None):
|
||||
_deprecated()
|
||||
return super(ZMQEventLoop, self).__init__(selector)
|
||||
|
||||
|
||||
_loop = None
|
||||
|
||||
|
||||
def _deprecated():
|
||||
if _deprecated.called:
|
||||
return
|
||||
_deprecated.called = True
|
||||
import warnings
|
||||
warnings.warn("ZMQEventLoop and zmq.asyncio.install are deprecated in pyzmq 17. Special eventloop integration is no longer needed.", DeprecationWarning, stacklevel=3)
|
||||
_deprecated.called = False
|
||||
|
||||
|
||||
def install():
|
||||
"""DEPRECATED: No longer needed in pyzmq 17"""
|
||||
_deprecated()
|
||||
|
||||
|
||||
__all__ = [
|
||||
'Context',
|
||||
'Socket',
|
||||
'Poller',
|
||||
'ZMQEventLoop',
|
||||
'install',
|
||||
]
|
Binary file not shown.
11
venv/Lib/site-packages/zmq/auth/__init__.py
Normal file
11
venv/Lib/site-packages/zmq/auth/__init__.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
"""Utilities for ZAP authentication.
|
||||
|
||||
To run authentication in a background thread, see :mod:`zmq.auth.thread`.
|
||||
For integration with the tornado eventloop, see :mod:`zmq.auth.ioloop`.
|
||||
For integration with the asyncio event loop, see :mod:`zmq.auth.asyncio`.
|
||||
|
||||
.. versionadded:: 14.1
|
||||
"""
|
||||
|
||||
from .base import *
|
||||
from .certs import *
|
Binary file not shown.
BIN
venv/Lib/site-packages/zmq/auth/__pycache__/base.cpython-36.pyc
Normal file
BIN
venv/Lib/site-packages/zmq/auth/__pycache__/base.cpython-36.pyc
Normal file
Binary file not shown.
BIN
venv/Lib/site-packages/zmq/auth/__pycache__/certs.cpython-36.pyc
Normal file
BIN
venv/Lib/site-packages/zmq/auth/__pycache__/certs.cpython-36.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
50
venv/Lib/site-packages/zmq/auth/asyncio/__init__.py
Normal file
50
venv/Lib/site-packages/zmq/auth/asyncio/__init__.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
"""ZAP Authenticator integrated with the asyncio IO loop.
|
||||
|
||||
.. versionadded:: 15.2
|
||||
"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import asyncio
|
||||
|
||||
import zmq
|
||||
from zmq.asyncio import Poller
|
||||
from ..base import Authenticator
|
||||
|
||||
|
||||
class AsyncioAuthenticator(Authenticator):
|
||||
"""ZAP authentication for use in the asyncio IO loop"""
|
||||
|
||||
def __init__(self, context=None, loop=None):
|
||||
super().__init__(context)
|
||||
self.loop = loop or asyncio.get_event_loop()
|
||||
self.__poller = None
|
||||
self.__task = None
|
||||
|
||||
@asyncio.coroutine
|
||||
def __handle_zap(self):
|
||||
while True:
|
||||
events = yield from self.__poller.poll()
|
||||
if self.zap_socket in dict(events):
|
||||
msg = yield from self.zap_socket.recv_multipart()
|
||||
self.handle_zap_message(msg)
|
||||
|
||||
def start(self):
|
||||
"""Start ZAP authentication"""
|
||||
super().start()
|
||||
self.__poller = Poller()
|
||||
self.__poller.register(self.zap_socket, zmq.POLLIN)
|
||||
self.__task = asyncio.ensure_future(self.__handle_zap())
|
||||
|
||||
def stop(self):
|
||||
"""Stop ZAP authentication"""
|
||||
if self.__task:
|
||||
self.__task.cancel()
|
||||
if self.__poller:
|
||||
self.__poller.unregister(self.zap_socket)
|
||||
self.__poller = None
|
||||
super().stop()
|
||||
|
||||
|
||||
__all__ = ['AsyncioAuthenticator']
|
Binary file not shown.
379
venv/Lib/site-packages/zmq/auth/base.py
Normal file
379
venv/Lib/site-packages/zmq/auth/base.py
Normal file
|
@ -0,0 +1,379 @@
|
|||
"""Base implementation of 0MQ authentication."""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import logging
|
||||
|
||||
import zmq
|
||||
from zmq.utils import z85
|
||||
from zmq.utils.strtypes import bytes, unicode, b, u
|
||||
from zmq.error import _check_version
|
||||
|
||||
from .certs import load_certificates
|
||||
|
||||
|
||||
CURVE_ALLOW_ANY = '*'
|
||||
VERSION = b'1.0'
|
||||
|
||||
class Authenticator(object):
|
||||
"""Implementation of ZAP authentication for zmq connections.
|
||||
|
||||
Note:
|
||||
|
||||
- libzmq provides four levels of security: default NULL (which the Authenticator does
|
||||
not see), and authenticated NULL, PLAIN, CURVE, and GSSAPI, which the Authenticator can see.
|
||||
- until you add policies, all incoming NULL connections are allowed.
|
||||
(classic ZeroMQ behavior), and all PLAIN and CURVE connections are denied.
|
||||
- GSSAPI requires no configuration.
|
||||
"""
|
||||
|
||||
def __init__(self, context=None, encoding='utf-8', log=None):
|
||||
_check_version((4,0), "security")
|
||||
self.context = context or zmq.Context.instance()
|
||||
self.encoding = encoding
|
||||
self.allow_any = False
|
||||
self.credentials_providers = {}
|
||||
self.zap_socket = None
|
||||
self.whitelist = set()
|
||||
self.blacklist = set()
|
||||
# passwords is a dict keyed by domain and contains values
|
||||
# of dicts with username:password pairs.
|
||||
self.passwords = {}
|
||||
# certs is dict keyed by domain and contains values
|
||||
# of dicts keyed by the public keys from the specified location.
|
||||
self.certs = {}
|
||||
self.log = log or logging.getLogger('zmq.auth')
|
||||
|
||||
def start(self):
|
||||
"""Create and bind the ZAP socket"""
|
||||
self.zap_socket = self.context.socket(zmq.REP)
|
||||
self.zap_socket.linger = 1
|
||||
self.zap_socket.bind("inproc://zeromq.zap.01")
|
||||
self.log.debug("Starting")
|
||||
|
||||
def stop(self):
|
||||
"""Close the ZAP socket"""
|
||||
if self.zap_socket:
|
||||
self.zap_socket.close()
|
||||
self.zap_socket = None
|
||||
|
||||
def allow(self, *addresses):
|
||||
"""Allow (whitelist) IP address(es).
|
||||
|
||||
Connections from addresses not in the whitelist will be rejected.
|
||||
|
||||
- For NULL, all clients from this address will be accepted.
|
||||
- For real auth setups, they will be allowed to continue with authentication.
|
||||
|
||||
whitelist is mutually exclusive with blacklist.
|
||||
"""
|
||||
if self.blacklist:
|
||||
raise ValueError("Only use a whitelist or a blacklist, not both")
|
||||
self.log.debug("Allowing %s", ','.join(addresses))
|
||||
self.whitelist.update(addresses)
|
||||
|
||||
def deny(self, *addresses):
|
||||
"""Deny (blacklist) IP address(es).
|
||||
|
||||
Addresses not in the blacklist will be allowed to continue with authentication.
|
||||
|
||||
Blacklist is mutually exclusive with whitelist.
|
||||
"""
|
||||
if self.whitelist:
|
||||
raise ValueError("Only use a whitelist or a blacklist, not both")
|
||||
self.log.debug("Denying %s", ','.join(addresses))
|
||||
self.blacklist.update(addresses)
|
||||
|
||||
def configure_plain(self, domain='*', passwords=None):
|
||||
"""Configure PLAIN authentication for a given domain.
|
||||
|
||||
PLAIN authentication uses a plain-text password file.
|
||||
To cover all domains, use "*".
|
||||
You can modify the password file at any time; it is reloaded automatically.
|
||||
"""
|
||||
if passwords:
|
||||
self.passwords[domain] = passwords
|
||||
self.log.debug("Configure plain: %s", domain)
|
||||
|
||||
def configure_curve(self, domain='*', location=None):
|
||||
"""Configure CURVE authentication for a given domain.
|
||||
|
||||
CURVE authentication uses a directory that holds all public client certificates,
|
||||
i.e. their public keys.
|
||||
|
||||
To cover all domains, use "*".
|
||||
|
||||
You can add and remove certificates in that directory at any time. configure_curve must be called
|
||||
every time certificates are added or removed, in order to update the Authenticator's state
|
||||
|
||||
To allow all client keys without checking, specify CURVE_ALLOW_ANY for the location.
|
||||
"""
|
||||
# If location is CURVE_ALLOW_ANY then allow all clients. Otherwise
|
||||
# treat location as a directory that holds the certificates.
|
||||
self.log.debug("Configure curve: %s[%s]", domain, location)
|
||||
if location == CURVE_ALLOW_ANY:
|
||||
self.allow_any = True
|
||||
else:
|
||||
self.allow_any = False
|
||||
try:
|
||||
self.certs[domain] = load_certificates(location)
|
||||
except Exception as e:
|
||||
self.log.error("Failed to load CURVE certs from %s: %s", location, e)
|
||||
|
||||
def configure_curve_callback(self, domain='*', credentials_provider=None):
|
||||
"""Configure CURVE authentication for a given domain.
|
||||
|
||||
CURVE authentication using a callback function validating
|
||||
the client public key according to a custom mechanism, e.g. checking the
|
||||
key against records in a db. credentials_provider is an object of a class which
|
||||
implements a callback method accepting two parameters (domain and key), e.g.::
|
||||
|
||||
class CredentialsProvider(object):
|
||||
|
||||
def __init__(self):
|
||||
...e.g. db connection
|
||||
|
||||
def callback(self, domain, key):
|
||||
valid = ...lookup key and/or domain in db
|
||||
if valid:
|
||||
logging.info('Authorizing: {0}, {1}'.format(domain, key))
|
||||
return True
|
||||
else:
|
||||
logging.warning('NOT Authorizing: {0}, {1}'.format(domain, key))
|
||||
return False
|
||||
|
||||
To cover all domains, use "*".
|
||||
|
||||
To allow all client keys without checking, specify CURVE_ALLOW_ANY for the location.
|
||||
"""
|
||||
|
||||
self.allow_any = False
|
||||
|
||||
if credentials_provider is not None:
|
||||
self.credentials_providers[domain] = credentials_provider
|
||||
else:
|
||||
self.log.error("None credentials_provider provided for domain:%s",domain)
|
||||
|
||||
def curve_user_id(self, client_public_key):
|
||||
"""Return the User-Id corresponding to a CURVE client's public key
|
||||
|
||||
Default implementation uses the z85-encoding of the public key.
|
||||
|
||||
Override to define a custom mapping of public key : user-id
|
||||
|
||||
This is only called on successful authentication.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
client_public_key: bytes
|
||||
The client public key used for the given message
|
||||
|
||||
Returns
|
||||
-------
|
||||
user_id: unicode
|
||||
The user ID as text
|
||||
"""
|
||||
return z85.encode(client_public_key).decode('ascii')
|
||||
|
||||
def configure_gssapi(self, domain='*', location=None):
|
||||
"""Configure GSSAPI authentication
|
||||
|
||||
Currently this is a no-op because there is nothing to configure with GSSAPI.
|
||||
"""
|
||||
pass
|
||||
|
||||
def handle_zap_message(self, msg):
|
||||
"""Perform ZAP authentication"""
|
||||
if len(msg) < 6:
|
||||
self.log.error("Invalid ZAP message, not enough frames: %r", msg)
|
||||
if len(msg) < 2:
|
||||
self.log.error("Not enough information to reply")
|
||||
else:
|
||||
self._send_zap_reply(msg[1], b"400", b"Not enough frames")
|
||||
return
|
||||
|
||||
version, request_id, domain, address, identity, mechanism = msg[:6]
|
||||
credentials = msg[6:]
|
||||
|
||||
domain = u(domain, self.encoding, 'replace')
|
||||
address = u(address, self.encoding, 'replace')
|
||||
|
||||
if (version != VERSION):
|
||||
self.log.error("Invalid ZAP version: %r", msg)
|
||||
self._send_zap_reply(request_id, b"400", b"Invalid version")
|
||||
return
|
||||
|
||||
self.log.debug("version: %r, request_id: %r, domain: %r,"
|
||||
" address: %r, identity: %r, mechanism: %r",
|
||||
version, request_id, domain,
|
||||
address, identity, mechanism,
|
||||
)
|
||||
|
||||
|
||||
# Is address is explicitly whitelisted or blacklisted?
|
||||
allowed = False
|
||||
denied = False
|
||||
reason = b"NO ACCESS"
|
||||
|
||||
if self.whitelist:
|
||||
if address in self.whitelist:
|
||||
allowed = True
|
||||
self.log.debug("PASSED (whitelist) address=%s", address)
|
||||
else:
|
||||
denied = True
|
||||
reason = b"Address not in whitelist"
|
||||
self.log.debug("DENIED (not in whitelist) address=%s", address)
|
||||
|
||||
elif self.blacklist:
|
||||
if address in self.blacklist:
|
||||
denied = True
|
||||
reason = b"Address is blacklisted"
|
||||
self.log.debug("DENIED (blacklist) address=%s", address)
|
||||
else:
|
||||
allowed = True
|
||||
self.log.debug("PASSED (not in blacklist) address=%s", address)
|
||||
|
||||
# Perform authentication mechanism-specific checks if necessary
|
||||
username = u("anonymous")
|
||||
if not denied:
|
||||
|
||||
if mechanism == b'NULL' and not allowed:
|
||||
# For NULL, we allow if the address wasn't blacklisted
|
||||
self.log.debug("ALLOWED (NULL)")
|
||||
allowed = True
|
||||
|
||||
elif mechanism == b'PLAIN':
|
||||
# For PLAIN, even a whitelisted address must authenticate
|
||||
if len(credentials) != 2:
|
||||
self.log.error("Invalid PLAIN credentials: %r", credentials)
|
||||
self._send_zap_reply(request_id, b"400", b"Invalid credentials")
|
||||
return
|
||||
username, password = [ u(c, self.encoding, 'replace') for c in credentials ]
|
||||
allowed, reason = self._authenticate_plain(domain, username, password)
|
||||
|
||||
elif mechanism == b'CURVE':
|
||||
# For CURVE, even a whitelisted address must authenticate
|
||||
if len(credentials) != 1:
|
||||
self.log.error("Invalid CURVE credentials: %r", credentials)
|
||||
self._send_zap_reply(request_id, b"400", b"Invalid credentials")
|
||||
return
|
||||
key = credentials[0]
|
||||
allowed, reason = self._authenticate_curve(domain, key)
|
||||
if allowed:
|
||||
username = self.curve_user_id(key)
|
||||
|
||||
elif mechanism == b'GSSAPI':
|
||||
if len(credentials) != 1:
|
||||
self.log.error("Invalid GSSAPI credentials: %r", credentials)
|
||||
self._send_zap_reply(request_id, b"400", b"Invalid credentials")
|
||||
return
|
||||
# use principal as user-id for now
|
||||
principal = username = credentials[0]
|
||||
allowed, reason = self._authenticate_gssapi(domain, principal)
|
||||
|
||||
if allowed:
|
||||
self._send_zap_reply(request_id, b"200", b"OK", username)
|
||||
else:
|
||||
self._send_zap_reply(request_id, b"400", reason)
|
||||
|
||||
def _authenticate_plain(self, domain, username, password):
|
||||
"""PLAIN ZAP authentication"""
|
||||
allowed = False
|
||||
reason = b""
|
||||
if self.passwords:
|
||||
# If no domain is not specified then use the default domain
|
||||
if not domain:
|
||||
domain = '*'
|
||||
|
||||
if domain in self.passwords:
|
||||
if username in self.passwords[domain]:
|
||||
if password == self.passwords[domain][username]:
|
||||
allowed = True
|
||||
else:
|
||||
reason = b"Invalid password"
|
||||
else:
|
||||
reason = b"Invalid username"
|
||||
else:
|
||||
reason = b"Invalid domain"
|
||||
|
||||
if allowed:
|
||||
self.log.debug("ALLOWED (PLAIN) domain=%s username=%s password=%s",
|
||||
domain, username, password,
|
||||
)
|
||||
else:
|
||||
self.log.debug("DENIED %s", reason)
|
||||
|
||||
else:
|
||||
reason = b"No passwords defined"
|
||||
self.log.debug("DENIED (PLAIN) %s", reason)
|
||||
|
||||
return allowed, reason
|
||||
|
||||
def _authenticate_curve(self, domain, client_key):
|
||||
"""CURVE ZAP authentication"""
|
||||
allowed = False
|
||||
reason = b""
|
||||
if self.allow_any:
|
||||
allowed = True
|
||||
reason = b"OK"
|
||||
self.log.debug("ALLOWED (CURVE allow any client)")
|
||||
elif self.credentials_providers != {}:
|
||||
# If no explicit domain is specified then use the default domain
|
||||
if not domain:
|
||||
domain = '*'
|
||||
|
||||
if domain in self.credentials_providers:
|
||||
z85_client_key = z85.encode(client_key)
|
||||
# Callback to check if key is Allowed
|
||||
if (self.credentials_providers[domain].callback(domain, z85_client_key)):
|
||||
allowed = True
|
||||
reason = b"OK"
|
||||
else:
|
||||
reason = b"Unknown key"
|
||||
|
||||
status = "ALLOWED" if allowed else "DENIED"
|
||||
self.log.debug("%s (CURVE auth_callback) domain=%s client_key=%s",
|
||||
status, domain, z85_client_key,
|
||||
)
|
||||
else:
|
||||
reason = b"Unknown domain"
|
||||
else:
|
||||
# If no explicit domain is specified then use the default domain
|
||||
if not domain:
|
||||
domain = '*'
|
||||
|
||||
if domain in self.certs:
|
||||
# The certs dict stores keys in z85 format, convert binary key to z85 bytes
|
||||
z85_client_key = z85.encode(client_key)
|
||||
if self.certs[domain].get(z85_client_key):
|
||||
allowed = True
|
||||
reason = b"OK"
|
||||
else:
|
||||
reason = b"Unknown key"
|
||||
|
||||
status = "ALLOWED" if allowed else "DENIED"
|
||||
self.log.debug("%s (CURVE) domain=%s client_key=%s",
|
||||
status, domain, z85_client_key,
|
||||
)
|
||||
else:
|
||||
reason = b"Unknown domain"
|
||||
|
||||
return allowed, reason
|
||||
|
||||
def _authenticate_gssapi(self, domain, principal):
|
||||
"""Nothing to do for GSSAPI, which has already been handled by an external service."""
|
||||
self.log.debug("ALLOWED (GSSAPI) domain=%s principal=%s", domain, principal)
|
||||
return True, b'OK'
|
||||
|
||||
def _send_zap_reply(self, request_id, status_code, status_text, user_id='anonymous'):
|
||||
"""Send a ZAP reply to finish the authentication."""
|
||||
user_id = user_id if status_code == b'200' else b''
|
||||
if isinstance(user_id, unicode):
|
||||
user_id = user_id.encode(self.encoding, 'replace')
|
||||
metadata = b'' # not currently used
|
||||
self.log.debug("ZAP reply code=%s text=%s", status_code, status_text)
|
||||
reply = [VERSION, request_id, status_code, status_text, user_id, metadata]
|
||||
self.zap_socket.send_multipart(reply)
|
||||
|
||||
__all__ = ['Authenticator', 'CURVE_ALLOW_ANY']
|
126
venv/Lib/site-packages/zmq/auth/certs.py
Normal file
126
venv/Lib/site-packages/zmq/auth/certs.py
Normal file
|
@ -0,0 +1,126 @@
|
|||
"""0MQ authentication related functions and classes."""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
import datetime
|
||||
import glob
|
||||
import io
|
||||
import os
|
||||
import zmq
|
||||
from zmq.utils.strtypes import bytes, unicode, b, u
|
||||
|
||||
|
||||
_cert_secret_banner = u("""# **** Generated on {0} by pyzmq ****
|
||||
# ZeroMQ CURVE **Secret** Certificate
|
||||
# DO NOT PROVIDE THIS FILE TO OTHER USERS nor change its permissions.
|
||||
|
||||
""")
|
||||
|
||||
_cert_public_banner = u("""# **** Generated on {0} by pyzmq ****
|
||||
# ZeroMQ CURVE Public Certificate
|
||||
# Exchange securely, or use a secure mechanism to verify the contents
|
||||
# of this file after exchange. Store public certificates in your home
|
||||
# directory, in the .curve subdirectory.
|
||||
|
||||
""")
|
||||
|
||||
def _write_key_file(key_filename, banner, public_key, secret_key=None, metadata=None, encoding='utf-8'):
|
||||
"""Create a certificate file"""
|
||||
if isinstance(public_key, bytes):
|
||||
public_key = public_key.decode(encoding)
|
||||
if isinstance(secret_key, bytes):
|
||||
secret_key = secret_key.decode(encoding)
|
||||
with io.open(key_filename, 'w', encoding='utf8') as f:
|
||||
f.write(banner.format(datetime.datetime.now()))
|
||||
|
||||
f.write(u('metadata\n'))
|
||||
if metadata:
|
||||
for k, v in metadata.items():
|
||||
if isinstance(k, bytes):
|
||||
k = k.decode(encoding)
|
||||
if isinstance(v, bytes):
|
||||
v = v.decode(encoding)
|
||||
f.write(u(" {0} = {1}\n").format(k, v))
|
||||
|
||||
f.write(u('curve\n'))
|
||||
f.write(u(" public-key = \"{0}\"\n").format(public_key))
|
||||
|
||||
if secret_key:
|
||||
f.write(u(" secret-key = \"{0}\"\n").format(secret_key))
|
||||
|
||||
|
||||
def create_certificates(key_dir, name, metadata=None):
|
||||
"""Create zmq certificates.
|
||||
|
||||
Returns the file paths to the public and secret certificate files.
|
||||
"""
|
||||
public_key, secret_key = zmq.curve_keypair()
|
||||
base_filename = os.path.join(key_dir, name)
|
||||
secret_key_file = "{0}.key_secret".format(base_filename)
|
||||
public_key_file = "{0}.key".format(base_filename)
|
||||
now = datetime.datetime.now()
|
||||
|
||||
_write_key_file(public_key_file,
|
||||
_cert_public_banner.format(now),
|
||||
public_key)
|
||||
|
||||
_write_key_file(secret_key_file,
|
||||
_cert_secret_banner.format(now),
|
||||
public_key,
|
||||
secret_key=secret_key,
|
||||
metadata=metadata)
|
||||
|
||||
return public_key_file, secret_key_file
|
||||
|
||||
|
||||
def load_certificate(filename):
|
||||
"""Load public and secret key from a zmq certificate.
|
||||
|
||||
Returns (public_key, secret_key)
|
||||
|
||||
If the certificate file only contains the public key,
|
||||
secret_key will be None.
|
||||
|
||||
If there is no public key found in the file, ValueError will be raised.
|
||||
"""
|
||||
public_key = None
|
||||
secret_key = None
|
||||
if not os.path.exists(filename):
|
||||
raise IOError("Invalid certificate file: {0}".format(filename))
|
||||
|
||||
with open(filename, 'rb') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line.startswith(b'#'):
|
||||
continue
|
||||
if line.startswith(b'public-key'):
|
||||
public_key = line.split(b"=", 1)[1].strip(b' \t\'"')
|
||||
if line.startswith(b'secret-key'):
|
||||
secret_key = line.split(b"=", 1)[1].strip(b' \t\'"')
|
||||
if public_key and secret_key:
|
||||
break
|
||||
|
||||
if public_key is None:
|
||||
raise ValueError("No public key found in %s" % filename)
|
||||
|
||||
return public_key, secret_key
|
||||
|
||||
|
||||
def load_certificates(directory='.'):
|
||||
"""Load public keys from all certificates in a directory"""
|
||||
certs = {}
|
||||
if not os.path.isdir(directory):
|
||||
raise IOError("Invalid certificate directory: {0}".format(directory))
|
||||
# Follow czmq pattern of public keys stored in *.key files.
|
||||
glob_string = os.path.join(directory, "*.key")
|
||||
|
||||
cert_files = glob.glob(glob_string)
|
||||
for cert_file in cert_files:
|
||||
public_key, _ = load_certificate(cert_file)
|
||||
if public_key:
|
||||
certs[public_key] = True
|
||||
return certs
|
||||
|
||||
__all__ = ['create_certificates', 'load_certificate', 'load_certificates']
|
35
venv/Lib/site-packages/zmq/auth/ioloop.py
Normal file
35
venv/Lib/site-packages/zmq/auth/ioloop.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
"""ZAP Authenticator integrated with the tornado IOLoop.
|
||||
|
||||
.. versionadded:: 14.1
|
||||
"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from tornado import ioloop
|
||||
from zmq.eventloop import zmqstream
|
||||
from .base import Authenticator
|
||||
|
||||
|
||||
class IOLoopAuthenticator(Authenticator):
|
||||
"""ZAP authentication for use in the tornado IOLoop"""
|
||||
|
||||
def __init__(self, context=None, encoding='utf-8', log=None, io_loop=None):
|
||||
super(IOLoopAuthenticator, self).__init__(context, encoding, log)
|
||||
self.zap_stream = None
|
||||
self.io_loop = io_loop or ioloop.IOLoop.current()
|
||||
|
||||
def start(self):
|
||||
"""Start ZAP authentication"""
|
||||
super(IOLoopAuthenticator, self).start()
|
||||
self.zap_stream = zmqstream.ZMQStream(self.zap_socket, self.io_loop)
|
||||
self.zap_stream.on_recv(self.handle_zap_message)
|
||||
|
||||
def stop(self):
|
||||
"""Stop ZAP authentication"""
|
||||
if self.zap_stream:
|
||||
self.zap_stream.close()
|
||||
self.zap_stream = None
|
||||
super(IOLoopAuthenticator, self).stop()
|
||||
|
||||
__all__ = ['IOLoopAuthenticator']
|
226
venv/Lib/site-packages/zmq/auth/thread.py
Normal file
226
venv/Lib/site-packages/zmq/auth/thread.py
Normal file
|
@ -0,0 +1,226 @@
|
|||
"""ZAP Authenticator in a Python Thread.
|
||||
|
||||
.. versionadded:: 14.1
|
||||
"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import time
|
||||
import logging
|
||||
from threading import Thread, Event
|
||||
|
||||
import zmq
|
||||
from zmq.utils import jsonapi
|
||||
from zmq.utils.strtypes import bytes, unicode, b, u
|
||||
import sys
|
||||
|
||||
from .base import Authenticator
|
||||
|
||||
class AuthenticationThread(Thread):
|
||||
"""A Thread for running a zmq Authenticator
|
||||
|
||||
This is run in the background by ThreadedAuthenticator
|
||||
"""
|
||||
|
||||
def __init__(self, context, endpoint, encoding='utf-8', log=None, authenticator=None):
|
||||
super(AuthenticationThread, self).__init__()
|
||||
self.context = context or zmq.Context.instance()
|
||||
self.encoding = encoding
|
||||
self.log = log = log or logging.getLogger('zmq.auth')
|
||||
self.started = Event()
|
||||
self.authenticator = authenticator or Authenticator(context, encoding=encoding, log=log)
|
||||
|
||||
# create a socket to communicate back to main thread.
|
||||
self.pipe = context.socket(zmq.PAIR)
|
||||
self.pipe.linger = 1
|
||||
self.pipe.connect(endpoint)
|
||||
|
||||
def run(self):
|
||||
"""Start the Authentication Agent thread task"""
|
||||
self.authenticator.start()
|
||||
self.started.set()
|
||||
zap = self.authenticator.zap_socket
|
||||
poller = zmq.Poller()
|
||||
poller.register(self.pipe, zmq.POLLIN)
|
||||
poller.register(zap, zmq.POLLIN)
|
||||
while True:
|
||||
try:
|
||||
socks = dict(poller.poll())
|
||||
except zmq.ZMQError:
|
||||
break # interrupted
|
||||
|
||||
if self.pipe in socks and socks[self.pipe] == zmq.POLLIN:
|
||||
# Make sure all API requests are processed before
|
||||
# looking at the ZAP socket.
|
||||
while True:
|
||||
try:
|
||||
msg = self.pipe.recv_multipart(flags=zmq.NOBLOCK)
|
||||
except zmq.Again:
|
||||
break
|
||||
|
||||
terminate = self._handle_pipe(msg)
|
||||
if terminate:
|
||||
break
|
||||
if terminate:
|
||||
break
|
||||
|
||||
if zap in socks and socks[zap] == zmq.POLLIN:
|
||||
self._handle_zap()
|
||||
|
||||
self.pipe.close()
|
||||
self.authenticator.stop()
|
||||
|
||||
def _handle_zap(self):
|
||||
"""
|
||||
Handle a message from the ZAP socket.
|
||||
"""
|
||||
msg = self.authenticator.zap_socket.recv_multipart()
|
||||
if not msg: return
|
||||
self.authenticator.handle_zap_message(msg)
|
||||
|
||||
def _handle_pipe(self, msg):
|
||||
"""
|
||||
Handle a message from front-end API.
|
||||
"""
|
||||
terminate = False
|
||||
|
||||
if msg is None:
|
||||
terminate = True
|
||||
return terminate
|
||||
|
||||
command = msg[0]
|
||||
self.log.debug("auth received API command %r", command)
|
||||
|
||||
if command == b'ALLOW':
|
||||
addresses = [u(m, self.encoding) for m in msg[1:]]
|
||||
try:
|
||||
self.authenticator.allow(*addresses)
|
||||
except Exception as e:
|
||||
self.log.exception("Failed to allow %s", addresses)
|
||||
|
||||
elif command == b'DENY':
|
||||
addresses = [u(m, self.encoding) for m in msg[1:]]
|
||||
try:
|
||||
self.authenticator.deny(*addresses)
|
||||
except Exception as e:
|
||||
self.log.exception("Failed to deny %s", addresses)
|
||||
|
||||
elif command == b'PLAIN':
|
||||
domain = u(msg[1], self.encoding)
|
||||
json_passwords = msg[2]
|
||||
self.authenticator.configure_plain(domain, jsonapi.loads(json_passwords))
|
||||
|
||||
elif command == b'CURVE':
|
||||
# For now we don't do anything with domains
|
||||
domain = u(msg[1], self.encoding)
|
||||
|
||||
# If location is CURVE_ALLOW_ANY, allow all clients. Otherwise
|
||||
# treat location as a directory that holds the certificates.
|
||||
location = u(msg[2], self.encoding)
|
||||
self.authenticator.configure_curve(domain, location)
|
||||
|
||||
elif command == b'TERMINATE':
|
||||
terminate = True
|
||||
|
||||
else:
|
||||
self.log.error("Invalid auth command from API: %r", command)
|
||||
|
||||
return terminate
|
||||
|
||||
def _inherit_docstrings(cls):
|
||||
"""inherit docstrings from Authenticator, so we don't duplicate them"""
|
||||
for name, method in cls.__dict__.items():
|
||||
if name.startswith('_') or not callable(method):
|
||||
continue
|
||||
upstream_method = getattr(Authenticator, name, None)
|
||||
if not method.__doc__:
|
||||
method.__doc__ = upstream_method.__doc__
|
||||
return cls
|
||||
|
||||
@_inherit_docstrings
|
||||
class ThreadAuthenticator(object):
|
||||
"""Run ZAP authentication in a background thread"""
|
||||
context = None
|
||||
log = None
|
||||
encoding = None
|
||||
pipe = None
|
||||
pipe_endpoint = ''
|
||||
thread = None
|
||||
auth = None
|
||||
|
||||
def __init__(self, context=None, encoding='utf-8', log=None):
|
||||
self.context = context or zmq.Context.instance()
|
||||
self.log = log
|
||||
self.encoding = encoding
|
||||
self.pipe = None
|
||||
self.pipe_endpoint = "inproc://{0}.inproc".format(id(self))
|
||||
self.thread = None
|
||||
|
||||
# proxy base Authenticator attributes
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
for obj in [self] + self.__class__.mro():
|
||||
if key in obj.__dict__:
|
||||
object.__setattr__(self, key, value)
|
||||
return
|
||||
setattr(self.thread.authenticator, key, value)
|
||||
|
||||
def __getattr__(self, key):
|
||||
try:
|
||||
object.__getattr__(self, key)
|
||||
except AttributeError:
|
||||
return getattr(self.thread.authenticator, key)
|
||||
|
||||
def allow(self, *addresses):
|
||||
self.pipe.send_multipart([b'ALLOW'] + [b(a, self.encoding) for a in addresses])
|
||||
|
||||
def deny(self, *addresses):
|
||||
self.pipe.send_multipart([b'DENY'] + [b(a, self.encoding) for a in addresses])
|
||||
|
||||
def configure_plain(self, domain='*', passwords=None):
|
||||
self.pipe.send_multipart([b'PLAIN', b(domain, self.encoding), jsonapi.dumps(passwords or {})])
|
||||
|
||||
def configure_curve(self, domain='*', location=''):
|
||||
domain = b(domain, self.encoding)
|
||||
location = b(location, self.encoding)
|
||||
self.pipe.send_multipart([b'CURVE', domain, location])
|
||||
|
||||
def configure_curve_callback(self, domain='*', credentials_provider=None):
|
||||
self.thread.authenticator.configure_curve_callback(domain, credentials_provider=credentials_provider)
|
||||
|
||||
def start(self):
|
||||
"""Start the authentication thread"""
|
||||
# create a socket to communicate with auth thread.
|
||||
self.pipe = self.context.socket(zmq.PAIR)
|
||||
self.pipe.linger = 1
|
||||
self.pipe.bind(self.pipe_endpoint)
|
||||
self.thread = AuthenticationThread(self.context, self.pipe_endpoint, encoding=self.encoding, log=self.log)
|
||||
self.thread.start()
|
||||
# Event.wait:Changed in version 2.7: Previously, the method always returned None.
|
||||
if sys.version_info < (2,7):
|
||||
self.thread.started.wait(timeout=10)
|
||||
else:
|
||||
if not self.thread.started.wait(timeout=10):
|
||||
raise RuntimeError("Authenticator thread failed to start")
|
||||
|
||||
def stop(self):
|
||||
"""Stop the authentication thread"""
|
||||
if self.pipe:
|
||||
self.pipe.send(b'TERMINATE')
|
||||
if self.is_alive():
|
||||
self.thread.join()
|
||||
self.thread = None
|
||||
self.pipe.close()
|
||||
self.pipe = None
|
||||
|
||||
def is_alive(self):
|
||||
"""Is the ZAP thread currently running?"""
|
||||
if self.thread and self.thread.is_alive():
|
||||
return True
|
||||
return False
|
||||
|
||||
def __del__(self):
|
||||
self.stop()
|
||||
|
||||
__all__ = ['ThreadAuthenticator']
|
44
venv/Lib/site-packages/zmq/backend/__init__.py
Normal file
44
venv/Lib/site-packages/zmq/backend/__init__.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
"""Import basic exposure of libzmq C API as a backend"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
|
||||
from .select import public_api, select_backend
|
||||
|
||||
if 'PYZMQ_BACKEND' in os.environ:
|
||||
backend = os.environ['PYZMQ_BACKEND']
|
||||
if backend in ('cython', 'cffi'):
|
||||
backend = 'zmq.backend.%s' % backend
|
||||
_ns = select_backend(backend)
|
||||
else:
|
||||
# default to cython, fallback to cffi
|
||||
# (reverse on PyPy)
|
||||
if platform.python_implementation() == 'PyPy':
|
||||
first, second = ('zmq.backend.cffi', 'zmq.backend.cython')
|
||||
else:
|
||||
first, second = ('zmq.backend.cython', 'zmq.backend.cffi')
|
||||
|
||||
try:
|
||||
_ns = select_backend(first)
|
||||
except Exception:
|
||||
exc_info = sys.exc_info()
|
||||
exc = exc_info[1]
|
||||
try:
|
||||
_ns = select_backend(second)
|
||||
except ImportError:
|
||||
# prevent 'During handling of the above exception...' on py3
|
||||
# can't use `raise ... from` on Python 2
|
||||
if hasattr(exc, '__cause__'):
|
||||
exc.__cause__ = None
|
||||
# raise the *first* error, not the fallback
|
||||
from zmq.utils.sixcerpt import reraise
|
||||
reraise(*exc_info)
|
||||
|
||||
globals().update(_ns)
|
||||
|
||||
__all__ = public_api
|
Binary file not shown.
Binary file not shown.
22
venv/Lib/site-packages/zmq/backend/cffi/__init__.py
Normal file
22
venv/Lib/site-packages/zmq/backend/cffi/__init__.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
"""CFFI backend (for PyPY)"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from zmq.backend.cffi import (constants, error, message, context, socket,
|
||||
_poll, devices, utils)
|
||||
|
||||
__all__ = []
|
||||
for submod in (constants, error, message, context, socket,
|
||||
_poll, devices, utils):
|
||||
__all__.extend(submod.__all__)
|
||||
|
||||
from .constants import *
|
||||
from .error import *
|
||||
from .message import *
|
||||
from .context import *
|
||||
from .socket import *
|
||||
from .devices import *
|
||||
from ._poll import *
|
||||
from ._cffi import zmq_version_info, ffi
|
||||
from .utils import *
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
70
venv/Lib/site-packages/zmq/backend/cffi/_cdefs.h
Normal file
70
venv/Lib/site-packages/zmq/backend/cffi/_cdefs.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
void zmq_version(int *major, int *minor, int *patch);
|
||||
|
||||
void* zmq_socket(void *context, int type);
|
||||
int zmq_close(void *socket);
|
||||
|
||||
int zmq_bind(void *socket, const char *endpoint);
|
||||
int zmq_connect(void *socket, const char *endpoint);
|
||||
|
||||
int zmq_errno(void);
|
||||
const char * zmq_strerror(int errnum);
|
||||
|
||||
int zmq_device(int device, void *frontend, void *backend);
|
||||
|
||||
int zmq_unbind(void *socket, const char *endpoint);
|
||||
int zmq_disconnect(void *socket, const char *endpoint);
|
||||
void* zmq_ctx_new();
|
||||
int zmq_ctx_destroy(void *context);
|
||||
int zmq_ctx_get(void *context, int opt);
|
||||
int zmq_ctx_set(void *context, int opt, int optval);
|
||||
int zmq_proxy(void *frontend, void *backend, void *capture);
|
||||
int zmq_proxy_steerable(void *frontend,
|
||||
void *backend,
|
||||
void *capture,
|
||||
void *control);
|
||||
int zmq_socket_monitor(void *socket, const char *addr, int events);
|
||||
|
||||
int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key);
|
||||
int zmq_curve_public (char *z85_public_key, char *z85_secret_key);
|
||||
int zmq_has (const char *capability);
|
||||
|
||||
typedef struct { ...; } zmq_msg_t;
|
||||
typedef ... zmq_free_fn;
|
||||
|
||||
int zmq_msg_init(zmq_msg_t *msg);
|
||||
int zmq_msg_init_size(zmq_msg_t *msg, size_t size);
|
||||
int zmq_msg_init_data(zmq_msg_t *msg,
|
||||
void *data,
|
||||
size_t size,
|
||||
zmq_free_fn *ffn,
|
||||
void *hint);
|
||||
|
||||
size_t zmq_msg_size(zmq_msg_t *msg);
|
||||
void *zmq_msg_data(zmq_msg_t *msg);
|
||||
int zmq_msg_close(zmq_msg_t *msg);
|
||||
|
||||
int zmq_msg_send(zmq_msg_t *msg, void *socket, int flags);
|
||||
int zmq_msg_recv(zmq_msg_t *msg, void *socket, int flags);
|
||||
|
||||
int zmq_getsockopt(void *socket,
|
||||
int option_name,
|
||||
void *option_value,
|
||||
size_t *option_len);
|
||||
|
||||
int zmq_setsockopt(void *socket,
|
||||
int option_name,
|
||||
const void *option_value,
|
||||
size_t option_len);
|
||||
typedef struct
|
||||
{
|
||||
void *socket;
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
} zmq_pollitem_t;
|
||||
|
||||
int zmq_poll(zmq_pollitem_t *items, int nitems, long timeout);
|
||||
|
||||
// miscellany
|
||||
void * memcpy(void *restrict s1, const void *restrict s2, size_t n);
|
||||
int get_ipc_path_max_len(void);
|
127
venv/Lib/site-packages/zmq/backend/cffi/_cffi.py
Normal file
127
venv/Lib/site-packages/zmq/backend/cffi/_cffi.py
Normal file
|
@ -0,0 +1,127 @@
|
|||
# coding: utf-8
|
||||
"""The main CFFI wrapping of libzmq"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
import json
|
||||
import os
|
||||
from os.path import dirname, join
|
||||
from cffi import FFI
|
||||
|
||||
from zmq.utils.constant_names import all_names, no_prefix
|
||||
|
||||
|
||||
base_zmq_version = (3,2,2)
|
||||
|
||||
def load_compiler_config():
|
||||
"""load pyzmq compiler arguments"""
|
||||
import zmq
|
||||
zmq_dir = dirname(zmq.__file__)
|
||||
zmq_parent = dirname(zmq_dir)
|
||||
|
||||
fname = join(zmq_dir, 'utils', 'compiler.json')
|
||||
if os.path.exists(fname):
|
||||
with open(fname) as f:
|
||||
cfg = json.load(f)
|
||||
else:
|
||||
cfg = {}
|
||||
|
||||
cfg.setdefault("include_dirs", [])
|
||||
cfg.setdefault("library_dirs", [])
|
||||
cfg.setdefault("runtime_library_dirs", [])
|
||||
cfg.setdefault("libraries", ["zmq"])
|
||||
|
||||
# cast to str, because cffi can't handle unicode paths (?!)
|
||||
cfg['libraries'] = [str(lib) for lib in cfg['libraries']]
|
||||
for key in ("include_dirs", "library_dirs", "runtime_library_dirs"):
|
||||
# interpret paths relative to parent of zmq (like source tree)
|
||||
abs_paths = []
|
||||
for p in cfg[key]:
|
||||
if p.startswith('zmq'):
|
||||
p = join(zmq_parent, p)
|
||||
abs_paths.append(str(p))
|
||||
cfg[key] = abs_paths
|
||||
return cfg
|
||||
|
||||
|
||||
def zmq_version_info():
|
||||
"""Get libzmq version as tuple of ints"""
|
||||
major = ffi.new('int*')
|
||||
minor = ffi.new('int*')
|
||||
patch = ffi.new('int*')
|
||||
|
||||
C.zmq_version(major, minor, patch)
|
||||
|
||||
return (int(major[0]), int(minor[0]), int(patch[0]))
|
||||
|
||||
|
||||
cfg = load_compiler_config()
|
||||
ffi = FFI()
|
||||
|
||||
def _make_defines(names):
|
||||
_names = []
|
||||
for name in names:
|
||||
define_line = "#define %s ..." % (name)
|
||||
_names.append(define_line)
|
||||
|
||||
return "\n".join(_names)
|
||||
|
||||
c_constant_names = ['PYZMQ_DRAFT_API']
|
||||
for name in all_names:
|
||||
if no_prefix(name):
|
||||
c_constant_names.append(name)
|
||||
else:
|
||||
c_constant_names.append("ZMQ_" + name)
|
||||
|
||||
# load ffi definitions
|
||||
here = os.path.dirname(__file__)
|
||||
with open(os.path.join(here, '_cdefs.h')) as f:
|
||||
_cdefs = f.read()
|
||||
|
||||
with open(os.path.join(here, '_verify.c')) as f:
|
||||
_verify = f.read()
|
||||
|
||||
ffi.cdef(_cdefs)
|
||||
ffi.cdef(_make_defines(c_constant_names))
|
||||
|
||||
try:
|
||||
C = ffi.verify(_verify,
|
||||
modulename='_cffi_ext',
|
||||
libraries=cfg['libraries'],
|
||||
include_dirs=cfg['include_dirs'],
|
||||
library_dirs=cfg['library_dirs'],
|
||||
runtime_library_dirs=cfg['runtime_library_dirs'],
|
||||
)
|
||||
_version_info = zmq_version_info()
|
||||
except Exception as e:
|
||||
raise ImportError("PyZMQ CFFI backend couldn't find zeromq: %s\n"
|
||||
"Please check that you have zeromq headers and libraries." % e)
|
||||
|
||||
if _version_info < (3,2,2):
|
||||
raise ImportError("PyZMQ CFFI backend requires zeromq >= 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()
|
80
venv/Lib/site-packages/zmq/backend/cffi/_poll.py
Normal file
80
venv/Lib/site-packages/zmq/backend/cffi/_poll.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
# coding: utf-8
|
||||
"""zmq poll function"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
try:
|
||||
from time import monotonic
|
||||
except ImportError:
|
||||
from time import clock as monotonic
|
||||
import warnings
|
||||
|
||||
from ._cffi import C, ffi
|
||||
from zmq.error import InterruptedSystemCall, _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 = {}
|
||||
from zmq import Socket
|
||||
for item in sockets:
|
||||
if isinstance(item[0], Socket):
|
||||
low_level_to_socket_obj[item[0]._zmq_socket] = item
|
||||
cffi_pollitem_list.append(_make_zmq_pollitem(item[0], item[1]))
|
||||
else:
|
||||
if not isinstance(item[0], int):
|
||||
# not an FD, get it from fileno()
|
||||
item = (item[0].fileno(), item[1])
|
||||
low_level_to_socket_obj[item[0]] = item
|
||||
cffi_pollitem_list.append(_make_zmq_pollitem_fromfd(item[0], item[1]))
|
||||
items = ffi.new('zmq_pollitem_t[]', cffi_pollitem_list)
|
||||
list_length = ffi.cast('int', len(cffi_pollitem_list))
|
||||
while True:
|
||||
c_timeout = ffi.cast('long', timeout)
|
||||
start = monotonic()
|
||||
rc = C.zmq_poll(items, list_length, c_timeout)
|
||||
try:
|
||||
_check_rc(rc)
|
||||
except InterruptedSystemCall:
|
||||
if timeout > 0:
|
||||
ms_passed = int(1000 * (monotonic() - start))
|
||||
if ms_passed < 0:
|
||||
# don't allow negative ms_passed,
|
||||
# which can happen on old Python versions without time.monotonic.
|
||||
warnings.warn(
|
||||
"Negative elapsed time for interrupted poll: %s."
|
||||
" Did the clock change?" % ms_passed,
|
||||
RuntimeWarning)
|
||||
ms_passed = 0
|
||||
timeout = max(0, timeout - ms_passed)
|
||||
continue
|
||||
else:
|
||||
break
|
||||
result = []
|
||||
for index in range(len(items)):
|
||||
if items[index].revents > 0:
|
||||
if not items[index].socket == ffi.NULL:
|
||||
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']
|
7
venv/Lib/site-packages/zmq/backend/cffi/_verify.c
Normal file
7
venv/Lib/site-packages/zmq/backend/cffi/_verify.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zmq.h>
|
||||
#include "zmq_compat.h"
|
||||
|
||||
#include "ipcmaxlen.h"
|
16
venv/Lib/site-packages/zmq/backend/cffi/constants.py
Normal file
16
venv/Lib/site-packages/zmq/backend/cffi/constants.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
# 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)
|
||||
|
||||
DRAFT_API = C.PYZMQ_DRAFT_API
|
||||
__all__ = ['DRAFT_API'] + all_names
|
77
venv/Lib/site-packages/zmq/backend/cffi/context.py
Normal file
77
venv/Lib/site-packages/zmq/backend/cffi/context.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
# coding: utf-8
|
||||
"""zmq Context class"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from ._cffi import C, ffi
|
||||
|
||||
from .constants import EINVAL, IO_THREADS, LINGER
|
||||
|
||||
from zmq.error import ZMQError, InterruptedSystemCall, _check_rc
|
||||
|
||||
class Context(object):
|
||||
_zmq_ctx = None
|
||||
_iothreads = None
|
||||
_closed = 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
|
||||
|
||||
@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 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
|
||||
|
||||
rc = C.zmq_ctx_destroy(self._zmq_ctx)
|
||||
try:
|
||||
_check_rc(rc)
|
||||
except InterruptedSystemCall:
|
||||
# ignore interrupted term
|
||||
# see PEP 475 notes about close & EINTR for why
|
||||
pass
|
||||
|
||||
self._zmq_ctx = None
|
||||
self._closed = True
|
||||
|
||||
__all__ = ['Context']
|
68
venv/Lib/site-packages/zmq/backend/cffi/devices.py
Normal file
68
venv/Lib/site-packages/zmq/backend/cffi/devices.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
# coding: utf-8
|
||||
"""zmq device functions"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from ._cffi import C, ffi
|
||||
from .socket import Socket
|
||||
from .utils import _retry_sys_call
|
||||
|
||||
|
||||
def device(device_type, frontend, backend):
|
||||
return proxy(frontend, backend)
|
||||
|
||||
|
||||
def proxy(frontend, backend, capture=None):
|
||||
if isinstance(capture, Socket):
|
||||
capture = capture._zmq_socket
|
||||
else:
|
||||
capture = ffi.NULL
|
||||
|
||||
_retry_sys_call(
|
||||
C.zmq_proxy,
|
||||
frontend._zmq_socket,
|
||||
backend._zmq_socket,
|
||||
capture
|
||||
)
|
||||
|
||||
|
||||
def proxy_steerable(frontend, backend, capture=None, control=None):
|
||||
"""proxy_steerable(frontend, backend, capture, control)
|
||||
|
||||
Start a zeromq proxy with control flow.
|
||||
|
||||
.. versionadded:: libzmq-4.1
|
||||
.. versionadded:: 18.0
|
||||
|
||||
Parameters
|
||||
----------
|
||||
frontend : Socket
|
||||
The Socket instance for the incoming traffic.
|
||||
backend : Socket
|
||||
The Socket instance for the outbound traffic.
|
||||
capture : Socket (optional)
|
||||
The Socket instance for capturing traffic.
|
||||
control : Socket (optional)
|
||||
The Socket instance for control flow.
|
||||
"""
|
||||
if isinstance(capture, Socket):
|
||||
capture = capture._zmq_socket
|
||||
else:
|
||||
capture = ffi.NULL
|
||||
|
||||
if isinstance(control, Socket):
|
||||
control = control._zmq_socket
|
||||
else:
|
||||
control = ffi.NULL
|
||||
|
||||
_retry_sys_call(
|
||||
C.zmq_proxy_steerable,
|
||||
frontend._zmq_socket,
|
||||
backend._zmq_socket,
|
||||
capture,
|
||||
control
|
||||
)
|
||||
|
||||
|
||||
__all__ = ['device', 'proxy', 'proxy_steerable']
|
17
venv/Lib/site-packages/zmq/backend/cffi/error.py
Normal file
17
venv/Lib/site-packages/zmq/backend/cffi/error.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
"""zmq error functions"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from ._cffi import C, ffi
|
||||
|
||||
def strerror(errno):
|
||||
s = ffi.string(C.zmq_strerror(errno))
|
||||
if not isinstance(s, str):
|
||||
# py3
|
||||
s = s.decode()
|
||||
return s
|
||||
|
||||
zmq_errno = C.zmq_errno
|
||||
|
||||
__all__ = ['strerror', 'zmq_errno']
|
64
venv/Lib/site-packages/zmq/backend/cffi/message.py
Normal file
64
venv/Lib/site-packages/zmq/backend/cffi/message.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
"""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
|
||||
|
||||
_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, copy=None, copy_threshold=None):
|
||||
try:
|
||||
memoryview(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._FINISHED_TRACKER
|
||||
|
||||
self.buffer = memoryview(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']
|
279
venv/Lib/site-packages/zmq/backend/cffi/socket.py
Normal file
279
venv/Lib/site-packages/zmq/backend/cffi/socket.py
Normal file
|
@ -0,0 +1,279 @@
|
|||
# coding: utf-8
|
||||
"""zmq Socket class"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
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 RCVMORE
|
||||
from .utils import _retry_sys_call
|
||||
|
||||
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
|
||||
copy_threshold = 0
|
||||
|
||||
def __init__(self, context=None, socket_type=None, shadow=None):
|
||||
self.context = context
|
||||
if shadow is not None:
|
||||
if isinstance(shadow, Socket):
|
||||
shadow = shadow.underlying
|
||||
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
|
||||
|
||||
@property
|
||||
def underlying(self):
|
||||
"""The address of the underlying libzmq socket"""
|
||||
return int(ffi.cast('size_t', self._zmq_socket))
|
||||
|
||||
def _check_closed_deep(self):
|
||||
"""thorough check of whether the socket has been closed,
|
||||
even if by another entity (e.g. ctx.destroy).
|
||||
|
||||
Only used by the `closed` property.
|
||||
|
||||
returns True if closed, False otherwise
|
||||
"""
|
||||
if self._closed:
|
||||
return True
|
||||
try:
|
||||
self.get(zmq.TYPE)
|
||||
except ZMQError as e:
|
||||
if e.errno == zmq.ENOTSOCK:
|
||||
self._closed = True
|
||||
return True
|
||||
else:
|
||||
raise
|
||||
return False
|
||||
|
||||
@property
|
||||
def closed(self):
|
||||
return self._check_closed_deep()
|
||||
|
||||
def close(self, linger=None):
|
||||
rc = 0
|
||||
if not self._closed and hasattr(self, '_zmq_socket'):
|
||||
if self._zmq_socket is not None:
|
||||
if linger is not None:
|
||||
self.set(zmq.LINGER, linger)
|
||||
rc = C.zmq_close(self._zmq_socket)
|
||||
self._closed = True
|
||||
if rc < 0:
|
||||
_check_rc(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)
|
||||
elif C.zmq_errno() == errno_mod.ENOENT:
|
||||
# py3compat: address is bytes, but msg wants str
|
||||
if str is unicode:
|
||||
address = address.decode('utf-8', 'replace')
|
||||
path = address.split('://', 1)[-1]
|
||||
msg = ('No such file or directory for ipc path "{0}".'.format(
|
||||
path))
|
||||
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]
|
||||
|
||||
_retry_sys_call(C.zmq_setsockopt,
|
||||
self._zmq_socket,
|
||||
option,
|
||||
ffi.cast('void*', c_value_pointer),
|
||||
c_sizet)
|
||||
|
||||
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]
|
||||
|
||||
_retry_sys_call(C.zmq_getsockopt,
|
||||
self._zmq_socket,
|
||||
option,
|
||||
c_value_pointer,
|
||||
c_sizet_pointer)
|
||||
|
||||
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*')
|
||||
if not isinstance(message, bytes):
|
||||
# cast any bufferable data to bytes via memoryview
|
||||
message = memoryview(message).tobytes()
|
||||
|
||||
c_message = ffi.new('char[]', message)
|
||||
rc = C.zmq_msg_init_size(zmq_msg, len(message))
|
||||
_check_rc(rc)
|
||||
C.memcpy(C.zmq_msg_data(zmq_msg), c_message, len(message))
|
||||
_retry_sys_call(C.zmq_msg_send, zmq_msg, self._zmq_socket, flags)
|
||||
rc2 = C.zmq_msg_close(zmq_msg)
|
||||
_check_rc(rc2)
|
||||
|
||||
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)
|
||||
|
||||
try:
|
||||
_retry_sys_call(C.zmq_msg_recv, zmq_msg, self._zmq_socket, flags)
|
||||
except Exception:
|
||||
C.zmq_msg_close(zmq_msg)
|
||||
raise
|
||||
|
||||
_buffer = ffi.buffer(C.zmq_msg_data(zmq_msg), C.zmq_msg_size(zmq_msg))
|
||||
value = _buffer[:]
|
||||
rc = C.zmq_msg_close(zmq_msg)
|
||||
_check_rc(rc)
|
||||
|
||||
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
|
||||
if isinstance(addr, unicode):
|
||||
addr = addr.encode('utf8')
|
||||
rc = C.zmq_socket_monitor(self._zmq_socket, addr, events)
|
||||
|
||||
|
||||
__all__ = ['Socket', 'IPC_PATH_MAX_LEN']
|
81
venv/Lib/site-packages/zmq/backend/cffi/utils.py
Normal file
81
venv/Lib/site-packages/zmq/backend/cffi/utils.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
# coding: utf-8
|
||||
"""miscellaneous zmq_utils wrapping"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from errno import EINTR
|
||||
|
||||
from ._cffi import ffi, C
|
||||
|
||||
from zmq.error import ZMQError, InterruptedSystemCall, _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 built with CURVE support.
|
||||
|
||||
Returns
|
||||
-------
|
||||
(public, secret) : two bytestrings
|
||||
The public and private keypair as 40 byte z85-encoded bytestrings.
|
||||
"""
|
||||
_check_version((3,2), "curve_keypair")
|
||||
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]
|
||||
|
||||
|
||||
def curve_public(private):
|
||||
""" Compute the public key corresponding to a private key for use
|
||||
with zmq.CURVE security
|
||||
|
||||
Requires libzmq (≥ 4.2) to have been built with CURVE support.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
private
|
||||
The private key as a 40 byte z85-encoded bytestring
|
||||
Returns
|
||||
-------
|
||||
bytestring
|
||||
The public key as a 40 byte z85-encoded bytestring.
|
||||
"""
|
||||
if isinstance(private, unicode):
|
||||
private = private.encode('utf8')
|
||||
_check_version((4,2), "curve_public")
|
||||
public = ffi.new('char[64]')
|
||||
rc = C.zmq_curve_public(public, private)
|
||||
_check_rc(rc)
|
||||
return ffi.buffer(public)[:40]
|
||||
|
||||
|
||||
def _retry_sys_call(f, *args, **kwargs):
|
||||
"""make a call, retrying if interrupted with EINTR"""
|
||||
while True:
|
||||
rc = f(*args)
|
||||
try:
|
||||
_check_rc(rc)
|
||||
except InterruptedSystemCall:
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
__all__ = ['has', 'curve_keypair', 'curve_public']
|
3
venv/Lib/site-packages/zmq/backend/cython/__init__.pxd
Normal file
3
venv/Lib/site-packages/zmq/backend/cython/__init__.pxd
Normal file
|
@ -0,0 +1,3 @@
|
|||
from zmq.backend.cython.context cimport Context
|
||||
from zmq.backend.cython.socket cimport Socket
|
||||
from zmq.backend.cython.message cimport Frame
|
26
venv/Lib/site-packages/zmq/backend/cython/__init__.py
Normal file
26
venv/Lib/site-packages/zmq/backend/cython/__init__.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""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,
|
||||
_proxy_steerable)
|
||||
|
||||
__all__ = []
|
||||
for submod in (constants, error, message, context,
|
||||
socket, utils, _poll, _version, _device,
|
||||
_proxy_steerable):
|
||||
__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 ._proxy_steerable import *
|
||||
from ._device import *
|
||||
from ._version import *
|
||||
|
Binary file not shown.
BIN
venv/Lib/site-packages/zmq/backend/cython/_device.cp36-win32.pyd
Normal file
BIN
venv/Lib/site-packages/zmq/backend/cython/_device.cp36-win32.pyd
Normal file
Binary file not shown.
BIN
venv/Lib/site-packages/zmq/backend/cython/_poll.cp36-win32.pyd
Normal file
BIN
venv/Lib/site-packages/zmq/backend/cython/_poll.cp36-win32.pyd
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
27
venv/Lib/site-packages/zmq/backend/cython/checkrc.pxd
Normal file
27
venv/Lib/site-packages/zmq/backend/cython/checkrc.pxd
Normal file
|
@ -0,0 +1,27 @@
|
|||
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 == -1: # if rc < -1, it's a bug in libzmq. Should we warn?
|
||||
if errno == EINTR:
|
||||
from zmq.error import InterruptedSystemCall
|
||||
raise InterruptedSystemCall(errno)
|
||||
elif 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 0
|
222
venv/Lib/site-packages/zmq/backend/cython/constant_enums.pxi
Normal file
222
venv/Lib/site-packages/zmq/backend/cython/constant_enums.pxi
Normal file
|
@ -0,0 +1,222 @@
|
|||
cdef extern from "zmq.h" nogil:
|
||||
enum: PYZMQ_DRAFT_API
|
||||
enum: ZMQ_VERSION
|
||||
enum: ZMQ_VERSION_MAJOR
|
||||
enum: ZMQ_VERSION_MINOR
|
||||
enum: ZMQ_VERSION_PATCH
|
||||
enum: ZMQ_NOBLOCK
|
||||
enum: ZMQ_DONTWAIT
|
||||
enum: ZMQ_POLLIN
|
||||
enum: ZMQ_POLLOUT
|
||||
enum: ZMQ_POLLERR
|
||||
enum: ZMQ_POLLPRI
|
||||
enum: ZMQ_SNDMORE
|
||||
enum: ZMQ_STREAMER
|
||||
enum: ZMQ_FORWARDER
|
||||
enum: ZMQ_QUEUE
|
||||
enum: ZMQ_IO_THREADS_DFLT
|
||||
enum: ZMQ_MAX_SOCKETS_DFLT
|
||||
enum: ZMQ_POLLITEMS_DFLT
|
||||
enum: ZMQ_THREAD_PRIORITY_DFLT
|
||||
enum: ZMQ_THREAD_SCHED_POLICY_DFLT
|
||||
enum: ZMQ_PAIR
|
||||
enum: ZMQ_PUB
|
||||
enum: ZMQ_SUB
|
||||
enum: ZMQ_REQ
|
||||
enum: ZMQ_REP
|
||||
enum: ZMQ_DEALER
|
||||
enum: ZMQ_ROUTER
|
||||
enum: ZMQ_XREQ
|
||||
enum: ZMQ_XREP
|
||||
enum: ZMQ_PULL
|
||||
enum: ZMQ_PUSH
|
||||
enum: ZMQ_XPUB
|
||||
enum: ZMQ_XSUB
|
||||
enum: ZMQ_UPSTREAM
|
||||
enum: ZMQ_DOWNSTREAM
|
||||
enum: ZMQ_STREAM
|
||||
enum: ZMQ_SERVER
|
||||
enum: ZMQ_CLIENT
|
||||
enum: ZMQ_RADIO
|
||||
enum: ZMQ_DISH
|
||||
enum: ZMQ_GATHER
|
||||
enum: ZMQ_SCATTER
|
||||
enum: ZMQ_DGRAM
|
||||
enum: ZMQ_EVENT_CONNECTED
|
||||
enum: ZMQ_EVENT_CONNECT_DELAYED
|
||||
enum: ZMQ_EVENT_CONNECT_RETRIED
|
||||
enum: ZMQ_EVENT_LISTENING
|
||||
enum: ZMQ_EVENT_BIND_FAILED
|
||||
enum: ZMQ_EVENT_ACCEPTED
|
||||
enum: ZMQ_EVENT_ACCEPT_FAILED
|
||||
enum: ZMQ_EVENT_CLOSED
|
||||
enum: ZMQ_EVENT_CLOSE_FAILED
|
||||
enum: ZMQ_EVENT_DISCONNECTED
|
||||
enum: ZMQ_EVENT_ALL
|
||||
enum: ZMQ_EVENT_MONITOR_STOPPED
|
||||
enum: ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
|
||||
enum: ZMQ_EVENT_HANDSHAKE_SUCCEEDED
|
||||
enum: ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
|
||||
enum: ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE
|
||||
enum: ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA
|
||||
enum: ZMQ_NOTIFY_CONNECT
|
||||
enum: ZMQ_NOTIFY_DISCONNECT
|
||||
enum: ZMQ_NULL
|
||||
enum: ZMQ_PLAIN
|
||||
enum: ZMQ_CURVE
|
||||
enum: ZMQ_GSSAPI
|
||||
enum: ZMQ_GSSAPI_NT_HOSTBASED
|
||||
enum: ZMQ_GSSAPI_NT_USER_NAME
|
||||
enum: ZMQ_GSSAPI_NT_KRB5_PRINCIPAL
|
||||
enum: ZMQ_EAGAIN "EAGAIN"
|
||||
enum: ZMQ_EINVAL "EINVAL"
|
||||
enum: ZMQ_EFAULT "EFAULT"
|
||||
enum: ZMQ_ENOMEM "ENOMEM"
|
||||
enum: ZMQ_ENODEV "ENODEV"
|
||||
enum: ZMQ_EMSGSIZE "EMSGSIZE"
|
||||
enum: ZMQ_EAFNOSUPPORT "EAFNOSUPPORT"
|
||||
enum: ZMQ_ENETUNREACH "ENETUNREACH"
|
||||
enum: ZMQ_ECONNABORTED "ECONNABORTED"
|
||||
enum: ZMQ_ECONNRESET "ECONNRESET"
|
||||
enum: ZMQ_ENOTCONN "ENOTCONN"
|
||||
enum: ZMQ_ETIMEDOUT "ETIMEDOUT"
|
||||
enum: ZMQ_EHOSTUNREACH "EHOSTUNREACH"
|
||||
enum: ZMQ_ENETRESET "ENETRESET"
|
||||
enum: ZMQ_HAUSNUMERO
|
||||
enum: ZMQ_ENOTSUP "ENOTSUP"
|
||||
enum: ZMQ_EPROTONOSUPPORT "EPROTONOSUPPORT"
|
||||
enum: ZMQ_ENOBUFS "ENOBUFS"
|
||||
enum: ZMQ_ENETDOWN "ENETDOWN"
|
||||
enum: ZMQ_EADDRINUSE "EADDRINUSE"
|
||||
enum: ZMQ_EADDRNOTAVAIL "EADDRNOTAVAIL"
|
||||
enum: ZMQ_ECONNREFUSED "ECONNREFUSED"
|
||||
enum: ZMQ_EINPROGRESS "EINPROGRESS"
|
||||
enum: ZMQ_ENOTSOCK "ENOTSOCK"
|
||||
enum: ZMQ_EFSM "EFSM"
|
||||
enum: ZMQ_ENOCOMPATPROTO "ENOCOMPATPROTO"
|
||||
enum: ZMQ_ETERM "ETERM"
|
||||
enum: ZMQ_EMTHREAD "EMTHREAD"
|
||||
enum: ZMQ_IO_THREADS
|
||||
enum: ZMQ_MAX_SOCKETS
|
||||
enum: ZMQ_SOCKET_LIMIT
|
||||
enum: ZMQ_THREAD_PRIORITY
|
||||
enum: ZMQ_THREAD_SCHED_POLICY
|
||||
enum: ZMQ_BLOCKY
|
||||
enum: ZMQ_MSG_T_SIZE
|
||||
enum: ZMQ_THREAD_AFFINITY_CPU_ADD
|
||||
enum: ZMQ_THREAD_AFFINITY_CPU_REMOVE
|
||||
enum: ZMQ_THREAD_NAME_PREFIX
|
||||
enum: ZMQ_IDENTITY
|
||||
enum: ZMQ_SUBSCRIBE
|
||||
enum: ZMQ_UNSUBSCRIBE
|
||||
enum: ZMQ_LAST_ENDPOINT
|
||||
enum: ZMQ_TCP_ACCEPT_FILTER
|
||||
enum: ZMQ_PLAIN_USERNAME
|
||||
enum: ZMQ_PLAIN_PASSWORD
|
||||
enum: ZMQ_CURVE_PUBLICKEY
|
||||
enum: ZMQ_CURVE_SECRETKEY
|
||||
enum: ZMQ_CURVE_SERVERKEY
|
||||
enum: ZMQ_ZAP_DOMAIN
|
||||
enum: ZMQ_CONNECT_RID
|
||||
enum: ZMQ_GSSAPI_PRINCIPAL
|
||||
enum: ZMQ_GSSAPI_SERVICE_PRINCIPAL
|
||||
enum: ZMQ_SOCKS_PROXY
|
||||
enum: ZMQ_XPUB_WELCOME_MSG
|
||||
enum: ZMQ_ROUTING_ID
|
||||
enum: ZMQ_CONNECT_ROUTING_ID
|
||||
enum: ZMQ_BINDTODEVICE
|
||||
enum: ZMQ_FD
|
||||
enum: ZMQ_RECONNECT_IVL_MAX
|
||||
enum: ZMQ_SNDTIMEO
|
||||
enum: ZMQ_RCVTIMEO
|
||||
enum: ZMQ_SNDHWM
|
||||
enum: ZMQ_RCVHWM
|
||||
enum: ZMQ_MULTICAST_HOPS
|
||||
enum: ZMQ_IPV4ONLY
|
||||
enum: ZMQ_ROUTER_BEHAVIOR
|
||||
enum: ZMQ_TCP_KEEPALIVE
|
||||
enum: ZMQ_TCP_KEEPALIVE_CNT
|
||||
enum: ZMQ_TCP_KEEPALIVE_IDLE
|
||||
enum: ZMQ_TCP_KEEPALIVE_INTVL
|
||||
enum: ZMQ_DELAY_ATTACH_ON_CONNECT
|
||||
enum: ZMQ_XPUB_VERBOSE
|
||||
enum: ZMQ_EVENTS
|
||||
enum: ZMQ_TYPE
|
||||
enum: ZMQ_LINGER
|
||||
enum: ZMQ_RECONNECT_IVL
|
||||
enum: ZMQ_BACKLOG
|
||||
enum: ZMQ_ROUTER_MANDATORY
|
||||
enum: ZMQ_FAIL_UNROUTABLE
|
||||
enum: ZMQ_ROUTER_RAW
|
||||
enum: ZMQ_IMMEDIATE
|
||||
enum: ZMQ_IPV6
|
||||
enum: ZMQ_MECHANISM
|
||||
enum: ZMQ_PLAIN_SERVER
|
||||
enum: ZMQ_CURVE_SERVER
|
||||
enum: ZMQ_PROBE_ROUTER
|
||||
enum: ZMQ_REQ_RELAXED
|
||||
enum: ZMQ_REQ_CORRELATE
|
||||
enum: ZMQ_CONFLATE
|
||||
enum: ZMQ_ROUTER_HANDOVER
|
||||
enum: ZMQ_TOS
|
||||
enum: ZMQ_IPC_FILTER_PID
|
||||
enum: ZMQ_IPC_FILTER_UID
|
||||
enum: ZMQ_IPC_FILTER_GID
|
||||
enum: ZMQ_GSSAPI_SERVER
|
||||
enum: ZMQ_GSSAPI_PLAINTEXT
|
||||
enum: ZMQ_HANDSHAKE_IVL
|
||||
enum: ZMQ_XPUB_NODROP
|
||||
enum: ZMQ_XPUB_MANUAL
|
||||
enum: ZMQ_STREAM_NOTIFY
|
||||
enum: ZMQ_INVERT_MATCHING
|
||||
enum: ZMQ_XPUB_VERBOSER
|
||||
enum: ZMQ_HEARTBEAT_IVL
|
||||
enum: ZMQ_HEARTBEAT_TTL
|
||||
enum: ZMQ_HEARTBEAT_TIMEOUT
|
||||
enum: ZMQ_CONNECT_TIMEOUT
|
||||
enum: ZMQ_TCP_MAXRT
|
||||
enum: ZMQ_THREAD_SAFE
|
||||
enum: ZMQ_MULTICAST_MAXTPDU
|
||||
enum: ZMQ_VMCI_CONNECT_TIMEOUT
|
||||
enum: ZMQ_USE_FD
|
||||
enum: ZMQ_GSSAPI_PRINCIPAL_NAMETYPE
|
||||
enum: ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE
|
||||
enum: ZMQ_MULTICAST_LOOP
|
||||
enum: ZMQ_ROUTER_NOTIFY
|
||||
enum: ZMQ_ZAP_ENFORCE_DOMAIN
|
||||
enum: ZMQ_AFFINITY
|
||||
enum: ZMQ_MAXMSGSIZE
|
||||
enum: ZMQ_HWM
|
||||
enum: ZMQ_SWAP
|
||||
enum: ZMQ_MCAST_LOOP
|
||||
enum: ZMQ_RECOVERY_IVL_MSEC
|
||||
enum: ZMQ_VMCI_BUFFER_SIZE
|
||||
enum: ZMQ_VMCI_BUFFER_MIN_SIZE
|
||||
enum: ZMQ_VMCI_BUFFER_MAX_SIZE
|
||||
enum: ZMQ_RATE
|
||||
enum: ZMQ_RECOVERY_IVL
|
||||
enum: ZMQ_SNDBUF
|
||||
enum: ZMQ_RCVBUF
|
||||
enum: ZMQ_RCVMORE
|
||||
enum: ZMQ_MORE
|
||||
enum: ZMQ_SRCFD
|
||||
enum: ZMQ_SHARED
|
Binary file not shown.
453
venv/Lib/site-packages/zmq/backend/cython/constants.pxi
Normal file
453
venv/Lib/site-packages/zmq/backend/cython/constants.pxi
Normal file
|
@ -0,0 +1,453 @@
|
|||
#-----------------------------------------------------------------------------
|
||||
# Python module level constants
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
DRAFT_API = PYZMQ_DRAFT_API
|
||||
|
||||
VERSION = ZMQ_VERSION
|
||||
VERSION_MAJOR = ZMQ_VERSION_MAJOR
|
||||
VERSION_MINOR = ZMQ_VERSION_MINOR
|
||||
VERSION_PATCH = ZMQ_VERSION_PATCH
|
||||
NOBLOCK = ZMQ_NOBLOCK
|
||||
DONTWAIT = ZMQ_DONTWAIT
|
||||
POLLIN = ZMQ_POLLIN
|
||||
POLLOUT = ZMQ_POLLOUT
|
||||
POLLERR = ZMQ_POLLERR
|
||||
POLLPRI = ZMQ_POLLPRI
|
||||
SNDMORE = ZMQ_SNDMORE
|
||||
STREAMER = ZMQ_STREAMER
|
||||
FORWARDER = ZMQ_FORWARDER
|
||||
QUEUE = ZMQ_QUEUE
|
||||
IO_THREADS_DFLT = ZMQ_IO_THREADS_DFLT
|
||||
MAX_SOCKETS_DFLT = ZMQ_MAX_SOCKETS_DFLT
|
||||
POLLITEMS_DFLT = ZMQ_POLLITEMS_DFLT
|
||||
THREAD_PRIORITY_DFLT = ZMQ_THREAD_PRIORITY_DFLT
|
||||
THREAD_SCHED_POLICY_DFLT = ZMQ_THREAD_SCHED_POLICY_DFLT
|
||||
PAIR = ZMQ_PAIR
|
||||
PUB = ZMQ_PUB
|
||||
SUB = ZMQ_SUB
|
||||
REQ = ZMQ_REQ
|
||||
REP = ZMQ_REP
|
||||
DEALER = ZMQ_DEALER
|
||||
ROUTER = ZMQ_ROUTER
|
||||
XREQ = ZMQ_XREQ
|
||||
XREP = ZMQ_XREP
|
||||
PULL = ZMQ_PULL
|
||||
PUSH = ZMQ_PUSH
|
||||
XPUB = ZMQ_XPUB
|
||||
XSUB = ZMQ_XSUB
|
||||
UPSTREAM = ZMQ_UPSTREAM
|
||||
DOWNSTREAM = ZMQ_DOWNSTREAM
|
||||
STREAM = ZMQ_STREAM
|
||||
SERVER = ZMQ_SERVER
|
||||
CLIENT = ZMQ_CLIENT
|
||||
RADIO = ZMQ_RADIO
|
||||
DISH = ZMQ_DISH
|
||||
GATHER = ZMQ_GATHER
|
||||
SCATTER = ZMQ_SCATTER
|
||||
DGRAM = ZMQ_DGRAM
|
||||
EVENT_CONNECTED = ZMQ_EVENT_CONNECTED
|
||||
EVENT_CONNECT_DELAYED = ZMQ_EVENT_CONNECT_DELAYED
|
||||
EVENT_CONNECT_RETRIED = ZMQ_EVENT_CONNECT_RETRIED
|
||||
EVENT_LISTENING = ZMQ_EVENT_LISTENING
|
||||
EVENT_BIND_FAILED = ZMQ_EVENT_BIND_FAILED
|
||||
EVENT_ACCEPTED = ZMQ_EVENT_ACCEPTED
|
||||
EVENT_ACCEPT_FAILED = ZMQ_EVENT_ACCEPT_FAILED
|
||||
EVENT_CLOSED = ZMQ_EVENT_CLOSED
|
||||
EVENT_CLOSE_FAILED = ZMQ_EVENT_CLOSE_FAILED
|
||||
EVENT_DISCONNECTED = ZMQ_EVENT_DISCONNECTED
|
||||
EVENT_ALL = ZMQ_EVENT_ALL
|
||||
EVENT_MONITOR_STOPPED = ZMQ_EVENT_MONITOR_STOPPED
|
||||
EVENT_HANDSHAKE_FAILED_NO_DETAIL = ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
|
||||
EVENT_HANDSHAKE_SUCCEEDED = ZMQ_EVENT_HANDSHAKE_SUCCEEDED
|
||||
EVENT_HANDSHAKE_FAILED_PROTOCOL = ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
|
||||
EVENT_HANDSHAKE_FAILED_AUTH = ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
|
||||
PROTOCOL_ERROR_ZMTP_UNSPECIFIED = ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED
|
||||
PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND = ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
|
||||
PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE = ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE
|
||||
PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE = ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE
|
||||
PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED = ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED
|
||||
PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE = ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE
|
||||
PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO = ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO
|
||||
PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE = ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE
|
||||
PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR = ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR
|
||||
PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY = ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY
|
||||
PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME = ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME
|
||||
PROTOCOL_ERROR_ZMTP_INVALID_METADATA = ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA
|
||||
PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC = ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC
|
||||
PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH = ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH
|
||||
PROTOCOL_ERROR_ZAP_UNSPECIFIED = ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED
|
||||
PROTOCOL_ERROR_ZAP_MALFORMED_REPLY = ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY
|
||||
PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID = ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID
|
||||
PROTOCOL_ERROR_ZAP_BAD_VERSION = ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION
|
||||
PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE = ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE
|
||||
PROTOCOL_ERROR_ZAP_INVALID_METADATA = ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA
|
||||
NOTIFY_CONNECT = ZMQ_NOTIFY_CONNECT
|
||||
NOTIFY_DISCONNECT = ZMQ_NOTIFY_DISCONNECT
|
||||
globals()['NULL'] = ZMQ_NULL
|
||||
PLAIN = ZMQ_PLAIN
|
||||
CURVE = ZMQ_CURVE
|
||||
GSSAPI = ZMQ_GSSAPI
|
||||
GSSAPI_NT_HOSTBASED = ZMQ_GSSAPI_NT_HOSTBASED
|
||||
GSSAPI_NT_USER_NAME = ZMQ_GSSAPI_NT_USER_NAME
|
||||
GSSAPI_NT_KRB5_PRINCIPAL = ZMQ_GSSAPI_NT_KRB5_PRINCIPAL
|
||||
EAGAIN = ZMQ_EAGAIN
|
||||
EINVAL = ZMQ_EINVAL
|
||||
EFAULT = ZMQ_EFAULT
|
||||
ENOMEM = ZMQ_ENOMEM
|
||||
ENODEV = ZMQ_ENODEV
|
||||
EMSGSIZE = ZMQ_EMSGSIZE
|
||||
EAFNOSUPPORT = ZMQ_EAFNOSUPPORT
|
||||
ENETUNREACH = ZMQ_ENETUNREACH
|
||||
ECONNABORTED = ZMQ_ECONNABORTED
|
||||
ECONNRESET = ZMQ_ECONNRESET
|
||||
ENOTCONN = ZMQ_ENOTCONN
|
||||
ETIMEDOUT = ZMQ_ETIMEDOUT
|
||||
EHOSTUNREACH = ZMQ_EHOSTUNREACH
|
||||
ENETRESET = ZMQ_ENETRESET
|
||||
HAUSNUMERO = ZMQ_HAUSNUMERO
|
||||
ENOTSUP = ZMQ_ENOTSUP
|
||||
EPROTONOSUPPORT = ZMQ_EPROTONOSUPPORT
|
||||
ENOBUFS = ZMQ_ENOBUFS
|
||||
ENETDOWN = ZMQ_ENETDOWN
|
||||
EADDRINUSE = ZMQ_EADDRINUSE
|
||||
EADDRNOTAVAIL = ZMQ_EADDRNOTAVAIL
|
||||
ECONNREFUSED = ZMQ_ECONNREFUSED
|
||||
EINPROGRESS = ZMQ_EINPROGRESS
|
||||
ENOTSOCK = ZMQ_ENOTSOCK
|
||||
EFSM = ZMQ_EFSM
|
||||
ENOCOMPATPROTO = ZMQ_ENOCOMPATPROTO
|
||||
ETERM = ZMQ_ETERM
|
||||
EMTHREAD = ZMQ_EMTHREAD
|
||||
IO_THREADS = ZMQ_IO_THREADS
|
||||
MAX_SOCKETS = ZMQ_MAX_SOCKETS
|
||||
SOCKET_LIMIT = ZMQ_SOCKET_LIMIT
|
||||
THREAD_PRIORITY = ZMQ_THREAD_PRIORITY
|
||||
THREAD_SCHED_POLICY = ZMQ_THREAD_SCHED_POLICY
|
||||
BLOCKY = ZMQ_BLOCKY
|
||||
MSG_T_SIZE = ZMQ_MSG_T_SIZE
|
||||
THREAD_AFFINITY_CPU_ADD = ZMQ_THREAD_AFFINITY_CPU_ADD
|
||||
THREAD_AFFINITY_CPU_REMOVE = ZMQ_THREAD_AFFINITY_CPU_REMOVE
|
||||
THREAD_NAME_PREFIX = ZMQ_THREAD_NAME_PREFIX
|
||||
IDENTITY = ZMQ_IDENTITY
|
||||
SUBSCRIBE = ZMQ_SUBSCRIBE
|
||||
UNSUBSCRIBE = ZMQ_UNSUBSCRIBE
|
||||
LAST_ENDPOINT = ZMQ_LAST_ENDPOINT
|
||||
TCP_ACCEPT_FILTER = ZMQ_TCP_ACCEPT_FILTER
|
||||
PLAIN_USERNAME = ZMQ_PLAIN_USERNAME
|
||||
PLAIN_PASSWORD = ZMQ_PLAIN_PASSWORD
|
||||
CURVE_PUBLICKEY = ZMQ_CURVE_PUBLICKEY
|
||||
CURVE_SECRETKEY = ZMQ_CURVE_SECRETKEY
|
||||
CURVE_SERVERKEY = ZMQ_CURVE_SERVERKEY
|
||||
ZAP_DOMAIN = ZMQ_ZAP_DOMAIN
|
||||
CONNECT_RID = ZMQ_CONNECT_RID
|
||||
GSSAPI_PRINCIPAL = ZMQ_GSSAPI_PRINCIPAL
|
||||
GSSAPI_SERVICE_PRINCIPAL = ZMQ_GSSAPI_SERVICE_PRINCIPAL
|
||||
SOCKS_PROXY = ZMQ_SOCKS_PROXY
|
||||
XPUB_WELCOME_MSG = ZMQ_XPUB_WELCOME_MSG
|
||||
ROUTING_ID = ZMQ_ROUTING_ID
|
||||
CONNECT_ROUTING_ID = ZMQ_CONNECT_ROUTING_ID
|
||||
BINDTODEVICE = ZMQ_BINDTODEVICE
|
||||
FD = ZMQ_FD
|
||||
RECONNECT_IVL_MAX = ZMQ_RECONNECT_IVL_MAX
|
||||
SNDTIMEO = ZMQ_SNDTIMEO
|
||||
RCVTIMEO = ZMQ_RCVTIMEO
|
||||
SNDHWM = ZMQ_SNDHWM
|
||||
RCVHWM = ZMQ_RCVHWM
|
||||
MULTICAST_HOPS = ZMQ_MULTICAST_HOPS
|
||||
IPV4ONLY = ZMQ_IPV4ONLY
|
||||
ROUTER_BEHAVIOR = ZMQ_ROUTER_BEHAVIOR
|
||||
TCP_KEEPALIVE = ZMQ_TCP_KEEPALIVE
|
||||
TCP_KEEPALIVE_CNT = ZMQ_TCP_KEEPALIVE_CNT
|
||||
TCP_KEEPALIVE_IDLE = ZMQ_TCP_KEEPALIVE_IDLE
|
||||
TCP_KEEPALIVE_INTVL = ZMQ_TCP_KEEPALIVE_INTVL
|
||||
DELAY_ATTACH_ON_CONNECT = ZMQ_DELAY_ATTACH_ON_CONNECT
|
||||
XPUB_VERBOSE = ZMQ_XPUB_VERBOSE
|
||||
EVENTS = ZMQ_EVENTS
|
||||
TYPE = ZMQ_TYPE
|
||||
LINGER = ZMQ_LINGER
|
||||
RECONNECT_IVL = ZMQ_RECONNECT_IVL
|
||||
BACKLOG = ZMQ_BACKLOG
|
||||
ROUTER_MANDATORY = ZMQ_ROUTER_MANDATORY
|
||||
FAIL_UNROUTABLE = ZMQ_FAIL_UNROUTABLE
|
||||
ROUTER_RAW = ZMQ_ROUTER_RAW
|
||||
IMMEDIATE = ZMQ_IMMEDIATE
|
||||
IPV6 = ZMQ_IPV6
|
||||
MECHANISM = ZMQ_MECHANISM
|
||||
PLAIN_SERVER = ZMQ_PLAIN_SERVER
|
||||
CURVE_SERVER = ZMQ_CURVE_SERVER
|
||||
PROBE_ROUTER = ZMQ_PROBE_ROUTER
|
||||
REQ_RELAXED = ZMQ_REQ_RELAXED
|
||||
REQ_CORRELATE = ZMQ_REQ_CORRELATE
|
||||
CONFLATE = ZMQ_CONFLATE
|
||||
ROUTER_HANDOVER = ZMQ_ROUTER_HANDOVER
|
||||
TOS = ZMQ_TOS
|
||||
IPC_FILTER_PID = ZMQ_IPC_FILTER_PID
|
||||
IPC_FILTER_UID = ZMQ_IPC_FILTER_UID
|
||||
IPC_FILTER_GID = ZMQ_IPC_FILTER_GID
|
||||
GSSAPI_SERVER = ZMQ_GSSAPI_SERVER
|
||||
GSSAPI_PLAINTEXT = ZMQ_GSSAPI_PLAINTEXT
|
||||
HANDSHAKE_IVL = ZMQ_HANDSHAKE_IVL
|
||||
XPUB_NODROP = ZMQ_XPUB_NODROP
|
||||
XPUB_MANUAL = ZMQ_XPUB_MANUAL
|
||||
STREAM_NOTIFY = ZMQ_STREAM_NOTIFY
|
||||
INVERT_MATCHING = ZMQ_INVERT_MATCHING
|
||||
XPUB_VERBOSER = ZMQ_XPUB_VERBOSER
|
||||
HEARTBEAT_IVL = ZMQ_HEARTBEAT_IVL
|
||||
HEARTBEAT_TTL = ZMQ_HEARTBEAT_TTL
|
||||
HEARTBEAT_TIMEOUT = ZMQ_HEARTBEAT_TIMEOUT
|
||||
CONNECT_TIMEOUT = ZMQ_CONNECT_TIMEOUT
|
||||
TCP_MAXRT = ZMQ_TCP_MAXRT
|
||||
THREAD_SAFE = ZMQ_THREAD_SAFE
|
||||
MULTICAST_MAXTPDU = ZMQ_MULTICAST_MAXTPDU
|
||||
VMCI_CONNECT_TIMEOUT = ZMQ_VMCI_CONNECT_TIMEOUT
|
||||
USE_FD = ZMQ_USE_FD
|
||||
GSSAPI_PRINCIPAL_NAMETYPE = ZMQ_GSSAPI_PRINCIPAL_NAMETYPE
|
||||
GSSAPI_SERVICE_PRINCIPAL_NAMETYPE = ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE
|
||||
MULTICAST_LOOP = ZMQ_MULTICAST_LOOP
|
||||
ROUTER_NOTIFY = ZMQ_ROUTER_NOTIFY
|
||||
ZAP_ENFORCE_DOMAIN = ZMQ_ZAP_ENFORCE_DOMAIN
|
||||
AFFINITY = ZMQ_AFFINITY
|
||||
MAXMSGSIZE = ZMQ_MAXMSGSIZE
|
||||
HWM = ZMQ_HWM
|
||||
SWAP = ZMQ_SWAP
|
||||
MCAST_LOOP = ZMQ_MCAST_LOOP
|
||||
RECOVERY_IVL_MSEC = ZMQ_RECOVERY_IVL_MSEC
|
||||
VMCI_BUFFER_SIZE = ZMQ_VMCI_BUFFER_SIZE
|
||||
VMCI_BUFFER_MIN_SIZE = ZMQ_VMCI_BUFFER_MIN_SIZE
|
||||
VMCI_BUFFER_MAX_SIZE = ZMQ_VMCI_BUFFER_MAX_SIZE
|
||||
RATE = ZMQ_RATE
|
||||
RECOVERY_IVL = ZMQ_RECOVERY_IVL
|
||||
SNDBUF = ZMQ_SNDBUF
|
||||
RCVBUF = ZMQ_RCVBUF
|
||||
RCVMORE = ZMQ_RCVMORE
|
||||
MORE = ZMQ_MORE
|
||||
SRCFD = ZMQ_SRCFD
|
||||
SHARED = ZMQ_SHARED
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Symbols to export
|
||||
#-----------------------------------------------------------------------------
|
||||
__all__ = [
|
||||
"DRAFT_API",
|
||||
"VERSION",
|
||||
"VERSION_MAJOR",
|
||||
"VERSION_MINOR",
|
||||
"VERSION_PATCH",
|
||||
"NOBLOCK",
|
||||
"DONTWAIT",
|
||||
"POLLIN",
|
||||
"POLLOUT",
|
||||
"POLLERR",
|
||||
"POLLPRI",
|
||||
"SNDMORE",
|
||||
"STREAMER",
|
||||
"FORWARDER",
|
||||
"QUEUE",
|
||||
"IO_THREADS_DFLT",
|
||||
"MAX_SOCKETS_DFLT",
|
||||
"POLLITEMS_DFLT",
|
||||
"THREAD_PRIORITY_DFLT",
|
||||
"THREAD_SCHED_POLICY_DFLT",
|
||||
"PAIR",
|
||||
"PUB",
|
||||
"SUB",
|
||||
"REQ",
|
||||
"REP",
|
||||
"DEALER",
|
||||
"ROUTER",
|
||||
"XREQ",
|
||||
"XREP",
|
||||
"PULL",
|
||||
"PUSH",
|
||||
"XPUB",
|
||||
"XSUB",
|
||||
"UPSTREAM",
|
||||
"DOWNSTREAM",
|
||||
"STREAM",
|
||||
"SERVER",
|
||||
"CLIENT",
|
||||
"RADIO",
|
||||
"DISH",
|
||||
"GATHER",
|
||||
"SCATTER",
|
||||
"DGRAM",
|
||||
"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",
|
||||
"EVENT_HANDSHAKE_FAILED_NO_DETAIL",
|
||||
"EVENT_HANDSHAKE_SUCCEEDED",
|
||||
"EVENT_HANDSHAKE_FAILED_PROTOCOL",
|
||||
"EVENT_HANDSHAKE_FAILED_AUTH",
|
||||
"PROTOCOL_ERROR_ZMTP_UNSPECIFIED",
|
||||
"PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND",
|
||||
"PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE",
|
||||
"PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE",
|
||||
"PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED",
|
||||
"PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE",
|
||||
"PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO",
|
||||
"PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE",
|
||||
"PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR",
|
||||
"PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY",
|
||||
"PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME",
|
||||
"PROTOCOL_ERROR_ZMTP_INVALID_METADATA",
|
||||
"PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC",
|
||||
"PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH",
|
||||
"PROTOCOL_ERROR_ZAP_UNSPECIFIED",
|
||||
"PROTOCOL_ERROR_ZAP_MALFORMED_REPLY",
|
||||
"PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID",
|
||||
"PROTOCOL_ERROR_ZAP_BAD_VERSION",
|
||||
"PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE",
|
||||
"PROTOCOL_ERROR_ZAP_INVALID_METADATA",
|
||||
"NOTIFY_CONNECT",
|
||||
"NOTIFY_DISCONNECT",
|
||||
"NULL",
|
||||
"PLAIN",
|
||||
"CURVE",
|
||||
"GSSAPI",
|
||||
"GSSAPI_NT_HOSTBASED",
|
||||
"GSSAPI_NT_USER_NAME",
|
||||
"GSSAPI_NT_KRB5_PRINCIPAL",
|
||||
"EAGAIN",
|
||||
"EINVAL",
|
||||
"EFAULT",
|
||||
"ENOMEM",
|
||||
"ENODEV",
|
||||
"EMSGSIZE",
|
||||
"EAFNOSUPPORT",
|
||||
"ENETUNREACH",
|
||||
"ECONNABORTED",
|
||||
"ECONNRESET",
|
||||
"ENOTCONN",
|
||||
"ETIMEDOUT",
|
||||
"EHOSTUNREACH",
|
||||
"ENETRESET",
|
||||
"HAUSNUMERO",
|
||||
"ENOTSUP",
|
||||
"EPROTONOSUPPORT",
|
||||
"ENOBUFS",
|
||||
"ENETDOWN",
|
||||
"EADDRINUSE",
|
||||
"EADDRNOTAVAIL",
|
||||
"ECONNREFUSED",
|
||||
"EINPROGRESS",
|
||||
"ENOTSOCK",
|
||||
"EFSM",
|
||||
"ENOCOMPATPROTO",
|
||||
"ETERM",
|
||||
"EMTHREAD",
|
||||
"IO_THREADS",
|
||||
"MAX_SOCKETS",
|
||||
"SOCKET_LIMIT",
|
||||
"THREAD_PRIORITY",
|
||||
"THREAD_SCHED_POLICY",
|
||||
"BLOCKY",
|
||||
"MSG_T_SIZE",
|
||||
"THREAD_AFFINITY_CPU_ADD",
|
||||
"THREAD_AFFINITY_CPU_REMOVE",
|
||||
"THREAD_NAME_PREFIX",
|
||||
"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",
|
||||
"XPUB_WELCOME_MSG",
|
||||
"ROUTING_ID",
|
||||
"CONNECT_ROUTING_ID",
|
||||
"BINDTODEVICE",
|
||||
"FD",
|
||||
"RECONNECT_IVL_MAX",
|
||||
"SNDTIMEO",
|
||||
"RCVTIMEO",
|
||||
"SNDHWM",
|
||||
"RCVHWM",
|
||||
"MULTICAST_HOPS",
|
||||
"IPV4ONLY",
|
||||
"ROUTER_BEHAVIOR",
|
||||
"TCP_KEEPALIVE",
|
||||
"TCP_KEEPALIVE_CNT",
|
||||
"TCP_KEEPALIVE_IDLE",
|
||||
"TCP_KEEPALIVE_INTVL",
|
||||
"DELAY_ATTACH_ON_CONNECT",
|
||||
"XPUB_VERBOSE",
|
||||
"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",
|
||||
"XPUB_MANUAL",
|
||||
"STREAM_NOTIFY",
|
||||
"INVERT_MATCHING",
|
||||
"XPUB_VERBOSER",
|
||||
"HEARTBEAT_IVL",
|
||||
"HEARTBEAT_TTL",
|
||||
"HEARTBEAT_TIMEOUT",
|
||||
"CONNECT_TIMEOUT",
|
||||
"TCP_MAXRT",
|
||||
"THREAD_SAFE",
|
||||
"MULTICAST_MAXTPDU",
|
||||
"VMCI_CONNECT_TIMEOUT",
|
||||
"USE_FD",
|
||||
"GSSAPI_PRINCIPAL_NAMETYPE",
|
||||
"GSSAPI_SERVICE_PRINCIPAL_NAMETYPE",
|
||||
"MULTICAST_LOOP",
|
||||
"ROUTER_NOTIFY",
|
||||
"ZAP_ENFORCE_DOMAIN",
|
||||
"AFFINITY",
|
||||
"MAXMSGSIZE",
|
||||
"HWM",
|
||||
"SWAP",
|
||||
"MCAST_LOOP",
|
||||
"RECOVERY_IVL_MSEC",
|
||||
"VMCI_BUFFER_SIZE",
|
||||
"VMCI_BUFFER_MIN_SIZE",
|
||||
"VMCI_BUFFER_MAX_SIZE",
|
||||
"RATE",
|
||||
"RECOVERY_IVL",
|
||||
"SNDBUF",
|
||||
"RCVBUF",
|
||||
"RCVMORE",
|
||||
"MORE",
|
||||
"SRCFD",
|
||||
"SHARED",
|
||||
]
|
BIN
venv/Lib/site-packages/zmq/backend/cython/context.cp36-win32.pyd
Normal file
BIN
venv/Lib/site-packages/zmq/backend/cython/context.cp36-win32.pyd
Normal file
Binary file not shown.
35
venv/Lib/site-packages/zmq/backend/cython/context.pxd
Normal file
35
venv/Lib/site-packages/zmq/backend/cython/context.pxd
Normal file
|
@ -0,0 +1,35 @@
|
|||
"""0MQ Context class declaration."""
|
||||
|
||||
#
|
||||
# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
|
||||
#
|
||||
# This file is part of pyzmq.
|
||||
#
|
||||
# pyzmq is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the Lesser GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# pyzmq is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# Lesser GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the Lesser GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Code
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
cdef class Context:
|
||||
|
||||
cdef object __weakref__ # enable weakref
|
||||
cdef void *handle # The C handle for the underlying zmq object.
|
||||
cdef bint _shadow # whether the Context is a shadow wrapper of another
|
||||
cdef 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)
|
||||
|
BIN
venv/Lib/site-packages/zmq/backend/cython/error.cp36-win32.pyd
Normal file
BIN
venv/Lib/site-packages/zmq/backend/cython/error.cp36-win32.pyd
Normal file
Binary file not shown.
117
venv/Lib/site-packages/zmq/backend/cython/libzmq.pxd
Normal file
117
venv/Lib/site-packages/zmq/backend/cython/libzmq.pxd
Normal file
|
@ -0,0 +1,117 @@
|
|||
"""All the C imports for 0MQ"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2010 Brian E. Granger & Min Ragan-Kelley
|
||||
#
|
||||
# This file is part of pyzmq.
|
||||
#
|
||||
# pyzmq is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the Lesser GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# pyzmq is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# Lesser GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the Lesser GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Import the C header files
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# were it not for Windows,
|
||||
# we could cimport these from libc.stdint
|
||||
cdef extern from "zmq_compat.h":
|
||||
ctypedef signed long long int64_t "pyzmq_int64_t"
|
||||
ctypedef unsigned int uint32_t "pyzmq_uint32_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
|
||||
const 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 *zmq_msg_gets (zmq_msg_t *msg, const char *property)
|
||||
int zmq_has (const char *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 *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)
|
||||
int zmq_proxy_steerable (void *frontend,
|
||||
void *backend,
|
||||
void *capture,
|
||||
void *control)
|
||||
|
||||
int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key)
|
||||
int zmq_curve_public (char *z85_public_key, char *z85_secret_key)
|
||||
|
||||
# 4.2 draft
|
||||
int zmq_join (void *s, const char *group)
|
||||
int zmq_leave (void *s, const char *group)
|
||||
|
||||
int zmq_msg_set_routing_id(zmq_msg_t *msg, uint32_t routing_id)
|
||||
uint32_t zmq_msg_routing_id(zmq_msg_t *msg)
|
||||
int zmq_msg_set_group(zmq_msg_t *msg, const char *group)
|
||||
const char *zmq_msg_group(zmq_msg_t *msg)
|
BIN
venv/Lib/site-packages/zmq/backend/cython/message.cp36-win32.pyd
Normal file
BIN
venv/Lib/site-packages/zmq/backend/cython/message.cp36-win32.pyd
Normal file
Binary file not shown.
63
venv/Lib/site-packages/zmq/backend/cython/message.pxd
Normal file
63
venv/Lib/site-packages/zmq/backend/cython/message.pxd
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
from cpython cimport PyBytes_FromStringAndSize
|
||||
|
||||
from zmq.backend.cython.libzmq cimport zmq_msg_t, zmq_msg_data, zmq_msg_size
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Code
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
cdef class MessageTracker(object):
|
||||
|
||||
cdef set events # Message Event objects to track.
|
||||
cdef set peers # Other Message or MessageTracker objects.
|
||||
|
||||
|
||||
cdef class Frame:
|
||||
|
||||
cdef zmq_msg_t zmq_msg
|
||||
cdef object _data # The actual message data as a Python object.
|
||||
cdef object _buffer # A Python Buffer/View of the message contents
|
||||
cdef object _bytes # A bytes/str copy of the message.
|
||||
cdef bint _failed_init # Flag to handle failed zmq_msg_init
|
||||
cdef public object tracker_event # Event for use with zmq_free_fn.
|
||||
cdef public object tracker # MessageTracker object.
|
||||
cdef public bint more # whether RCVMORE was set
|
||||
|
||||
cdef Frame fast_copy(self) # Create shallow copy of Message object.
|
||||
cdef object _getbuffer(self) # Construct self._buffer.
|
||||
|
||||
|
||||
cdef inline object copy_zmq_msg_bytes(zmq_msg_t *zmq_msg):
|
||||
""" Copy the data from a zmq_msg_t """
|
||||
cdef char *data_c = NULL
|
||||
cdef Py_ssize_t data_len_c
|
||||
data_c = <char *>zmq_msg_data(zmq_msg)
|
||||
data_len_c = zmq_msg_size(zmq_msg)
|
||||
return PyBytes_FromStringAndSize(data_c, data_len_c)
|
||||
|
||||
|
BIN
venv/Lib/site-packages/zmq/backend/cython/socket.cp36-win32.pyd
Normal file
BIN
venv/Lib/site-packages/zmq/backend/cython/socket.cp36-win32.pyd
Normal file
Binary file not shown.
49
venv/Lib/site-packages/zmq/backend/cython/socket.pxd
Normal file
49
venv/Lib/site-packages/zmq/backend/cython/socket.pxd
Normal file
|
@ -0,0 +1,49 @@
|
|||
"""0MQ Socket class declaration."""
|
||||
|
||||
#
|
||||
# Copyright (c) 2010-2011 Brian E. Granger & Min Ragan-Kelley
|
||||
#
|
||||
# This file is part of pyzmq.
|
||||
#
|
||||
# pyzmq is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the Lesser GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# pyzmq is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# Lesser GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the Lesser GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
from .context cimport Context
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Code
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
cdef class Socket:
|
||||
|
||||
cdef object __weakref__ # enable weakref
|
||||
cdef void *handle # The C handle for the underlying zmq object.
|
||||
cdef bint _shadow # whether the Socket is a shadow wrapper of another
|
||||
# Hold on to a reference to the context to make sure it is not garbage
|
||||
# collected until the socket it done with it.
|
||||
cdef public Context context # The zmq Context object that owns this.
|
||||
cdef public bint _closed # bool property for a closed socket.
|
||||
cdef public int copy_threshold # threshold below which pyzmq will always copy messages
|
||||
cdef int _pid # the pid of the process which created me (for fork safety)
|
||||
cdef void _c_close(self) # underlying close of zmq socket
|
||||
|
||||
# cpdef methods for direct-cython access:
|
||||
cpdef object send(self, object data, int flags=*, copy=*, track=*)
|
||||
cpdef object recv(self, int flags=*, copy=*, track=*)
|
||||
|
BIN
venv/Lib/site-packages/zmq/backend/cython/utils.cp36-win32.pyd
Normal file
BIN
venv/Lib/site-packages/zmq/backend/cython/utils.cp36-win32.pyd
Normal file
Binary file not shown.
40
venv/Lib/site-packages/zmq/backend/select.py
Normal file
40
venv/Lib/site-packages/zmq/backend/select.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
"""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',
|
||||
'device',
|
||||
'proxy',
|
||||
'proxy_steerable',
|
||||
'zmq_poll',
|
||||
'strerror',
|
||||
'zmq_errno',
|
||||
'has',
|
||||
'curve_keypair',
|
||||
'curve_public',
|
||||
'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
|
BIN
venv/Lib/site-packages/zmq/concrt140.dll
Normal file
BIN
venv/Lib/site-packages/zmq/concrt140.dll
Normal file
Binary file not shown.
188
venv/Lib/site-packages/zmq/decorators.py
Normal file
188
venv/Lib/site-packages/zmq/decorators.py
Normal file
|
@ -0,0 +1,188 @@
|
|||
"""Decorators for running functions with context/sockets.
|
||||
|
||||
.. versionadded:: 15.3
|
||||
|
||||
Like using Contexts and Sockets as context managers, but with decorator syntax.
|
||||
Context and sockets are closed at the end of the function.
|
||||
|
||||
For example::
|
||||
|
||||
from zmq.decorators import context, socket
|
||||
|
||||
@context()
|
||||
@socket(zmq.PUSH)
|
||||
def work(ctx, push):
|
||||
...
|
||||
"""
|
||||
|
||||
# Copyright (c) PyZMQ Developers.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
__all__ = (
|
||||
'context',
|
||||
'socket',
|
||||
)
|
||||
|
||||
from functools import wraps
|
||||
|
||||
import zmq
|
||||
from zmq.utils.strtypes import basestring
|
||||
|
||||
|
||||
class _Decorator(object):
|
||||
'''The mini decorator factory'''
|
||||
|
||||
def __init__(self, target=None):
|
||||
self._target = target
|
||||
|
||||
def __call__(self, *dec_args, **dec_kwargs):
|
||||
'''
|
||||
The main logic of decorator
|
||||
|
||||
Here is how those arguments works::
|
||||
|
||||
@out_decorator(*dec_args, *dec_kwargs)
|
||||
def func(*wrap_args, **wrap_kwargs):
|
||||
...
|
||||
|
||||
And in the ``wrapper``, we simply create ``self.target`` instance via
|
||||
``with``::
|
||||
|
||||
target = self.get_target(*args, **kwargs)
|
||||
with target(*dec_args, **dec_kwargs) as obj:
|
||||
...
|
||||
|
||||
'''
|
||||
kw_name, dec_args, dec_kwargs = self.process_decorator_args(*dec_args, **dec_kwargs)
|
||||
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
target = self.get_target(*args, **kwargs)
|
||||
|
||||
with target(*dec_args, **dec_kwargs) as obj:
|
||||
# insert our object into args
|
||||
if kw_name and kw_name not in kwargs:
|
||||
kwargs[kw_name] = obj
|
||||
elif kw_name and kw_name in kwargs:
|
||||
raise TypeError(
|
||||
"{0}() got multiple values for"
|
||||
" argument '{1}'".format(
|
||||
func.__name__, kw_name))
|
||||
else:
|
||||
args = args + (obj,)
|
||||
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
def get_target(self, *args, **kwargs):
|
||||
"""Return the target function
|
||||
|
||||
Allows modifying args/kwargs to be passed.
|
||||
"""
|
||||
return self._target
|
||||
|
||||
def process_decorator_args(self, *args, **kwargs):
|
||||
"""Process args passed to the decorator.
|
||||
|
||||
args not consumed by the decorator will be passed to the target factory
|
||||
(Context/Socket constructor).
|
||||
"""
|
||||
kw_name = None
|
||||
|
||||
if isinstance(kwargs.get('name'), basestring):
|
||||
kw_name = kwargs.pop('name')
|
||||
elif len(args) >= 1 and isinstance(args[0], basestring):
|
||||
kw_name = args[0]
|
||||
args = args[1:]
|
||||
|
||||
return kw_name, args, kwargs
|
||||
|
||||
|
||||
class _ContextDecorator(_Decorator):
|
||||
"""Decorator subclass for Contexts"""
|
||||
def __init__(self):
|
||||
super(_ContextDecorator, self).__init__(zmq.Context)
|
||||
|
||||
|
||||
class _SocketDecorator(_Decorator):
|
||||
"""Decorator subclass for sockets
|
||||
|
||||
Gets the context from other args.
|
||||
"""
|
||||
|
||||
def process_decorator_args(self, *args, **kwargs):
|
||||
"""Also grab context_name out of kwargs"""
|
||||
kw_name, args, kwargs = super(_SocketDecorator, self).process_decorator_args(*args, **kwargs)
|
||||
self.context_name = kwargs.pop('context_name', 'context')
|
||||
return kw_name, args, kwargs
|
||||
|
||||
def get_target(self, *args, **kwargs):
|
||||
"""Get context, based on call-time args"""
|
||||
context = self._get_context(*args, **kwargs)
|
||||
return context.socket
|
||||
|
||||
def _get_context(self, *args, **kwargs):
|
||||
'''
|
||||
Find the ``zmq.Context`` from ``args`` and ``kwargs`` at call time.
|
||||
|
||||
First, if there is an keyword argument named ``context`` and it is a
|
||||
``zmq.Context`` instance , we will take it.
|
||||
|
||||
Second, we check all the ``args``, take the first ``zmq.Context``
|
||||
instance.
|
||||
|
||||
Finally, we will provide default Context -- ``zmq.Context.instance``
|
||||
|
||||
:return: a ``zmq.Context`` instance
|
||||
'''
|
||||
if self.context_name in kwargs:
|
||||
ctx = kwargs[self.context_name]
|
||||
|
||||
if isinstance(ctx, zmq.Context):
|
||||
return ctx
|
||||
|
||||
for arg in args:
|
||||
if isinstance(arg, zmq.Context):
|
||||
return arg
|
||||
# not specified by any decorator
|
||||
return zmq.Context.instance()
|
||||
|
||||
|
||||
def context(*args, **kwargs):
|
||||
'''Decorator for adding a Context to a function.
|
||||
|
||||
Usage::
|
||||
|
||||
@context()
|
||||
def foo(ctx):
|
||||
...
|
||||
|
||||
.. versionadded:: 15.3
|
||||
|
||||
:param str name: the keyword argument passed to decorated function
|
||||
'''
|
||||
return _ContextDecorator()(*args, **kwargs)
|
||||
|
||||
|
||||
def socket(*args, **kwargs):
|
||||
'''Decorator for adding a socket to a function.
|
||||
|
||||
Usage::
|
||||
|
||||
@socket(zmq.PUSH)
|
||||
def foo(push):
|
||||
...
|
||||
|
||||
.. versionadded:: 15.3
|
||||
|
||||
:param str name: the keyword argument passed to decorated function
|
||||
:param str context_name: the keyword only argument to identify context
|
||||
object
|
||||
'''
|
||||
return _SocketDecorator()(*args, **kwargs)
|
||||
|
||||
|
29
venv/Lib/site-packages/zmq/devices/__init__.py
Normal file
29
venv/Lib/site-packages/zmq/devices/__init__.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
"""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,
|
||||
monitoredqueue,
|
||||
monitoredqueuedevice,
|
||||
proxydevice,
|
||||
proxysteerabledevice,
|
||||
)
|
||||
|
||||
from zmq.devices.basedevice import *
|
||||
from zmq.devices.proxydevice import *
|
||||
from zmq.devices.proxysteerabledevice import *
|
||||
from zmq.devices.monitoredqueue import *
|
||||
from zmq.devices.monitoredqueuedevice import *
|
||||
|
||||
__all__ = ['device']
|
||||
for submod in (
|
||||
basedevice,
|
||||
proxydevice,
|
||||
proxysteerabledevice,
|
||||
monitoredqueue,
|
||||
monitoredqueuedevice
|
||||
):
|
||||
__all__.extend(submod.__all__)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
281
venv/Lib/site-packages/zmq/devices/basedevice.py
Normal file
281
venv/Lib/site-packages/zmq/devices/basedevice.py
Normal file
|
@ -0,0 +1,281 @@
|
|||
"""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, REQ, Context, ETERM, ZMQBindError, 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._random_addrs = []
|
||||
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 bind_in_to_random_port(self, addr, *args, **kwargs):
|
||||
"""Enqueue a random port on the given interface for binding on
|
||||
in_socket.
|
||||
|
||||
See zmq.Socket.bind_to_random_port for details.
|
||||
|
||||
.. versionadded:: 18.0
|
||||
"""
|
||||
port = self._reserve_random_port(addr, *args, **kwargs)
|
||||
|
||||
self.bind_in('%s:%i' % (addr, port))
|
||||
|
||||
return port
|
||||
|
||||
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 bind_out_to_random_port(self, addr, *args, **kwargs):
|
||||
"""Enqueue a random port on the given interface for binding on
|
||||
out_socket.
|
||||
|
||||
See zmq.Socket.bind_to_random_port for details.
|
||||
|
||||
.. versionadded:: 18.0
|
||||
"""
|
||||
port = self._reserve_random_port(addr, *args, **kwargs)
|
||||
|
||||
self.bind_out('%s:%i' % (addr, port))
|
||||
|
||||
return port
|
||||
|
||||
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 _reserve_random_port(self, addr, *args, **kwargs):
|
||||
ctx = Context()
|
||||
|
||||
binder = ctx.socket(REQ)
|
||||
|
||||
for i in range(5):
|
||||
port = binder.bind_to_random_port(addr, *args, **kwargs)
|
||||
|
||||
new_addr = '%s:%i' % (addr, port)
|
||||
|
||||
if new_addr in self._random_addrs:
|
||||
continue
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise ZMQBindError("Could not reserve random port.")
|
||||
|
||||
self._random_addrs.append(new_addr)
|
||||
|
||||
binder.close()
|
||||
|
||||
return port
|
||||
|
||||
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']
|
BIN
venv/Lib/site-packages/zmq/devices/monitoredqueue.cp36-win32.pyd
Normal file
BIN
venv/Lib/site-packages/zmq/devices/monitoredqueue.cp36-win32.pyd
Normal file
Binary file not shown.
177
venv/Lib/site-packages/zmq/devices/monitoredqueue.pxd
Normal file
177
venv/Lib/site-packages/zmq/devices/monitoredqueue.pxd
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
from zmq.backend.cython.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
|
37
venv/Lib/site-packages/zmq/devices/monitoredqueue.py
Normal file
37
venv/Lib/site-packages/zmq/devices/monitoredqueue.py
Normal file
|
@ -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']
|
66
venv/Lib/site-packages/zmq/devices/monitoredqueuedevice.py
Normal file
66
venv/Lib/site-packages/zmq/devices/monitoredqueuedevice.py
Normal file
|
@ -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'
|
||||
]
|
104
venv/Lib/site-packages/zmq/devices/proxydevice.py
Normal file
104
venv/Lib/site-packages/zmq/devices/proxydevice.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
"""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 bind_mon_to_random_port(self, addr, *args, **kwargs):
|
||||
"""Enqueue a random port on the given interface for binding on
|
||||
mon_socket.
|
||||
|
||||
See zmq.Socket.bind_to_random_port for details.
|
||||
|
||||
.. versionadded:: 18.0
|
||||
"""
|
||||
port = self._reserve_random_port(addr, *args, **kwargs)
|
||||
|
||||
self.bind_mon('%s:%i' % (addr, port))
|
||||
|
||||
return port
|
||||
|
||||
def connect_mon(self, addr):
|
||||
"""Enqueue ZMQ address for connecting on mon_socket.
|
||||
|
||||
See zmq.Socket.connect for details.
|
||||
"""
|
||||
self._mon_connects.append(addr)
|
||||
|
||||
def setsockopt_mon(self, opt, value):
|
||||
"""Enqueue setsockopt(opt, value) for mon_socket
|
||||
|
||||
See zmq.Socket.setsockopt for details.
|
||||
"""
|
||||
self._mon_sockopts.append((opt, value))
|
||||
|
||||
def _setup_sockets(self):
|
||||
ins,outs = Device._setup_sockets(self)
|
||||
ctx = self._context
|
||||
mons = ctx.socket(self.mon_type)
|
||||
|
||||
# set sockopts (must be done first, in case of zmq.IDENTITY)
|
||||
for opt,value in self._mon_sockopts:
|
||||
mons.setsockopt(opt, value)
|
||||
|
||||
for iface in self._mon_binds:
|
||||
mons.bind(iface)
|
||||
|
||||
for iface in self._mon_connects:
|
||||
mons.connect(iface)
|
||||
|
||||
return ins,outs,mons
|
||||
|
||||
def run_device(self):
|
||||
ins,outs,mons = self._setup_sockets()
|
||||
zmq.proxy(ins, outs, mons)
|
||||
|
||||
class Proxy(ProxyBase, Device):
|
||||
"""Threadsafe Proxy object.
|
||||
|
||||
See zmq.devices.Device for most of the spec. This subclass adds a
|
||||
<method>_mon version of each <method>_{in|out} method, for configuring the
|
||||
monitor socket.
|
||||
|
||||
A Proxy is a 3-socket ZMQ Device that functions just like a
|
||||
QUEUE, except each message is also sent out on the monitor socket.
|
||||
|
||||
A PUB socket is the most logical choice for the mon_socket, but it is not required.
|
||||
"""
|
||||
pass
|
||||
|
||||
class ThreadProxy(ProxyBase, ThreadDevice):
|
||||
"""Proxy in a Thread. See Proxy for more."""
|
||||
pass
|
||||
|
||||
class ProcessProxy(ProxyBase, ProcessDevice):
|
||||
"""Proxy in a Process. See Proxy for more."""
|
||||
pass
|
||||
|
||||
|
||||
__all__ = [
|
||||
'Proxy',
|
||||
'ThreadProxy',
|
||||
'ProcessProxy',
|
||||
]
|
112
venv/Lib/site-packages/zmq/devices/proxysteerabledevice.py
Normal file
112
venv/Lib/site-packages/zmq/devices/proxysteerabledevice.py
Normal file
|
@ -0,0 +1,112 @@
|
|||
"""Classes for running a steerable ZMQ proxy"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import zmq
|
||||
from zmq.devices.proxydevice import Proxy, ThreadProxy, ProcessProxy
|
||||
|
||||
|
||||
class ProxySteerableBase(object):
|
||||
"""Base class for overriding methods."""
|
||||
|
||||
def __init__(self, in_type, out_type, mon_type=zmq.PUB, ctrl_type=None):
|
||||
super(ProxySteerableBase, self).__init__(
|
||||
in_type=in_type,
|
||||
out_type=out_type,
|
||||
mon_type=mon_type
|
||||
)
|
||||
self.ctrl_type = ctrl_type
|
||||
self._ctrl_binds = []
|
||||
self._ctrl_connects = []
|
||||
self._ctrl_sockopts = []
|
||||
|
||||
def bind_ctrl(self, addr):
|
||||
"""Enqueue ZMQ address for binding on ctrl_socket.
|
||||
|
||||
See zmq.Socket.bind for details.
|
||||
"""
|
||||
self._ctrl_binds.append(addr)
|
||||
|
||||
def bind_ctrl_to_random_port(self, addr, *args, **kwargs):
|
||||
"""Enqueue a random port on the given interface for binding on
|
||||
ctrl_socket.
|
||||
|
||||
See zmq.Socket.bind_to_random_port for details.
|
||||
"""
|
||||
port = self._reserve_random_port(addr, *args, **kwargs)
|
||||
|
||||
self.bind_ctrl('%s:%i' % (addr, port))
|
||||
|
||||
return port
|
||||
|
||||
def connect_ctrl(self, addr):
|
||||
"""Enqueue ZMQ address for connecting on ctrl_socket.
|
||||
|
||||
See zmq.Socket.connect for details.
|
||||
"""
|
||||
self._ctrl_connects.append(addr)
|
||||
|
||||
def setsockopt_ctrl(self, opt, value):
|
||||
"""Enqueue setsockopt(opt, value) for ctrl_socket
|
||||
|
||||
See zmq.Socket.setsockopt for details.
|
||||
"""
|
||||
self._ctrl_sockopts.append((opt, value))
|
||||
|
||||
def _setup_sockets(self):
|
||||
ins, outs, mons = super(ProxySteerableBase, self)._setup_sockets()
|
||||
ctx = self._context
|
||||
ctrls = ctx.socket(self.ctrl_type)
|
||||
|
||||
for opt, value in self._ctrl_sockopts:
|
||||
ctrls.setsockopt(opt, value)
|
||||
|
||||
for iface in self._ctrl_binds:
|
||||
ctrls.bind(iface)
|
||||
|
||||
for iface in self._ctrl_connects:
|
||||
ctrls.connect(iface)
|
||||
|
||||
return ins, outs, mons, ctrls
|
||||
|
||||
def run_device(self):
|
||||
ins, outs, mons, ctrls = self._setup_sockets()
|
||||
zmq.proxy_steerable(ins, outs, mons, ctrls)
|
||||
|
||||
|
||||
class ProxySteerable(ProxySteerableBase, Proxy):
|
||||
"""Class for running a steerable proxy in the background.
|
||||
|
||||
See zmq.devices.Proxy for most of the spec. If the control socket is not
|
||||
NULL, the proxy supports control flow, provided by the socket.
|
||||
|
||||
If PAUSE is received on this socket, the proxy suspends its activities. If
|
||||
RESUME is received, it goes on. If TERMINATE is received, it terminates
|
||||
smoothly. If the control socket is NULL, the proxy behave exactly as if
|
||||
zmq.devices.Proxy had been used.
|
||||
|
||||
This subclass adds a <method>_ctrl version of each <method>_{in|out}
|
||||
method, for configuring the control socket.
|
||||
|
||||
.. versionadded:: libzmq-4.1
|
||||
.. versionadded:: 18.0
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ThreadProxySteerable(ProxySteerableBase, ThreadProxy):
|
||||
"""ProxySteerable in a Thread. See ProxySteerable for details."""
|
||||
pass
|
||||
|
||||
|
||||
class ProcessProxySteerable(ProxySteerableBase, ProcessProxy):
|
||||
"""ProxySteerable in a Process. See ProxySteerable for details."""
|
||||
pass
|
||||
|
||||
|
||||
__all__ = [
|
||||
'ProxySteerable',
|
||||
'ThreadProxySteerable',
|
||||
'ProcessProxySteerable',
|
||||
]
|
196
venv/Lib/site-packages/zmq/error.py
Normal file
196
venv/Lib/site-packages/zmq/error.py
Normal file
|
@ -0,0 +1,196 @@
|
|||
"""0MQ Error classes and functions."""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from errno import EINTR
|
||||
|
||||
|
||||
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 "%s('%s')" % (self.__class__.__name__, str(self))
|
||||
|
||||
|
||||
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
|
||||
"""
|
||||
def __init__(self, errno='ignored', msg='ignored'):
|
||||
from zmq import ETERM
|
||||
super(ContextTerminated, self).__init__(ETERM)
|
||||
|
||||
|
||||
class Again(ZMQError):
|
||||
"""Wrapper for zmq.EAGAIN
|
||||
|
||||
.. versionadded:: 13.0
|
||||
"""
|
||||
|
||||
def __init__(self, errno='ignored', msg='ignored'):
|
||||
from zmq import EAGAIN
|
||||
super(Again, self).__init__(EAGAIN)
|
||||
|
||||
|
||||
try:
|
||||
InterruptedError
|
||||
except NameError:
|
||||
InterruptedError = OSError
|
||||
|
||||
class InterruptedSystemCall(ZMQError, InterruptedError):
|
||||
"""Wrapper for EINTR
|
||||
|
||||
This exception should be caught internally in pyzmq
|
||||
to retry system calls, and not propagate to the user.
|
||||
|
||||
.. versionadded:: 14.7
|
||||
"""
|
||||
|
||||
def __init__(self, errno='ignored', msg='ignored'):
|
||||
super(InterruptedSystemCall, self).__init__(EINTR)
|
||||
|
||||
def __str__(self):
|
||||
s = super(InterruptedSystemCall, self).__str__()
|
||||
return s + ": This call should have been retried. Please report this to pyzmq."
|
||||
|
||||
|
||||
def _check_rc(rc, errno=None):
|
||||
"""internal utility for checking zmq return condition
|
||||
|
||||
and raising the appropriate Exception class
|
||||
"""
|
||||
if rc == -1:
|
||||
if errno is None:
|
||||
from zmq.backend import zmq_errno
|
||||
errno = zmq_errno()
|
||||
from zmq import EAGAIN, ETERM
|
||||
if errno == EINTR:
|
||||
raise InterruptedSystemCall(errno)
|
||||
elif 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',
|
||||
'InterruptedSystemCall',
|
||||
'Again',
|
||||
'ZMQVersionError',
|
||||
]
|
5
venv/Lib/site-packages/zmq/eventloop/__init__.py
Normal file
5
venv/Lib/site-packages/zmq/eventloop/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
"""Tornado eventloop integration for pyzmq"""
|
||||
|
||||
from zmq.eventloop.ioloop import IOLoop
|
||||
|
||||
__all__ = ['IOLoop']
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
214
venv/Lib/site-packages/zmq/eventloop/_deprecated.py
Normal file
214
venv/Lib/site-packages/zmq/eventloop/_deprecated.py
Normal file
|
@ -0,0 +1,214 @@
|
|||
# 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 = ()
|
||||
|
||||
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
|
||||
|
||||
Minor modifications, so that .current/.instance return self
|
||||
"""
|
||||
|
||||
_zmq_impl = ZMQPoller
|
||||
|
||||
def initialize(self, impl=None, **kwargs):
|
||||
impl = self._zmq_impl() if impl is None else impl
|
||||
super(ZMQIOLoop, self).initialize(impl=impl, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def instance(cls, *args, **kwargs):
|
||||
"""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(cls)
|
||||
loop = PollIOLoop.instance(*args, **kwargs)
|
||||
if not isinstance(loop, cls):
|
||||
warnings.warn("IOLoop.current expected instance of %r, got %r" % (cls, loop),
|
||||
RuntimeWarning, stacklevel=2,
|
||||
)
|
||||
return loop
|
||||
|
||||
@classmethod
|
||||
def current(cls, *args, **kwargs):
|
||||
"""Returns the current thread’s IOLoop.
|
||||
"""
|
||||
# install ZMQIOLoop as the active IOLoop implementation
|
||||
# when using tornado 3
|
||||
if tornado_version >= (3,):
|
||||
PollIOLoop.configure(cls)
|
||||
loop = PollIOLoop.current(*args, **kwargs)
|
||||
if not isinstance(loop, cls):
|
||||
warnings.warn("IOLoop.current expected instance of %r, got %r" % (cls, loop),
|
||||
RuntimeWarning, stacklevel=2,
|
||||
)
|
||||
return loop
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
super(ZMQIOLoop, self).start()
|
||||
except ZMQError as e:
|
||||
if e.errno == ETERM:
|
||||
# quietly return on ETERM
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
if (3, 0) <= 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()
|
||||
|
73
venv/Lib/site-packages/zmq/eventloop/future.py
Normal file
73
venv/Lib/site-packages/zmq/eventloop/future.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
"""Future-returning APIs for tornado coroutines.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:mod:`zmq.asyncio`
|
||||
|
||||
"""
|
||||
|
||||
# Copyright (c) PyZMQ Developers.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import zmq as _zmq
|
||||
|
||||
from zmq._future import _AsyncPoller, _AsyncSocket
|
||||
|
||||
from tornado.concurrent import Future
|
||||
from tornado.ioloop import IOLoop
|
||||
|
||||
class CancelledError(Exception):
|
||||
pass
|
||||
|
||||
class _TornadoFuture(Future):
|
||||
"""Subclass Tornado Future, reinstating cancellation."""
|
||||
def cancel(self):
|
||||
if self.done():
|
||||
return False
|
||||
self.set_exception(CancelledError())
|
||||
return True
|
||||
|
||||
def cancelled(self):
|
||||
return self.done() and isinstance(self.exception(), CancelledError)
|
||||
|
||||
# mixin for tornado/asyncio compatibility
|
||||
|
||||
class _AsyncTornado(object):
|
||||
_Future = _TornadoFuture
|
||||
_READ = IOLoop.READ
|
||||
_WRITE = IOLoop.WRITE
|
||||
def _default_loop(self):
|
||||
return IOLoop.current()
|
||||
|
||||
|
||||
class Poller(_AsyncTornado, _AsyncPoller):
|
||||
def _watch_raw_socket(self, loop, socket, evt, f):
|
||||
"""Schedule callback for a raw socket"""
|
||||
loop.add_handler(socket, lambda *args: f(), evt)
|
||||
|
||||
def _unwatch_raw_sockets(self, loop, *sockets):
|
||||
"""Unschedule callback for a raw socket"""
|
||||
for socket in sockets:
|
||||
loop.remove_handler(socket)
|
||||
|
||||
|
||||
class Socket(_AsyncTornado, _AsyncSocket):
|
||||
_poller_class = Poller
|
||||
|
||||
Poller._socket_class = Socket
|
||||
|
||||
class Context(_zmq.Context):
|
||||
|
||||
# avoid sharing instance with base Context class
|
||||
_instance = None
|
||||
|
||||
io_loop = None
|
||||
@staticmethod
|
||||
def _socket_class(self, socket_type):
|
||||
return Socket(self, socket_type, io_loop=self.io_loop)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
io_loop = kwargs.pop('io_loop', None)
|
||||
super(Context, self).__init__(*args, **kwargs)
|
||||
self.io_loop = io_loop or IOLoop.current()
|
||||
|
136
venv/Lib/site-packages/zmq/eventloop/ioloop.py
Normal file
136
venv/Lib/site-packages/zmq/eventloop/ioloop.py
Normal file
|
@ -0,0 +1,136 @@
|
|||
# coding: utf-8
|
||||
"""tornado IOLoop API with zmq compatibility
|
||||
|
||||
This module is deprecated in pyzmq 17.
|
||||
To use zmq with tornado,
|
||||
eventloop integration is no longer required
|
||||
and tornado itself should be used.
|
||||
"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from __future__ import absolute_import, division, with_statement
|
||||
|
||||
import time
|
||||
import warnings
|
||||
|
||||
try:
|
||||
import tornado
|
||||
from tornado.log import gen_log
|
||||
from tornado import ioloop
|
||||
if not hasattr(ioloop.IOLoop, 'configurable_default'):
|
||||
raise ImportError("Tornado too old: %s" % getattr(tornado, 'version', 'unknown'))
|
||||
except ImportError:
|
||||
from .minitornado import ioloop
|
||||
from .minitornado.log import gen_log
|
||||
|
||||
PeriodicCallback = ioloop.PeriodicCallback
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def _deprecated():
|
||||
if _deprecated.called:
|
||||
return
|
||||
_deprecated.called = True
|
||||
warnings.warn("zmq.eventloop.ioloop is deprecated in pyzmq 17."
|
||||
" pyzmq now works with default tornado and asyncio eventloops.",
|
||||
DeprecationWarning, stacklevel=3)
|
||||
_deprecated.called = False
|
||||
|
||||
|
||||
# resolve 'true' default loop
|
||||
if '.minitornado.' in ioloop.__name__:
|
||||
from ._deprecated import ZMQIOLoop as _IOLoop
|
||||
else:
|
||||
_IOLoop = ioloop.IOLoop
|
||||
while _IOLoop.configurable_default() is not _IOLoop:
|
||||
_IOLoop = _IOLoop.configurable_default()
|
||||
|
||||
|
||||
class ZMQIOLoop(_IOLoop):
|
||||
"""DEPRECATED: No longer needed as of pyzmq-17
|
||||
|
||||
PyZMQ tornado integration now works with the default :mod:`tornado.ioloop.IOLoop`.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
_deprecated()
|
||||
# super is object, which takes no args
|
||||
return super(ZMQIOLoop, self).__init__()
|
||||
|
||||
@classmethod
|
||||
def instance(cls, *args, **kwargs):
|
||||
"""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
|
||||
ioloop.IOLoop.configure(cls)
|
||||
_deprecated()
|
||||
loop = ioloop.IOLoop.instance(*args, **kwargs)
|
||||
return loop
|
||||
|
||||
@classmethod
|
||||
def current(cls, *args, **kwargs):
|
||||
"""Returns the current thread’s IOLoop.
|
||||
"""
|
||||
# install ZMQIOLoop as the active IOLoop implementation
|
||||
# when using tornado 3
|
||||
ioloop.IOLoop.configure(cls)
|
||||
_deprecated()
|
||||
loop = ioloop.IOLoop.current(*args, **kwargs)
|
||||
return loop
|
||||
|
||||
|
||||
# public API name
|
||||
IOLoop = ZMQIOLoop
|
||||
|
||||
|
||||
def install():
|
||||
"""DEPRECATED
|
||||
|
||||
pyzmq 17 no longer needs any special integration for tornado.
|
||||
"""
|
||||
_deprecated()
|
||||
ioloop.IOLoop.configure(ZMQIOLoop)
|
||||
|
||||
|
||||
# if minitornado is used, fallback on deprecated ZMQIOLoop, install implementations
|
||||
if '.minitornado.' in ioloop.__name__:
|
||||
from ._deprecated import ZMQIOLoop, install, IOLoop
|
||||
|
11
venv/Lib/site-packages/zmq/eventloop/minitornado/__init__.py
Normal file
11
venv/Lib/site-packages/zmq/eventloop/minitornado/__init__.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
import warnings
|
||||
class VisibleDeprecationWarning(UserWarning):
|
||||
"""A DeprecationWarning that users should see."""
|
||||
pass
|
||||
|
||||
warnings.warn("""zmq.eventloop.minitornado is deprecated in pyzmq 14.0 and will be removed.
|
||||
Install tornado itself to use zmq with the tornado IOLoop.
|
||||
""",
|
||||
VisibleDeprecationWarning,
|
||||
stacklevel=4,
|
||||
)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue