koichi12 commited on
Commit
9112421
·
verified ·
1 Parent(s): a10357c

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -0
  2. .venv/lib/python3.11/site-packages/fsspec/tests/abstract/__init__.py +289 -0
  3. .venv/lib/python3.11/site-packages/fsspec/tests/abstract/__pycache__/get.cpython-311.pyc +0 -0
  4. .venv/lib/python3.11/site-packages/fsspec/tests/abstract/__pycache__/pipe.cpython-311.pyc +0 -0
  5. .venv/lib/python3.11/site-packages/fsspec/tests/abstract/__pycache__/put.cpython-311.pyc +0 -0
  6. .venv/lib/python3.11/site-packages/fsspec/tests/abstract/open.py +11 -0
  7. .venv/lib/python3.11/site-packages/functorch/_C.cpython-311-x86_64-linux-gnu.so +3 -0
  8. .venv/lib/python3.11/site-packages/zmq/__init__.pxd +1 -0
  9. .venv/lib/python3.11/site-packages/zmq/__init__.py +94 -0
  10. .venv/lib/python3.11/site-packages/zmq/__init__.pyi +29 -0
  11. .venv/lib/python3.11/site-packages/zmq/__pycache__/__init__.cpython-311.pyc +0 -0
  12. .venv/lib/python3.11/site-packages/zmq/__pycache__/_future.cpython-311.pyc +0 -0
  13. .venv/lib/python3.11/site-packages/zmq/__pycache__/_typing.cpython-311.pyc +0 -0
  14. .venv/lib/python3.11/site-packages/zmq/__pycache__/asyncio.cpython-311.pyc +0 -0
  15. .venv/lib/python3.11/site-packages/zmq/__pycache__/constants.cpython-311.pyc +0 -0
  16. .venv/lib/python3.11/site-packages/zmq/__pycache__/decorators.cpython-311.pyc +0 -0
  17. .venv/lib/python3.11/site-packages/zmq/__pycache__/error.cpython-311.pyc +0 -0
  18. .venv/lib/python3.11/site-packages/zmq/_future.pyi +92 -0
  19. .venv/lib/python3.11/site-packages/zmq/_typing.py +30 -0
  20. .venv/lib/python3.11/site-packages/zmq/auth/__init__.py +13 -0
  21. .venv/lib/python3.11/site-packages/zmq/auth/__pycache__/__init__.cpython-311.pyc +0 -0
  22. .venv/lib/python3.11/site-packages/zmq/auth/__pycache__/asyncio.cpython-311.pyc +0 -0
  23. .venv/lib/python3.11/site-packages/zmq/auth/__pycache__/base.cpython-311.pyc +0 -0
  24. .venv/lib/python3.11/site-packages/zmq/auth/__pycache__/certs.cpython-311.pyc +0 -0
  25. .venv/lib/python3.11/site-packages/zmq/auth/__pycache__/ioloop.cpython-311.pyc +0 -0
  26. .venv/lib/python3.11/site-packages/zmq/auth/__pycache__/thread.cpython-311.pyc +0 -0
  27. .venv/lib/python3.11/site-packages/zmq/auth/asyncio.py +66 -0
  28. .venv/lib/python3.11/site-packages/zmq/auth/base.py +445 -0
  29. .venv/lib/python3.11/site-packages/zmq/auth/certs.py +140 -0
  30. .venv/lib/python3.11/site-packages/zmq/auth/ioloop.py +48 -0
  31. .venv/lib/python3.11/site-packages/zmq/auth/thread.py +139 -0
  32. .venv/lib/python3.11/site-packages/zmq/constants.py +974 -0
  33. .venv/lib/python3.11/site-packages/zmq/devices/__init__.py +28 -0
  34. .venv/lib/python3.11/site-packages/zmq/devices/__pycache__/__init__.cpython-311.pyc +0 -0
  35. .venv/lib/python3.11/site-packages/zmq/devices/__pycache__/basedevice.cpython-311.pyc +0 -0
  36. .venv/lib/python3.11/site-packages/zmq/devices/__pycache__/monitoredqueue.cpython-311.pyc +0 -0
  37. .venv/lib/python3.11/site-packages/zmq/devices/__pycache__/monitoredqueuedevice.cpython-311.pyc +0 -0
  38. .venv/lib/python3.11/site-packages/zmq/devices/__pycache__/proxydevice.cpython-311.pyc +0 -0
  39. .venv/lib/python3.11/site-packages/zmq/devices/__pycache__/proxysteerabledevice.cpython-311.pyc +0 -0
  40. .venv/lib/python3.11/site-packages/zmq/devices/basedevice.py +310 -0
  41. .venv/lib/python3.11/site-packages/zmq/devices/monitoredqueue.py +51 -0
  42. .venv/lib/python3.11/site-packages/zmq/devices/monitoredqueuedevice.py +60 -0
  43. .venv/lib/python3.11/site-packages/zmq/devices/proxydevice.py +104 -0
  44. .venv/lib/python3.11/site-packages/zmq/devices/proxysteerabledevice.py +106 -0
  45. .venv/lib/python3.11/site-packages/zmq/log/__init__.py +0 -0
  46. .venv/lib/python3.11/site-packages/zmq/log/__main__.py +135 -0
  47. .venv/lib/python3.11/site-packages/zmq/log/__pycache__/__init__.cpython-311.pyc +0 -0
  48. .venv/lib/python3.11/site-packages/zmq/log/__pycache__/__main__.cpython-311.pyc +0 -0
  49. .venv/lib/python3.11/site-packages/zmq/log/__pycache__/handlers.cpython-311.pyc +0 -0
  50. .venv/lib/python3.11/site-packages/zmq/log/handlers.py +232 -0
.gitattributes CHANGED
@@ -211,3 +211,4 @@ tuning-competition-baseline/.venv/lib/python3.11/site-packages/torch/_inductor/_
211
  .venv/lib/python3.11/site-packages/watchfiles/_rust_notify.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
212
  .venv/lib/python3.11/site-packages/frozenlist/_frozenlist.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
213
  .venv/lib/python3.11/site-packages/uvloop/loop.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
 
 
211
  .venv/lib/python3.11/site-packages/watchfiles/_rust_notify.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
212
  .venv/lib/python3.11/site-packages/frozenlist/_frozenlist.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
213
  .venv/lib/python3.11/site-packages/uvloop/loop.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
214
+ .venv/lib/python3.11/site-packages/functorch/_C.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
.venv/lib/python3.11/site-packages/fsspec/tests/abstract/__init__.py ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from hashlib import md5
3
+
4
+ import pytest
5
+
6
+ from fsspec.implementations.local import LocalFileSystem
7
+ from fsspec.tests.abstract.copy import AbstractCopyTests # noqa: F401
8
+ from fsspec.tests.abstract.get import AbstractGetTests # noqa: F401
9
+ from fsspec.tests.abstract.open import AbstractOpenTests # noqa: F401
10
+ from fsspec.tests.abstract.pipe import AbstractPipeTests # noqa: F401
11
+ from fsspec.tests.abstract.put import AbstractPutTests # noqa: F401
12
+
13
+
14
+ class BaseAbstractFixtures:
15
+ """
16
+ Abstract base class containing fixtures that are used by but never need to
17
+ be overridden in derived filesystem-specific classes to run the abstract
18
+ tests on such filesystems.
19
+ """
20
+
21
+ @pytest.fixture
22
+ def fs_bulk_operations_scenario_0(self, fs, fs_join, fs_path):
23
+ """
24
+ Scenario on remote filesystem that is used for many cp/get/put tests.
25
+
26
+ Cleans up at the end of each test it which it is used.
27
+ """
28
+ source = self._bulk_operations_scenario_0(fs, fs_join, fs_path)
29
+ yield source
30
+ fs.rm(source, recursive=True)
31
+
32
+ @pytest.fixture
33
+ def fs_glob_edge_cases_files(self, fs, fs_join, fs_path):
34
+ """
35
+ Scenario on remote filesystem that is used for glob edge cases cp/get/put tests.
36
+
37
+ Cleans up at the end of each test it which it is used.
38
+ """
39
+ source = self._glob_edge_cases_files(fs, fs_join, fs_path)
40
+ yield source
41
+ fs.rm(source, recursive=True)
42
+
43
+ @pytest.fixture
44
+ def fs_dir_and_file_with_same_name_prefix(self, fs, fs_join, fs_path):
45
+ """
46
+ Scenario on remote filesystem that is used to check cp/get/put on directory
47
+ and file with the same name prefixes.
48
+
49
+ Cleans up at the end of each test it which it is used.
50
+ """
51
+ source = self._dir_and_file_with_same_name_prefix(fs, fs_join, fs_path)
52
+ yield source
53
+ fs.rm(source, recursive=True)
54
+
55
+ @pytest.fixture
56
+ def fs_10_files_with_hashed_names(self, fs, fs_join, fs_path):
57
+ """
58
+ Scenario on remote filesystem that is used to check cp/get/put files order
59
+ when source and destination are lists.
60
+
61
+ Cleans up at the end of each test it which it is used.
62
+ """
63
+ source = self._10_files_with_hashed_names(fs, fs_join, fs_path)
64
+ yield source
65
+ fs.rm(source, recursive=True)
66
+
67
+ @pytest.fixture
68
+ def fs_target(self, fs, fs_join, fs_path):
69
+ """
70
+ Return name of remote directory that does not yet exist to copy into.
71
+
72
+ Cleans up at the end of each test it which it is used.
73
+ """
74
+ target = fs_join(fs_path, "target")
75
+ yield target
76
+ if fs.exists(target):
77
+ fs.rm(target, recursive=True)
78
+
79
+ @pytest.fixture
80
+ def local_bulk_operations_scenario_0(self, local_fs, local_join, local_path):
81
+ """
82
+ Scenario on local filesystem that is used for many cp/get/put tests.
83
+
84
+ Cleans up at the end of each test it which it is used.
85
+ """
86
+ source = self._bulk_operations_scenario_0(local_fs, local_join, local_path)
87
+ yield source
88
+ local_fs.rm(source, recursive=True)
89
+
90
+ @pytest.fixture
91
+ def local_glob_edge_cases_files(self, local_fs, local_join, local_path):
92
+ """
93
+ Scenario on local filesystem that is used for glob edge cases cp/get/put tests.
94
+
95
+ Cleans up at the end of each test it which it is used.
96
+ """
97
+ source = self._glob_edge_cases_files(local_fs, local_join, local_path)
98
+ yield source
99
+ local_fs.rm(source, recursive=True)
100
+
101
+ @pytest.fixture
102
+ def local_dir_and_file_with_same_name_prefix(
103
+ self, local_fs, local_join, local_path
104
+ ):
105
+ """
106
+ Scenario on local filesystem that is used to check cp/get/put on directory
107
+ and file with the same name prefixes.
108
+
109
+ Cleans up at the end of each test it which it is used.
110
+ """
111
+ source = self._dir_and_file_with_same_name_prefix(
112
+ local_fs, local_join, local_path
113
+ )
114
+ yield source
115
+ local_fs.rm(source, recursive=True)
116
+
117
+ @pytest.fixture
118
+ def local_10_files_with_hashed_names(self, local_fs, local_join, local_path):
119
+ """
120
+ Scenario on local filesystem that is used to check cp/get/put files order
121
+ when source and destination are lists.
122
+
123
+ Cleans up at the end of each test it which it is used.
124
+ """
125
+ source = self._10_files_with_hashed_names(local_fs, local_join, local_path)
126
+ yield source
127
+ local_fs.rm(source, recursive=True)
128
+
129
+ @pytest.fixture
130
+ def local_target(self, local_fs, local_join, local_path):
131
+ """
132
+ Return name of local directory that does not yet exist to copy into.
133
+
134
+ Cleans up at the end of each test it which it is used.
135
+ """
136
+ target = local_join(local_path, "target")
137
+ yield target
138
+ if local_fs.exists(target):
139
+ local_fs.rm(target, recursive=True)
140
+
141
+ def _glob_edge_cases_files(self, some_fs, some_join, some_path):
142
+ """
143
+ Scenario that is used for glob edge cases cp/get/put tests.
144
+ Creates the following directory and file structure:
145
+
146
+ 📁 source
147
+ ├── 📄 file1
148
+ ├── 📄 file2
149
+ ├── 📁 subdir0
150
+ │ ├── 📄 subfile1
151
+ │ ├── 📄 subfile2
152
+ │ └── 📁 nesteddir
153
+ │ └── 📄 nestedfile
154
+ └── 📁 subdir1
155
+ ├── 📄 subfile1
156
+ ├── 📄 subfile2
157
+ └── 📁 nesteddir
158
+ └── 📄 nestedfile
159
+ """
160
+ source = some_join(some_path, "source")
161
+ some_fs.touch(some_join(source, "file1"))
162
+ some_fs.touch(some_join(source, "file2"))
163
+
164
+ for subdir_idx in range(2):
165
+ subdir = some_join(source, f"subdir{subdir_idx}")
166
+ nesteddir = some_join(subdir, "nesteddir")
167
+ some_fs.makedirs(nesteddir)
168
+ some_fs.touch(some_join(subdir, "subfile1"))
169
+ some_fs.touch(some_join(subdir, "subfile2"))
170
+ some_fs.touch(some_join(nesteddir, "nestedfile"))
171
+
172
+ return source
173
+
174
+ def _bulk_operations_scenario_0(self, some_fs, some_join, some_path):
175
+ """
176
+ Scenario that is used for many cp/get/put tests. Creates the following
177
+ directory and file structure:
178
+
179
+ 📁 source
180
+ ├── 📄 file1
181
+ ├── 📄 file2
182
+ └── 📁 subdir
183
+ ├── 📄 subfile1
184
+ ├── 📄 subfile2
185
+ └── 📁 nesteddir
186
+ └── 📄 nestedfile
187
+ """
188
+ source = some_join(some_path, "source")
189
+ subdir = some_join(source, "subdir")
190
+ nesteddir = some_join(subdir, "nesteddir")
191
+ some_fs.makedirs(nesteddir)
192
+ some_fs.touch(some_join(source, "file1"))
193
+ some_fs.touch(some_join(source, "file2"))
194
+ some_fs.touch(some_join(subdir, "subfile1"))
195
+ some_fs.touch(some_join(subdir, "subfile2"))
196
+ some_fs.touch(some_join(nesteddir, "nestedfile"))
197
+ return source
198
+
199
+ def _dir_and_file_with_same_name_prefix(self, some_fs, some_join, some_path):
200
+ """
201
+ Scenario that is used to check cp/get/put on directory and file with
202
+ the same name prefixes. Creates the following directory and file structure:
203
+
204
+ 📁 source
205
+ ├── 📄 subdir.txt
206
+ └── 📁 subdir
207
+ └── 📄 subfile.txt
208
+ """
209
+ source = some_join(some_path, "source")
210
+ subdir = some_join(source, "subdir")
211
+ file = some_join(source, "subdir.txt")
212
+ subfile = some_join(subdir, "subfile.txt")
213
+ some_fs.makedirs(subdir)
214
+ some_fs.touch(file)
215
+ some_fs.touch(subfile)
216
+ return source
217
+
218
+ def _10_files_with_hashed_names(self, some_fs, some_join, some_path):
219
+ """
220
+ Scenario that is used to check cp/get/put files order when source and
221
+ destination are lists. Creates the following directory and file structure:
222
+
223
+ 📁 source
224
+ └── 📄 {hashed([0-9])}.txt
225
+ """
226
+ source = some_join(some_path, "source")
227
+ for i in range(10):
228
+ hashed_i = md5(str(i).encode("utf-8")).hexdigest()
229
+ path = some_join(source, f"{hashed_i}.txt")
230
+ some_fs.pipe(path=path, value=f"{i}".encode())
231
+ return source
232
+
233
+
234
+ class AbstractFixtures(BaseAbstractFixtures):
235
+ """
236
+ Abstract base class containing fixtures that may be overridden in derived
237
+ filesystem-specific classes to run the abstract tests on such filesystems.
238
+
239
+ For any particular filesystem some of these fixtures must be overridden,
240
+ such as ``fs`` and ``fs_path``, and others may be overridden if the
241
+ default functions here are not appropriate, such as ``fs_join``.
242
+ """
243
+
244
+ @pytest.fixture
245
+ def fs(self):
246
+ raise NotImplementedError("This function must be overridden in derived classes")
247
+
248
+ @pytest.fixture
249
+ def fs_join(self):
250
+ """
251
+ Return a function that joins its arguments together into a path.
252
+
253
+ Most fsspec implementations join paths in a platform-dependent way,
254
+ but some will override this to always use a forward slash.
255
+ """
256
+ return os.path.join
257
+
258
+ @pytest.fixture
259
+ def fs_path(self):
260
+ raise NotImplementedError("This function must be overridden in derived classes")
261
+
262
+ @pytest.fixture(scope="class")
263
+ def local_fs(self):
264
+ # Maybe need an option for auto_mkdir=False? This is only relevant
265
+ # for certain implementations.
266
+ return LocalFileSystem(auto_mkdir=True)
267
+
268
+ @pytest.fixture
269
+ def local_join(self):
270
+ """
271
+ Return a function that joins its arguments together into a path, on
272
+ the local filesystem.
273
+ """
274
+ return os.path.join
275
+
276
+ @pytest.fixture
277
+ def local_path(self, tmpdir):
278
+ return tmpdir
279
+
280
+ @pytest.fixture
281
+ def supports_empty_directories(self):
282
+ """
283
+ Return whether this implementation supports empty directories.
284
+ """
285
+ return True
286
+
287
+ @pytest.fixture
288
+ def fs_sanitize_path(self):
289
+ return lambda x: x
.venv/lib/python3.11/site-packages/fsspec/tests/abstract/__pycache__/get.cpython-311.pyc ADDED
Binary file (26.3 kB). View file
 
.venv/lib/python3.11/site-packages/fsspec/tests/abstract/__pycache__/pipe.cpython-311.pyc ADDED
Binary file (1.32 kB). View file
 
.venv/lib/python3.11/site-packages/fsspec/tests/abstract/__pycache__/put.cpython-311.pyc ADDED
Binary file (27.8 kB). View file
 
.venv/lib/python3.11/site-packages/fsspec/tests/abstract/open.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+
4
+ class AbstractOpenTests:
5
+ def test_open_exclusive(self, fs, fs_target):
6
+ with fs.open(fs_target, "wb") as f:
7
+ f.write(b"data")
8
+ with fs.open(fs_target, "rb") as f:
9
+ assert f.read() == b"data"
10
+ with pytest.raises(FileExistsError):
11
+ fs.open(fs_target, "xb")
.venv/lib/python3.11/site-packages/functorch/_C.cpython-311-x86_64-linux-gnu.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:39dc1f80069251db7f97e91763cbde3e2a9b53d8db73007ad0ddf7b041fee1d5
3
+ size 324432
.venv/lib/python3.11/site-packages/zmq/__init__.pxd ADDED
@@ -0,0 +1 @@
 
 
1
+ from zmq.backend.cython cimport Context, Frame, Socket, libzmq
.venv/lib/python3.11/site-packages/zmq/__init__.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Python bindings for 0MQ"""
2
+
3
+ # Copyright (C) PyZMQ Developers
4
+ # Distributed under the terms of the Modified BSD License.
5
+
6
+ from __future__ import annotations
7
+
8
+ import os
9
+ import sys
10
+ from contextlib import contextmanager
11
+
12
+
13
+ @contextmanager
14
+ def _libs_on_path():
15
+ """context manager for libs directory on $PATH
16
+
17
+ Works around mysterious issue where os.add_dll_directory
18
+ does not resolve imports (conda-forge Python >= 3.8)
19
+ """
20
+
21
+ if not sys.platform.startswith("win"):
22
+ yield
23
+ return
24
+
25
+ libs_dir = os.path.abspath(
26
+ os.path.join(
27
+ os.path.dirname(__file__),
28
+ os.pardir,
29
+ "pyzmq.libs",
30
+ )
31
+ )
32
+ if not os.path.exists(libs_dir):
33
+ # no bundled libs
34
+ yield
35
+ return
36
+
37
+ path_before = os.environ.get("PATH")
38
+ try:
39
+ os.environ["PATH"] = os.pathsep.join([path_before or "", libs_dir])
40
+ yield
41
+ finally:
42
+ if path_before is None:
43
+ os.environ.pop("PATH")
44
+ else:
45
+ os.environ["PATH"] = path_before
46
+
47
+
48
+ # zmq top-level imports
49
+
50
+ # workaround for Windows
51
+ with _libs_on_path():
52
+ from zmq import backend
53
+
54
+ from . import constants # noqa
55
+ from .constants import * # noqa
56
+ from zmq.backend import * # noqa
57
+ from zmq import sugar
58
+ from zmq.sugar import * # noqa
59
+
60
+
61
+ def get_includes():
62
+ """Return a list of directories to include for linking against pyzmq with cython."""
63
+ from os.path import abspath, dirname, exists, join, pardir
64
+
65
+ base = dirname(__file__)
66
+ parent = abspath(join(base, pardir))
67
+ includes = [parent] + [join(parent, base, subdir) for subdir in ('utils',)]
68
+ if exists(join(parent, base, 'include')):
69
+ includes.append(join(parent, base, 'include'))
70
+ return includes
71
+
72
+
73
+ def get_library_dirs():
74
+ """Return a list of directories used to link against pyzmq's bundled libzmq."""
75
+ from os.path import abspath, dirname, join, pardir
76
+
77
+ base = dirname(__file__)
78
+ parent = abspath(join(base, pardir))
79
+ return [join(parent, base)]
80
+
81
+
82
+ COPY_THRESHOLD = 65536
83
+ DRAFT_API = backend.has("draft")
84
+
85
+ __all__ = (
86
+ [
87
+ 'get_includes',
88
+ 'COPY_THRESHOLD',
89
+ 'DRAFT_API',
90
+ ]
91
+ + constants.__all__
92
+ + sugar.__all__
93
+ + backend.__all__
94
+ )
.venv/lib/python3.11/site-packages/zmq/__init__.pyi ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List
2
+
3
+ from . import backend, sugar
4
+
5
+ COPY_THRESHOLD: int
6
+ DRAFT_API: bool
7
+ __version__: str
8
+
9
+ # mypy doesn't like overwriting symbols with * so be explicit
10
+ # about what comes from backend, not from sugar
11
+ # see tools/backend_imports.py to generate this list
12
+ # note: `x as x` is required for re-export
13
+ # see https://github.com/python/mypy/issues/2190
14
+ from .backend import IPC_PATH_MAX_LEN as IPC_PATH_MAX_LEN
15
+ from .backend import curve_keypair as curve_keypair
16
+ from .backend import curve_public as curve_public
17
+ from .backend import device as device
18
+ from .backend import has as has
19
+ from .backend import proxy as proxy
20
+ from .backend import proxy_steerable as proxy_steerable
21
+ from .backend import strerror as strerror
22
+ from .backend import zmq_errno as zmq_errno
23
+ from .backend import zmq_poll as zmq_poll
24
+ from .constants import *
25
+ from .error import *
26
+ from .sugar import *
27
+
28
+ def get_includes() -> list[str]: ...
29
+ def get_library_dirs() -> list[str]: ...
.venv/lib/python3.11/site-packages/zmq/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (4.12 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/__pycache__/_future.cpython-311.pyc ADDED
Binary file (32.2 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/__pycache__/_typing.cpython-311.pyc ADDED
Binary file (1.47 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/__pycache__/asyncio.cpython-311.pyc ADDED
Binary file (10.2 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/__pycache__/constants.cpython-311.pyc ADDED
Binary file (30.8 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/__pycache__/decorators.cpython-311.pyc ADDED
Binary file (7.61 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/__pycache__/error.cpython-311.pyc ADDED
Binary file (8.9 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/_future.pyi ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """type annotations for async sockets"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from asyncio import Future
6
+ from pickle import DEFAULT_PROTOCOL
7
+ from typing import Any, Awaitable, Literal, Sequence, TypeVar, overload
8
+
9
+ import zmq as _zmq
10
+
11
+ class _AsyncPoller(_zmq.Poller):
12
+ _socket_class: type[_AsyncSocket]
13
+
14
+ def poll(self, timeout=-1) -> Awaitable[list[tuple[Any, int]]]: ... # type: ignore
15
+
16
+ T = TypeVar("T", bound="_AsyncSocket")
17
+
18
+ class _AsyncSocket(_zmq.Socket[Future]):
19
+ @classmethod
20
+ def from_socket(cls: type[T], socket: _zmq.Socket, io_loop: Any = None) -> T: ...
21
+ def send( # type: ignore
22
+ self,
23
+ data: Any,
24
+ flags: int = 0,
25
+ copy: bool = True,
26
+ track: bool = False,
27
+ routing_id: int | None = None,
28
+ group: str | None = None,
29
+ ) -> Awaitable[_zmq.MessageTracker | None]: ...
30
+ @overload # type: ignore
31
+ def recv(self, flags: int = 0, *, track: bool = False) -> Awaitable[bytes]: ...
32
+ @overload
33
+ def recv(
34
+ self, flags: int = 0, *, copy: Literal[True], track: bool = False
35
+ ) -> Awaitable[bytes]: ...
36
+ @overload
37
+ def recv(
38
+ self, flags: int = 0, *, copy: Literal[False], track: bool = False
39
+ ) -> Awaitable[_zmq.Frame]: ...
40
+ @overload
41
+ def recv(
42
+ self, flags: int = 0, copy: bool = True, track: bool = False
43
+ ) -> Awaitable[bytes | _zmq.Frame]: ...
44
+ def send_multipart( # type: ignore
45
+ self,
46
+ msg_parts: Sequence,
47
+ flags: int = 0,
48
+ copy: bool = True,
49
+ track: bool = False,
50
+ routing_id: int | None = None,
51
+ group: str | None = None,
52
+ ) -> Awaitable[_zmq.MessageTracker | None]: ...
53
+ @overload # type: ignore
54
+ def recv_multipart(
55
+ self, flags: int = 0, *, track: bool = False
56
+ ) -> Awaitable[list[bytes]]: ...
57
+ @overload
58
+ def recv_multipart(
59
+ self, flags: int = 0, *, copy: Literal[True], track: bool = False
60
+ ) -> Awaitable[list[bytes]]: ...
61
+ @overload
62
+ def recv_multipart(
63
+ self, flags: int = 0, *, copy: Literal[False], track: bool = False
64
+ ) -> Awaitable[list[_zmq.Frame]]: ...
65
+ @overload
66
+ def recv_multipart(
67
+ self, flags: int = 0, copy: bool = True, track: bool = False
68
+ ) -> Awaitable[list[bytes] | list[_zmq.Frame]]: ...
69
+
70
+ # serialization wrappers
71
+
72
+ def send_string( # type: ignore
73
+ self,
74
+ u: str,
75
+ flags: int = 0,
76
+ copy: bool = True,
77
+ *,
78
+ encoding: str = 'utf-8',
79
+ **kwargs,
80
+ ) -> Awaitable[_zmq.Frame | None]: ...
81
+ def recv_string( # type: ignore
82
+ self, flags: int = 0, encoding: str = 'utf-8'
83
+ ) -> Awaitable[str]: ...
84
+ def send_pyobj( # type: ignore
85
+ self, obj: Any, flags: int = 0, protocol: int = DEFAULT_PROTOCOL, **kwargs
86
+ ) -> Awaitable[_zmq.Frame | None]: ...
87
+ def recv_pyobj(self, flags: int = 0) -> Awaitable[Any]: ... # type: ignore
88
+ def send_json( # type: ignore
89
+ self, obj: Any, flags: int = 0, **kwargs
90
+ ) -> Awaitable[_zmq.Frame | None]: ...
91
+ def recv_json(self, flags: int = 0, **kwargs) -> Awaitable[Any]: ... # type: ignore
92
+ def poll(self, timeout=-1) -> Awaitable[list[tuple[Any, int]]]: ... # type: ignore
.venv/lib/python3.11/site-packages/zmq/_typing.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from typing import Any, Dict
5
+
6
+ if sys.version_info >= (3, 8):
7
+ from typing import Literal, TypedDict
8
+ else:
9
+ # avoid runtime dependency on typing_extensions on py37
10
+ try:
11
+ from typing_extensions import Literal, TypedDict # type: ignore
12
+ except ImportError:
13
+
14
+ class _Literal:
15
+ def __getitem__(self, key):
16
+ return Any
17
+
18
+ Literal = _Literal() # type: ignore
19
+
20
+ class TypedDict(Dict): # type: ignore
21
+ pass
22
+
23
+
24
+ if sys.version_info >= (3, 10):
25
+ from typing import TypeAlias
26
+ else:
27
+ try:
28
+ from typing_extensions import TypeAlias
29
+ except ImportError:
30
+ TypeAlias = type # type: ignore
.venv/lib/python3.11/site-packages/zmq/auth/__init__.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Utilities for ZAP authentication.
2
+
3
+ To run authentication in a background thread, see :mod:`zmq.auth.thread`.
4
+ For integration with the asyncio event loop, see :mod:`zmq.auth.asyncio`.
5
+
6
+ Authentication examples are provided in the pyzmq codebase, under
7
+ `/examples/security/`.
8
+
9
+ .. versionadded:: 14.1
10
+ """
11
+
12
+ from .base import *
13
+ from .certs import *
.venv/lib/python3.11/site-packages/zmq/auth/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (564 Bytes). View file
 
.venv/lib/python3.11/site-packages/zmq/auth/__pycache__/asyncio.cpython-311.pyc ADDED
Binary file (3.68 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/auth/__pycache__/base.cpython-311.pyc ADDED
Binary file (19.1 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/auth/__pycache__/certs.cpython-311.pyc ADDED
Binary file (6.82 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/auth/__pycache__/ioloop.cpython-311.pyc ADDED
Binary file (2.05 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/auth/__pycache__/thread.cpython-311.pyc ADDED
Binary file (8.01 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/auth/asyncio.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ZAP Authenticator integrated with the asyncio IO loop.
2
+
3
+ .. versionadded:: 15.2
4
+ """
5
+
6
+ # Copyright (C) PyZMQ Developers
7
+ # Distributed under the terms of the Modified BSD License.
8
+
9
+ import asyncio
10
+ import warnings
11
+ from typing import Any, Optional
12
+
13
+ import zmq
14
+ from zmq.asyncio import Poller
15
+
16
+ from .base import Authenticator
17
+
18
+
19
+ class AsyncioAuthenticator(Authenticator):
20
+ """ZAP authentication for use in the asyncio IO loop"""
21
+
22
+ __poller: Optional[Poller]
23
+ __task: Any
24
+
25
+ def __init__(
26
+ self,
27
+ context: Optional["zmq.Context"] = None,
28
+ loop: Any = None,
29
+ encoding: str = 'utf-8',
30
+ log: Any = None,
31
+ ):
32
+ super().__init__(context, encoding, log)
33
+ if loop is not None:
34
+ warnings.warn(
35
+ f"{self.__class__.__name__}(loop) is deprecated and ignored",
36
+ DeprecationWarning,
37
+ stacklevel=2,
38
+ )
39
+ self.__poller = None
40
+ self.__task = None
41
+
42
+ async def __handle_zap(self) -> None:
43
+ while self.__poller is not None:
44
+ events = await self.__poller.poll()
45
+ if self.zap_socket in dict(events):
46
+ msg = self.zap_socket.recv_multipart()
47
+ await self.handle_zap_message(msg)
48
+
49
+ def start(self) -> None:
50
+ """Start ZAP authentication"""
51
+ super().start()
52
+ self.__poller = Poller()
53
+ self.__poller.register(self.zap_socket, zmq.POLLIN)
54
+ self.__task = asyncio.ensure_future(self.__handle_zap())
55
+
56
+ def stop(self) -> None:
57
+ """Stop ZAP authentication"""
58
+ if self.__task:
59
+ self.__task.cancel()
60
+ if self.__poller:
61
+ self.__poller.unregister(self.zap_socket)
62
+ self.__poller = None
63
+ super().stop()
64
+
65
+
66
+ __all__ = ["AsyncioAuthenticator"]
.venv/lib/python3.11/site-packages/zmq/auth/base.py ADDED
@@ -0,0 +1,445 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Base implementation of 0MQ authentication."""
2
+
3
+ # Copyright (C) PyZMQ Developers
4
+ # Distributed under the terms of the Modified BSD License.
5
+
6
+ import logging
7
+ import os
8
+ from typing import Any, Awaitable, Dict, List, Optional, Set, Tuple, Union
9
+
10
+ import zmq
11
+ from zmq.error import _check_version
12
+ from zmq.utils import z85
13
+
14
+ from .certs import load_certificates
15
+
16
+ CURVE_ALLOW_ANY = '*'
17
+ VERSION = b'1.0'
18
+
19
+
20
+ class Authenticator:
21
+ """Implementation of ZAP authentication for zmq connections.
22
+
23
+ This authenticator class does not register with an event loop. As a result,
24
+ you will need to manually call `handle_zap_message`::
25
+
26
+ auth = zmq.Authenticator()
27
+ auth.allow("127.0.0.1")
28
+ auth.start()
29
+ while True:
30
+ await auth.handle_zap_msg(auth.zap_socket.recv_multipart())
31
+
32
+ Alternatively, you can register `auth.zap_socket` with a poller.
33
+
34
+ Since many users will want to run ZAP in a way that does not block the
35
+ main thread, other authentication classes (such as :mod:`zmq.auth.thread`)
36
+ are provided.
37
+
38
+ Note:
39
+
40
+ - libzmq provides four levels of security: default NULL (which the Authenticator does
41
+ not see), and authenticated NULL, PLAIN, CURVE, and GSSAPI, which the Authenticator can see.
42
+ - until you add policies, all incoming NULL connections are allowed.
43
+ (classic ZeroMQ behavior), and all PLAIN and CURVE connections are denied.
44
+ - GSSAPI requires no configuration.
45
+ """
46
+
47
+ context: "zmq.Context"
48
+ encoding: str
49
+ allow_any: bool
50
+ credentials_providers: Dict[str, Any]
51
+ zap_socket: "zmq.Socket"
52
+ _allowed: Set[str]
53
+ _denied: Set[str]
54
+ passwords: Dict[str, Dict[str, str]]
55
+ certs: Dict[str, Dict[bytes, Any]]
56
+ log: Any
57
+
58
+ def __init__(
59
+ self,
60
+ context: Optional["zmq.Context"] = None,
61
+ encoding: str = 'utf-8',
62
+ log: Any = None,
63
+ ):
64
+ _check_version((4, 0), "security")
65
+ self.context = context or zmq.Context.instance()
66
+ self.encoding = encoding
67
+ self.allow_any = False
68
+ self.credentials_providers = {}
69
+ self.zap_socket = None # type: ignore
70
+ self._allowed = set()
71
+ self._denied = set()
72
+ # passwords is a dict keyed by domain and contains values
73
+ # of dicts with username:password pairs.
74
+ self.passwords = {}
75
+ # certs is dict keyed by domain and contains values
76
+ # of dicts keyed by the public keys from the specified location.
77
+ self.certs = {}
78
+ self.log = log or logging.getLogger('zmq.auth')
79
+
80
+ def start(self) -> None:
81
+ """Create and bind the ZAP socket"""
82
+ self.zap_socket = self.context.socket(zmq.REP, socket_class=zmq.Socket)
83
+ self.zap_socket.linger = 1
84
+ self.zap_socket.bind("inproc://zeromq.zap.01")
85
+ self.log.debug("Starting")
86
+
87
+ def stop(self) -> None:
88
+ """Close the ZAP socket"""
89
+ if self.zap_socket:
90
+ self.zap_socket.close()
91
+ self.zap_socket = None # type: ignore
92
+
93
+ def allow(self, *addresses: str) -> None:
94
+ """Allow IP address(es).
95
+
96
+ Connections from addresses not explicitly allowed will be rejected.
97
+
98
+ - For NULL, all clients from this address will be accepted.
99
+ - For real auth setups, they will be allowed to continue with authentication.
100
+
101
+ allow is mutually exclusive with deny.
102
+ """
103
+ if self._denied:
104
+ raise ValueError("Only use allow or deny, not both")
105
+ self.log.debug("Allowing %s", ','.join(addresses))
106
+ self._allowed.update(addresses)
107
+
108
+ def deny(self, *addresses: str) -> None:
109
+ """Deny IP address(es).
110
+
111
+ Addresses not explicitly denied will be allowed to continue with authentication.
112
+
113
+ deny is mutually exclusive with allow.
114
+ """
115
+ if self._allowed:
116
+ raise ValueError("Only use a allow or deny, not both")
117
+ self.log.debug("Denying %s", ','.join(addresses))
118
+ self._denied.update(addresses)
119
+
120
+ def configure_plain(
121
+ self, domain: str = '*', passwords: Optional[Dict[str, str]] = None
122
+ ) -> None:
123
+ """Configure PLAIN authentication for a given domain.
124
+
125
+ PLAIN authentication uses a plain-text password file.
126
+ To cover all domains, use "*".
127
+ You can modify the password file at any time; it is reloaded automatically.
128
+ """
129
+ if passwords:
130
+ self.passwords[domain] = passwords
131
+ self.log.debug("Configure plain: %s", domain)
132
+
133
+ def configure_curve(
134
+ self, domain: str = '*', location: Union[str, os.PathLike] = "."
135
+ ) -> None:
136
+ """Configure CURVE authentication for a given domain.
137
+
138
+ CURVE authentication uses a directory that holds all public client certificates,
139
+ i.e. their public keys.
140
+
141
+ To cover all domains, use "*".
142
+
143
+ You can add and remove certificates in that directory at any time. configure_curve must be called
144
+ every time certificates are added or removed, in order to update the Authenticator's state
145
+
146
+ To allow all client keys without checking, specify CURVE_ALLOW_ANY for the location.
147
+ """
148
+ # If location is CURVE_ALLOW_ANY then allow all clients. Otherwise
149
+ # treat location as a directory that holds the certificates.
150
+ self.log.debug("Configure curve: %s[%s]", domain, location)
151
+ if location == CURVE_ALLOW_ANY:
152
+ self.allow_any = True
153
+ else:
154
+ self.allow_any = False
155
+ try:
156
+ self.certs[domain] = load_certificates(location)
157
+ except Exception as e:
158
+ self.log.error("Failed to load CURVE certs from %s: %s", location, e)
159
+
160
+ def configure_curve_callback(
161
+ self, domain: str = '*', credentials_provider: Any = None
162
+ ) -> None:
163
+ """Configure CURVE authentication for a given domain.
164
+
165
+ CURVE authentication using a callback function validating
166
+ the client public key according to a custom mechanism, e.g. checking the
167
+ key against records in a db. credentials_provider is an object of a class which
168
+ implements a callback method accepting two parameters (domain and key), e.g.::
169
+
170
+ class CredentialsProvider(object):
171
+
172
+ def __init__(self):
173
+ ...e.g. db connection
174
+
175
+ def callback(self, domain, key):
176
+ valid = ...lookup key and/or domain in db
177
+ if valid:
178
+ logging.info('Authorizing: {0}, {1}'.format(domain, key))
179
+ return True
180
+ else:
181
+ logging.warning('NOT Authorizing: {0}, {1}'.format(domain, key))
182
+ return False
183
+
184
+ To cover all domains, use "*".
185
+ """
186
+
187
+ self.allow_any = False
188
+
189
+ if credentials_provider is not None:
190
+ self.credentials_providers[domain] = credentials_provider
191
+ else:
192
+ self.log.error("None credentials_provider provided for domain:%s", domain)
193
+
194
+ def curve_user_id(self, client_public_key: bytes) -> str:
195
+ """Return the User-Id corresponding to a CURVE client's public key
196
+
197
+ Default implementation uses the z85-encoding of the public key.
198
+
199
+ Override to define a custom mapping of public key : user-id
200
+
201
+ This is only called on successful authentication.
202
+
203
+ Parameters
204
+ ----------
205
+ client_public_key: bytes
206
+ The client public key used for the given message
207
+
208
+ Returns
209
+ -------
210
+ user_id: unicode
211
+ The user ID as text
212
+ """
213
+ return z85.encode(client_public_key).decode('ascii')
214
+
215
+ def configure_gssapi(
216
+ self, domain: str = '*', location: Optional[str] = None
217
+ ) -> None:
218
+ """Configure GSSAPI authentication
219
+
220
+ Currently this is a no-op because there is nothing to configure with GSSAPI.
221
+ """
222
+
223
+ async def handle_zap_message(self, msg: List[bytes]):
224
+ """Perform ZAP authentication"""
225
+ if len(msg) < 6:
226
+ self.log.error("Invalid ZAP message, not enough frames: %r", msg)
227
+ if len(msg) < 2:
228
+ self.log.error("Not enough information to reply")
229
+ else:
230
+ self._send_zap_reply(msg[1], b"400", b"Not enough frames")
231
+ return
232
+
233
+ version, request_id, domain, address, identity, mechanism = msg[:6]
234
+ credentials = msg[6:]
235
+
236
+ domain = domain.decode(self.encoding, 'replace')
237
+ address = address.decode(self.encoding, 'replace')
238
+
239
+ if version != VERSION:
240
+ self.log.error("Invalid ZAP version: %r", msg)
241
+ self._send_zap_reply(request_id, b"400", b"Invalid version")
242
+ return
243
+
244
+ self.log.debug(
245
+ "version: %r, request_id: %r, domain: %r,"
246
+ " address: %r, identity: %r, mechanism: %r",
247
+ version,
248
+ request_id,
249
+ domain,
250
+ address,
251
+ identity,
252
+ mechanism,
253
+ )
254
+
255
+ # Is address is explicitly allowed or _denied?
256
+ allowed = False
257
+ denied = False
258
+ reason = b"NO ACCESS"
259
+
260
+ if self._allowed:
261
+ if address in self._allowed:
262
+ allowed = True
263
+ self.log.debug("PASSED (allowed) address=%s", address)
264
+ else:
265
+ denied = True
266
+ reason = b"Address not allowed"
267
+ self.log.debug("DENIED (not allowed) address=%s", address)
268
+
269
+ elif self._denied:
270
+ if address in self._denied:
271
+ denied = True
272
+ reason = b"Address denied"
273
+ self.log.debug("DENIED (denied) address=%s", address)
274
+ else:
275
+ allowed = True
276
+ self.log.debug("PASSED (not denied) address=%s", address)
277
+
278
+ # Perform authentication mechanism-specific checks if necessary
279
+ username = "anonymous"
280
+ if not denied:
281
+ if mechanism == b'NULL' and not allowed:
282
+ # For NULL, we allow if the address wasn't denied
283
+ self.log.debug("ALLOWED (NULL)")
284
+ allowed = True
285
+
286
+ elif mechanism == b'PLAIN':
287
+ # For PLAIN, even a _alloweded address must authenticate
288
+ if len(credentials) != 2:
289
+ self.log.error("Invalid PLAIN credentials: %r", credentials)
290
+ self._send_zap_reply(request_id, b"400", b"Invalid credentials")
291
+ return
292
+ username, password = (
293
+ c.decode(self.encoding, 'replace') for c in credentials
294
+ )
295
+ allowed, reason = self._authenticate_plain(domain, username, password)
296
+
297
+ elif mechanism == b'CURVE':
298
+ # For CURVE, even a _alloweded address must authenticate
299
+ if len(credentials) != 1:
300
+ self.log.error("Invalid CURVE credentials: %r", credentials)
301
+ self._send_zap_reply(request_id, b"400", b"Invalid credentials")
302
+ return
303
+ key = credentials[0]
304
+ allowed, reason = await self._authenticate_curve(domain, key)
305
+ if allowed:
306
+ username = self.curve_user_id(key)
307
+
308
+ elif mechanism == b'GSSAPI':
309
+ if len(credentials) != 1:
310
+ self.log.error("Invalid GSSAPI credentials: %r", credentials)
311
+ self._send_zap_reply(request_id, b"400", b"Invalid credentials")
312
+ return
313
+ # use principal as user-id for now
314
+ principal = credentials[0]
315
+ username = principal.decode("utf8")
316
+ allowed, reason = self._authenticate_gssapi(domain, principal)
317
+
318
+ if allowed:
319
+ self._send_zap_reply(request_id, b"200", b"OK", username)
320
+ else:
321
+ self._send_zap_reply(request_id, b"400", reason)
322
+
323
+ def _authenticate_plain(
324
+ self, domain: str, username: str, password: str
325
+ ) -> Tuple[bool, bytes]:
326
+ """PLAIN ZAP authentication"""
327
+ allowed = False
328
+ reason = b""
329
+ if self.passwords:
330
+ # If no domain is not specified then use the default domain
331
+ if not domain:
332
+ domain = '*'
333
+
334
+ if domain in self.passwords:
335
+ if username in self.passwords[domain]:
336
+ if password == self.passwords[domain][username]:
337
+ allowed = True
338
+ else:
339
+ reason = b"Invalid password"
340
+ else:
341
+ reason = b"Invalid username"
342
+ else:
343
+ reason = b"Invalid domain"
344
+
345
+ if allowed:
346
+ self.log.debug(
347
+ "ALLOWED (PLAIN) domain=%s username=%s password=%s",
348
+ domain,
349
+ username,
350
+ password,
351
+ )
352
+ else:
353
+ self.log.debug("DENIED %s", reason)
354
+
355
+ else:
356
+ reason = b"No passwords defined"
357
+ self.log.debug("DENIED (PLAIN) %s", reason)
358
+
359
+ return allowed, reason
360
+
361
+ async def _authenticate_curve(
362
+ self, domain: str, client_key: bytes
363
+ ) -> Tuple[bool, bytes]:
364
+ """CURVE ZAP authentication"""
365
+ allowed = False
366
+ reason = b""
367
+ if self.allow_any:
368
+ allowed = True
369
+ reason = b"OK"
370
+ self.log.debug("ALLOWED (CURVE allow any client)")
371
+ elif self.credentials_providers != {}:
372
+ # If no explicit domain is specified then use the default domain
373
+ if not domain:
374
+ domain = '*'
375
+
376
+ if domain in self.credentials_providers:
377
+ z85_client_key = z85.encode(client_key)
378
+ # Callback to check if key is Allowed
379
+ r = self.credentials_providers[domain].callback(domain, z85_client_key)
380
+ if isinstance(r, Awaitable):
381
+ r = await r
382
+ if r:
383
+ allowed = True
384
+ reason = b"OK"
385
+ else:
386
+ reason = b"Unknown key"
387
+
388
+ status = "ALLOWED" if allowed else "DENIED"
389
+ self.log.debug(
390
+ "%s (CURVE auth_callback) domain=%s client_key=%s",
391
+ status,
392
+ domain,
393
+ z85_client_key,
394
+ )
395
+ else:
396
+ reason = b"Unknown domain"
397
+ else:
398
+ # If no explicit domain is specified then use the default domain
399
+ if not domain:
400
+ domain = '*'
401
+
402
+ if domain in self.certs:
403
+ # The certs dict stores keys in z85 format, convert binary key to z85 bytes
404
+ z85_client_key = z85.encode(client_key)
405
+ if self.certs[domain].get(z85_client_key):
406
+ allowed = True
407
+ reason = b"OK"
408
+ else:
409
+ reason = b"Unknown key"
410
+
411
+ status = "ALLOWED" if allowed else "DENIED"
412
+ self.log.debug(
413
+ "%s (CURVE) domain=%s client_key=%s",
414
+ status,
415
+ domain,
416
+ z85_client_key,
417
+ )
418
+ else:
419
+ reason = b"Unknown domain"
420
+
421
+ return allowed, reason
422
+
423
+ def _authenticate_gssapi(self, domain: str, principal: bytes) -> Tuple[bool, bytes]:
424
+ """Nothing to do for GSSAPI, which has already been handled by an external service."""
425
+ self.log.debug("ALLOWED (GSSAPI) domain=%s principal=%s", domain, principal)
426
+ return True, b'OK'
427
+
428
+ def _send_zap_reply(
429
+ self,
430
+ request_id: bytes,
431
+ status_code: bytes,
432
+ status_text: bytes,
433
+ user_id: str = 'anonymous',
434
+ ) -> None:
435
+ """Send a ZAP reply to finish the authentication."""
436
+ user_id = user_id if status_code == b'200' else b''
437
+ if isinstance(user_id, str):
438
+ user_id = user_id.encode(self.encoding, 'replace')
439
+ metadata = b'' # not currently used
440
+ self.log.debug("ZAP reply code=%s text=%s", status_code, status_text)
441
+ reply = [VERSION, request_id, status_code, status_text, user_id, metadata]
442
+ self.zap_socket.send_multipart(reply)
443
+
444
+
445
+ __all__ = ['Authenticator', 'CURVE_ALLOW_ANY']
.venv/lib/python3.11/site-packages/zmq/auth/certs.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """0MQ authentication related functions and classes."""
2
+
3
+ # Copyright (C) PyZMQ Developers
4
+ # Distributed under the terms of the Modified BSD License.
5
+
6
+ import datetime
7
+ import glob
8
+ import os
9
+ from typing import Dict, Optional, Tuple, Union
10
+
11
+ import zmq
12
+
13
+ _cert_secret_banner = """# **** Generated on {0} by pyzmq ****
14
+ # ZeroMQ CURVE **Secret** Certificate
15
+ # DO NOT PROVIDE THIS FILE TO OTHER USERS nor change its permissions.
16
+
17
+ """
18
+
19
+
20
+ _cert_public_banner = """# **** Generated on {0} by pyzmq ****
21
+ # ZeroMQ CURVE Public Certificate
22
+ # Exchange securely, or use a secure mechanism to verify the contents
23
+ # of this file after exchange. Store public certificates in your home
24
+ # directory, in the .curve subdirectory.
25
+
26
+ """
27
+
28
+
29
+ def _write_key_file(
30
+ key_filename: Union[str, os.PathLike],
31
+ banner: str,
32
+ public_key: Union[str, bytes],
33
+ secret_key: Optional[Union[str, bytes]] = None,
34
+ metadata: Optional[Dict[str, str]] = None,
35
+ encoding: str = 'utf-8',
36
+ ) -> None:
37
+ """Create a certificate file"""
38
+ if isinstance(public_key, bytes):
39
+ public_key = public_key.decode(encoding)
40
+ if isinstance(secret_key, bytes):
41
+ secret_key = secret_key.decode(encoding)
42
+ with open(key_filename, 'w', encoding='utf8') as f:
43
+ f.write(banner.format(datetime.datetime.now()))
44
+
45
+ f.write('metadata\n')
46
+ if metadata:
47
+ for k, v in metadata.items():
48
+ if isinstance(k, bytes):
49
+ k = k.decode(encoding)
50
+ if isinstance(v, bytes):
51
+ v = v.decode(encoding)
52
+ f.write(f" {k} = {v}\n")
53
+
54
+ f.write('curve\n')
55
+ f.write(f" public-key = \"{public_key}\"\n")
56
+
57
+ if secret_key:
58
+ f.write(f" secret-key = \"{secret_key}\"\n")
59
+
60
+
61
+ def create_certificates(
62
+ key_dir: Union[str, os.PathLike],
63
+ name: str,
64
+ metadata: Optional[Dict[str, str]] = None,
65
+ ) -> Tuple[str, str]:
66
+ """Create zmq certificates.
67
+
68
+ Returns the file paths to the public and secret certificate files.
69
+ """
70
+ public_key, secret_key = zmq.curve_keypair()
71
+ base_filename = os.path.join(key_dir, name)
72
+ secret_key_file = f"{base_filename}.key_secret"
73
+ public_key_file = f"{base_filename}.key"
74
+ now = datetime.datetime.now()
75
+
76
+ _write_key_file(public_key_file, _cert_public_banner.format(now), public_key)
77
+
78
+ _write_key_file(
79
+ secret_key_file,
80
+ _cert_secret_banner.format(now),
81
+ public_key,
82
+ secret_key=secret_key,
83
+ metadata=metadata,
84
+ )
85
+
86
+ return public_key_file, secret_key_file
87
+
88
+
89
+ def load_certificate(
90
+ filename: Union[str, os.PathLike],
91
+ ) -> Tuple[bytes, Optional[bytes]]:
92
+ """Load public and secret key from a zmq certificate.
93
+
94
+ Returns (public_key, secret_key)
95
+
96
+ If the certificate file only contains the public key,
97
+ secret_key will be None.
98
+
99
+ If there is no public key found in the file, ValueError will be raised.
100
+ """
101
+ public_key = None
102
+ secret_key = None
103
+ if not os.path.exists(filename):
104
+ raise OSError(f"Invalid certificate file: {filename}")
105
+
106
+ with open(filename, 'rb') as f:
107
+ for line in f:
108
+ line = line.strip()
109
+ if line.startswith(b'#'):
110
+ continue
111
+ if line.startswith(b'public-key'):
112
+ public_key = line.split(b"=", 1)[1].strip(b' \t\'"')
113
+ if line.startswith(b'secret-key'):
114
+ secret_key = line.split(b"=", 1)[1].strip(b' \t\'"')
115
+ if public_key and secret_key:
116
+ break
117
+
118
+ if public_key is None:
119
+ raise ValueError(f"No public key found in {filename}")
120
+
121
+ return public_key, secret_key
122
+
123
+
124
+ def load_certificates(directory: Union[str, os.PathLike] = '.') -> Dict[bytes, bool]:
125
+ """Load public keys from all certificates in a directory"""
126
+ certs = {}
127
+ if not os.path.isdir(directory):
128
+ raise OSError(f"Invalid certificate directory: {directory}")
129
+ # Follow czmq pattern of public keys stored in *.key files.
130
+ glob_string = os.path.join(directory, "*.key")
131
+
132
+ cert_files = glob.glob(glob_string)
133
+ for cert_file in cert_files:
134
+ public_key, _ = load_certificate(cert_file)
135
+ if public_key:
136
+ certs[public_key] = True
137
+ return certs
138
+
139
+
140
+ __all__ = ['create_certificates', 'load_certificate', 'load_certificates']
.venv/lib/python3.11/site-packages/zmq/auth/ioloop.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ZAP Authenticator integrated with the tornado IOLoop.
2
+
3
+ .. versionadded:: 14.1
4
+ .. deprecated:: 25
5
+ Use asyncio.AsyncioAuthenticator instead.
6
+ Since tornado runs on asyncio, the asyncio authenticator
7
+ offers the same functionality in tornado.
8
+ """
9
+
10
+ import warnings
11
+
12
+ # Copyright (C) PyZMQ Developers
13
+ # Distributed under the terms of the Modified BSD License.
14
+ from typing import Any, Optional
15
+
16
+ import zmq
17
+
18
+ from .asyncio import AsyncioAuthenticator
19
+
20
+ warnings.warn(
21
+ "zmq.auth.ioloop.IOLoopAuthenticator is deprecated. Use zmq.auth.asyncio.AsyncioAuthenticator",
22
+ DeprecationWarning,
23
+ stacklevel=2,
24
+ )
25
+
26
+
27
+ class IOLoopAuthenticator(AsyncioAuthenticator):
28
+ """ZAP authentication for use in the tornado IOLoop"""
29
+
30
+ def __init__(
31
+ self,
32
+ context: Optional["zmq.Context"] = None,
33
+ encoding: str = 'utf-8',
34
+ log: Any = None,
35
+ io_loop: Any = None,
36
+ ):
37
+ loop = None
38
+ if io_loop is not None:
39
+ warnings.warn(
40
+ f"{self.__class__.__name__}(io_loop) is deprecated and ignored",
41
+ DeprecationWarning,
42
+ stacklevel=2,
43
+ )
44
+ loop = io_loop.asyncio_loop
45
+ super().__init__(context=context, encoding=encoding, log=log, loop=loop)
46
+
47
+
48
+ __all__ = ['IOLoopAuthenticator']
.venv/lib/python3.11/site-packages/zmq/auth/thread.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ZAP Authenticator in a Python Thread.
2
+
3
+ .. versionadded:: 14.1
4
+ """
5
+
6
+ # Copyright (C) PyZMQ Developers
7
+ # Distributed under the terms of the Modified BSD License.
8
+
9
+ import asyncio
10
+ from threading import Event, Thread
11
+ from typing import Any, List, Optional
12
+
13
+ import zmq
14
+ import zmq.asyncio
15
+
16
+ from .base import Authenticator
17
+
18
+
19
+ class AuthenticationThread(Thread):
20
+ """A Thread for running a zmq Authenticator
21
+
22
+ This is run in the background by ThreadAuthenticator
23
+ """
24
+
25
+ pipe: zmq.Socket
26
+ loop: asyncio.AbstractEventLoop
27
+ authenticator: Authenticator
28
+ poller: Optional[zmq.asyncio.Poller] = None
29
+
30
+ def __init__(
31
+ self,
32
+ authenticator: Authenticator,
33
+ pipe: zmq.Socket,
34
+ ) -> None:
35
+ super().__init__(daemon=True)
36
+ self.authenticator = authenticator
37
+ self.log = authenticator.log
38
+ self.pipe = pipe
39
+
40
+ self.started = Event()
41
+
42
+ def run(self) -> None:
43
+ """Start the Authentication Agent thread task"""
44
+
45
+ loop = asyncio.new_event_loop()
46
+ try:
47
+ loop.run_until_complete(self._run())
48
+ finally:
49
+ if self.pipe:
50
+ self.pipe.close()
51
+ self.pipe = None # type: ignore
52
+
53
+ loop.close()
54
+
55
+ async def _run(self):
56
+ self.poller = zmq.asyncio.Poller()
57
+ self.poller.register(self.pipe, zmq.POLLIN)
58
+ self.poller.register(self.authenticator.zap_socket, zmq.POLLIN)
59
+ self.started.set()
60
+
61
+ while True:
62
+ events = dict(await self.poller.poll())
63
+ if self.pipe in events:
64
+ msg = self.pipe.recv_multipart()
65
+ if self._handle_pipe_message(msg):
66
+ return
67
+ if self.authenticator.zap_socket in events:
68
+ msg = self.authenticator.zap_socket.recv_multipart()
69
+ await self.authenticator.handle_zap_message(msg)
70
+
71
+ def _handle_pipe_message(self, msg: List[bytes]) -> bool:
72
+ command = msg[0]
73
+ self.log.debug("auth received API command %r", command)
74
+
75
+ if command == b'TERMINATE':
76
+ return True
77
+
78
+ else:
79
+ self.log.error("Invalid auth command from API: %r", command)
80
+ self.pipe.send(b'ERROR')
81
+
82
+ return False
83
+
84
+
85
+ class ThreadAuthenticator(Authenticator):
86
+ """Run ZAP authentication in a background thread"""
87
+
88
+ pipe: "zmq.Socket"
89
+ pipe_endpoint: str = ''
90
+ thread: AuthenticationThread
91
+
92
+ def __init__(
93
+ self,
94
+ context: Optional["zmq.Context"] = None,
95
+ encoding: str = 'utf-8',
96
+ log: Any = None,
97
+ ):
98
+ super().__init__(context=context, encoding=encoding, log=log)
99
+ self.pipe = None # type: ignore
100
+ self.pipe_endpoint = f"inproc://{id(self)}.inproc"
101
+ self.thread = None # type: ignore
102
+
103
+ def start(self) -> None:
104
+ """Start the authentication thread"""
105
+ # start the Authenticator
106
+ super().start()
107
+
108
+ # create a socket pair to communicate with auth thread.
109
+ self.pipe = self.context.socket(zmq.PAIR, socket_class=zmq.Socket)
110
+ self.pipe.linger = 1
111
+ self.pipe.bind(self.pipe_endpoint)
112
+ thread_pipe = self.context.socket(zmq.PAIR, socket_class=zmq.Socket)
113
+ thread_pipe.linger = 1
114
+ thread_pipe.connect(self.pipe_endpoint)
115
+ self.thread = AuthenticationThread(authenticator=self, pipe=thread_pipe)
116
+ self.thread.start()
117
+ if not self.thread.started.wait(timeout=10):
118
+ raise RuntimeError("Authenticator thread failed to start")
119
+
120
+ def stop(self) -> None:
121
+ """Stop the authentication thread"""
122
+ if self.pipe:
123
+ self.pipe.send(b'TERMINATE')
124
+ if self.is_alive():
125
+ self.thread.join()
126
+ self.thread = None # type: ignore
127
+ self.pipe.close()
128
+ self.pipe = None # type: ignore
129
+ super().stop()
130
+
131
+ def is_alive(self) -> bool:
132
+ """Is the ZAP thread currently running?"""
133
+ return bool(self.thread and self.thread.is_alive())
134
+
135
+ def __del__(self) -> None:
136
+ self.stop()
137
+
138
+
139
+ __all__ = ['ThreadAuthenticator']
.venv/lib/python3.11/site-packages/zmq/constants.py ADDED
@@ -0,0 +1,974 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """zmq constants as enums"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import errno
6
+ import sys
7
+ from enum import Enum, IntEnum, IntFlag
8
+
9
+ _HAUSNUMERO = 156384712
10
+
11
+
12
+ class Errno(IntEnum):
13
+ """libzmq error codes
14
+
15
+ .. versionadded:: 23
16
+ """
17
+
18
+ EAGAIN = errno.EAGAIN
19
+ EFAULT = errno.EFAULT
20
+ EINVAL = errno.EINVAL
21
+
22
+ if sys.platform.startswith("win"):
23
+ # Windows: libzmq uses errno.h
24
+ # while Python errno prefers WSA* variants
25
+ # many of these were introduced to errno.h in vs2010
26
+ # ref: https://github.com/python/cpython/blob/3.9/Modules/errnomodule.c#L10-L37
27
+ # source: https://docs.microsoft.com/en-us/cpp/c-runtime-library/errno-constants
28
+ ENOTSUP = 129
29
+ EPROTONOSUPPORT = 135
30
+ ENOBUFS = 119
31
+ ENETDOWN = 116
32
+ EADDRINUSE = 100
33
+ EADDRNOTAVAIL = 101
34
+ ECONNREFUSED = 107
35
+ EINPROGRESS = 112
36
+ ENOTSOCK = 128
37
+ EMSGSIZE = 115
38
+ EAFNOSUPPORT = 102
39
+ ENETUNREACH = 118
40
+ ECONNABORTED = 106
41
+ ECONNRESET = 108
42
+ ENOTCONN = 126
43
+ ETIMEDOUT = 138
44
+ EHOSTUNREACH = 110
45
+ ENETRESET = 117
46
+
47
+ else:
48
+ ENOTSUP = getattr(errno, "ENOTSUP", _HAUSNUMERO + 1)
49
+ EPROTONOSUPPORT = getattr(errno, "EPROTONOSUPPORT", _HAUSNUMERO + 2)
50
+ ENOBUFS = getattr(errno, "ENOBUFS", _HAUSNUMERO + 3)
51
+ ENETDOWN = getattr(errno, "ENETDOWN", _HAUSNUMERO + 4)
52
+ EADDRINUSE = getattr(errno, "EADDRINUSE", _HAUSNUMERO + 5)
53
+ EADDRNOTAVAIL = getattr(errno, "EADDRNOTAVAIL", _HAUSNUMERO + 6)
54
+ ECONNREFUSED = getattr(errno, "ECONNREFUSED", _HAUSNUMERO + 7)
55
+ EINPROGRESS = getattr(errno, "EINPROGRESS", _HAUSNUMERO + 8)
56
+ ENOTSOCK = getattr(errno, "ENOTSOCK", _HAUSNUMERO + 9)
57
+ EMSGSIZE = getattr(errno, "EMSGSIZE", _HAUSNUMERO + 10)
58
+ EAFNOSUPPORT = getattr(errno, "EAFNOSUPPORT", _HAUSNUMERO + 11)
59
+ ENETUNREACH = getattr(errno, "ENETUNREACH", _HAUSNUMERO + 12)
60
+ ECONNABORTED = getattr(errno, "ECONNABORTED", _HAUSNUMERO + 13)
61
+ ECONNRESET = getattr(errno, "ECONNRESET", _HAUSNUMERO + 14)
62
+ ENOTCONN = getattr(errno, "ENOTCONN", _HAUSNUMERO + 15)
63
+ ETIMEDOUT = getattr(errno, "ETIMEDOUT", _HAUSNUMERO + 16)
64
+ EHOSTUNREACH = getattr(errno, "EHOSTUNREACH", _HAUSNUMERO + 17)
65
+ ENETRESET = getattr(errno, "ENETRESET", _HAUSNUMERO + 18)
66
+
67
+ # Native 0MQ error codes
68
+ EFSM = _HAUSNUMERO + 51
69
+ ENOCOMPATPROTO = _HAUSNUMERO + 52
70
+ ETERM = _HAUSNUMERO + 53
71
+ EMTHREAD = _HAUSNUMERO + 54
72
+
73
+
74
+ class ContextOption(IntEnum):
75
+ """Options for Context.get/set
76
+
77
+ .. versionadded:: 23
78
+ """
79
+
80
+ IO_THREADS = 1
81
+ MAX_SOCKETS = 2
82
+ SOCKET_LIMIT = 3
83
+ THREAD_PRIORITY = 3
84
+ THREAD_SCHED_POLICY = 4
85
+ MAX_MSGSZ = 5
86
+ MSG_T_SIZE = 6
87
+ THREAD_AFFINITY_CPU_ADD = 7
88
+ THREAD_AFFINITY_CPU_REMOVE = 8
89
+ THREAD_NAME_PREFIX = 9
90
+
91
+
92
+ class SocketType(IntEnum):
93
+ """zmq socket types
94
+
95
+ .. versionadded:: 23
96
+ """
97
+
98
+ PAIR = 0
99
+ PUB = 1
100
+ SUB = 2
101
+ REQ = 3
102
+ REP = 4
103
+ DEALER = 5
104
+ ROUTER = 6
105
+ PULL = 7
106
+ PUSH = 8
107
+ XPUB = 9
108
+ XSUB = 10
109
+ STREAM = 11
110
+
111
+ # deprecated aliases
112
+ XREQ = DEALER
113
+ XREP = ROUTER
114
+
115
+ # DRAFT socket types
116
+ SERVER = 12
117
+ CLIENT = 13
118
+ RADIO = 14
119
+ DISH = 15
120
+ GATHER = 16
121
+ SCATTER = 17
122
+ DGRAM = 18
123
+ PEER = 19
124
+ CHANNEL = 20
125
+
126
+
127
+ class _OptType(Enum):
128
+ int = 'int'
129
+ int64 = 'int64'
130
+ bytes = 'bytes'
131
+ fd = 'fd'
132
+
133
+
134
+ class SocketOption(IntEnum):
135
+ """Options for Socket.get/set
136
+
137
+ .. versionadded:: 23
138
+ """
139
+
140
+ _opt_type: _OptType
141
+
142
+ def __new__(cls, value: int, opt_type: _OptType = _OptType.int):
143
+ """Attach option type as `._opt_type`"""
144
+ obj = int.__new__(cls, value)
145
+ obj._value_ = value
146
+ obj._opt_type = opt_type
147
+ return obj
148
+
149
+ HWM = 1
150
+ AFFINITY = 4, _OptType.int64
151
+ ROUTING_ID = 5, _OptType.bytes
152
+ SUBSCRIBE = 6, _OptType.bytes
153
+ UNSUBSCRIBE = 7, _OptType.bytes
154
+ RATE = 8
155
+ RECOVERY_IVL = 9
156
+ SNDBUF = 11
157
+ RCVBUF = 12
158
+ RCVMORE = 13
159
+ FD = 14, _OptType.fd
160
+ EVENTS = 15
161
+ TYPE = 16
162
+ LINGER = 17
163
+ RECONNECT_IVL = 18
164
+ BACKLOG = 19
165
+ RECONNECT_IVL_MAX = 21
166
+ MAXMSGSIZE = 22, _OptType.int64
167
+ SNDHWM = 23
168
+ RCVHWM = 24
169
+ MULTICAST_HOPS = 25
170
+ RCVTIMEO = 27
171
+ SNDTIMEO = 28
172
+ LAST_ENDPOINT = 32, _OptType.bytes
173
+ ROUTER_MANDATORY = 33
174
+ TCP_KEEPALIVE = 34
175
+ TCP_KEEPALIVE_CNT = 35
176
+ TCP_KEEPALIVE_IDLE = 36
177
+ TCP_KEEPALIVE_INTVL = 37
178
+ IMMEDIATE = 39
179
+ XPUB_VERBOSE = 40
180
+ ROUTER_RAW = 41
181
+ IPV6 = 42
182
+ MECHANISM = 43
183
+ PLAIN_SERVER = 44
184
+ PLAIN_USERNAME = 45, _OptType.bytes
185
+ PLAIN_PASSWORD = 46, _OptType.bytes
186
+ CURVE_SERVER = 47
187
+ CURVE_PUBLICKEY = 48, _OptType.bytes
188
+ CURVE_SECRETKEY = 49, _OptType.bytes
189
+ CURVE_SERVERKEY = 50, _OptType.bytes
190
+ PROBE_ROUTER = 51
191
+ REQ_CORRELATE = 52
192
+ REQ_RELAXED = 53
193
+ CONFLATE = 54
194
+ ZAP_DOMAIN = 55, _OptType.bytes
195
+ ROUTER_HANDOVER = 56
196
+ TOS = 57
197
+ CONNECT_ROUTING_ID = 61, _OptType.bytes
198
+ GSSAPI_SERVER = 62
199
+ GSSAPI_PRINCIPAL = 63, _OptType.bytes
200
+ GSSAPI_SERVICE_PRINCIPAL = 64, _OptType.bytes
201
+ GSSAPI_PLAINTEXT = 65
202
+ HANDSHAKE_IVL = 66
203
+ SOCKS_PROXY = 68, _OptType.bytes
204
+ XPUB_NODROP = 69
205
+ BLOCKY = 70
206
+ XPUB_MANUAL = 71
207
+ XPUB_WELCOME_MSG = 72, _OptType.bytes
208
+ STREAM_NOTIFY = 73
209
+ INVERT_MATCHING = 74
210
+ HEARTBEAT_IVL = 75
211
+ HEARTBEAT_TTL = 76
212
+ HEARTBEAT_TIMEOUT = 77
213
+ XPUB_VERBOSER = 78
214
+ CONNECT_TIMEOUT = 79
215
+ TCP_MAXRT = 80
216
+ THREAD_SAFE = 81
217
+ MULTICAST_MAXTPDU = 84
218
+ VMCI_BUFFER_SIZE = 85, _OptType.int64
219
+ VMCI_BUFFER_MIN_SIZE = 86, _OptType.int64
220
+ VMCI_BUFFER_MAX_SIZE = 87, _OptType.int64
221
+ VMCI_CONNECT_TIMEOUT = 88
222
+ USE_FD = 89
223
+ GSSAPI_PRINCIPAL_NAMETYPE = 90
224
+ GSSAPI_SERVICE_PRINCIPAL_NAMETYPE = 91
225
+ BINDTODEVICE = 92, _OptType.bytes
226
+
227
+ # Deprecated options and aliases
228
+ # must not use name-assignment, must have the same value
229
+ IDENTITY = ROUTING_ID
230
+ CONNECT_RID = CONNECT_ROUTING_ID
231
+ TCP_ACCEPT_FILTER = 38, _OptType.bytes
232
+ IPC_FILTER_PID = 58
233
+ IPC_FILTER_UID = 59
234
+ IPC_FILTER_GID = 60
235
+ IPV4ONLY = 31
236
+ DELAY_ATTACH_ON_CONNECT = IMMEDIATE
237
+ FAIL_UNROUTABLE = ROUTER_MANDATORY
238
+ ROUTER_BEHAVIOR = ROUTER_MANDATORY
239
+
240
+ # Draft socket options
241
+ ZAP_ENFORCE_DOMAIN = 93
242
+ LOOPBACK_FASTPATH = 94
243
+ METADATA = 95, _OptType.bytes
244
+ MULTICAST_LOOP = 96
245
+ ROUTER_NOTIFY = 97
246
+ XPUB_MANUAL_LAST_VALUE = 98
247
+ SOCKS_USERNAME = 99, _OptType.bytes
248
+ SOCKS_PASSWORD = 100, _OptType.bytes
249
+ IN_BATCH_SIZE = 101
250
+ OUT_BATCH_SIZE = 102
251
+ WSS_KEY_PEM = 103, _OptType.bytes
252
+ WSS_CERT_PEM = 104, _OptType.bytes
253
+ WSS_TRUST_PEM = 105, _OptType.bytes
254
+ WSS_HOSTNAME = 106, _OptType.bytes
255
+ WSS_TRUST_SYSTEM = 107
256
+ ONLY_FIRST_SUBSCRIBE = 108
257
+ RECONNECT_STOP = 109
258
+ HELLO_MSG = 110, _OptType.bytes
259
+ DISCONNECT_MSG = 111, _OptType.bytes
260
+ PRIORITY = 112
261
+ # 4.3.5
262
+ BUSY_POLL = 113
263
+ HICCUP_MSG = 114, _OptType.bytes
264
+ XSUB_VERBOSE_UNSUBSCRIBE = 115
265
+ TOPICS_COUNT = 116
266
+ NORM_MODE = 117
267
+ NORM_UNICAST_NACK = 118
268
+ NORM_BUFFER_SIZE = 119
269
+ NORM_SEGMENT_SIZE = 120
270
+ NORM_BLOCK_SIZE = 121
271
+ NORM_NUM_PARITY = 122
272
+ NORM_NUM_AUTOPARITY = 123
273
+ NORM_PUSH = 124
274
+
275
+
276
+ class MessageOption(IntEnum):
277
+ """Options on zmq.Frame objects
278
+
279
+ .. versionadded:: 23
280
+ """
281
+
282
+ MORE = 1
283
+ SHARED = 3
284
+ # Deprecated message options
285
+ SRCFD = 2
286
+
287
+
288
+ class Flag(IntFlag):
289
+ """Send/recv flags
290
+
291
+ .. versionadded:: 23
292
+ """
293
+
294
+ DONTWAIT = 1
295
+ SNDMORE = 2
296
+ NOBLOCK = DONTWAIT
297
+
298
+
299
+ class RouterNotify(IntEnum):
300
+ """Values for zmq.ROUTER_NOTIFY socket option
301
+
302
+ .. versionadded:: 26
303
+ .. versionadded:: libzmq-4.3.0 (draft)
304
+ """
305
+
306
+ @staticmethod
307
+ def _global_name(name):
308
+ return f"NOTIFY_{name}"
309
+
310
+ CONNECT = 1
311
+ DISCONNECT = 2
312
+
313
+
314
+ class NormMode(IntEnum):
315
+ """Values for zmq.NORM_MODE socket option
316
+
317
+ .. versionadded:: 26
318
+ .. versionadded:: libzmq-4.3.5 (draft)
319
+ """
320
+
321
+ @staticmethod
322
+ def _global_name(name):
323
+ return f"NORM_{name}"
324
+
325
+ FIXED = 0
326
+ CC = 1
327
+ CCL = 2
328
+ CCE = 3
329
+ CCE_ECNONLY = 4
330
+
331
+
332
+ class SecurityMechanism(IntEnum):
333
+ """Security mechanisms (as returned by ``socket.get(zmq.MECHANISM)``)
334
+
335
+ .. versionadded:: 23
336
+ """
337
+
338
+ NULL = 0
339
+ PLAIN = 1
340
+ CURVE = 2
341
+ GSSAPI = 3
342
+
343
+
344
+ class ReconnectStop(IntEnum):
345
+ """Select behavior for socket.reconnect_stop
346
+
347
+ .. versionadded:: 25
348
+ """
349
+
350
+ @staticmethod
351
+ def _global_name(name):
352
+ return f"RECONNECT_STOP_{name}"
353
+
354
+ CONN_REFUSED = 0x1
355
+ HANDSHAKE_FAILED = 0x2
356
+ AFTER_DISCONNECT = 0x4
357
+
358
+
359
+ class Event(IntFlag):
360
+ """Socket monitoring events
361
+
362
+ .. versionadded:: 23
363
+ """
364
+
365
+ @staticmethod
366
+ def _global_name(name):
367
+ if name.startswith("PROTOCOL_ERROR_"):
368
+ return name
369
+ else:
370
+ # add EVENT_ prefix
371
+ return "EVENT_" + name
372
+
373
+ PROTOCOL_ERROR_WS_UNSPECIFIED = 0x30000000
374
+ PROTOCOL_ERROR_ZMTP_UNSPECIFIED = 0x10000000
375
+ PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND = 0x10000001
376
+ PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE = 0x10000002
377
+ PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE = 0x10000003
378
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED = 0x10000011
379
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE = 0x10000012
380
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO = 0x10000013
381
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE = 0x10000014
382
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR = 0x10000015
383
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY = 0x10000016
384
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME = 0x10000017
385
+ PROTOCOL_ERROR_ZMTP_INVALID_METADATA = 0x10000018
386
+
387
+ PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC = 0x11000001
388
+ PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH = 0x11000002
389
+ PROTOCOL_ERROR_ZAP_UNSPECIFIED = 0x20000000
390
+ PROTOCOL_ERROR_ZAP_MALFORMED_REPLY = 0x20000001
391
+ PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID = 0x20000002
392
+ PROTOCOL_ERROR_ZAP_BAD_VERSION = 0x20000003
393
+ PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE = 0x20000004
394
+ PROTOCOL_ERROR_ZAP_INVALID_METADATA = 0x20000005
395
+
396
+ # define event types _after_ overlapping protocol error masks
397
+ CONNECTED = 0x0001
398
+ CONNECT_DELAYED = 0x0002
399
+ CONNECT_RETRIED = 0x0004
400
+ LISTENING = 0x0008
401
+ BIND_FAILED = 0x0010
402
+ ACCEPTED = 0x0020
403
+ ACCEPT_FAILED = 0x0040
404
+ CLOSED = 0x0080
405
+ CLOSE_FAILED = 0x0100
406
+ DISCONNECTED = 0x0200
407
+ MONITOR_STOPPED = 0x0400
408
+
409
+ HANDSHAKE_FAILED_NO_DETAIL = 0x0800
410
+ HANDSHAKE_SUCCEEDED = 0x1000
411
+ HANDSHAKE_FAILED_PROTOCOL = 0x2000
412
+ HANDSHAKE_FAILED_AUTH = 0x4000
413
+
414
+ ALL_V1 = 0xFFFF
415
+ ALL = ALL_V1
416
+
417
+ # DRAFT Socket monitoring events
418
+ PIPES_STATS = 0x10000
419
+ ALL_V2 = ALL_V1 | PIPES_STATS
420
+
421
+
422
+ class PollEvent(IntFlag):
423
+ """Which events to poll for in poll methods
424
+
425
+ .. versionadded: 23
426
+ """
427
+
428
+ POLLIN = 1
429
+ POLLOUT = 2
430
+ POLLERR = 4
431
+ POLLPRI = 8
432
+
433
+
434
+ class DeviceType(IntEnum):
435
+ """Device type constants for zmq.device
436
+
437
+ .. versionadded: 23
438
+ """
439
+
440
+ STREAMER = 1
441
+ FORWARDER = 2
442
+ QUEUE = 3
443
+
444
+
445
+ # AUTOGENERATED_BELOW_HERE
446
+
447
+
448
+ IO_THREADS: int = ContextOption.IO_THREADS
449
+ MAX_SOCKETS: int = ContextOption.MAX_SOCKETS
450
+ SOCKET_LIMIT: int = ContextOption.SOCKET_LIMIT
451
+ THREAD_PRIORITY: int = ContextOption.THREAD_PRIORITY
452
+ THREAD_SCHED_POLICY: int = ContextOption.THREAD_SCHED_POLICY
453
+ MAX_MSGSZ: int = ContextOption.MAX_MSGSZ
454
+ MSG_T_SIZE: int = ContextOption.MSG_T_SIZE
455
+ THREAD_AFFINITY_CPU_ADD: int = ContextOption.THREAD_AFFINITY_CPU_ADD
456
+ THREAD_AFFINITY_CPU_REMOVE: int = ContextOption.THREAD_AFFINITY_CPU_REMOVE
457
+ THREAD_NAME_PREFIX: int = ContextOption.THREAD_NAME_PREFIX
458
+ STREAMER: int = DeviceType.STREAMER
459
+ FORWARDER: int = DeviceType.FORWARDER
460
+ QUEUE: int = DeviceType.QUEUE
461
+ EAGAIN: int = Errno.EAGAIN
462
+ EFAULT: int = Errno.EFAULT
463
+ EINVAL: int = Errno.EINVAL
464
+ ENOTSUP: int = Errno.ENOTSUP
465
+ EPROTONOSUPPORT: int = Errno.EPROTONOSUPPORT
466
+ ENOBUFS: int = Errno.ENOBUFS
467
+ ENETDOWN: int = Errno.ENETDOWN
468
+ EADDRINUSE: int = Errno.EADDRINUSE
469
+ EADDRNOTAVAIL: int = Errno.EADDRNOTAVAIL
470
+ ECONNREFUSED: int = Errno.ECONNREFUSED
471
+ EINPROGRESS: int = Errno.EINPROGRESS
472
+ ENOTSOCK: int = Errno.ENOTSOCK
473
+ EMSGSIZE: int = Errno.EMSGSIZE
474
+ EAFNOSUPPORT: int = Errno.EAFNOSUPPORT
475
+ ENETUNREACH: int = Errno.ENETUNREACH
476
+ ECONNABORTED: int = Errno.ECONNABORTED
477
+ ECONNRESET: int = Errno.ECONNRESET
478
+ ENOTCONN: int = Errno.ENOTCONN
479
+ ETIMEDOUT: int = Errno.ETIMEDOUT
480
+ EHOSTUNREACH: int = Errno.EHOSTUNREACH
481
+ ENETRESET: int = Errno.ENETRESET
482
+ EFSM: int = Errno.EFSM
483
+ ENOCOMPATPROTO: int = Errno.ENOCOMPATPROTO
484
+ ETERM: int = Errno.ETERM
485
+ EMTHREAD: int = Errno.EMTHREAD
486
+ PROTOCOL_ERROR_WS_UNSPECIFIED: int = Event.PROTOCOL_ERROR_WS_UNSPECIFIED
487
+ PROTOCOL_ERROR_ZMTP_UNSPECIFIED: int = Event.PROTOCOL_ERROR_ZMTP_UNSPECIFIED
488
+ PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND: int = (
489
+ Event.PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND
490
+ )
491
+ PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE: int = Event.PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE
492
+ PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE: int = Event.PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE
493
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED: int = (
494
+ Event.PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED
495
+ )
496
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE: int = (
497
+ Event.PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE
498
+ )
499
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO: int = (
500
+ Event.PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO
501
+ )
502
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE: int = (
503
+ Event.PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE
504
+ )
505
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR: int = (
506
+ Event.PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR
507
+ )
508
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY: int = (
509
+ Event.PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY
510
+ )
511
+ PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME: int = (
512
+ Event.PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME
513
+ )
514
+ PROTOCOL_ERROR_ZMTP_INVALID_METADATA: int = Event.PROTOCOL_ERROR_ZMTP_INVALID_METADATA
515
+ PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC: int = Event.PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC
516
+ PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH: int = (
517
+ Event.PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH
518
+ )
519
+ PROTOCOL_ERROR_ZAP_UNSPECIFIED: int = Event.PROTOCOL_ERROR_ZAP_UNSPECIFIED
520
+ PROTOCOL_ERROR_ZAP_MALFORMED_REPLY: int = Event.PROTOCOL_ERROR_ZAP_MALFORMED_REPLY
521
+ PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID: int = Event.PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID
522
+ PROTOCOL_ERROR_ZAP_BAD_VERSION: int = Event.PROTOCOL_ERROR_ZAP_BAD_VERSION
523
+ PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE: int = (
524
+ Event.PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE
525
+ )
526
+ PROTOCOL_ERROR_ZAP_INVALID_METADATA: int = Event.PROTOCOL_ERROR_ZAP_INVALID_METADATA
527
+ EVENT_CONNECTED: int = Event.CONNECTED
528
+ EVENT_CONNECT_DELAYED: int = Event.CONNECT_DELAYED
529
+ EVENT_CONNECT_RETRIED: int = Event.CONNECT_RETRIED
530
+ EVENT_LISTENING: int = Event.LISTENING
531
+ EVENT_BIND_FAILED: int = Event.BIND_FAILED
532
+ EVENT_ACCEPTED: int = Event.ACCEPTED
533
+ EVENT_ACCEPT_FAILED: int = Event.ACCEPT_FAILED
534
+ EVENT_CLOSED: int = Event.CLOSED
535
+ EVENT_CLOSE_FAILED: int = Event.CLOSE_FAILED
536
+ EVENT_DISCONNECTED: int = Event.DISCONNECTED
537
+ EVENT_MONITOR_STOPPED: int = Event.MONITOR_STOPPED
538
+ EVENT_HANDSHAKE_FAILED_NO_DETAIL: int = Event.HANDSHAKE_FAILED_NO_DETAIL
539
+ EVENT_HANDSHAKE_SUCCEEDED: int = Event.HANDSHAKE_SUCCEEDED
540
+ EVENT_HANDSHAKE_FAILED_PROTOCOL: int = Event.HANDSHAKE_FAILED_PROTOCOL
541
+ EVENT_HANDSHAKE_FAILED_AUTH: int = Event.HANDSHAKE_FAILED_AUTH
542
+ EVENT_ALL_V1: int = Event.ALL_V1
543
+ EVENT_ALL: int = Event.ALL
544
+ EVENT_PIPES_STATS: int = Event.PIPES_STATS
545
+ EVENT_ALL_V2: int = Event.ALL_V2
546
+ DONTWAIT: int = Flag.DONTWAIT
547
+ SNDMORE: int = Flag.SNDMORE
548
+ NOBLOCK: int = Flag.NOBLOCK
549
+ MORE: int = MessageOption.MORE
550
+ SHARED: int = MessageOption.SHARED
551
+ SRCFD: int = MessageOption.SRCFD
552
+ NORM_FIXED: int = NormMode.FIXED
553
+ NORM_CC: int = NormMode.CC
554
+ NORM_CCL: int = NormMode.CCL
555
+ NORM_CCE: int = NormMode.CCE
556
+ NORM_CCE_ECNONLY: int = NormMode.CCE_ECNONLY
557
+ POLLIN: int = PollEvent.POLLIN
558
+ POLLOUT: int = PollEvent.POLLOUT
559
+ POLLERR: int = PollEvent.POLLERR
560
+ POLLPRI: int = PollEvent.POLLPRI
561
+ RECONNECT_STOP_CONN_REFUSED: int = ReconnectStop.CONN_REFUSED
562
+ RECONNECT_STOP_HANDSHAKE_FAILED: int = ReconnectStop.HANDSHAKE_FAILED
563
+ RECONNECT_STOP_AFTER_DISCONNECT: int = ReconnectStop.AFTER_DISCONNECT
564
+ NOTIFY_CONNECT: int = RouterNotify.CONNECT
565
+ NOTIFY_DISCONNECT: int = RouterNotify.DISCONNECT
566
+ NULL: int = SecurityMechanism.NULL
567
+ PLAIN: int = SecurityMechanism.PLAIN
568
+ CURVE: int = SecurityMechanism.CURVE
569
+ GSSAPI: int = SecurityMechanism.GSSAPI
570
+ HWM: int = SocketOption.HWM
571
+ AFFINITY: int = SocketOption.AFFINITY
572
+ ROUTING_ID: int = SocketOption.ROUTING_ID
573
+ SUBSCRIBE: int = SocketOption.SUBSCRIBE
574
+ UNSUBSCRIBE: int = SocketOption.UNSUBSCRIBE
575
+ RATE: int = SocketOption.RATE
576
+ RECOVERY_IVL: int = SocketOption.RECOVERY_IVL
577
+ SNDBUF: int = SocketOption.SNDBUF
578
+ RCVBUF: int = SocketOption.RCVBUF
579
+ RCVMORE: int = SocketOption.RCVMORE
580
+ FD: int = SocketOption.FD
581
+ EVENTS: int = SocketOption.EVENTS
582
+ TYPE: int = SocketOption.TYPE
583
+ LINGER: int = SocketOption.LINGER
584
+ RECONNECT_IVL: int = SocketOption.RECONNECT_IVL
585
+ BACKLOG: int = SocketOption.BACKLOG
586
+ RECONNECT_IVL_MAX: int = SocketOption.RECONNECT_IVL_MAX
587
+ MAXMSGSIZE: int = SocketOption.MAXMSGSIZE
588
+ SNDHWM: int = SocketOption.SNDHWM
589
+ RCVHWM: int = SocketOption.RCVHWM
590
+ MULTICAST_HOPS: int = SocketOption.MULTICAST_HOPS
591
+ RCVTIMEO: int = SocketOption.RCVTIMEO
592
+ SNDTIMEO: int = SocketOption.SNDTIMEO
593
+ LAST_ENDPOINT: int = SocketOption.LAST_ENDPOINT
594
+ ROUTER_MANDATORY: int = SocketOption.ROUTER_MANDATORY
595
+ TCP_KEEPALIVE: int = SocketOption.TCP_KEEPALIVE
596
+ TCP_KEEPALIVE_CNT: int = SocketOption.TCP_KEEPALIVE_CNT
597
+ TCP_KEEPALIVE_IDLE: int = SocketOption.TCP_KEEPALIVE_IDLE
598
+ TCP_KEEPALIVE_INTVL: int = SocketOption.TCP_KEEPALIVE_INTVL
599
+ IMMEDIATE: int = SocketOption.IMMEDIATE
600
+ XPUB_VERBOSE: int = SocketOption.XPUB_VERBOSE
601
+ ROUTER_RAW: int = SocketOption.ROUTER_RAW
602
+ IPV6: int = SocketOption.IPV6
603
+ MECHANISM: int = SocketOption.MECHANISM
604
+ PLAIN_SERVER: int = SocketOption.PLAIN_SERVER
605
+ PLAIN_USERNAME: int = SocketOption.PLAIN_USERNAME
606
+ PLAIN_PASSWORD: int = SocketOption.PLAIN_PASSWORD
607
+ CURVE_SERVER: int = SocketOption.CURVE_SERVER
608
+ CURVE_PUBLICKEY: int = SocketOption.CURVE_PUBLICKEY
609
+ CURVE_SECRETKEY: int = SocketOption.CURVE_SECRETKEY
610
+ CURVE_SERVERKEY: int = SocketOption.CURVE_SERVERKEY
611
+ PROBE_ROUTER: int = SocketOption.PROBE_ROUTER
612
+ REQ_CORRELATE: int = SocketOption.REQ_CORRELATE
613
+ REQ_RELAXED: int = SocketOption.REQ_RELAXED
614
+ CONFLATE: int = SocketOption.CONFLATE
615
+ ZAP_DOMAIN: int = SocketOption.ZAP_DOMAIN
616
+ ROUTER_HANDOVER: int = SocketOption.ROUTER_HANDOVER
617
+ TOS: int = SocketOption.TOS
618
+ CONNECT_ROUTING_ID: int = SocketOption.CONNECT_ROUTING_ID
619
+ GSSAPI_SERVER: int = SocketOption.GSSAPI_SERVER
620
+ GSSAPI_PRINCIPAL: int = SocketOption.GSSAPI_PRINCIPAL
621
+ GSSAPI_SERVICE_PRINCIPAL: int = SocketOption.GSSAPI_SERVICE_PRINCIPAL
622
+ GSSAPI_PLAINTEXT: int = SocketOption.GSSAPI_PLAINTEXT
623
+ HANDSHAKE_IVL: int = SocketOption.HANDSHAKE_IVL
624
+ SOCKS_PROXY: int = SocketOption.SOCKS_PROXY
625
+ XPUB_NODROP: int = SocketOption.XPUB_NODROP
626
+ BLOCKY: int = SocketOption.BLOCKY
627
+ XPUB_MANUAL: int = SocketOption.XPUB_MANUAL
628
+ XPUB_WELCOME_MSG: int = SocketOption.XPUB_WELCOME_MSG
629
+ STREAM_NOTIFY: int = SocketOption.STREAM_NOTIFY
630
+ INVERT_MATCHING: int = SocketOption.INVERT_MATCHING
631
+ HEARTBEAT_IVL: int = SocketOption.HEARTBEAT_IVL
632
+ HEARTBEAT_TTL: int = SocketOption.HEARTBEAT_TTL
633
+ HEARTBEAT_TIMEOUT: int = SocketOption.HEARTBEAT_TIMEOUT
634
+ XPUB_VERBOSER: int = SocketOption.XPUB_VERBOSER
635
+ CONNECT_TIMEOUT: int = SocketOption.CONNECT_TIMEOUT
636
+ TCP_MAXRT: int = SocketOption.TCP_MAXRT
637
+ THREAD_SAFE: int = SocketOption.THREAD_SAFE
638
+ MULTICAST_MAXTPDU: int = SocketOption.MULTICAST_MAXTPDU
639
+ VMCI_BUFFER_SIZE: int = SocketOption.VMCI_BUFFER_SIZE
640
+ VMCI_BUFFER_MIN_SIZE: int = SocketOption.VMCI_BUFFER_MIN_SIZE
641
+ VMCI_BUFFER_MAX_SIZE: int = SocketOption.VMCI_BUFFER_MAX_SIZE
642
+ VMCI_CONNECT_TIMEOUT: int = SocketOption.VMCI_CONNECT_TIMEOUT
643
+ USE_FD: int = SocketOption.USE_FD
644
+ GSSAPI_PRINCIPAL_NAMETYPE: int = SocketOption.GSSAPI_PRINCIPAL_NAMETYPE
645
+ GSSAPI_SERVICE_PRINCIPAL_NAMETYPE: int = SocketOption.GSSAPI_SERVICE_PRINCIPAL_NAMETYPE
646
+ BINDTODEVICE: int = SocketOption.BINDTODEVICE
647
+ IDENTITY: int = SocketOption.IDENTITY
648
+ CONNECT_RID: int = SocketOption.CONNECT_RID
649
+ TCP_ACCEPT_FILTER: int = SocketOption.TCP_ACCEPT_FILTER
650
+ IPC_FILTER_PID: int = SocketOption.IPC_FILTER_PID
651
+ IPC_FILTER_UID: int = SocketOption.IPC_FILTER_UID
652
+ IPC_FILTER_GID: int = SocketOption.IPC_FILTER_GID
653
+ IPV4ONLY: int = SocketOption.IPV4ONLY
654
+ DELAY_ATTACH_ON_CONNECT: int = SocketOption.DELAY_ATTACH_ON_CONNECT
655
+ FAIL_UNROUTABLE: int = SocketOption.FAIL_UNROUTABLE
656
+ ROUTER_BEHAVIOR: int = SocketOption.ROUTER_BEHAVIOR
657
+ ZAP_ENFORCE_DOMAIN: int = SocketOption.ZAP_ENFORCE_DOMAIN
658
+ LOOPBACK_FASTPATH: int = SocketOption.LOOPBACK_FASTPATH
659
+ METADATA: int = SocketOption.METADATA
660
+ MULTICAST_LOOP: int = SocketOption.MULTICAST_LOOP
661
+ ROUTER_NOTIFY: int = SocketOption.ROUTER_NOTIFY
662
+ XPUB_MANUAL_LAST_VALUE: int = SocketOption.XPUB_MANUAL_LAST_VALUE
663
+ SOCKS_USERNAME: int = SocketOption.SOCKS_USERNAME
664
+ SOCKS_PASSWORD: int = SocketOption.SOCKS_PASSWORD
665
+ IN_BATCH_SIZE: int = SocketOption.IN_BATCH_SIZE
666
+ OUT_BATCH_SIZE: int = SocketOption.OUT_BATCH_SIZE
667
+ WSS_KEY_PEM: int = SocketOption.WSS_KEY_PEM
668
+ WSS_CERT_PEM: int = SocketOption.WSS_CERT_PEM
669
+ WSS_TRUST_PEM: int = SocketOption.WSS_TRUST_PEM
670
+ WSS_HOSTNAME: int = SocketOption.WSS_HOSTNAME
671
+ WSS_TRUST_SYSTEM: int = SocketOption.WSS_TRUST_SYSTEM
672
+ ONLY_FIRST_SUBSCRIBE: int = SocketOption.ONLY_FIRST_SUBSCRIBE
673
+ RECONNECT_STOP: int = SocketOption.RECONNECT_STOP
674
+ HELLO_MSG: int = SocketOption.HELLO_MSG
675
+ DISCONNECT_MSG: int = SocketOption.DISCONNECT_MSG
676
+ PRIORITY: int = SocketOption.PRIORITY
677
+ BUSY_POLL: int = SocketOption.BUSY_POLL
678
+ HICCUP_MSG: int = SocketOption.HICCUP_MSG
679
+ XSUB_VERBOSE_UNSUBSCRIBE: int = SocketOption.XSUB_VERBOSE_UNSUBSCRIBE
680
+ TOPICS_COUNT: int = SocketOption.TOPICS_COUNT
681
+ NORM_MODE: int = SocketOption.NORM_MODE
682
+ NORM_UNICAST_NACK: int = SocketOption.NORM_UNICAST_NACK
683
+ NORM_BUFFER_SIZE: int = SocketOption.NORM_BUFFER_SIZE
684
+ NORM_SEGMENT_SIZE: int = SocketOption.NORM_SEGMENT_SIZE
685
+ NORM_BLOCK_SIZE: int = SocketOption.NORM_BLOCK_SIZE
686
+ NORM_NUM_PARITY: int = SocketOption.NORM_NUM_PARITY
687
+ NORM_NUM_AUTOPARITY: int = SocketOption.NORM_NUM_AUTOPARITY
688
+ NORM_PUSH: int = SocketOption.NORM_PUSH
689
+ PAIR: int = SocketType.PAIR
690
+ PUB: int = SocketType.PUB
691
+ SUB: int = SocketType.SUB
692
+ REQ: int = SocketType.REQ
693
+ REP: int = SocketType.REP
694
+ DEALER: int = SocketType.DEALER
695
+ ROUTER: int = SocketType.ROUTER
696
+ PULL: int = SocketType.PULL
697
+ PUSH: int = SocketType.PUSH
698
+ XPUB: int = SocketType.XPUB
699
+ XSUB: int = SocketType.XSUB
700
+ STREAM: int = SocketType.STREAM
701
+ XREQ: int = SocketType.XREQ
702
+ XREP: int = SocketType.XREP
703
+ SERVER: int = SocketType.SERVER
704
+ CLIENT: int = SocketType.CLIENT
705
+ RADIO: int = SocketType.RADIO
706
+ DISH: int = SocketType.DISH
707
+ GATHER: int = SocketType.GATHER
708
+ SCATTER: int = SocketType.SCATTER
709
+ DGRAM: int = SocketType.DGRAM
710
+ PEER: int = SocketType.PEER
711
+ CHANNEL: int = SocketType.CHANNEL
712
+
713
+ __all__: list[str] = [
714
+ "ContextOption",
715
+ "IO_THREADS",
716
+ "MAX_SOCKETS",
717
+ "SOCKET_LIMIT",
718
+ "THREAD_PRIORITY",
719
+ "THREAD_SCHED_POLICY",
720
+ "MAX_MSGSZ",
721
+ "MSG_T_SIZE",
722
+ "THREAD_AFFINITY_CPU_ADD",
723
+ "THREAD_AFFINITY_CPU_REMOVE",
724
+ "THREAD_NAME_PREFIX",
725
+ "DeviceType",
726
+ "STREAMER",
727
+ "FORWARDER",
728
+ "QUEUE",
729
+ "Enum",
730
+ "Errno",
731
+ "EAGAIN",
732
+ "EFAULT",
733
+ "EINVAL",
734
+ "ENOTSUP",
735
+ "EPROTONOSUPPORT",
736
+ "ENOBUFS",
737
+ "ENETDOWN",
738
+ "EADDRINUSE",
739
+ "EADDRNOTAVAIL",
740
+ "ECONNREFUSED",
741
+ "EINPROGRESS",
742
+ "ENOTSOCK",
743
+ "EMSGSIZE",
744
+ "EAFNOSUPPORT",
745
+ "ENETUNREACH",
746
+ "ECONNABORTED",
747
+ "ECONNRESET",
748
+ "ENOTCONN",
749
+ "ETIMEDOUT",
750
+ "EHOSTUNREACH",
751
+ "ENETRESET",
752
+ "EFSM",
753
+ "ENOCOMPATPROTO",
754
+ "ETERM",
755
+ "EMTHREAD",
756
+ "Event",
757
+ "PROTOCOL_ERROR_WS_UNSPECIFIED",
758
+ "PROTOCOL_ERROR_ZMTP_UNSPECIFIED",
759
+ "PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND",
760
+ "PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE",
761
+ "PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE",
762
+ "PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED",
763
+ "PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE",
764
+ "PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO",
765
+ "PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE",
766
+ "PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR",
767
+ "PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY",
768
+ "PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME",
769
+ "PROTOCOL_ERROR_ZMTP_INVALID_METADATA",
770
+ "PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC",
771
+ "PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH",
772
+ "PROTOCOL_ERROR_ZAP_UNSPECIFIED",
773
+ "PROTOCOL_ERROR_ZAP_MALFORMED_REPLY",
774
+ "PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID",
775
+ "PROTOCOL_ERROR_ZAP_BAD_VERSION",
776
+ "PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE",
777
+ "PROTOCOL_ERROR_ZAP_INVALID_METADATA",
778
+ "EVENT_CONNECTED",
779
+ "EVENT_CONNECT_DELAYED",
780
+ "EVENT_CONNECT_RETRIED",
781
+ "EVENT_LISTENING",
782
+ "EVENT_BIND_FAILED",
783
+ "EVENT_ACCEPTED",
784
+ "EVENT_ACCEPT_FAILED",
785
+ "EVENT_CLOSED",
786
+ "EVENT_CLOSE_FAILED",
787
+ "EVENT_DISCONNECTED",
788
+ "EVENT_MONITOR_STOPPED",
789
+ "EVENT_HANDSHAKE_FAILED_NO_DETAIL",
790
+ "EVENT_HANDSHAKE_SUCCEEDED",
791
+ "EVENT_HANDSHAKE_FAILED_PROTOCOL",
792
+ "EVENT_HANDSHAKE_FAILED_AUTH",
793
+ "EVENT_ALL_V1",
794
+ "EVENT_ALL",
795
+ "EVENT_PIPES_STATS",
796
+ "EVENT_ALL_V2",
797
+ "Flag",
798
+ "DONTWAIT",
799
+ "SNDMORE",
800
+ "NOBLOCK",
801
+ "IntEnum",
802
+ "IntFlag",
803
+ "MessageOption",
804
+ "MORE",
805
+ "SHARED",
806
+ "SRCFD",
807
+ "NormMode",
808
+ "NORM_FIXED",
809
+ "NORM_CC",
810
+ "NORM_CCL",
811
+ "NORM_CCE",
812
+ "NORM_CCE_ECNONLY",
813
+ "PollEvent",
814
+ "POLLIN",
815
+ "POLLOUT",
816
+ "POLLERR",
817
+ "POLLPRI",
818
+ "ReconnectStop",
819
+ "RECONNECT_STOP_CONN_REFUSED",
820
+ "RECONNECT_STOP_HANDSHAKE_FAILED",
821
+ "RECONNECT_STOP_AFTER_DISCONNECT",
822
+ "RouterNotify",
823
+ "NOTIFY_CONNECT",
824
+ "NOTIFY_DISCONNECT",
825
+ "SecurityMechanism",
826
+ "NULL",
827
+ "PLAIN",
828
+ "CURVE",
829
+ "GSSAPI",
830
+ "SocketOption",
831
+ "HWM",
832
+ "AFFINITY",
833
+ "ROUTING_ID",
834
+ "SUBSCRIBE",
835
+ "UNSUBSCRIBE",
836
+ "RATE",
837
+ "RECOVERY_IVL",
838
+ "SNDBUF",
839
+ "RCVBUF",
840
+ "RCVMORE",
841
+ "FD",
842
+ "EVENTS",
843
+ "TYPE",
844
+ "LINGER",
845
+ "RECONNECT_IVL",
846
+ "BACKLOG",
847
+ "RECONNECT_IVL_MAX",
848
+ "MAXMSGSIZE",
849
+ "SNDHWM",
850
+ "RCVHWM",
851
+ "MULTICAST_HOPS",
852
+ "RCVTIMEO",
853
+ "SNDTIMEO",
854
+ "LAST_ENDPOINT",
855
+ "ROUTER_MANDATORY",
856
+ "TCP_KEEPALIVE",
857
+ "TCP_KEEPALIVE_CNT",
858
+ "TCP_KEEPALIVE_IDLE",
859
+ "TCP_KEEPALIVE_INTVL",
860
+ "IMMEDIATE",
861
+ "XPUB_VERBOSE",
862
+ "ROUTER_RAW",
863
+ "IPV6",
864
+ "MECHANISM",
865
+ "PLAIN_SERVER",
866
+ "PLAIN_USERNAME",
867
+ "PLAIN_PASSWORD",
868
+ "CURVE_SERVER",
869
+ "CURVE_PUBLICKEY",
870
+ "CURVE_SECRETKEY",
871
+ "CURVE_SERVERKEY",
872
+ "PROBE_ROUTER",
873
+ "REQ_CORRELATE",
874
+ "REQ_RELAXED",
875
+ "CONFLATE",
876
+ "ZAP_DOMAIN",
877
+ "ROUTER_HANDOVER",
878
+ "TOS",
879
+ "CONNECT_ROUTING_ID",
880
+ "GSSAPI_SERVER",
881
+ "GSSAPI_PRINCIPAL",
882
+ "GSSAPI_SERVICE_PRINCIPAL",
883
+ "GSSAPI_PLAINTEXT",
884
+ "HANDSHAKE_IVL",
885
+ "SOCKS_PROXY",
886
+ "XPUB_NODROP",
887
+ "BLOCKY",
888
+ "XPUB_MANUAL",
889
+ "XPUB_WELCOME_MSG",
890
+ "STREAM_NOTIFY",
891
+ "INVERT_MATCHING",
892
+ "HEARTBEAT_IVL",
893
+ "HEARTBEAT_TTL",
894
+ "HEARTBEAT_TIMEOUT",
895
+ "XPUB_VERBOSER",
896
+ "CONNECT_TIMEOUT",
897
+ "TCP_MAXRT",
898
+ "THREAD_SAFE",
899
+ "MULTICAST_MAXTPDU",
900
+ "VMCI_BUFFER_SIZE",
901
+ "VMCI_BUFFER_MIN_SIZE",
902
+ "VMCI_BUFFER_MAX_SIZE",
903
+ "VMCI_CONNECT_TIMEOUT",
904
+ "USE_FD",
905
+ "GSSAPI_PRINCIPAL_NAMETYPE",
906
+ "GSSAPI_SERVICE_PRINCIPAL_NAMETYPE",
907
+ "BINDTODEVICE",
908
+ "IDENTITY",
909
+ "CONNECT_RID",
910
+ "TCP_ACCEPT_FILTER",
911
+ "IPC_FILTER_PID",
912
+ "IPC_FILTER_UID",
913
+ "IPC_FILTER_GID",
914
+ "IPV4ONLY",
915
+ "DELAY_ATTACH_ON_CONNECT",
916
+ "FAIL_UNROUTABLE",
917
+ "ROUTER_BEHAVIOR",
918
+ "ZAP_ENFORCE_DOMAIN",
919
+ "LOOPBACK_FASTPATH",
920
+ "METADATA",
921
+ "MULTICAST_LOOP",
922
+ "ROUTER_NOTIFY",
923
+ "XPUB_MANUAL_LAST_VALUE",
924
+ "SOCKS_USERNAME",
925
+ "SOCKS_PASSWORD",
926
+ "IN_BATCH_SIZE",
927
+ "OUT_BATCH_SIZE",
928
+ "WSS_KEY_PEM",
929
+ "WSS_CERT_PEM",
930
+ "WSS_TRUST_PEM",
931
+ "WSS_HOSTNAME",
932
+ "WSS_TRUST_SYSTEM",
933
+ "ONLY_FIRST_SUBSCRIBE",
934
+ "RECONNECT_STOP",
935
+ "HELLO_MSG",
936
+ "DISCONNECT_MSG",
937
+ "PRIORITY",
938
+ "BUSY_POLL",
939
+ "HICCUP_MSG",
940
+ "XSUB_VERBOSE_UNSUBSCRIBE",
941
+ "TOPICS_COUNT",
942
+ "NORM_MODE",
943
+ "NORM_UNICAST_NACK",
944
+ "NORM_BUFFER_SIZE",
945
+ "NORM_SEGMENT_SIZE",
946
+ "NORM_BLOCK_SIZE",
947
+ "NORM_NUM_PARITY",
948
+ "NORM_NUM_AUTOPARITY",
949
+ "NORM_PUSH",
950
+ "SocketType",
951
+ "PAIR",
952
+ "PUB",
953
+ "SUB",
954
+ "REQ",
955
+ "REP",
956
+ "DEALER",
957
+ "ROUTER",
958
+ "PULL",
959
+ "PUSH",
960
+ "XPUB",
961
+ "XSUB",
962
+ "STREAM",
963
+ "XREQ",
964
+ "XREP",
965
+ "SERVER",
966
+ "CLIENT",
967
+ "RADIO",
968
+ "DISH",
969
+ "GATHER",
970
+ "SCATTER",
971
+ "DGRAM",
972
+ "PEER",
973
+ "CHANNEL",
974
+ ]
.venv/lib/python3.11/site-packages/zmq/devices/__init__.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """0MQ Device classes for running in background threads or processes."""
2
+
3
+ # Copyright (C) PyZMQ Developers
4
+ # Distributed under the terms of the Modified BSD License.
5
+
6
+ from zmq import device
7
+ from zmq.devices import (
8
+ basedevice,
9
+ monitoredqueue,
10
+ monitoredqueuedevice,
11
+ proxydevice,
12
+ proxysteerabledevice,
13
+ )
14
+ from zmq.devices.basedevice import *
15
+ from zmq.devices.monitoredqueue import *
16
+ from zmq.devices.monitoredqueuedevice import *
17
+ from zmq.devices.proxydevice import *
18
+ from zmq.devices.proxysteerabledevice import *
19
+
20
+ __all__ = ['device']
21
+ for submod in (
22
+ basedevice,
23
+ proxydevice,
24
+ proxysteerabledevice,
25
+ monitoredqueue,
26
+ monitoredqueuedevice,
27
+ ):
28
+ __all__.extend(submod.__all__) # type: ignore
.venv/lib/python3.11/site-packages/zmq/devices/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (972 Bytes). View file
 
.venv/lib/python3.11/site-packages/zmq/devices/__pycache__/basedevice.cpython-311.pyc ADDED
Binary file (14.4 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/devices/__pycache__/monitoredqueue.cpython-311.pyc ADDED
Binary file (1.99 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/devices/__pycache__/monitoredqueuedevice.cpython-311.pyc ADDED
Binary file (3.15 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/devices/__pycache__/proxydevice.cpython-311.pyc ADDED
Binary file (5.03 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/devices/__pycache__/proxysteerabledevice.cpython-311.pyc ADDED
Binary file (5.64 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/devices/basedevice.py ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Classes for running 0MQ Devices in the background."""
2
+
3
+ # Copyright (C) PyZMQ Developers
4
+ # Distributed under the terms of the Modified BSD License.
5
+
6
+ import time
7
+ from multiprocessing import Process
8
+ from threading import Thread
9
+ from typing import Any, Callable, List, Optional, Tuple
10
+
11
+ import zmq
12
+ from zmq import ENOTSOCK, ETERM, PUSH, QUEUE, Context, ZMQBindError, ZMQError, device
13
+
14
+
15
+ class Device:
16
+ """A 0MQ Device to be run in the background.
17
+
18
+ You do not pass Socket instances to this, but rather Socket types::
19
+
20
+ Device(device_type, in_socket_type, out_socket_type)
21
+
22
+ For instance::
23
+
24
+ dev = Device(zmq.QUEUE, zmq.DEALER, zmq.ROUTER)
25
+
26
+ Similar to zmq.device, but socket types instead of sockets themselves are
27
+ passed, and the sockets are created in the work thread, to avoid issues
28
+ with thread safety. As a result, additional bind_{in|out} and
29
+ connect_{in|out} methods and setsockopt_{in|out} allow users to specify
30
+ connections for the sockets.
31
+
32
+ Parameters
33
+ ----------
34
+ device_type : int
35
+ The 0MQ Device type
36
+ {in|out}_type : int
37
+ zmq socket types, to be passed later to context.socket(). e.g.
38
+ zmq.PUB, zmq.SUB, zmq.REQ. If out_type is < 0, then in_socket is used
39
+ for both in_socket and out_socket.
40
+
41
+ Methods
42
+ -------
43
+ bind_{in_out}(iface)
44
+ passthrough for ``{in|out}_socket.bind(iface)``, to be called in the thread
45
+ connect_{in_out}(iface)
46
+ passthrough for ``{in|out}_socket.connect(iface)``, to be called in the
47
+ thread
48
+ setsockopt_{in_out}(opt,value)
49
+ passthrough for ``{in|out}_socket.setsockopt(opt, value)``, to be called in
50
+ the thread
51
+
52
+ Attributes
53
+ ----------
54
+ daemon : bool
55
+ sets whether the thread should be run as a daemon
56
+ Default is true, because if it is false, the thread will not
57
+ exit unless it is killed
58
+ context_factory : callable
59
+ This is a class attribute.
60
+ Function for creating the Context. This will be Context.instance
61
+ in ThreadDevices, and Context in ProcessDevices. The only reason
62
+ it is not instance() in ProcessDevices is that there may be a stale
63
+ Context instance already initialized, and the forked environment
64
+ should *never* try to use it.
65
+ """
66
+
67
+ context_factory: Callable[[], zmq.Context] = Context.instance
68
+ """Callable that returns a context. Typically either Context.instance or Context,
69
+ depending on whether the device should share the global instance or not.
70
+ """
71
+
72
+ daemon: bool
73
+ device_type: int
74
+ in_type: int
75
+ out_type: int
76
+
77
+ _in_binds: List[str]
78
+ _in_connects: List[str]
79
+ _in_sockopts: List[Tuple[int, Any]]
80
+ _out_binds: List[str]
81
+ _out_connects: List[str]
82
+ _out_sockopts: List[Tuple[int, Any]]
83
+ _random_addrs: List[str]
84
+ _sockets: List[zmq.Socket]
85
+
86
+ def __init__(
87
+ self,
88
+ device_type: int = QUEUE,
89
+ in_type: Optional[int] = None,
90
+ out_type: Optional[int] = None,
91
+ ) -> None:
92
+ self.device_type = device_type
93
+ if in_type is None:
94
+ raise TypeError("in_type must be specified")
95
+ if out_type is None:
96
+ raise TypeError("out_type must be specified")
97
+ self.in_type = in_type
98
+ self.out_type = out_type
99
+ self._in_binds = []
100
+ self._in_connects = []
101
+ self._in_sockopts = []
102
+ self._out_binds = []
103
+ self._out_connects = []
104
+ self._out_sockopts = []
105
+ self._random_addrs = []
106
+ self.daemon = True
107
+ self.done = False
108
+ self._sockets = []
109
+
110
+ def bind_in(self, addr: str) -> None:
111
+ """Enqueue ZMQ address for binding on in_socket.
112
+
113
+ See zmq.Socket.bind for details.
114
+ """
115
+ self._in_binds.append(addr)
116
+
117
+ def bind_in_to_random_port(self, addr: str, *args, **kwargs) -> int:
118
+ """Enqueue a random port on the given interface for binding on
119
+ in_socket.
120
+
121
+ See zmq.Socket.bind_to_random_port for details.
122
+
123
+ .. versionadded:: 18.0
124
+ """
125
+ port = self._reserve_random_port(addr, *args, **kwargs)
126
+
127
+ self.bind_in(f'{addr}:{port}')
128
+
129
+ return port
130
+
131
+ def connect_in(self, addr: str) -> None:
132
+ """Enqueue ZMQ address for connecting on in_socket.
133
+
134
+ See zmq.Socket.connect for details.
135
+ """
136
+ self._in_connects.append(addr)
137
+
138
+ def setsockopt_in(self, opt: int, value: Any) -> None:
139
+ """Enqueue setsockopt(opt, value) for in_socket
140
+
141
+ See zmq.Socket.setsockopt for details.
142
+ """
143
+ self._in_sockopts.append((opt, value))
144
+
145
+ def bind_out(self, addr: str) -> None:
146
+ """Enqueue ZMQ address for binding on out_socket.
147
+
148
+ See zmq.Socket.bind for details.
149
+ """
150
+ self._out_binds.append(addr)
151
+
152
+ def bind_out_to_random_port(self, addr: str, *args, **kwargs) -> int:
153
+ """Enqueue a random port on the given interface for binding on
154
+ out_socket.
155
+
156
+ See zmq.Socket.bind_to_random_port for details.
157
+
158
+ .. versionadded:: 18.0
159
+ """
160
+ port = self._reserve_random_port(addr, *args, **kwargs)
161
+
162
+ self.bind_out(f'{addr}:{port}')
163
+
164
+ return port
165
+
166
+ def connect_out(self, addr: str):
167
+ """Enqueue ZMQ address for connecting on out_socket.
168
+
169
+ See zmq.Socket.connect for details.
170
+ """
171
+ self._out_connects.append(addr)
172
+
173
+ def setsockopt_out(self, opt: int, value: Any):
174
+ """Enqueue setsockopt(opt, value) for out_socket
175
+
176
+ See zmq.Socket.setsockopt for details.
177
+ """
178
+ self._out_sockopts.append((opt, value))
179
+
180
+ def _reserve_random_port(self, addr: str, *args, **kwargs) -> int:
181
+ with Context() as ctx:
182
+ with ctx.socket(PUSH) as binder:
183
+ for i in range(5):
184
+ port = binder.bind_to_random_port(addr, *args, **kwargs)
185
+
186
+ new_addr = f'{addr}:{port}'
187
+
188
+ if new_addr in self._random_addrs:
189
+ continue
190
+ else:
191
+ break
192
+ else:
193
+ raise ZMQBindError("Could not reserve random port.")
194
+
195
+ self._random_addrs.append(new_addr)
196
+
197
+ return port
198
+
199
+ def _setup_sockets(self) -> Tuple[zmq.Socket, zmq.Socket]:
200
+ ctx: zmq.Context[zmq.Socket] = self.context_factory() # type: ignore
201
+ self._context = ctx
202
+
203
+ # create the sockets
204
+ ins = ctx.socket(self.in_type)
205
+ self._sockets.append(ins)
206
+ if self.out_type < 0:
207
+ outs = ins
208
+ else:
209
+ outs = ctx.socket(self.out_type)
210
+ self._sockets.append(outs)
211
+
212
+ # set sockopts (must be done first, in case of zmq.IDENTITY)
213
+ for opt, value in self._in_sockopts:
214
+ ins.setsockopt(opt, value)
215
+ for opt, value in self._out_sockopts:
216
+ outs.setsockopt(opt, value)
217
+
218
+ for iface in self._in_binds:
219
+ ins.bind(iface)
220
+ for iface in self._out_binds:
221
+ outs.bind(iface)
222
+
223
+ for iface in self._in_connects:
224
+ ins.connect(iface)
225
+ for iface in self._out_connects:
226
+ outs.connect(iface)
227
+
228
+ return ins, outs
229
+
230
+ def run_device(self) -> None:
231
+ """The runner method.
232
+
233
+ Do not call me directly, instead call ``self.start()``, just like a Thread.
234
+ """
235
+ ins, outs = self._setup_sockets()
236
+ device(self.device_type, ins, outs)
237
+
238
+ def _close_sockets(self):
239
+ """Cleanup sockets we created"""
240
+ for s in self._sockets:
241
+ if s and not s.closed:
242
+ s.close()
243
+
244
+ def run(self) -> None:
245
+ """wrap run_device in try/catch ETERM"""
246
+ try:
247
+ self.run_device()
248
+ except ZMQError as e:
249
+ if e.errno in {ETERM, ENOTSOCK}:
250
+ # silence TERM, ENOTSOCK errors, because this should be a clean shutdown
251
+ pass
252
+ else:
253
+ raise
254
+ finally:
255
+ self.done = True
256
+ self._close_sockets()
257
+
258
+ def start(self) -> None:
259
+ """Start the device. Override me in subclass for other launchers."""
260
+ return self.run()
261
+
262
+ def join(self, timeout: Optional[float] = None) -> None:
263
+ """wait for me to finish, like Thread.join.
264
+
265
+ Reimplemented appropriately by subclasses."""
266
+ tic = time.monotonic()
267
+ toc = tic
268
+ while not self.done and not (timeout is not None and toc - tic > timeout):
269
+ time.sleep(0.001)
270
+ toc = time.monotonic()
271
+
272
+
273
+ class BackgroundDevice(Device):
274
+ """Base class for launching Devices in background processes and threads."""
275
+
276
+ launcher: Any = None
277
+ _launch_class: Any = None
278
+
279
+ def start(self) -> None:
280
+ self.launcher = self._launch_class(target=self.run)
281
+ self.launcher.daemon = self.daemon
282
+ return self.launcher.start()
283
+
284
+ def join(self, timeout: Optional[float] = None) -> None:
285
+ return self.launcher.join(timeout=timeout)
286
+
287
+
288
+ class ThreadDevice(BackgroundDevice):
289
+ """A Device that will be run in a background Thread.
290
+
291
+ See Device for details.
292
+ """
293
+
294
+ _launch_class = Thread
295
+
296
+
297
+ class ProcessDevice(BackgroundDevice):
298
+ """A Device that will be run in a background Process.
299
+
300
+ See Device for details.
301
+ """
302
+
303
+ _launch_class = Process
304
+ context_factory = Context
305
+ """Callable that returns a context. Typically either Context.instance or Context,
306
+ depending on whether the device should share the global instance or not.
307
+ """
308
+
309
+
310
+ __all__ = ['Device', 'ThreadDevice', 'ProcessDevice']
.venv/lib/python3.11/site-packages/zmq/devices/monitoredqueue.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """pure Python monitored_queue function
2
+
3
+ For use when Cython extension is unavailable (PyPy).
4
+
5
+ Authors
6
+ -------
7
+ * MinRK
8
+ """
9
+
10
+ # Copyright (C) PyZMQ Developers
11
+ # Distributed under the terms of the Modified BSD License.
12
+
13
+ from typing import Callable
14
+
15
+ import zmq
16
+ from zmq.backend import monitored_queue as _backend_mq
17
+
18
+
19
+ def _relay(ins, outs, sides, prefix, swap_ids):
20
+ msg = ins.recv_multipart()
21
+ if swap_ids:
22
+ msg[:2] = msg[:2][::-1]
23
+ outs.send_multipart(msg)
24
+ sides.send_multipart([prefix] + msg)
25
+
26
+
27
+ def _monitored_queue(
28
+ in_socket, out_socket, mon_socket, in_prefix=b'in', out_prefix=b'out'
29
+ ):
30
+ swap_ids = in_socket.type == zmq.ROUTER and out_socket.type == zmq.ROUTER
31
+
32
+ poller = zmq.Poller()
33
+ poller.register(in_socket, zmq.POLLIN)
34
+ poller.register(out_socket, zmq.POLLIN)
35
+ while True:
36
+ events = dict(poller.poll())
37
+ if in_socket in events:
38
+ _relay(in_socket, out_socket, mon_socket, in_prefix, swap_ids)
39
+ if out_socket in events:
40
+ _relay(out_socket, in_socket, mon_socket, out_prefix, swap_ids)
41
+
42
+
43
+ monitored_queue: Callable
44
+ if _backend_mq is not None:
45
+ monitored_queue = _backend_mq # type: ignore
46
+ else:
47
+ # backend has no monitored_queue
48
+ monitored_queue = _monitored_queue
49
+
50
+
51
+ __all__ = ['monitored_queue']
.venv/lib/python3.11/site-packages/zmq/devices/monitoredqueuedevice.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """MonitoredQueue classes and functions."""
2
+
3
+ # Copyright (C) PyZMQ Developers
4
+ # Distributed under the terms of the Modified BSD License.
5
+
6
+ from zmq import PUB
7
+ from zmq.devices.monitoredqueue import monitored_queue
8
+ from zmq.devices.proxydevice import ProcessProxy, Proxy, ProxyBase, ThreadProxy
9
+
10
+
11
+ class MonitoredQueueBase(ProxyBase):
12
+ """Base class for overriding methods."""
13
+
14
+ _in_prefix = b''
15
+ _out_prefix = b''
16
+
17
+ def __init__(
18
+ self, in_type, out_type, mon_type=PUB, in_prefix=b'in', out_prefix=b'out'
19
+ ):
20
+ ProxyBase.__init__(self, in_type=in_type, out_type=out_type, mon_type=mon_type)
21
+
22
+ self._in_prefix = in_prefix
23
+ self._out_prefix = out_prefix
24
+
25
+ def run_device(self):
26
+ ins, outs, mons = self._setup_sockets()
27
+ monitored_queue(ins, outs, mons, self._in_prefix, self._out_prefix)
28
+
29
+
30
+ class MonitoredQueue(MonitoredQueueBase, Proxy):
31
+ """Class for running monitored_queue in the background.
32
+
33
+ See zmq.devices.Device for most of the spec. MonitoredQueue differs from Proxy,
34
+ only in that it adds a ``prefix`` to messages sent on the monitor socket,
35
+ with a different prefix for each direction.
36
+
37
+ MQ also supports ROUTER on both sides, which zmq.proxy does not.
38
+
39
+ If a message arrives on `in_sock`, it will be prefixed with `in_prefix` on the monitor socket.
40
+ If it arrives on out_sock, it will be prefixed with `out_prefix`.
41
+
42
+ A PUB socket is the most logical choice for the mon_socket, but it is not required.
43
+ """
44
+
45
+
46
+ class ThreadMonitoredQueue(MonitoredQueueBase, ThreadProxy):
47
+ """Run zmq.monitored_queue in a background thread.
48
+
49
+ See MonitoredQueue and Proxy for details.
50
+ """
51
+
52
+
53
+ class ProcessMonitoredQueue(MonitoredQueueBase, ProcessProxy):
54
+ """Run zmq.monitored_queue in a separate process.
55
+
56
+ See MonitoredQueue and Proxy for details.
57
+ """
58
+
59
+
60
+ __all__ = ['MonitoredQueue', 'ThreadMonitoredQueue', 'ProcessMonitoredQueue']
.venv/lib/python3.11/site-packages/zmq/devices/proxydevice.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Proxy classes and functions."""
2
+
3
+ # Copyright (C) PyZMQ Developers
4
+ # Distributed under the terms of the Modified BSD License.
5
+
6
+ import zmq
7
+ from zmq.devices.basedevice import Device, ProcessDevice, ThreadDevice
8
+
9
+
10
+ class ProxyBase:
11
+ """Base class for overriding methods."""
12
+
13
+ def __init__(self, in_type, out_type, mon_type=zmq.PUB):
14
+ Device.__init__(self, in_type=in_type, out_type=out_type)
15
+ self.mon_type = mon_type
16
+ self._mon_binds = []
17
+ self._mon_connects = []
18
+ self._mon_sockopts = []
19
+
20
+ def bind_mon(self, addr):
21
+ """Enqueue ZMQ address for binding on mon_socket.
22
+
23
+ See zmq.Socket.bind for details.
24
+ """
25
+ self._mon_binds.append(addr)
26
+
27
+ def bind_mon_to_random_port(self, addr, *args, **kwargs):
28
+ """Enqueue a random port on the given interface for binding on
29
+ mon_socket.
30
+
31
+ See zmq.Socket.bind_to_random_port for details.
32
+
33
+ .. versionadded:: 18.0
34
+ """
35
+ port = self._reserve_random_port(addr, *args, **kwargs)
36
+
37
+ self.bind_mon(f'{addr}:{port}')
38
+
39
+ return port
40
+
41
+ def connect_mon(self, addr):
42
+ """Enqueue ZMQ address for connecting on mon_socket.
43
+
44
+ See zmq.Socket.connect for details.
45
+ """
46
+ self._mon_connects.append(addr)
47
+
48
+ def setsockopt_mon(self, opt, value):
49
+ """Enqueue setsockopt(opt, value) for mon_socket
50
+
51
+ See zmq.Socket.setsockopt for details.
52
+ """
53
+ self._mon_sockopts.append((opt, value))
54
+
55
+ def _setup_sockets(self):
56
+ ins, outs = Device._setup_sockets(self)
57
+ ctx = self._context
58
+ mons = ctx.socket(self.mon_type)
59
+ self._sockets.append(mons)
60
+
61
+ # set sockopts (must be done first, in case of zmq.IDENTITY)
62
+ for opt, value in self._mon_sockopts:
63
+ mons.setsockopt(opt, value)
64
+
65
+ for iface in self._mon_binds:
66
+ mons.bind(iface)
67
+
68
+ for iface in self._mon_connects:
69
+ mons.connect(iface)
70
+
71
+ return ins, outs, mons
72
+
73
+ def run_device(self):
74
+ ins, outs, mons = self._setup_sockets()
75
+ zmq.proxy(ins, outs, mons)
76
+
77
+
78
+ class Proxy(ProxyBase, Device):
79
+ """Threadsafe Proxy object.
80
+
81
+ See zmq.devices.Device for most of the spec. This subclass adds a
82
+ <method>_mon version of each <method>_{in|out} method, for configuring the
83
+ monitor socket.
84
+
85
+ A Proxy is a 3-socket ZMQ Device that functions just like a
86
+ QUEUE, except each message is also sent out on the monitor socket.
87
+
88
+ A PUB socket is the most logical choice for the mon_socket, but it is not required.
89
+ """
90
+
91
+
92
+ class ThreadProxy(ProxyBase, ThreadDevice):
93
+ """Proxy in a Thread. See Proxy for more."""
94
+
95
+
96
+ class ProcessProxy(ProxyBase, ProcessDevice):
97
+ """Proxy in a Process. See Proxy for more."""
98
+
99
+
100
+ __all__ = [
101
+ 'Proxy',
102
+ 'ThreadProxy',
103
+ 'ProcessProxy',
104
+ ]
.venv/lib/python3.11/site-packages/zmq/devices/proxysteerabledevice.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Classes for running a steerable ZMQ proxy"""
2
+
3
+ # Copyright (C) PyZMQ Developers
4
+ # Distributed under the terms of the Modified BSD License.
5
+
6
+ import zmq
7
+ from zmq.devices.proxydevice import ProcessProxy, Proxy, ThreadProxy
8
+
9
+
10
+ class ProxySteerableBase:
11
+ """Base class for overriding methods."""
12
+
13
+ def __init__(self, in_type, out_type, mon_type=zmq.PUB, ctrl_type=None):
14
+ super().__init__(in_type=in_type, out_type=out_type, mon_type=mon_type)
15
+ self.ctrl_type = ctrl_type
16
+ self._ctrl_binds = []
17
+ self._ctrl_connects = []
18
+ self._ctrl_sockopts = []
19
+
20
+ def bind_ctrl(self, addr):
21
+ """Enqueue ZMQ address for binding on ctrl_socket.
22
+
23
+ See zmq.Socket.bind for details.
24
+ """
25
+ self._ctrl_binds.append(addr)
26
+
27
+ def bind_ctrl_to_random_port(self, addr, *args, **kwargs):
28
+ """Enqueue a random port on the given interface for binding on
29
+ ctrl_socket.
30
+
31
+ See zmq.Socket.bind_to_random_port for details.
32
+ """
33
+ port = self._reserve_random_port(addr, *args, **kwargs)
34
+
35
+ self.bind_ctrl(f'{addr}:{port}')
36
+
37
+ return port
38
+
39
+ def connect_ctrl(self, addr):
40
+ """Enqueue ZMQ address for connecting on ctrl_socket.
41
+
42
+ See zmq.Socket.connect for details.
43
+ """
44
+ self._ctrl_connects.append(addr)
45
+
46
+ def setsockopt_ctrl(self, opt, value):
47
+ """Enqueue setsockopt(opt, value) for ctrl_socket
48
+
49
+ See zmq.Socket.setsockopt for details.
50
+ """
51
+ self._ctrl_sockopts.append((opt, value))
52
+
53
+ def _setup_sockets(self):
54
+ ins, outs, mons = super()._setup_sockets()
55
+ ctx = self._context
56
+ ctrls = ctx.socket(self.ctrl_type)
57
+ self._sockets.append(ctrls)
58
+
59
+ for opt, value in self._ctrl_sockopts:
60
+ ctrls.setsockopt(opt, value)
61
+
62
+ for iface in self._ctrl_binds:
63
+ ctrls.bind(iface)
64
+
65
+ for iface in self._ctrl_connects:
66
+ ctrls.connect(iface)
67
+
68
+ return ins, outs, mons, ctrls
69
+
70
+ def run_device(self):
71
+ ins, outs, mons, ctrls = self._setup_sockets()
72
+ zmq.proxy_steerable(ins, outs, mons, ctrls)
73
+
74
+
75
+ class ProxySteerable(ProxySteerableBase, Proxy):
76
+ """Class for running a steerable proxy in the background.
77
+
78
+ See zmq.devices.Proxy for most of the spec. If the control socket is not
79
+ NULL, the proxy supports control flow, provided by the socket.
80
+
81
+ If PAUSE is received on this socket, the proxy suspends its activities. If
82
+ RESUME is received, it goes on. If TERMINATE is received, it terminates
83
+ smoothly. If the control socket is NULL, the proxy behave exactly as if
84
+ zmq.devices.Proxy had been used.
85
+
86
+ This subclass adds a <method>_ctrl version of each <method>_{in|out}
87
+ method, for configuring the control socket.
88
+
89
+ .. versionadded:: libzmq-4.1
90
+ .. versionadded:: 18.0
91
+ """
92
+
93
+
94
+ class ThreadProxySteerable(ProxySteerableBase, ThreadProxy):
95
+ """ProxySteerable in a Thread. See ProxySteerable for details."""
96
+
97
+
98
+ class ProcessProxySteerable(ProxySteerableBase, ProcessProxy):
99
+ """ProxySteerable in a Process. See ProxySteerable for details."""
100
+
101
+
102
+ __all__ = [
103
+ 'ProxySteerable',
104
+ 'ThreadProxySteerable',
105
+ 'ProcessProxySteerable',
106
+ ]
.venv/lib/python3.11/site-packages/zmq/log/__init__.py ADDED
File without changes
.venv/lib/python3.11/site-packages/zmq/log/__main__.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """pyzmq log watcher.
2
+
3
+ Easily view log messages published by the PUBHandler in zmq.log.handlers
4
+
5
+ Designed to be run as an executable module - try this to see options:
6
+ python -m zmq.log -h
7
+
8
+ Subscribes to the '' (empty string) topic by default which means it will work
9
+ out-of-the-box with a PUBHandler object instantiated with default settings.
10
+ If you change the root topic with PUBHandler.setRootTopic() you must pass
11
+ the value to this script with the --topic argument.
12
+
13
+ Note that the default formats for the PUBHandler object selectively include
14
+ the log level in the message. This creates redundancy in this script as it
15
+ always prints the topic of the message, which includes the log level.
16
+ Consider overriding the default formats with PUBHandler.setFormat() to
17
+ avoid this issue.
18
+
19
+ """
20
+
21
+ # encoding: utf-8
22
+
23
+ # Copyright (C) PyZMQ Developers
24
+ # Distributed under the terms of the Modified BSD License.
25
+
26
+ import argparse
27
+ from datetime import datetime
28
+ from typing import Dict
29
+
30
+ import zmq
31
+
32
+ parser = argparse.ArgumentParser('ZMQ Log Watcher')
33
+ parser.add_argument('zmq_pub_url', type=str, help='URL to a ZMQ publisher socket.')
34
+ parser.add_argument(
35
+ '-t',
36
+ '--topic',
37
+ type=str,
38
+ default='',
39
+ help='Only receive messages that start with this topic.',
40
+ )
41
+ parser.add_argument(
42
+ '--timestamp', action='store_true', help='Append local time to the log messages.'
43
+ )
44
+ parser.add_argument(
45
+ '--separator',
46
+ type=str,
47
+ default=' | ',
48
+ help='String to print between topic and message.',
49
+ )
50
+ parser.add_argument(
51
+ '--dateformat',
52
+ type=str,
53
+ default='%Y-%d-%m %H:%M',
54
+ help='Set alternative date format for use with --timestamp.',
55
+ )
56
+ parser.add_argument(
57
+ '--align',
58
+ action='store_true',
59
+ default=False,
60
+ help='Try to align messages by the width of their topics.',
61
+ )
62
+ parser.add_argument(
63
+ '--color',
64
+ action='store_true',
65
+ default=False,
66
+ help='Color the output based on the error level. Requires the colorama module.',
67
+ )
68
+ args = parser.parse_args()
69
+
70
+
71
+ if args.color:
72
+ import colorama
73
+
74
+ colorama.init()
75
+ colors = {
76
+ 'DEBUG': colorama.Fore.LIGHTCYAN_EX,
77
+ 'INFO': colorama.Fore.LIGHTWHITE_EX,
78
+ 'WARNING': colorama.Fore.YELLOW,
79
+ 'ERROR': colorama.Fore.LIGHTRED_EX,
80
+ 'CRITICAL': colorama.Fore.LIGHTRED_EX,
81
+ '__RESET__': colorama.Fore.RESET,
82
+ }
83
+ else:
84
+ colors = {}
85
+
86
+
87
+ ctx = zmq.Context()
88
+ sub = ctx.socket(zmq.SUB)
89
+ sub.subscribe(args.topic.encode("utf8"))
90
+ sub.connect(args.zmq_pub_url)
91
+
92
+ topic_widths: Dict[int, int] = {}
93
+
94
+ while True:
95
+ try:
96
+ if sub.poll(10, zmq.POLLIN):
97
+ topic, msg = sub.recv_multipart()
98
+ topics = topic.decode('utf8').strip().split('.')
99
+
100
+ if args.align:
101
+ topics.extend(' ' for extra in range(len(topics), len(topic_widths)))
102
+ aligned_parts = []
103
+ for key, part in enumerate(topics):
104
+ topic_widths[key] = max(len(part), topic_widths.get(key, 0))
105
+ fmt = ''.join(('{:<', str(topic_widths[key]), '}'))
106
+ aligned_parts.append(fmt.format(part))
107
+
108
+ if len(topics) == 1:
109
+ level = topics[0]
110
+ else:
111
+ level = topics[1]
112
+
113
+ fields = {
114
+ 'msg': msg.decode('utf8').strip(),
115
+ 'ts': (
116
+ datetime.now().strftime(args.dateformat) + ' '
117
+ if args.timestamp
118
+ else ''
119
+ ),
120
+ 'aligned': (
121
+ '.'.join(aligned_parts)
122
+ if args.align
123
+ else topic.decode('utf8').strip()
124
+ ),
125
+ 'color': colors.get(level, ''),
126
+ 'color_rst': colors.get('__RESET__', ''),
127
+ 'sep': args.separator,
128
+ }
129
+ print('{ts}{color}{aligned}{sep}{msg}{color_rst}'.format(**fields))
130
+ except KeyboardInterrupt:
131
+ break
132
+
133
+ sub.disconnect(args.zmq_pub_url)
134
+ if args.color:
135
+ print(colorama.Fore.RESET)
.venv/lib/python3.11/site-packages/zmq/log/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (180 Bytes). View file
 
.venv/lib/python3.11/site-packages/zmq/log/__pycache__/__main__.cpython-311.pyc ADDED
Binary file (5.98 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/log/__pycache__/handlers.cpython-311.pyc ADDED
Binary file (9.73 kB). View file
 
.venv/lib/python3.11/site-packages/zmq/log/handlers.py ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """pyzmq logging handlers.
2
+
3
+ This mainly defines the PUBHandler object for publishing logging messages over
4
+ a zmq.PUB socket.
5
+
6
+ The PUBHandler can be used with the regular logging module, as in::
7
+
8
+ >>> import logging
9
+ >>> handler = PUBHandler('tcp://127.0.0.1:12345')
10
+ >>> handler.root_topic = 'foo'
11
+ >>> logger = logging.getLogger('foobar')
12
+ >>> logger.setLevel(logging.DEBUG)
13
+ >>> logger.addHandler(handler)
14
+
15
+ Or using ``dictConfig``, as in::
16
+
17
+ >>> from logging.config import dictConfig
18
+ >>> socket = Context.instance().socket(PUB)
19
+ >>> socket.connect('tcp://127.0.0.1:12345')
20
+ >>> dictConfig({
21
+ >>> 'version': 1,
22
+ >>> 'handlers': {
23
+ >>> 'zmq': {
24
+ >>> 'class': 'zmq.log.handlers.PUBHandler',
25
+ >>> 'level': logging.DEBUG,
26
+ >>> 'root_topic': 'foo',
27
+ >>> 'interface_or_socket': socket
28
+ >>> }
29
+ >>> },
30
+ >>> 'root': {
31
+ >>> 'level': 'DEBUG',
32
+ >>> 'handlers': ['zmq'],
33
+ >>> }
34
+ >>> })
35
+
36
+
37
+ After this point, all messages logged by ``logger`` will be published on the
38
+ PUB socket.
39
+
40
+ Code adapted from StarCluster:
41
+
42
+ https://github.com/jtriley/StarCluster/blob/StarCluster-0.91/starcluster/logger.py
43
+ """
44
+
45
+ from __future__ import annotations
46
+
47
+ import logging
48
+ from copy import copy
49
+
50
+ import zmq
51
+
52
+ # Copyright (C) PyZMQ Developers
53
+ # Distributed under the terms of the Modified BSD License.
54
+
55
+
56
+ TOPIC_DELIM = "::" # delimiter for splitting topics on the receiving end.
57
+
58
+
59
+ class PUBHandler(logging.Handler):
60
+ """A basic logging handler that emits log messages through a PUB socket.
61
+
62
+ Takes a PUB socket already bound to interfaces or an interface to bind to.
63
+
64
+ Example::
65
+
66
+ sock = context.socket(zmq.PUB)
67
+ sock.bind('inproc://log')
68
+ handler = PUBHandler(sock)
69
+
70
+ Or::
71
+
72
+ handler = PUBHandler('inproc://loc')
73
+
74
+ These are equivalent.
75
+
76
+ Log messages handled by this handler are broadcast with ZMQ topics
77
+ ``this.root_topic`` comes first, followed by the log level
78
+ (DEBUG,INFO,etc.), followed by any additional subtopics specified in the
79
+ message by: log.debug("subtopic.subsub::the real message")
80
+ """
81
+
82
+ ctx: zmq.Context
83
+ socket: zmq.Socket
84
+
85
+ def __init__(
86
+ self,
87
+ interface_or_socket: str | zmq.Socket,
88
+ context: zmq.Context | None = None,
89
+ root_topic: str = '',
90
+ ) -> None:
91
+ logging.Handler.__init__(self)
92
+ self.root_topic = root_topic
93
+ self.formatters = {
94
+ logging.DEBUG: logging.Formatter(
95
+ "%(levelname)s %(filename)s:%(lineno)d - %(message)s\n"
96
+ ),
97
+ logging.INFO: logging.Formatter("%(message)s\n"),
98
+ logging.WARN: logging.Formatter(
99
+ "%(levelname)s %(filename)s:%(lineno)d - %(message)s\n"
100
+ ),
101
+ logging.ERROR: logging.Formatter(
102
+ "%(levelname)s %(filename)s:%(lineno)d - %(message)s - %(exc_info)s\n"
103
+ ),
104
+ logging.CRITICAL: logging.Formatter(
105
+ "%(levelname)s %(filename)s:%(lineno)d - %(message)s\n"
106
+ ),
107
+ }
108
+ if isinstance(interface_or_socket, zmq.Socket):
109
+ self.socket = interface_or_socket
110
+ self.ctx = self.socket.context
111
+ else:
112
+ self.ctx = context or zmq.Context()
113
+ self.socket = self.ctx.socket(zmq.PUB)
114
+ self.socket.bind(interface_or_socket)
115
+
116
+ @property
117
+ def root_topic(self) -> str:
118
+ return self._root_topic
119
+
120
+ @root_topic.setter
121
+ def root_topic(self, value: str):
122
+ self.setRootTopic(value)
123
+
124
+ def setRootTopic(self, root_topic: str):
125
+ """Set the root topic for this handler.
126
+
127
+ This value is prepended to all messages published by this handler, and it
128
+ defaults to the empty string ''. When you subscribe to this socket, you must
129
+ set your subscription to an empty string, or to at least the first letter of
130
+ the binary representation of this string to ensure you receive any messages
131
+ from this handler.
132
+
133
+ If you use the default empty string root topic, messages will begin with
134
+ the binary representation of the log level string (INFO, WARN, etc.).
135
+ Note that ZMQ SUB sockets can have multiple subscriptions.
136
+ """
137
+ if isinstance(root_topic, bytes):
138
+ root_topic = root_topic.decode("utf8")
139
+ self._root_topic = root_topic
140
+
141
+ def setFormatter(self, fmt, level=logging.NOTSET):
142
+ """Set the Formatter for this handler.
143
+
144
+ If no level is provided, the same format is used for all levels. This
145
+ will overwrite all selective formatters set in the object constructor.
146
+ """
147
+ if level == logging.NOTSET:
148
+ for fmt_level in self.formatters.keys():
149
+ self.formatters[fmt_level] = fmt
150
+ else:
151
+ self.formatters[level] = fmt
152
+
153
+ def format(self, record):
154
+ """Format a record."""
155
+ return self.formatters[record.levelno].format(record)
156
+
157
+ def emit(self, record):
158
+ """Emit a log message on my socket."""
159
+
160
+ # LogRecord.getMessage explicitly allows msg to be anything _castable_ to a str
161
+ try:
162
+ topic, msg = str(record.msg).split(TOPIC_DELIM, 1)
163
+ except ValueError:
164
+ topic = ""
165
+ else:
166
+ # copy to avoid mutating LogRecord in-place
167
+ record = copy(record)
168
+ record.msg = msg
169
+
170
+ try:
171
+ bmsg = self.format(record).encode("utf8")
172
+ except Exception:
173
+ self.handleError(record)
174
+ return
175
+
176
+ topic_list = []
177
+
178
+ if self.root_topic:
179
+ topic_list.append(self.root_topic)
180
+
181
+ topic_list.append(record.levelname)
182
+
183
+ if topic:
184
+ topic_list.append(topic)
185
+
186
+ btopic = '.'.join(topic_list).encode("utf8", "replace")
187
+
188
+ self.socket.send_multipart([btopic, bmsg])
189
+
190
+
191
+ class TopicLogger(logging.Logger):
192
+ """A simple wrapper that takes an additional argument to log methods.
193
+
194
+ All the regular methods exist, but instead of one msg argument, two
195
+ arguments: topic, msg are passed.
196
+
197
+ That is::
198
+
199
+ logger.debug('msg')
200
+
201
+ Would become::
202
+
203
+ logger.debug('topic.sub', 'msg')
204
+ """
205
+
206
+ def log(self, level, topic, msg, *args, **kwargs):
207
+ """Log 'msg % args' with level and topic.
208
+
209
+ To pass exception information, use the keyword argument exc_info
210
+ with a True value::
211
+
212
+ logger.log(level, "zmq.fun", "We have a %s",
213
+ "mysterious problem", exc_info=1)
214
+ """
215
+ logging.Logger.log(self, level, f'{topic}{TOPIC_DELIM}{msg}', *args, **kwargs)
216
+
217
+
218
+ # Generate the methods of TopicLogger, since they are just adding a
219
+ # topic prefix to a message.
220
+ for name in "debug warn warning error critical fatal".split():
221
+ try:
222
+ meth = getattr(logging.Logger, name)
223
+ except AttributeError:
224
+ # some methods are missing, e.g. Logger.warn was removed from Python 3.13
225
+ continue
226
+ setattr(
227
+ TopicLogger,
228
+ name,
229
+ lambda self, level, topic, msg, *args, **kwargs: meth(
230
+ self, level, topic + TOPIC_DELIM + msg, *args, **kwargs
231
+ ),
232
+ )