omlish 0.0.0.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of omlish might be problematic. Click here for more details.

Files changed (187) hide show
  1. omlish/__about__.py +7 -0
  2. omlish/__init__.py +0 -0
  3. omlish/argparse.py +223 -0
  4. omlish/asyncs/__init__.py +17 -0
  5. omlish/asyncs/anyio.py +23 -0
  6. omlish/asyncs/asyncio.py +19 -0
  7. omlish/asyncs/asyncs.py +76 -0
  8. omlish/asyncs/futures.py +179 -0
  9. omlish/asyncs/trio.py +11 -0
  10. omlish/c3.py +173 -0
  11. omlish/cached.py +9 -0
  12. omlish/check.py +231 -0
  13. omlish/collections/__init__.py +63 -0
  14. omlish/collections/_abc.py +156 -0
  15. omlish/collections/_io_abc.py +78 -0
  16. omlish/collections/cache/__init__.py +11 -0
  17. omlish/collections/cache/descriptor.py +188 -0
  18. omlish/collections/cache/impl.py +485 -0
  19. omlish/collections/cache/types.py +37 -0
  20. omlish/collections/coerce.py +337 -0
  21. omlish/collections/frozen.py +148 -0
  22. omlish/collections/identity.py +106 -0
  23. omlish/collections/indexed.py +75 -0
  24. omlish/collections/mappings.py +127 -0
  25. omlish/collections/ordered.py +81 -0
  26. omlish/collections/persistent.py +36 -0
  27. omlish/collections/skiplist.py +193 -0
  28. omlish/collections/sorted.py +126 -0
  29. omlish/collections/treap.py +228 -0
  30. omlish/collections/treapmap.py +144 -0
  31. omlish/collections/unmodifiable.py +174 -0
  32. omlish/collections/utils.py +110 -0
  33. omlish/configs/__init__.py +0 -0
  34. omlish/configs/flattening.py +147 -0
  35. omlish/configs/props.py +64 -0
  36. omlish/dataclasses/__init__.py +83 -0
  37. omlish/dataclasses/impl/__init__.py +6 -0
  38. omlish/dataclasses/impl/api.py +260 -0
  39. omlish/dataclasses/impl/as_.py +76 -0
  40. omlish/dataclasses/impl/exceptions.py +2 -0
  41. omlish/dataclasses/impl/fields.py +148 -0
  42. omlish/dataclasses/impl/frozen.py +55 -0
  43. omlish/dataclasses/impl/hashing.py +85 -0
  44. omlish/dataclasses/impl/init.py +173 -0
  45. omlish/dataclasses/impl/internals.py +118 -0
  46. omlish/dataclasses/impl/main.py +150 -0
  47. omlish/dataclasses/impl/metaclass.py +126 -0
  48. omlish/dataclasses/impl/metadata.py +74 -0
  49. omlish/dataclasses/impl/order.py +47 -0
  50. omlish/dataclasses/impl/params.py +150 -0
  51. omlish/dataclasses/impl/processing.py +16 -0
  52. omlish/dataclasses/impl/reflect.py +173 -0
  53. omlish/dataclasses/impl/replace.py +40 -0
  54. omlish/dataclasses/impl/repr.py +34 -0
  55. omlish/dataclasses/impl/simple.py +92 -0
  56. omlish/dataclasses/impl/slots.py +80 -0
  57. omlish/dataclasses/impl/utils.py +167 -0
  58. omlish/defs.py +193 -0
  59. omlish/dispatch/__init__.py +3 -0
  60. omlish/dispatch/dispatch.py +137 -0
  61. omlish/dispatch/functions.py +52 -0
  62. omlish/dispatch/methods.py +162 -0
  63. omlish/docker.py +149 -0
  64. omlish/dynamic.py +220 -0
  65. omlish/graphs/__init__.py +0 -0
  66. omlish/graphs/dot/__init__.py +19 -0
  67. omlish/graphs/dot/items.py +162 -0
  68. omlish/graphs/dot/rendering.py +147 -0
  69. omlish/graphs/dot/utils.py +30 -0
  70. omlish/graphs/trees.py +249 -0
  71. omlish/http/__init__.py +0 -0
  72. omlish/http/consts.py +20 -0
  73. omlish/http/wsgi.py +34 -0
  74. omlish/inject/__init__.py +85 -0
  75. omlish/inject/binder.py +12 -0
  76. omlish/inject/bindings.py +49 -0
  77. omlish/inject/eagers.py +21 -0
  78. omlish/inject/elements.py +43 -0
  79. omlish/inject/exceptions.py +49 -0
  80. omlish/inject/impl/__init__.py +0 -0
  81. omlish/inject/impl/bindings.py +19 -0
  82. omlish/inject/impl/elements.py +154 -0
  83. omlish/inject/impl/injector.py +182 -0
  84. omlish/inject/impl/inspect.py +98 -0
  85. omlish/inject/impl/private.py +109 -0
  86. omlish/inject/impl/providers.py +132 -0
  87. omlish/inject/impl/scopes.py +198 -0
  88. omlish/inject/injector.py +40 -0
  89. omlish/inject/inspect.py +14 -0
  90. omlish/inject/keys.py +43 -0
  91. omlish/inject/managed.py +24 -0
  92. omlish/inject/overrides.py +18 -0
  93. omlish/inject/private.py +29 -0
  94. omlish/inject/providers.py +111 -0
  95. omlish/inject/proxy.py +48 -0
  96. omlish/inject/scopes.py +84 -0
  97. omlish/inject/types.py +21 -0
  98. omlish/iterators.py +184 -0
  99. omlish/json.py +194 -0
  100. omlish/lang/__init__.py +112 -0
  101. omlish/lang/cached.py +267 -0
  102. omlish/lang/classes/__init__.py +24 -0
  103. omlish/lang/classes/abstract.py +74 -0
  104. omlish/lang/classes/restrict.py +137 -0
  105. omlish/lang/classes/simple.py +120 -0
  106. omlish/lang/classes/test/__init__.py +0 -0
  107. omlish/lang/classes/test/test_abstract.py +89 -0
  108. omlish/lang/classes/test/test_restrict.py +71 -0
  109. omlish/lang/classes/test/test_simple.py +58 -0
  110. omlish/lang/classes/test/test_virtual.py +72 -0
  111. omlish/lang/classes/virtual.py +130 -0
  112. omlish/lang/clsdct.py +67 -0
  113. omlish/lang/cmp.py +63 -0
  114. omlish/lang/contextmanagers.py +249 -0
  115. omlish/lang/datetimes.py +67 -0
  116. omlish/lang/descriptors.py +52 -0
  117. omlish/lang/functions.py +126 -0
  118. omlish/lang/imports.py +153 -0
  119. omlish/lang/iterables.py +54 -0
  120. omlish/lang/maybes.py +136 -0
  121. omlish/lang/objects.py +103 -0
  122. omlish/lang/resolving.py +50 -0
  123. omlish/lang/strings.py +128 -0
  124. omlish/lang/typing.py +92 -0
  125. omlish/libc.py +532 -0
  126. omlish/logs/__init__.py +9 -0
  127. omlish/logs/_abc.py +247 -0
  128. omlish/logs/configs.py +62 -0
  129. omlish/logs/filters.py +9 -0
  130. omlish/logs/formatters.py +67 -0
  131. omlish/logs/utils.py +20 -0
  132. omlish/marshal/__init__.py +52 -0
  133. omlish/marshal/any.py +25 -0
  134. omlish/marshal/base.py +201 -0
  135. omlish/marshal/base64.py +25 -0
  136. omlish/marshal/dataclasses.py +115 -0
  137. omlish/marshal/datetimes.py +90 -0
  138. omlish/marshal/enums.py +43 -0
  139. omlish/marshal/exceptions.py +7 -0
  140. omlish/marshal/factories.py +129 -0
  141. omlish/marshal/global_.py +33 -0
  142. omlish/marshal/iterables.py +57 -0
  143. omlish/marshal/mappings.py +66 -0
  144. omlish/marshal/naming.py +17 -0
  145. omlish/marshal/objects.py +106 -0
  146. omlish/marshal/optionals.py +49 -0
  147. omlish/marshal/polymorphism.py +147 -0
  148. omlish/marshal/primitives.py +43 -0
  149. omlish/marshal/registries.py +57 -0
  150. omlish/marshal/standard.py +80 -0
  151. omlish/marshal/utils.py +23 -0
  152. omlish/marshal/uuids.py +29 -0
  153. omlish/marshal/values.py +30 -0
  154. omlish/math.py +184 -0
  155. omlish/os.py +32 -0
  156. omlish/reflect.py +359 -0
  157. omlish/replserver/__init__.py +5 -0
  158. omlish/replserver/__main__.py +4 -0
  159. omlish/replserver/console.py +247 -0
  160. omlish/replserver/server.py +146 -0
  161. omlish/runmodule.py +28 -0
  162. omlish/stats.py +342 -0
  163. omlish/term.py +222 -0
  164. omlish/testing/__init__.py +7 -0
  165. omlish/testing/pydevd.py +225 -0
  166. omlish/testing/pytest/__init__.py +8 -0
  167. omlish/testing/pytest/helpers.py +35 -0
  168. omlish/testing/pytest/inject/__init__.py +1 -0
  169. omlish/testing/pytest/inject/harness.py +159 -0
  170. omlish/testing/pytest/plugins/__init__.py +20 -0
  171. omlish/testing/pytest/plugins/_registry.py +6 -0
  172. omlish/testing/pytest/plugins/logging.py +13 -0
  173. omlish/testing/pytest/plugins/pycharm.py +54 -0
  174. omlish/testing/pytest/plugins/repeat.py +19 -0
  175. omlish/testing/pytest/plugins/skips.py +32 -0
  176. omlish/testing/pytest/plugins/spacing.py +19 -0
  177. omlish/testing/pytest/plugins/switches.py +70 -0
  178. omlish/testing/testing.py +102 -0
  179. omlish/text/__init__.py +0 -0
  180. omlish/text/delimit.py +171 -0
  181. omlish/text/indent.py +50 -0
  182. omlish/text/parts.py +265 -0
  183. omlish-0.0.0.dev1.dist-info/LICENSE +21 -0
  184. omlish-0.0.0.dev1.dist-info/METADATA +17 -0
  185. omlish-0.0.0.dev1.dist-info/RECORD +187 -0
  186. omlish-0.0.0.dev1.dist-info/WHEEL +5 -0
  187. omlish-0.0.0.dev1.dist-info/top_level.txt +1 -0
omlish/libc.py ADDED
@@ -0,0 +1,532 @@
1
+ import ctypes as ct
2
+ import errno
3
+ import platform
4
+ import signal
5
+ import socket
6
+ import sys
7
+ import typing as ta
8
+
9
+
10
+ LINUX_PLATFORMS = ('linux',)
11
+ DARWIN_PLATFORMS = ('darwin',)
12
+
13
+ LINUX = False
14
+ DARWIN = False
15
+
16
+ if sys.platform in LINUX_PLATFORMS:
17
+ libc = ct.CDLL('libc.so.6')
18
+ LINUX = True
19
+
20
+ elif sys.platform in DARWIN_PLATFORMS:
21
+ libc = ct.CDLL('/usr/lib/libc.dylib')
22
+ DARWIN = True
23
+
24
+ else:
25
+ raise OSError('Unsupported platform')
26
+
27
+
28
+ ##
29
+
30
+
31
+ libc.errno = ct.cast(libc.errno, ct.POINTER(ct.c_int)) # type: ignore
32
+
33
+
34
+ def lasterr() -> tuple[int, str]:
35
+ err = libc.errno.contents.value # type: ignore
36
+ return err, errno.errorcode[err]
37
+
38
+
39
+ # int raise(int sig);
40
+ libc._raise = libc['raise'] # type: ignore
41
+ libc._raise.restype = ct.c_int
42
+ libc._raise.argtypes = [ct.c_int]
43
+ _raise = libc._raise
44
+
45
+
46
+ def sigtrap() -> None:
47
+ libc._raise(signal.SIGTRAP)
48
+
49
+
50
+ ##
51
+
52
+
53
+ libc.malloc = libc['malloc'] # type: ignore
54
+ libc.malloc.restype = ct.c_void_p
55
+ libc.malloc.argtypes = [ct.c_size_t]
56
+
57
+
58
+ libc.free = libc['free'] # type: ignore
59
+ libc.free.restype = None
60
+ libc.free.argtypes = [ct.c_void_p]
61
+
62
+
63
+ class Malloc:
64
+
65
+ def __init__(self, sz: int) -> None:
66
+ super().__init__()
67
+
68
+ self._sz = sz
69
+ self._base: int | None = None
70
+
71
+ def __enter__(self) -> ta.Self:
72
+ base = self._base = libc.malloc(self._sz)
73
+ return base
74
+
75
+ def __exit__(self, et, e, tb) -> None:
76
+ if self._base is not None:
77
+ libc.free(self._base)
78
+ self._base = None
79
+
80
+ def __int__(self) -> int:
81
+ if self._base is None:
82
+ raise ValueError
83
+ return int(self._base)
84
+
85
+
86
+ ##
87
+
88
+
89
+ # void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
90
+ libc.mmap.restype = ct.c_void_p
91
+ libc.mmap.argtypes = [
92
+ ct.c_void_p,
93
+ ct.c_size_t,
94
+ ct.c_int,
95
+ ct.c_int,
96
+ ct.c_int,
97
+ ct.c_size_t
98
+ ]
99
+ mmap = libc.mmap
100
+
101
+ PROT_NONE = 0x0 # Page can not be accessed.
102
+ PROT_READ = 0x1 # Page can be read.
103
+ PROT_WRITE = 0x2 # Page can be written.
104
+ PROT_EXEC = 0x4 # Page can be executed.
105
+
106
+ MAP_FAILED = -1
107
+
108
+ if LINUX:
109
+ MAP_SHARED = 0x01 # Share changes.
110
+ MAP_PRIVATE = 0x02 # Changes are private.
111
+ MAP_ANONYMOUS = 0x20 # Don't use a file.
112
+ MAP_GROWSDOWN = 0x00100 # Stack-like segment.
113
+ MAP_DENYWRITE = 0x00800 # ETXTBSY
114
+ MAP_EXECUTABLE = 0x01000 # Mark it as an executable.
115
+ MAP_LOCKED = 0x02000 # Lock the mapping.
116
+ MAP_NORESERVE = 0x04000 # Don't check for reservations.
117
+ MAP_POPULATE = 0x08000 # Populate (prefault) pagetables.
118
+ MAP_NONBLOCK = 0x10000 # Do not block on IO.
119
+ MAP_STACK = 0x20000 # Allocation is for a stack.
120
+ MAP_HUGETLB = 0x40000 # create a huge page mapping
121
+
122
+ elif DARWIN:
123
+ MAP_SHARED = 0x0001 # [MF|SHM] share changes
124
+ MAP_PRIVATE = 0x0002 # [MF|SHM] changes are private
125
+ MAP_FIXED = 0x0010 # [MF|SHM] interpret addr exactly
126
+ MAP_RENAME = 0x0020 # Sun: rename private pages to file
127
+ MAP_NORESERVE = 0x0040 # Sun: don't reserve needed swap area
128
+ MAP_RESERVED0080 = 0x0080 # previously unimplemented MAP_INHERIT
129
+ MAP_NOEXTEND = 0x0100 # for MAP_FILE, don't change file size
130
+ MAP_HASSEMAPHORE = 0x0200 # region may contain semaphores
131
+ MAP_NOCACHE = 0x0400 # don't cache pages for this mapping
132
+ MAP_JIT = 0x0800 # Allocate a region that will be used for JIT purposes
133
+ MAP_FILE = 0x0000 # map from file (default)
134
+ MAP_ANON = 0x1000 # allocated from memory, swap space
135
+
136
+
137
+ # int munmap(void *addr, size_t length);
138
+ libc.munmap.restype = ct.c_int
139
+ libc.munmap.argtypes = [
140
+ ct.c_void_p,
141
+ ct.c_size_t
142
+ ]
143
+ munmap = libc.munmap
144
+
145
+
146
+ # int mprotect(const void *addr, size_t len, int prot);
147
+ libc.mprotect.restype = ct.c_int
148
+ libc.mprotect.argtypes = [
149
+ ct.c_void_p,
150
+ ct.c_size_t,
151
+ ct.c_int
152
+ ]
153
+ mprotect = libc.mprotect
154
+
155
+ if LINUX:
156
+ PROT_GROWSDOWN = 0x01000000 # Extend change to start of growsdown vma (mprotect only).
157
+ PROT_GROWSUP = 0x02000000 # Extend change to start of growsup vma (mprotect only).
158
+
159
+
160
+ if LINUX:
161
+ # void *mremap(void *old_address, size_t old_size, size_t new_size, int flags);
162
+ libc.mremap.restype = ct.c_void_p
163
+ libc.mremap.argtypes = [
164
+ ct.c_void_p,
165
+ ct.c_size_t,
166
+ ct.c_size_t,
167
+ ct.c_int
168
+ ]
169
+ mremap = libc.mremap
170
+
171
+ MREMAP_MAYMOVE = 1
172
+ MREMAP_FIXED = 2
173
+
174
+
175
+ class Mmap:
176
+
177
+ def __init__(
178
+ self,
179
+ length: int,
180
+ *,
181
+ prot: int = PROT_READ | PROT_WRITE,
182
+ flags: ta.Optional[int] = None,
183
+ fd: int = -1,
184
+ offset: int = 0,
185
+ desired_base: int = 0,
186
+ ) -> None:
187
+ super().__init__()
188
+
189
+ if flags is None:
190
+ if LINUX:
191
+ flags = MAP_SHARED | MAP_ANONYMOUS
192
+ elif DARWIN:
193
+ flags = MAP_SHARED | MAP_ANON
194
+ else:
195
+ raise OSError
196
+
197
+ self._length = length
198
+ self._prot = prot
199
+ self._flags = flags
200
+ self._fd = fd
201
+ self._offset = offset
202
+ self._desired_base = desired_base
203
+
204
+ self._base = None
205
+ self._is_mapped = False
206
+
207
+ @property
208
+ def base(self) -> ta.Optional[int]:
209
+ return self._base
210
+
211
+ def __enter__(self) -> 'Mmap':
212
+ base = mmap(self._desired_base, self._length, self._prot, self._flags, self._fd, self._offset)
213
+ if base == MAP_FAILED:
214
+ err, msg = lasterr()
215
+ raise OSError(err, 'mmap failed: ' + msg)
216
+ self._base = base
217
+ self._is_mapped = True
218
+ return self
219
+
220
+ def __exit__(self, et, e, tb) -> None:
221
+ if self._is_mapped:
222
+ res = munmap(self._base, self._length)
223
+ if res != 0:
224
+ err, msg = lasterr()
225
+ raise OSError(err, 'munmap failed: ' + msg)
226
+ self._is_mapped = False
227
+
228
+
229
+ ##
230
+
231
+
232
+ if LINUX:
233
+ # int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
234
+ libc.prctl.restype = ct.c_int
235
+ libc.prctl.argtypes = [ct.c_int, ct.c_ulong, ct.c_ulong, ct.c_ulong, ct.c_ulong]
236
+
237
+ prctl = libc.prctl
238
+
239
+ # Values to pass as first argument to prctl()
240
+
241
+ PR_SET_PDEATHSIG = 1 # Second arg is a signal
242
+ PR_GET_PDEATHSIG = 2 # Second arg is a ptr to return the signal
243
+
244
+ # Get/set current->mm->dumpable
245
+ PR_GET_DUMPABLE = 3
246
+ PR_SET_DUMPABLE = 4
247
+
248
+ # Get/set unaligned access control bits (if meaningful)
249
+ PR_GET_UNALIGN = 5
250
+ PR_SET_UNALIGN = 6
251
+ PR_UNALIGN_NOPRINT = 1 # silently fix up unaligned user accesses
252
+ PR_UNALIGN_SIGBUS = 2 # generate SIGBUS on unaligned user access
253
+
254
+ # Get/set whether or not to drop capabilities on setuid() away from uid 0 (as per security/commoncap.c)
255
+ PR_GET_KEEPCAPS = 7
256
+ PR_SET_KEEPCAPS = 8
257
+
258
+ # Get/set floating-point emulation control bits (if meaningful)
259
+ PR_GET_FPEMU = 9
260
+ PR_SET_FPEMU = 10
261
+ PR_FPEMU_NOPRINT = 1 # silently emulate fp operations accesses
262
+ PR_FPEMU_SIGFPE = 2 # don't emulate fp operations, send SIGFPE instead
263
+
264
+ # Get/set floating-point exception mode (if meaningful)
265
+ PR_GET_FPEXC = 11
266
+ PR_SET_FPEXC = 12
267
+ PR_FP_EXC_SW_ENABLE = 0x80 # Use FPEXC for FP exception enables
268
+ PR_FP_EXC_DIV = 0x010000 # floating point divide by zero
269
+ PR_FP_EXC_OVF = 0x020000 # floating point overflow
270
+ PR_FP_EXC_UND = 0x040000 # floating point underflow
271
+ PR_FP_EXC_RES = 0x080000 # floating point inexact result
272
+ PR_FP_EXC_INV = 0x100000 # floating point invalid operation
273
+ PR_FP_EXC_DISABLED = 0 # FP exceptions disabled
274
+ PR_FP_EXC_NONRECOV = 1 # async non-recoverable exc. mode
275
+ PR_FP_EXC_ASYNC = 2 # async recoverable exception mode
276
+ PR_FP_EXC_PRECISE = 3 # precise exception mode
277
+
278
+ # Get/set whether we use statistical process timing or accurate timestamp process timing
279
+ PR_SET_NAME = 15 # Set process name
280
+ PR_GET_NAME = 16 # Get process name
281
+
282
+ # Get/set process endian
283
+ PR_GET_ENDIAN = 19
284
+ PR_SET_ENDIAN = 20
285
+ PR_ENDIAN_BIG = 0
286
+ PR_ENDIAN_LITTLE = 1 # True little endian mode
287
+ PR_ENDIAN_PPC_LITTLE = 2 # "PowerPC" pseudo little endian
288
+
289
+ # Get/set process seccomp mode
290
+ PR_GET_SECCOMP = 21
291
+ PR_SET_SECCOMP = 22
292
+
293
+ # Get/set the capability bounding set (as per security/commoncap.c)
294
+ PR_CAPBSET_READ = 23
295
+ PR_CAPBSET_DROP = 24
296
+
297
+ # Get/set the process' ability to use the timestamp counter instruction
298
+ PR_GET_TSC = 25
299
+ PR_SET_TSC = 26
300
+ PR_TSC_ENABLE = 1 # allow the use of the timestamp counter
301
+ PR_TSC_SIGSEGV = 2 # throw a SIGSEGV instead of reading the TSC
302
+
303
+ # Get/set securebits (as per security/commoncap.c)
304
+ PR_GET_SECUREBITS = 27
305
+ PR_SET_SECUREBITS = 28
306
+
307
+ # Get/set the timerslack as used by poll/select/nanosleep. A value of 0 means "use default"
308
+ PR_SET_TIMERSLACK = 29
309
+ PR_GET_TIMERSLACK = 30
310
+
311
+ PR_TASK_PERF_EVENTS_DISABLE = 31
312
+ PR_TASK_PERF_EVENTS_ENABLE = 32
313
+
314
+ # Set early/late kill mode for hwpoison memory corruption. This influences when the process gets killed on a memory
315
+ # corruption.
316
+ PR_MCE_KILL = 33
317
+ PR_MCE_KILL_CLEAR = 0
318
+ PR_MCE_KILL_SET = 1
319
+
320
+ PR_MCE_KILL_LATE = 0
321
+ PR_MCE_KILL_EARLY = 1
322
+ PR_MCE_KILL_DEFAULT = 2
323
+
324
+ PR_MCE_KILL_GET = 34
325
+
326
+
327
+ ##
328
+
329
+
330
+ if LINUX or DARWIN:
331
+ SCM_RIGHTS = 1
332
+
333
+ ct.c_ssize_t = ct.c_size_t # type: ignore
334
+
335
+ class iovec(ct.Structure):
336
+ pass
337
+
338
+ iovec._fields_ = [
339
+ ('iov_base', ct.c_void_p), # Pointer to data.
340
+ ('iov_len', ct.c_size_t), # Length of data.
341
+ ]
342
+
343
+ class msghdr(ct.Structure):
344
+ pass
345
+
346
+ msghdr._fields_ = [
347
+ ('msg_name', ct.c_void_p), # Address to send to/receive from.
348
+ ('msg_namelen', ct.c_uint), # Length of address data.
349
+ ('msg_iov', ct.POINTER(iovec)), # Vector of data to send/receive into.
350
+ ('msg_iovlen', ct.c_size_t), # Number of elements in the vector.
351
+ ('msg_control', ct.c_void_p), # Ancillary data (eg BSD filedesc passing).
352
+ ('msg_controllen', ct.c_size_t), # Ancillary data buffer length. !! The type should be
353
+ # socklen_t but the definition of the kernel is incompatible with this
354
+ ('msg_flags', ct.c_int), # Flags on received message.
355
+ ]
356
+
357
+ class cmsghdr(ct.Structure):
358
+ pass
359
+
360
+ cmsghdr._fields_ = [
361
+ ('cmsg_len', ct.c_size_t), # Length of data in cmsg_data plus length
362
+ # of cmsghdr structure. !! The type should be socklen_t but the definition of the kernel is incompatible with
363
+ # this.
364
+ ('cmsg_level', ct.c_int), # Originating protocol.
365
+ ('cmsg_type', ct.c_int), # Protocol specific type.
366
+ ]
367
+
368
+ # ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
369
+ libc.sendmsg.restype = ct.c_ssize_t
370
+ libc.sendmsg.argtypes = [ct.c_int, ct.POINTER(msghdr), ct.c_int]
371
+
372
+ # ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
373
+ libc.sendmsg.restype = ct.c_ssize_t
374
+ libc.sendmsg.argtypes = [ct.c_int, ct.POINTER(msghdr), ct.c_int]
375
+
376
+ def CMSG_ALIGN(sz):
377
+ i = ct.sizeof(ct.c_size_t)
378
+ return ((sz + i - 1) // i) * i
379
+
380
+ def CMSG_SPACE(sz):
381
+ return CMSG_ALIGN(sz) + CMSG_ALIGN(ct.sizeof(cmsghdr))
382
+
383
+ def CMSG_LEN(sz):
384
+ return CMSG_ALIGN(ct.sizeof(cmsghdr)) + sz
385
+
386
+ def sendfd(sock, fd, data='.'):
387
+ if not data:
388
+ raise ValueError(data)
389
+
390
+ iov = iovec()
391
+ iov.iov_base = ct.cast(ct.c_char_p(data), ct.c_void_p) # noqa
392
+ iov.iov_len = len(data)
393
+
394
+ cmsg_size = CMSG_SPACE(ct.sizeof(ct.c_int))
395
+ msg_control = (ct.c_char * cmsg_size)() # noqa
396
+
397
+ msgh = msghdr()
398
+ msgh.msg_name = None
399
+ msgh.msg_namelen = 0
400
+ msgh.msg_iov = ct.cast(ct.addressof(iov), ct.POINTER(iovec))
401
+ msgh.msg_iovlen = 1
402
+ msgh.msg_control = ct.cast(ct.addressof(msg_control), ct.c_void_p)
403
+ msgh.msg_controllen = cmsg_size
404
+ msgh.msg_flags = 0
405
+
406
+ h = ct.cast(ct.addressof(msg_control), ct.POINTER(cmsghdr))
407
+ h.contents.cmsg_len = CMSG_LEN(ct.sizeof(ct.c_int))
408
+ h.contents.cmsg_level = socket.SOL_SOCKET
409
+ h.contents.cmsg_type = SCM_RIGHTS
410
+
411
+ p_fd = ct.cast(
412
+ ct.addressof(msg_control) + ct.sizeof(cmsghdr),
413
+ ct.POINTER(ct.c_int))
414
+ p_fd.contents = ct.c_int(fd)
415
+
416
+ return libc.sendmsg(sock, msgh, 0)
417
+
418
+ def recvfd(sock, buf_len=4096):
419
+ if buf_len < 1:
420
+ raise ValueError(buf_len)
421
+
422
+ cmsg_size = CMSG_SPACE(ct.sizeof(ct.c_int))
423
+ cmsg_buf = (ct.c_char * cmsg_size)() # noqa
424
+ data_buf = (ct.c_char * buf_len)() # noqa
425
+
426
+ iov = iovec()
427
+ iov.iov_base = ct.cast(ct.addressof(data_buf), ct.c_void_p)
428
+ iov.iov_len = buf_len
429
+
430
+ msgh = msghdr()
431
+ msgh.msg_name = None
432
+ msgh.msg_namelen = 0
433
+ msgh.msg_iov = ct.cast(ct.addressof(iov), ct.POINTER(iovec))
434
+ msgh.msg_iovlen = 1
435
+ msgh.msg_control = ct.cast(ct.addressof(cmsg_buf), ct.c_void_p)
436
+ msgh.msg_controllen = cmsg_size
437
+ msgh.msg_flags = 0
438
+
439
+ recv_len = libc.recvmsg(sock, ct.cast(ct.addressof(msgh), ct.POINTER(msghdr)), 0)
440
+ if recv_len < 0:
441
+ return recv_len, None
442
+
443
+ h = ct.cast(ct.addressof(cmsg_buf), ct.POINTER(cmsghdr))
444
+ if (h.contents.cmsg_len != CMSG_LEN(ct.sizeof(ct.c_int))) or \
445
+ (h.contents.cmsg_level != socket.SOL_SOCKET) or \
446
+ (h.contents.cmsg_type != SCM_RIGHTS):
447
+ return -2, None
448
+
449
+ p_fd = ct.cast(
450
+ ct.addressof(cmsg_buf) + ct.sizeof(cmsghdr),
451
+ ct.POINTER(ct.c_int))
452
+ fd = p_fd.contents.value
453
+ if fd < 0:
454
+ return -3, None
455
+
456
+ return fd, data_buf[:recv_len]
457
+
458
+
459
+ ##
460
+
461
+
462
+ if LINUX:
463
+ dl = ct.CDLL('libdl.so.2')
464
+
465
+ dl.dlopen.restype = ct.c_void_p
466
+ dl.dlopen.argtypes = [ct.c_char_p, ct.c_int]
467
+ dlopen = dl.dlopen
468
+
469
+ dl.dlsym.restype = ct.c_void_p
470
+ dl.dlsym.argtypes = [ct.c_void_p, ct.c_char_p]
471
+ dlsym = dl.dlsym
472
+
473
+ dl.dlerror.restype = ct.c_char_p
474
+ dl.dlerror.argtypes = []
475
+ dlerror = dl.dlerror
476
+
477
+ dl.dlclose.restype = ct.c_int
478
+ dl.dlclose.argtypes = [ct.c_void_p]
479
+ dlclose = dl.dlclose
480
+
481
+ elif DARWIN:
482
+ libc.dlopen.restype = ct.c_void_p
483
+ libc.dlopen.argtypes = [ct.c_char_p, ct.c_int]
484
+ dlopen = libc.dlopen
485
+
486
+ libc.dlsym.restype = ct.c_void_p
487
+ libc.dlsym.argtypes = [ct.c_void_p, ct.c_char_p]
488
+ dlsym = libc.dlsym
489
+
490
+ libc.dlerror.restype = ct.c_char_p
491
+ libc.dlerror.argtypes = []
492
+ dlerror = libc.dlerror
493
+
494
+ libc.dlclose.restype = ct.c_int
495
+ libc.dlclose.argtypes = [ct.c_void_p]
496
+ dlclose = libc.dlclose
497
+
498
+
499
+ ##
500
+
501
+
502
+ if LINUX:
503
+ F_SETPIPE_SZ = 1031
504
+
505
+
506
+ ##
507
+
508
+
509
+ if LINUX:
510
+ SO_PASSCRED = 16 # noqa
511
+ SO_PEERCRED = 17
512
+
513
+ elif DARWIN:
514
+ SOL_LOCAL = 1
515
+ LOCAL_PEERCRED = 1
516
+
517
+
518
+ ##
519
+
520
+
521
+ if LINUX:
522
+ def gettid():
523
+ syscalls = {
524
+ 'i386': 224, # unistd_32.h: #define __NR_gettid 224
525
+ 'x86_64': 186, # unistd_64.h: #define __NR_gettid 186
526
+ 'aarch64': 178, # asm-generic/unistd.h: #define __NR_gettid 178
527
+ }
528
+ try:
529
+ tid = ct.CDLL('libc.so.6').syscall(syscalls[platform.machine()])
530
+ except Exception: # noqa
531
+ tid = -1
532
+ return tid
@@ -0,0 +1,9 @@
1
+ from .configs import build_log_format # noqa
2
+ from .configs import configure_standard_logging # noqa
3
+ from .configs import DictConfig # noqa
4
+ from .configs import NOISY_LOGGERS # noqa
5
+ from .configs import STANDARD_LOG_FORMAT_PARTS # noqa
6
+ from .filters import TidFilter # noqa
7
+ from .formatters import ColorLogFormatter # noqa
8
+ from .formatters import JsonLogFormatter # noqa
9
+ from .utils import error_logging # noqa