first comit
This commit is contained in:
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.
234
venv/lib/python3.10/site-packages/zmq/utils/buffers.pxd
Normal file
234
venv/lib/python3.10/site-packages/zmq/utils/buffers.pxd
Normal file
@@ -0,0 +1,234 @@
|
||||
"""Python version-independent methods for C/Python buffers.
|
||||
|
||||
This file was copied and adapted from mpi4py.
|
||||
|
||||
Authors
|
||||
-------
|
||||
* MinRK
|
||||
"""
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (c) 2010 Lisandro Dalcin
|
||||
# All rights reserved.
|
||||
# Used under BSD License: http://www.opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# Retrieval:
|
||||
# Jul 23, 2010 18:00 PST (r539)
|
||||
# http://code.google.com/p/mpi4py/source/browse/trunk/src/MPI/asbuffer.pxi
|
||||
#
|
||||
# Modifications from original:
|
||||
# Copyright (c) 2010-2012 Brian Granger, Min Ragan-Kelley
|
||||
#
|
||||
# Distributed under the terms of the New BSD License. The full license is in
|
||||
# the file LICENSE.BSD, distributed as part of this software.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Python includes.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# get version-independent aliases:
|
||||
cdef extern from "pyversion_compat.h":
|
||||
pass
|
||||
|
||||
# Python 3 buffer interface (PEP 3118)
|
||||
cdef extern from "Python.h":
|
||||
int PY_MAJOR_VERSION
|
||||
int PY_MINOR_VERSION
|
||||
ctypedef int Py_ssize_t
|
||||
ctypedef struct PyMemoryViewObject:
|
||||
pass
|
||||
ctypedef struct Py_buffer:
|
||||
void *buf
|
||||
Py_ssize_t len
|
||||
int readonly
|
||||
char *format
|
||||
int ndim
|
||||
Py_ssize_t *shape
|
||||
Py_ssize_t *strides
|
||||
Py_ssize_t *suboffsets
|
||||
Py_ssize_t itemsize
|
||||
void *internal
|
||||
cdef enum:
|
||||
PyBUF_SIMPLE
|
||||
PyBUF_WRITABLE
|
||||
PyBUF_FORMAT
|
||||
PyBUF_ANY_CONTIGUOUS
|
||||
int PyObject_CheckBuffer(object)
|
||||
int PyObject_GetBuffer(object, Py_buffer *, int) except -1
|
||||
void PyBuffer_Release(Py_buffer *)
|
||||
|
||||
int PyBuffer_FillInfo(Py_buffer *view, object obj, void *buf,
|
||||
Py_ssize_t len, int readonly, int infoflags) except -1
|
||||
object PyMemoryView_FromBuffer(Py_buffer *info)
|
||||
|
||||
object PyMemoryView_FromObject(object)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# asbuffer: C buffer from python object
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
cdef inline int check_buffer(object ob):
|
||||
"""Version independent check for whether an object is a buffer.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
object : object
|
||||
Any Python object
|
||||
|
||||
Returns
|
||||
-------
|
||||
int : 0 if no buffer interface, 3 if newstyle buffer interface, 2 if oldstyle (removed).
|
||||
"""
|
||||
if PyObject_CheckBuffer(ob):
|
||||
return 3
|
||||
return 0
|
||||
|
||||
|
||||
cdef inline object asbuffer(object ob, int writable, int format,
|
||||
void **base, Py_ssize_t *size,
|
||||
Py_ssize_t *itemsize):
|
||||
"""Turn an object into a C buffer in a Python version-independent way.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ob : object
|
||||
The object to be turned into a buffer.
|
||||
Must provide a Python Buffer interface
|
||||
writable : int
|
||||
Whether the resulting buffer should be allowed to write
|
||||
to the object.
|
||||
format : int
|
||||
The format of the buffer. See Python buffer docs.
|
||||
base : void **
|
||||
The pointer that will be used to store the resulting C buffer.
|
||||
size : Py_ssize_t *
|
||||
The size of the buffer(s).
|
||||
itemsize : Py_ssize_t *
|
||||
The size of an item, if the buffer is non-contiguous.
|
||||
|
||||
Returns
|
||||
-------
|
||||
An object describing the buffer format. Generally a str, such as 'B'.
|
||||
"""
|
||||
|
||||
cdef void *bptr = NULL
|
||||
cdef Py_ssize_t blen = 0, bitemlen = 0
|
||||
cdef Py_buffer view
|
||||
cdef int flags = PyBUF_SIMPLE
|
||||
cdef int mode = 0
|
||||
|
||||
bfmt = None
|
||||
|
||||
mode = check_buffer(ob)
|
||||
if mode == 0:
|
||||
raise TypeError("%r does not provide a buffer interface."%ob)
|
||||
|
||||
if mode == 3:
|
||||
flags = PyBUF_ANY_CONTIGUOUS
|
||||
if writable:
|
||||
flags |= PyBUF_WRITABLE
|
||||
if format:
|
||||
flags |= PyBUF_FORMAT
|
||||
PyObject_GetBuffer(ob, &view, flags)
|
||||
bptr = view.buf
|
||||
blen = view.len
|
||||
if format:
|
||||
if view.format != NULL:
|
||||
bfmt = view.format
|
||||
bitemlen = view.itemsize
|
||||
PyBuffer_Release(&view)
|
||||
|
||||
if base: base[0] = <void *>bptr
|
||||
if size: size[0] = <Py_ssize_t>blen
|
||||
if itemsize: itemsize[0] = <Py_ssize_t>bitemlen
|
||||
|
||||
if bfmt is not None:
|
||||
return bfmt.decode('ascii')
|
||||
return bfmt
|
||||
|
||||
|
||||
cdef inline object asbuffer_r(object ob, void **base, Py_ssize_t *size):
|
||||
"""Wrapper for standard calls to asbuffer with a readonly buffer."""
|
||||
asbuffer(ob, 0, 0, base, size, NULL)
|
||||
return ob
|
||||
|
||||
|
||||
cdef inline object asbuffer_w(object ob, void **base, Py_ssize_t *size):
|
||||
"""Wrapper for standard calls to asbuffer with a writable buffer."""
|
||||
asbuffer(ob, 1, 0, base, size, NULL)
|
||||
return ob
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# frombuffer: python buffer/view from C buffer
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
|
||||
cdef inline object frombuffer(void *ptr, Py_ssize_t s, int readonly):
|
||||
"""Create a Python Memory View of a C array.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ptr : void *
|
||||
Pointer to the array to be copied.
|
||||
s : size_t
|
||||
Length of the buffer.
|
||||
readonly : int
|
||||
whether the resulting object should be allowed to write to the buffer.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Python Memory View of the C buffer.
|
||||
"""
|
||||
cdef Py_buffer pybuf
|
||||
cdef Py_ssize_t *shape = [s]
|
||||
cdef str astr=""
|
||||
PyBuffer_FillInfo(&pybuf, astr, ptr, s, readonly, PyBUF_SIMPLE)
|
||||
pybuf.format = "B"
|
||||
pybuf.shape = shape
|
||||
pybuf.ndim = 1
|
||||
return PyMemoryView_FromBuffer(&pybuf)
|
||||
|
||||
|
||||
cdef inline object frombuffer_r(void *ptr, Py_ssize_t s):
|
||||
"""Wrapper for readonly view frombuffer."""
|
||||
return frombuffer(ptr, s, 1)
|
||||
|
||||
|
||||
cdef inline object frombuffer_w(void *ptr, Py_ssize_t s):
|
||||
"""Wrapper for writable view frombuffer."""
|
||||
return frombuffer(ptr, s, 0)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# viewfromobject: python buffer/view from python object, refcounts intact
|
||||
# frombuffer(asbuffer(obj)) would lose track of refs
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
cdef inline object viewfromobject(object obj, int readonly):
|
||||
"""Construct a Python Memory View object from another Python object.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obj : object
|
||||
The input object to be cast as a buffer
|
||||
readonly : int
|
||||
Whether the result should be prevented from overwriting the original.
|
||||
|
||||
Returns
|
||||
-------
|
||||
MemoryView of the original object.
|
||||
"""
|
||||
return PyMemoryView_FromObject(obj)
|
||||
|
||||
|
||||
cdef inline object viewfromobject_r(object obj):
|
||||
"""Wrapper for readonly viewfromobject."""
|
||||
return viewfromobject(obj, 1)
|
||||
|
||||
|
||||
cdef inline object viewfromobject_w(object obj):
|
||||
"""Wrapper for writable viewfromobject."""
|
||||
return viewfromobject(obj, 0)
|
||||
22
venv/lib/python3.10/site-packages/zmq/utils/compiler.json
Normal file
22
venv/lib/python3.10/site-packages/zmq/utils/compiler.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"libraries": [
|
||||
"zmq"
|
||||
],
|
||||
"include_dirs": [
|
||||
"/usr/local/include",
|
||||
"zmq/utils"
|
||||
],
|
||||
"library_dirs": [
|
||||
"/usr/local/lib"
|
||||
],
|
||||
"runtime_library_dirs": [
|
||||
"/usr/local/lib"
|
||||
],
|
||||
"extra_link_args": [],
|
||||
"define_macros": [
|
||||
[
|
||||
"HAVE_SYS_UN_H",
|
||||
1
|
||||
]
|
||||
]
|
||||
}
|
||||
13
venv/lib/python3.10/site-packages/zmq/utils/config.json
Normal file
13
venv/lib/python3.10/site-packages/zmq/utils/config.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"zmq_prefix": "/usr/local",
|
||||
"zmq_draft_api": false,
|
||||
"libzmq_extension": false,
|
||||
"no_libzmq_extension": true,
|
||||
"skip_check_zmq": false,
|
||||
"allow_legacy_libzmq": true,
|
||||
"bundle_msvcp": null,
|
||||
"build_ext": {},
|
||||
"bdist_egg": {},
|
||||
"win_ver": null,
|
||||
"have_sys_un_h": true
|
||||
}
|
||||
214
venv/lib/python3.10/site-packages/zmq/utils/garbage.py
Normal file
214
venv/lib/python3.10/site-packages/zmq/utils/garbage.py
Normal file
@@ -0,0 +1,214 @@
|
||||
"""Garbage collection thread for representing zmq refcount of Python objects
|
||||
used in zero-copy sends.
|
||||
"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
import atexit
|
||||
import struct
|
||||
import warnings
|
||||
from collections import namedtuple
|
||||
from os import getpid
|
||||
from threading import Event, Lock, Thread
|
||||
|
||||
import zmq
|
||||
|
||||
gcref = namedtuple('gcref', ['obj', 'event'])
|
||||
|
||||
|
||||
class GarbageCollectorThread(Thread):
|
||||
"""Thread in which garbage collection actually happens."""
|
||||
|
||||
def __init__(self, gc):
|
||||
super().__init__()
|
||||
self.gc = gc
|
||||
self.daemon = True
|
||||
self.pid = getpid()
|
||||
self.ready = Event()
|
||||
|
||||
def run(self):
|
||||
# detect fork at beginning of the thread
|
||||
if getpid is None or getpid() != self.pid:
|
||||
self.ready.set()
|
||||
return
|
||||
try:
|
||||
s = self.gc.context.socket(zmq.PULL)
|
||||
s.linger = 0
|
||||
s.bind(self.gc.url)
|
||||
finally:
|
||||
self.ready.set()
|
||||
|
||||
while True:
|
||||
# detect fork
|
||||
if getpid is None or getpid() != self.pid:
|
||||
return
|
||||
msg = s.recv()
|
||||
if msg == b'DIE':
|
||||
break
|
||||
fmt = 'L' if len(msg) == 4 else 'Q'
|
||||
key = struct.unpack(fmt, msg)[0]
|
||||
tup = self.gc.refs.pop(key, None)
|
||||
if tup and tup.event:
|
||||
tup.event.set()
|
||||
del tup
|
||||
s.close()
|
||||
|
||||
|
||||
class GarbageCollector:
|
||||
"""PyZMQ Garbage Collector
|
||||
|
||||
Used for representing the reference held by libzmq during zero-copy sends.
|
||||
This object holds a dictionary, keyed by Python id,
|
||||
of the Python objects whose memory are currently in use by zeromq.
|
||||
|
||||
When zeromq is done with the memory, it sends a message on an inproc PUSH socket
|
||||
containing the packed size_t (32 or 64-bit unsigned int),
|
||||
which is the key in the dict.
|
||||
When the PULL socket in the gc thread receives that message,
|
||||
the reference is popped from the dict,
|
||||
and any tracker events that should be signaled fire.
|
||||
"""
|
||||
|
||||
refs = None
|
||||
_context = None
|
||||
_lock = None
|
||||
url = "inproc://pyzmq.gc.01"
|
||||
|
||||
def __init__(self, context=None):
|
||||
super().__init__()
|
||||
self.refs = {}
|
||||
self.pid = None
|
||||
self.thread = None
|
||||
self._context = context
|
||||
self._lock = Lock()
|
||||
self._stay_down = False
|
||||
self._push = None
|
||||
self._push_mutex = None
|
||||
atexit.register(self._atexit)
|
||||
|
||||
@property
|
||||
def context(self):
|
||||
if self._context is None:
|
||||
if Thread.__module__.startswith('gevent'):
|
||||
# gevent has monkey-patched Thread, use green Context
|
||||
from zmq import green
|
||||
|
||||
self._context = green.Context()
|
||||
else:
|
||||
self._context = zmq.Context()
|
||||
return self._context
|
||||
|
||||
@context.setter
|
||||
def context(self, ctx):
|
||||
if self.is_alive():
|
||||
if self.refs:
|
||||
warnings.warn(
|
||||
"Replacing gc context while gc is running", RuntimeWarning
|
||||
)
|
||||
self.stop()
|
||||
self._context = ctx
|
||||
|
||||
def _atexit(self):
|
||||
"""atexit callback
|
||||
|
||||
sets _stay_down flag so that gc doesn't try to start up again in other atexit handlers
|
||||
"""
|
||||
self._stay_down = True
|
||||
self.stop()
|
||||
|
||||
def stop(self):
|
||||
"""stop the garbage-collection thread"""
|
||||
if not self.is_alive():
|
||||
return
|
||||
self._stop()
|
||||
|
||||
def _clear(self):
|
||||
"""Clear state
|
||||
|
||||
called after stop or when setting up a new subprocess
|
||||
"""
|
||||
self._push = None
|
||||
self._push_mutex = None
|
||||
self.thread = None
|
||||
self.refs.clear()
|
||||
self.context = None
|
||||
|
||||
def _stop(self):
|
||||
push = self.context.socket(zmq.PUSH)
|
||||
push.connect(self.url)
|
||||
push.send(b'DIE')
|
||||
push.close()
|
||||
if self._push:
|
||||
self._push.close()
|
||||
self.thread.join()
|
||||
self.context.term()
|
||||
self._clear()
|
||||
|
||||
@property
|
||||
def _push_socket(self):
|
||||
"""The PUSH socket for use in the zmq message destructor callback."""
|
||||
if getattr(self, "_stay_down", False):
|
||||
raise RuntimeError("zmq gc socket requested during shutdown")
|
||||
if not self.is_alive() or self._push is None:
|
||||
self._push = self.context.socket(zmq.PUSH)
|
||||
self._push.connect(self.url)
|
||||
return self._push
|
||||
|
||||
def start(self):
|
||||
"""Start a new garbage collection thread.
|
||||
|
||||
Creates a new zmq Context used for garbage collection.
|
||||
Under most circumstances, this will only be called once per process.
|
||||
"""
|
||||
if self.thread is not None and self.pid != getpid():
|
||||
# It's re-starting, must free earlier thread's context
|
||||
# since a fork probably broke it
|
||||
self._clear()
|
||||
self.pid = getpid()
|
||||
self.refs = {}
|
||||
self.thread = GarbageCollectorThread(self)
|
||||
self.thread.start()
|
||||
self.thread.ready.wait()
|
||||
|
||||
def is_alive(self):
|
||||
"""Is the garbage collection thread currently running?
|
||||
|
||||
Includes checks for process shutdown or fork.
|
||||
"""
|
||||
if (
|
||||
getpid is None
|
||||
or getpid() != self.pid
|
||||
or self.thread is None
|
||||
or not self.thread.is_alive()
|
||||
):
|
||||
return False
|
||||
return True
|
||||
|
||||
def store(self, obj, event=None):
|
||||
"""store an object and (optionally) event for zero-copy"""
|
||||
if not self.is_alive():
|
||||
if self._stay_down:
|
||||
return 0
|
||||
# safely start the gc thread
|
||||
# use lock and double check,
|
||||
# so we don't start multiple threads
|
||||
with self._lock:
|
||||
if not self.is_alive():
|
||||
self.start()
|
||||
tup = gcref(obj, event)
|
||||
theid = id(tup)
|
||||
self.refs[theid] = tup
|
||||
return theid
|
||||
|
||||
def __del__(self):
|
||||
if not self.is_alive():
|
||||
return
|
||||
try:
|
||||
self.stop()
|
||||
except Exception as e:
|
||||
raise (e)
|
||||
|
||||
|
||||
gc = GarbageCollector()
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#ifdef _WIN32
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
29
venv/lib/python3.10/site-packages/zmq/utils/interop.py
Normal file
29
venv/lib/python3.10/site-packages/zmq/utils/interop.py
Normal file
@@ -0,0 +1,29 @@
|
||||
"""Utils for interoperability with other libraries.
|
||||
|
||||
Just CFFI pointer casting for now.
|
||||
"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
def cast_int_addr(n: Any) -> int:
|
||||
"""Cast an address to a Python int
|
||||
|
||||
This could be a Python integer or a CFFI pointer
|
||||
"""
|
||||
if isinstance(n, int):
|
||||
return n
|
||||
try:
|
||||
import cffi # type: ignore
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
# from pyzmq, this is an FFI void *
|
||||
ffi = cffi.FFI()
|
||||
if isinstance(n, ffi.CData):
|
||||
return int(ffi.cast("size_t", n))
|
||||
|
||||
raise ValueError("Cannot cast %r to int" % n)
|
||||
27
venv/lib/python3.10/site-packages/zmq/utils/ipcmaxlen.h
Normal file
27
venv/lib/python3.10/site-packages/zmq/utils/ipcmaxlen.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
|
||||
Platform-independant detection of IPC path max length
|
||||
|
||||
Copyright (c) 2012 Godefroid Chapelle
|
||||
|
||||
Distributed under the terms of the New BSD License. The full license is in
|
||||
the file LICENSE.BSD, distributed as part of this software.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(HAVE_SYS_UN_H)
|
||||
#if defined _MSC_VER
|
||||
#include <afunix.h>
|
||||
#else
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
int get_ipc_path_max_len(void) {
|
||||
struct sockaddr_un *dummy;
|
||||
return sizeof(dummy->sun_path) - 1;
|
||||
}
|
||||
#else
|
||||
int get_ipc_path_max_len(void) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
37
venv/lib/python3.10/site-packages/zmq/utils/jsonapi.py
Normal file
37
venv/lib/python3.10/site-packages/zmq/utils/jsonapi.py
Normal file
@@ -0,0 +1,37 @@
|
||||
"""JSON serialize to/from utf8 bytes
|
||||
|
||||
.. versionchanged:: 22.2
|
||||
Remove optional imports of different JSON implementations.
|
||||
Now that we require recent Python, unconditionally use the standard library.
|
||||
Custom JSON libraries can be used via custom serialization functions.
|
||||
"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import json
|
||||
from typing import Any, Dict, List, Union
|
||||
|
||||
# backward-compatibility, unused
|
||||
jsonmod = json
|
||||
|
||||
|
||||
def dumps(o: Any, **kwargs) -> bytes:
|
||||
"""Serialize object to JSON bytes (utf-8).
|
||||
|
||||
Keyword arguments are passed along to :py:func:`json.dumps`.
|
||||
"""
|
||||
return json.dumps(o, **kwargs).encode("utf8")
|
||||
|
||||
|
||||
def loads(s: Union[bytes, str], **kwargs) -> Union[Dict, List, str, int, float]:
|
||||
"""Load object from JSON bytes (utf-8).
|
||||
|
||||
Keyword arguments are passed along to :py:func:`json.loads`.
|
||||
"""
|
||||
if isinstance(s, bytes):
|
||||
s = s.decode("utf8")
|
||||
return json.loads(s, **kwargs)
|
||||
|
||||
|
||||
__all__ = ['dumps', 'loads']
|
||||
126
venv/lib/python3.10/site-packages/zmq/utils/monitor.py
Normal file
126
venv/lib/python3.10/site-packages/zmq/utils/monitor.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""Module holding utility and convenience functions for zmq event monitoring."""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import struct
|
||||
from typing import Awaitable, List, Union, overload
|
||||
|
||||
import zmq
|
||||
import zmq.asyncio
|
||||
from zmq._typing import TypedDict
|
||||
from zmq.error import _check_version
|
||||
|
||||
|
||||
class _MonitorMessage(TypedDict):
|
||||
event: int
|
||||
value: int
|
||||
endpoint: bytes
|
||||
|
||||
|
||||
def parse_monitor_message(msg: List[bytes]) -> _MonitorMessage:
|
||||
"""decode zmq_monitor event messages.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
msg : list(bytes)
|
||||
zmq multipart message that has arrived on a monitor PAIR socket.
|
||||
|
||||
First frame is::
|
||||
|
||||
16 bit event id
|
||||
32 bit event value
|
||||
no padding
|
||||
|
||||
Second frame is the endpoint as a bytestring
|
||||
|
||||
Returns
|
||||
-------
|
||||
event : dict
|
||||
event description as dict with the keys `event`, `value`, and `endpoint`.
|
||||
"""
|
||||
if len(msg) != 2 or len(msg[0]) != 6:
|
||||
raise RuntimeError("Invalid event message format: %s" % msg)
|
||||
event_id, value = struct.unpack("=hi", msg[0])
|
||||
event: _MonitorMessage = {
|
||||
'event': zmq.Event(event_id),
|
||||
'value': zmq.Event(value),
|
||||
'endpoint': msg[1],
|
||||
}
|
||||
return event
|
||||
|
||||
|
||||
async def _parse_monitor_msg_async(
|
||||
awaitable_msg: Awaitable[List[bytes]],
|
||||
) -> _MonitorMessage:
|
||||
"""Like parse_monitor_msg, but awaitable
|
||||
|
||||
Given awaitable message, return awaitable for the parsed monitor message.
|
||||
"""
|
||||
|
||||
msg = await awaitable_msg
|
||||
# 4.0-style event API
|
||||
return parse_monitor_message(msg)
|
||||
|
||||
|
||||
@overload
|
||||
def recv_monitor_message(
|
||||
socket: "zmq.asyncio.Socket",
|
||||
flags: int = 0,
|
||||
) -> Awaitable[_MonitorMessage]:
|
||||
...
|
||||
|
||||
|
||||
@overload
|
||||
def recv_monitor_message(
|
||||
socket: zmq.Socket[bytes],
|
||||
flags: int = 0,
|
||||
) -> _MonitorMessage:
|
||||
...
|
||||
|
||||
|
||||
def recv_monitor_message(
|
||||
socket: zmq.Socket,
|
||||
flags: int = 0,
|
||||
) -> Union[_MonitorMessage, Awaitable[_MonitorMessage]]:
|
||||
"""Receive and decode the given raw message from the monitoring socket and return a dict.
|
||||
|
||||
Requires libzmq ≥ 4.0
|
||||
|
||||
The returned dict will have the following entries:
|
||||
event : int, the event id as described in libzmq.zmq_socket_monitor
|
||||
value : int, the event value associated with the event, see libzmq.zmq_socket_monitor
|
||||
endpoint : string, the affected endpoint
|
||||
|
||||
.. versionchanged:: 23.1
|
||||
Support for async sockets added.
|
||||
When called with a async socket,
|
||||
returns an awaitable for the monitor message.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
socket : zmq PAIR socket
|
||||
The PAIR socket (created by other.get_monitor_socket()) on which to recv the message
|
||||
flags : bitfield (int)
|
||||
standard zmq recv flags
|
||||
|
||||
Returns
|
||||
-------
|
||||
event : dict
|
||||
event description as dict with the keys `event`, `value`, and `endpoint`.
|
||||
"""
|
||||
|
||||
_check_version((4, 0), 'libzmq event API')
|
||||
# will always return a list
|
||||
msg = socket.recv_multipart(flags)
|
||||
|
||||
# transparently handle asyncio socket,
|
||||
# returns a Future instead of a dict
|
||||
if isinstance(msg, Awaitable):
|
||||
return _parse_monitor_msg_async(msg)
|
||||
|
||||
# 4.0-style event API
|
||||
return parse_monitor_message(msg)
|
||||
|
||||
|
||||
__all__ = ['parse_monitor_message', 'recv_monitor_message']
|
||||
82
venv/lib/python3.10/site-packages/zmq/utils/mutex.h
Normal file
82
venv/lib/python3.10/site-packages/zmq/utils/mutex.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* simplified from mutex.c from Foundation Library, in the Public Domain
|
||||
* https://github.com/rampantpixels/foundation_lib/blob/master/foundation/mutex.c
|
||||
*
|
||||
* This file is Copyright (C) PyZMQ Developers
|
||||
* Distributed under the terms of the Modified BSD License.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#if defined(_WIN32)
|
||||
CRITICAL_SECTION csection;
|
||||
#else
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
} mutex_t;
|
||||
|
||||
|
||||
static void
|
||||
_mutex_initialize(mutex_t* mutex) {
|
||||
#if defined(_WIN32)
|
||||
InitializeCriticalSectionAndSpinCount(&mutex->csection, 4000);
|
||||
#else
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mutex->mutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
_mutex_finalize(mutex_t* mutex) {
|
||||
#if defined(_WIN32)
|
||||
DeleteCriticalSection(&mutex->csection);
|
||||
#else
|
||||
pthread_mutex_destroy(&mutex->mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
mutex_t*
|
||||
mutex_allocate(void) {
|
||||
mutex_t* mutex = (mutex_t*)malloc(sizeof(mutex_t));
|
||||
_mutex_initialize(mutex);
|
||||
return mutex;
|
||||
}
|
||||
|
||||
void
|
||||
mutex_deallocate(mutex_t* mutex) {
|
||||
if (!mutex)
|
||||
return;
|
||||
_mutex_finalize(mutex);
|
||||
free(mutex);
|
||||
}
|
||||
|
||||
int
|
||||
mutex_lock(mutex_t* mutex) {
|
||||
#if defined(_WIN32)
|
||||
EnterCriticalSection(&mutex->csection);
|
||||
return 0;
|
||||
#else
|
||||
return pthread_mutex_lock(&mutex->mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
mutex_unlock(mutex_t* mutex) {
|
||||
#if defined(_WIN32)
|
||||
LeaveCriticalSection(&mutex->csection);
|
||||
return 0;
|
||||
#else
|
||||
return pthread_mutex_unlock(&mutex->mutex);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "Python.h"
|
||||
|
||||
// default to Python's own target Windows version(s)
|
||||
// override by setting WINVER, _WIN32_WINNT, (maybe also NTDDI_VERSION?) macros
|
||||
#ifdef Py_WINVER
|
||||
#ifndef WINVER
|
||||
#define WINVER Py_WINVER
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT Py_WINVER
|
||||
#endif
|
||||
#endif
|
||||
62
venv/lib/python3.10/site-packages/zmq/utils/strtypes.py
Normal file
62
venv/lib/python3.10/site-packages/zmq/utils/strtypes.py
Normal file
@@ -0,0 +1,62 @@
|
||||
"""Declare basic string types unambiguously for various Python versions.
|
||||
|
||||
Authors
|
||||
-------
|
||||
* MinRK
|
||||
"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import warnings
|
||||
|
||||
bytes = bytes
|
||||
unicode = str
|
||||
basestring = (str,)
|
||||
|
||||
|
||||
def cast_bytes(s, encoding='utf8', errors='strict'):
|
||||
"""cast unicode or bytes to bytes"""
|
||||
warnings.warn(
|
||||
"zmq.utils.strtypes is deprecated in pyzmq 23.",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
if isinstance(s, bytes):
|
||||
return s
|
||||
elif isinstance(s, str):
|
||||
return s.encode(encoding, errors)
|
||||
else:
|
||||
raise TypeError("Expected unicode or bytes, got %r" % s)
|
||||
|
||||
|
||||
def cast_unicode(s, encoding='utf8', errors='strict'):
|
||||
"""cast bytes or unicode to unicode"""
|
||||
warnings.warn(
|
||||
"zmq.utils.strtypes is deprecated in pyzmq 23.",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
if isinstance(s, bytes):
|
||||
return s.decode(encoding, errors)
|
||||
elif isinstance(s, str):
|
||||
return s
|
||||
else:
|
||||
raise TypeError("Expected unicode or bytes, got %r" % s)
|
||||
|
||||
|
||||
# give short 'b' alias for cast_bytes, so that we can use fake b'stuff'
|
||||
# to simulate b'stuff'
|
||||
b = asbytes = cast_bytes
|
||||
u = cast_unicode
|
||||
|
||||
__all__ = [
|
||||
'asbytes',
|
||||
'bytes',
|
||||
'unicode',
|
||||
'basestring',
|
||||
'b',
|
||||
'u',
|
||||
'cast_bytes',
|
||||
'cast_unicode',
|
||||
]
|
||||
126
venv/lib/python3.10/site-packages/zmq/utils/win32.py
Normal file
126
venv/lib/python3.10/site-packages/zmq/utils/win32.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""Win32 compatibility utilities."""
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
from typing import Any, Callable, Optional
|
||||
|
||||
|
||||
class allow_interrupt:
|
||||
"""Utility for fixing CTRL-C events on Windows.
|
||||
|
||||
On Windows, the Python interpreter intercepts CTRL-C events in order to
|
||||
translate them into ``KeyboardInterrupt`` exceptions. It (presumably)
|
||||
does this by setting a flag in its "console control handler" and
|
||||
checking it later at a convenient location in the interpreter.
|
||||
|
||||
However, when the Python interpreter is blocked waiting for the ZMQ
|
||||
poll operation to complete, it must wait for ZMQ's ``select()``
|
||||
operation to complete before translating the CTRL-C event into the
|
||||
``KeyboardInterrupt`` exception.
|
||||
|
||||
The only way to fix this seems to be to add our own "console control
|
||||
handler" and perform some application-defined operation that will
|
||||
unblock the ZMQ polling operation in order to force ZMQ to pass control
|
||||
back to the Python interpreter.
|
||||
|
||||
This context manager performs all that Windows-y stuff, providing you
|
||||
with a hook that is called when a CTRL-C event is intercepted. This
|
||||
hook allows you to unblock your ZMQ poll operation immediately, which
|
||||
will then result in the expected ``KeyboardInterrupt`` exception.
|
||||
|
||||
Without this context manager, your ZMQ-based application will not
|
||||
respond normally to CTRL-C events on Windows. If a CTRL-C event occurs
|
||||
while blocked on ZMQ socket polling, the translation to a
|
||||
``KeyboardInterrupt`` exception will be delayed until the I/O completes
|
||||
and control returns to the Python interpreter (this may never happen if
|
||||
you use an infinite timeout).
|
||||
|
||||
A no-op implementation is provided on non-Win32 systems to avoid the
|
||||
application from having to conditionally use it.
|
||||
|
||||
Example usage:
|
||||
|
||||
.. sourcecode:: python
|
||||
|
||||
def stop_my_application():
|
||||
# ...
|
||||
|
||||
with allow_interrupt(stop_my_application):
|
||||
# main polling loop.
|
||||
|
||||
In a typical ZMQ application, you would use the "self pipe trick" to
|
||||
send message to a ``PAIR`` socket in order to interrupt your blocking
|
||||
socket polling operation.
|
||||
|
||||
In a Tornado event loop, you can use the ``IOLoop.stop`` method to
|
||||
unblock your I/O loop.
|
||||
"""
|
||||
|
||||
def __init__(self, action: Optional[Callable[[], Any]] = None) -> None:
|
||||
"""Translate ``action`` into a CTRL-C handler.
|
||||
|
||||
``action`` is a callable that takes no arguments and returns no
|
||||
value (returned value is ignored). It must *NEVER* raise an
|
||||
exception.
|
||||
|
||||
If unspecified, a no-op will be used.
|
||||
"""
|
||||
if os.name != "nt":
|
||||
return
|
||||
self._init_action(action)
|
||||
|
||||
def _init_action(self, action):
|
||||
from ctypes import WINFUNCTYPE, windll
|
||||
from ctypes.wintypes import BOOL, DWORD
|
||||
|
||||
kernel32 = windll.LoadLibrary('kernel32')
|
||||
|
||||
# <http://msdn.microsoft.com/en-us/library/ms686016.aspx>
|
||||
PHANDLER_ROUTINE = WINFUNCTYPE(BOOL, DWORD)
|
||||
SetConsoleCtrlHandler = (
|
||||
self._SetConsoleCtrlHandler
|
||||
) = kernel32.SetConsoleCtrlHandler
|
||||
SetConsoleCtrlHandler.argtypes = (PHANDLER_ROUTINE, BOOL)
|
||||
SetConsoleCtrlHandler.restype = BOOL
|
||||
|
||||
if action is None:
|
||||
action = lambda: None
|
||||
self.action = action
|
||||
|
||||
@PHANDLER_ROUTINE
|
||||
def handle(event):
|
||||
if event == 0: # CTRL_C_EVENT
|
||||
action()
|
||||
# Typical C implementations would return 1 to indicate that
|
||||
# the event was processed and other control handlers in the
|
||||
# stack should not be executed. However, that would
|
||||
# prevent the Python interpreter's handler from translating
|
||||
# CTRL-C to a `KeyboardInterrupt` exception, so we pretend
|
||||
# that we didn't handle it.
|
||||
return 0
|
||||
|
||||
self.handle = handle
|
||||
|
||||
def __enter__(self):
|
||||
"""Install the custom CTRL-C handler."""
|
||||
if os.name != "nt":
|
||||
return
|
||||
result = self._SetConsoleCtrlHandler(self.handle, 1)
|
||||
if result == 0:
|
||||
# Have standard library automatically call `GetLastError()` and
|
||||
# `FormatMessage()` into a nice exception object :-)
|
||||
raise OSError()
|
||||
|
||||
def __exit__(self, *args):
|
||||
"""Remove the custom CTRL-C handler."""
|
||||
if os.name != "nt":
|
||||
return
|
||||
result = self._SetConsoleCtrlHandler(self.handle, 0)
|
||||
if result == 0:
|
||||
# Have standard library automatically call `GetLastError()` and
|
||||
# `FormatMessage()` into a nice exception object :-)
|
||||
raise OSError()
|
||||
58
venv/lib/python3.10/site-packages/zmq/utils/z85.py
Normal file
58
venv/lib/python3.10/site-packages/zmq/utils/z85.py
Normal file
@@ -0,0 +1,58 @@
|
||||
"""Python implementation of Z85 85-bit encoding
|
||||
|
||||
Z85 encoding is a plaintext encoding for a bytestring interpreted as 32bit integers.
|
||||
Since the chunks are 32bit, a bytestring must be a multiple of 4 bytes.
|
||||
See ZMQ RFC 32 for details.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
# Copyright (C) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import struct
|
||||
|
||||
# Z85CHARS is the base 85 symbol table
|
||||
Z85CHARS = b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#"
|
||||
# Z85MAP maps integers in [0,84] to the appropriate character in Z85CHARS
|
||||
Z85MAP = {c: idx for idx, c in enumerate(Z85CHARS)}
|
||||
|
||||
_85s = [85**i for i in range(5)][::-1]
|
||||
|
||||
|
||||
def encode(rawbytes):
|
||||
"""encode raw bytes into Z85"""
|
||||
# Accepts only byte arrays bounded to 4 bytes
|
||||
if len(rawbytes) % 4:
|
||||
raise ValueError("length must be multiple of 4, not %i" % len(rawbytes))
|
||||
|
||||
nvalues = len(rawbytes) / 4
|
||||
|
||||
values = struct.unpack('>%dI' % nvalues, rawbytes)
|
||||
encoded = []
|
||||
for v in values:
|
||||
for offset in _85s:
|
||||
encoded.append(Z85CHARS[(v // offset) % 85])
|
||||
|
||||
return bytes(encoded)
|
||||
|
||||
|
||||
def decode(z85bytes):
|
||||
"""decode Z85 bytes to raw bytes, accepts ASCII string"""
|
||||
if isinstance(z85bytes, str):
|
||||
try:
|
||||
z85bytes = z85bytes.encode('ascii')
|
||||
except UnicodeEncodeError:
|
||||
raise ValueError('string argument should contain only ASCII characters')
|
||||
|
||||
if len(z85bytes) % 5:
|
||||
raise ValueError("Z85 length must be multiple of 5, not %i" % len(z85bytes))
|
||||
|
||||
nvalues = len(z85bytes) / 5
|
||||
values = []
|
||||
for i in range(0, len(z85bytes), 5):
|
||||
value = 0
|
||||
for j, offset in enumerate(_85s):
|
||||
value += Z85MAP[z85bytes[i + j]] * offset
|
||||
values.append(value)
|
||||
return struct.pack('>%dI' % nvalues, *values)
|
||||
112
venv/lib/python3.10/site-packages/zmq/utils/zmq_compat.h
Normal file
112
venv/lib/python3.10/site-packages/zmq/utils/zmq_compat.h
Normal file
@@ -0,0 +1,112 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2010 Brian Granger, Min Ragan-Kelley
|
||||
//
|
||||
// Distributed under the terms of the New BSD License. The full license is in
|
||||
// the file LICENSE.BSD, distributed as part of this software.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define pyzmq_int64_t __int64
|
||||
#define pyzmq_uint32_t unsigned __int32
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#define pyzmq_int64_t int64_t
|
||||
#define pyzmq_uint32_t uint32_t
|
||||
#endif
|
||||
|
||||
|
||||
#include "zmq.h"
|
||||
|
||||
#define _missing (-1)
|
||||
|
||||
#if (ZMQ_VERSION >= 40303)
|
||||
// libzmq >= 4.3.3 defines zmq_fd_t for us
|
||||
#define ZMQ_FD_T zmq_fd_t
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1400
|
||||
#define ZMQ_FD_T UINT_PTR
|
||||
#else
|
||||
#define ZMQ_FD_T SOCKET
|
||||
#endif
|
||||
#else
|
||||
#define ZMQ_FD_T int
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (ZMQ_VERSION >= 40200)
|
||||
// Nothing to remove
|
||||
#else
|
||||
#define zmq_curve_public(z85_public_key, z85_secret_key) _missing
|
||||
#endif
|
||||
|
||||
// use unambiguous aliases for zmq_send/recv functions
|
||||
|
||||
#if ZMQ_VERSION_MAJOR >= 4
|
||||
// nothing to remove
|
||||
#if ZMQ_VERSION_MAJOR == 4 && ZMQ_VERSION_MINOR == 0
|
||||
// zmq 4.1 deprecates zmq_utils.h
|
||||
// we only get zmq_curve_keypair from it
|
||||
#include "zmq_utils.h"
|
||||
#endif
|
||||
#else
|
||||
#define zmq_curve_keypair(z85_public_key, z85_secret_key) _missing
|
||||
#endif
|
||||
|
||||
// libzmq 4.2 draft API
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
#if ZMQ_VERSION >= 40200
|
||||
#define PYZMQ_DRAFT_42
|
||||
#endif
|
||||
#endif
|
||||
#ifndef PYZMQ_DRAFT_42
|
||||
#define zmq_join(s, group) _missing
|
||||
#define zmq_leave(s, group) _missing
|
||||
#define zmq_msg_set_routing_id(msg, routing_id) _missing
|
||||
#define zmq_msg_routing_id(msg) 0
|
||||
#define zmq_msg_set_group(msg, group) _missing
|
||||
#define zmq_msg_group(msg) NULL
|
||||
#endif
|
||||
|
||||
#if ZMQ_VERSION >= 40100
|
||||
// nothing to remove
|
||||
#else
|
||||
#define zmq_msg_gets(msg, prop) _missing
|
||||
#define zmq_has(capability) _missing
|
||||
#define zmq_proxy_steerable(in, out, mon, ctrl) _missing
|
||||
#endif
|
||||
|
||||
#if ZMQ_VERSION_MAJOR >= 3
|
||||
#define zmq_sendbuf zmq_send
|
||||
#define zmq_recvbuf zmq_recv
|
||||
|
||||
// 3.x deprecations - these symbols haven't been removed,
|
||||
// but let's protect against their planned removal
|
||||
#define zmq_device(device_type, isocket, osocket) _missing
|
||||
#define zmq_init(io_threads) ((void*)NULL)
|
||||
#define zmq_term zmq_ctx_destroy
|
||||
#else
|
||||
#define zmq_ctx_set(ctx, opt, val) _missing
|
||||
#define zmq_ctx_get(ctx, opt) _missing
|
||||
#define zmq_ctx_destroy zmq_term
|
||||
#define zmq_ctx_new() ((void*)NULL)
|
||||
|
||||
#define zmq_proxy(a,b,c) _missing
|
||||
|
||||
#define zmq_disconnect(s, addr) _missing
|
||||
#define zmq_unbind(s, addr) _missing
|
||||
|
||||
#define zmq_msg_more(msg) _missing
|
||||
#define zmq_msg_get(msg, opt) _missing
|
||||
#define zmq_msg_set(msg, opt, val) _missing
|
||||
#define zmq_msg_send(msg, s, flags) zmq_send(s, msg, flags)
|
||||
#define zmq_msg_recv(msg, s, flags) zmq_recv(s, msg, flags)
|
||||
|
||||
#define zmq_sendbuf(s, buf, len, flags) _missing
|
||||
#define zmq_recvbuf(s, buf, len, flags) _missing
|
||||
|
||||
#define zmq_socket_monitor(s, addr, flags) _missing
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user