omlish 0.0.0.dev226__py3-none-any.whl → 0.0.0.dev228__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.
- omlish/__about__.py +3 -3
- omlish/diag/lslocks.py +4 -4
- omlish/diag/lsof.py +3 -4
- omlish/diag/ps.py +9 -0
- omlish/lite/timeouts.py +1 -1
- omlish/marshal/__init__.py +39 -24
- omlish/marshal/composite/__init__.py +0 -0
- omlish/marshal/{iterables.py → composite/iterables.py} +10 -10
- omlish/marshal/{literals.py → composite/literals.py} +9 -9
- omlish/marshal/{mappings.py → composite/mappings.py} +10 -10
- omlish/marshal/{maybes.py → composite/maybes.py} +11 -11
- omlish/marshal/{newtypes.py → composite/newtypes.py} +8 -8
- omlish/marshal/{optionals.py → composite/optionals.py} +9 -9
- omlish/marshal/objects/__init__.py +7 -0
- omlish/marshal/{dataclasses.py → objects/dataclasses.py} +24 -24
- omlish/marshal/{helpers.py → objects/helpers.py} +6 -3
- omlish/marshal/objects/marshal.py +108 -0
- omlish/marshal/objects/metadata.py +124 -0
- omlish/marshal/{namedtuples.py → objects/namedtuples.py} +16 -16
- omlish/marshal/objects/unmarshal.py +141 -0
- omlish/marshal/polymorphism/__init__.py +7 -0
- omlish/marshal/polymorphism/marshal.py +66 -0
- omlish/marshal/polymorphism/metadata.py +140 -0
- omlish/marshal/{unions.py → polymorphism/unions.py} +18 -18
- omlish/marshal/polymorphism/unmarshal.py +73 -0
- omlish/marshal/singular/__init__.py +0 -0
- omlish/marshal/{any.py → singular/any.py} +8 -8
- omlish/marshal/{base64.py → singular/base64.py} +9 -9
- omlish/marshal/{datetimes.py → singular/datetimes.py} +9 -9
- omlish/marshal/{enums.py → singular/enums.py} +9 -9
- omlish/marshal/{numbers.py → singular/numbers.py} +8 -8
- omlish/marshal/{primitives.py → singular/primitives.py} +8 -8
- omlish/marshal/{uuids.py → singular/uuids.py} +8 -8
- omlish/marshal/standard.py +32 -32
- omlish/os/death.py +70 -4
- omlish/os/fcntl.py +11 -12
- omlish/os/files.py +18 -3
- omlish/os/forkhooks.py +215 -0
- omlish/os/pidfiles/manager.py +4 -1
- omlish/os/pidfiles/pidfile.py +31 -11
- omlish/os/pidfiles/pinning.py +250 -0
- omlish/sockets/bind.py +4 -4
- {omlish-0.0.0.dev226.dist-info → omlish-0.0.0.dev228.dist-info}/METADATA +3 -3
- {omlish-0.0.0.dev226.dist-info → omlish-0.0.0.dev228.dist-info}/RECORD +48 -38
- omlish/marshal/objects.py +0 -317
- omlish/marshal/polymorphism.py +0 -267
- {omlish-0.0.0.dev226.dist-info → omlish-0.0.0.dev228.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev226.dist-info → omlish-0.0.0.dev228.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev226.dist-info → omlish-0.0.0.dev228.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev226.dist-info → omlish-0.0.0.dev228.dist-info}/top_level.txt +0 -0
omlish/os/pidfiles/pidfile.py
CHANGED
@@ -109,7 +109,7 @@ class Pidfile:
|
|
109
109
|
del self._f
|
110
110
|
return True
|
111
111
|
|
112
|
-
def
|
112
|
+
def try_acquire_lock(self) -> bool:
|
113
113
|
try:
|
114
114
|
fcntl.flock(self._f, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
115
115
|
return True
|
@@ -117,14 +117,29 @@ class Pidfile:
|
|
117
117
|
except OSError:
|
118
118
|
return False
|
119
119
|
|
120
|
-
|
121
|
-
|
122
|
-
|
120
|
+
#
|
121
|
+
|
122
|
+
class Error(Exception):
|
123
|
+
pass
|
124
|
+
|
125
|
+
class LockedError(Error):
|
126
|
+
pass
|
127
|
+
|
128
|
+
def acquire_lock(self) -> None:
|
129
|
+
if not self.try_acquire_lock():
|
130
|
+
raise self.LockedError
|
131
|
+
|
132
|
+
class NotLockedError(Error):
|
133
|
+
pass
|
134
|
+
|
135
|
+
def ensure_cannot_lock(self) -> None:
|
136
|
+
if self.try_acquire_lock():
|
137
|
+
raise self.NotLockedError
|
123
138
|
|
124
139
|
#
|
125
140
|
|
126
141
|
def write(self, pid: ta.Optional[int] = None) -> None:
|
127
|
-
self.
|
142
|
+
self.acquire_lock()
|
128
143
|
|
129
144
|
if pid is None:
|
130
145
|
pid = os.getpid()
|
@@ -135,18 +150,23 @@ class Pidfile:
|
|
135
150
|
self._f.flush()
|
136
151
|
|
137
152
|
def clear(self) -> None:
|
138
|
-
self.
|
153
|
+
self.acquire_lock()
|
139
154
|
|
140
155
|
self._f.seek(0)
|
141
156
|
self._f.truncate()
|
142
157
|
|
143
|
-
|
144
|
-
|
145
|
-
|
158
|
+
#
|
159
|
+
|
160
|
+
def read(self) -> ta.Optional[int]:
|
161
|
+
self.ensure_cannot_lock()
|
146
162
|
|
147
163
|
self._f.seek(0)
|
148
|
-
|
164
|
+
buf = self._f.read()
|
165
|
+
if not buf:
|
166
|
+
return None
|
167
|
+
return int(buf)
|
149
168
|
|
150
169
|
def kill(self, sig: int = signal.SIGTERM) -> None:
|
151
|
-
pid
|
170
|
+
if (pid := self.read()) is None:
|
171
|
+
raise self.Error(f'Pidfile locked but empty')
|
152
172
|
os.kill(pid, sig)
|
@@ -0,0 +1,250 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
# @omlish-lite
|
3
|
+
"""
|
4
|
+
Notes:
|
5
|
+
- still racy as to if it's a different actual process as initial check, just with same pid, but due to 'identity' /
|
6
|
+
semantic meaning of the named pidfile the processes are considered equivalent
|
7
|
+
|
8
|
+
Strategies:
|
9
|
+
- linux
|
10
|
+
- get pid of owner (lslocks or F_GETLK)
|
11
|
+
- open pidfd to owner pid
|
12
|
+
- re-check pid of owner
|
13
|
+
- darwin
|
14
|
+
- get pids of referrers (lsof)
|
15
|
+
- read pid from file
|
16
|
+
- ensure pid is in referrers
|
17
|
+
- optionally loop
|
18
|
+
- ? setup pid death watcher? still a race
|
19
|
+
"""
|
20
|
+
import abc
|
21
|
+
import contextlib
|
22
|
+
import os.path
|
23
|
+
import shutil
|
24
|
+
import sys
|
25
|
+
import time
|
26
|
+
import typing as ta
|
27
|
+
|
28
|
+
from ...diag.lslocks import LslocksCommand
|
29
|
+
from ...diag.lsof import LsofCommand
|
30
|
+
from ...lite.timeouts import Timeout
|
31
|
+
from ...lite.timeouts import TimeoutLike
|
32
|
+
from ...subprocesses.sync import subprocesses # noqa
|
33
|
+
from .pidfile import Pidfile
|
34
|
+
|
35
|
+
|
36
|
+
##
|
37
|
+
|
38
|
+
|
39
|
+
class PidfilePinner(abc.ABC):
|
40
|
+
def __init__(
|
41
|
+
self,
|
42
|
+
*,
|
43
|
+
sleep_s: float = .1,
|
44
|
+
) -> None:
|
45
|
+
super().__init__()
|
46
|
+
|
47
|
+
self._sleep_s = sleep_s
|
48
|
+
|
49
|
+
@classmethod
|
50
|
+
@abc.abstractmethod
|
51
|
+
def is_available(cls) -> bool:
|
52
|
+
raise NotImplementedError
|
53
|
+
|
54
|
+
class NoOwnerError(Exception):
|
55
|
+
pass
|
56
|
+
|
57
|
+
@abc.abstractmethod
|
58
|
+
def _pin_pidfile_owner(self, pidfile: Pidfile, timeout: Timeout) -> ta.ContextManager[int]:
|
59
|
+
raise NotImplementedError
|
60
|
+
|
61
|
+
@contextlib.contextmanager
|
62
|
+
def pin_pidfile_owner(
|
63
|
+
self,
|
64
|
+
path: str,
|
65
|
+
*,
|
66
|
+
timeout: ta.Optional[TimeoutLike] = None,
|
67
|
+
) -> ta.Iterator[int]:
|
68
|
+
timeout = Timeout.of(timeout)
|
69
|
+
|
70
|
+
if not os.path.isfile(path):
|
71
|
+
raise self.NoOwnerError
|
72
|
+
|
73
|
+
with Pidfile(path, inheritable=False) as pf:
|
74
|
+
try:
|
75
|
+
with self._pin_pidfile_owner(pf, timeout) as pid:
|
76
|
+
yield pid
|
77
|
+
|
78
|
+
except Pidfile.NotLockedError:
|
79
|
+
raise self.NoOwnerError from None
|
80
|
+
|
81
|
+
@classmethod
|
82
|
+
def default_impl(cls) -> ta.Type['PidfilePinner']:
|
83
|
+
for impl in [
|
84
|
+
LslocksPidfdPidfilePinner,
|
85
|
+
LsofPidfilePinner,
|
86
|
+
]:
|
87
|
+
if impl.is_available():
|
88
|
+
return impl
|
89
|
+
return UnverifiedPidfilePinner
|
90
|
+
|
91
|
+
|
92
|
+
##
|
93
|
+
|
94
|
+
|
95
|
+
class UnverifiedPidfilePinner(PidfilePinner):
|
96
|
+
@classmethod
|
97
|
+
def is_available(cls) -> bool:
|
98
|
+
return True
|
99
|
+
|
100
|
+
@contextlib.contextmanager
|
101
|
+
def _pin_pidfile_owner(self, pidfile: Pidfile, timeout: Timeout) -> ta.Iterator[int]:
|
102
|
+
while (pid := pidfile.read()) is None:
|
103
|
+
time.sleep(self._sleep_s)
|
104
|
+
timeout()
|
105
|
+
|
106
|
+
yield pid
|
107
|
+
|
108
|
+
|
109
|
+
##
|
110
|
+
|
111
|
+
|
112
|
+
class LsofPidfilePinner(PidfilePinner):
|
113
|
+
"""
|
114
|
+
Fundamentally wrong, but still better than nothing. Simply reads the file contents and ensures a valid contained pid
|
115
|
+
has the file open via `lsof`.
|
116
|
+
"""
|
117
|
+
|
118
|
+
@classmethod
|
119
|
+
def is_available(cls) -> bool:
|
120
|
+
return shutil.which('lsof') is not None
|
121
|
+
|
122
|
+
def _try_read_and_verify(self, pf: Pidfile, timeout: Timeout) -> ta.Optional[int]:
|
123
|
+
if (initial_pid := pf.read()) is None:
|
124
|
+
return None
|
125
|
+
|
126
|
+
lsof_output = LsofCommand(
|
127
|
+
# pid=initial_pid,
|
128
|
+
file=os.path.abspath(pf.path),
|
129
|
+
).run(
|
130
|
+
timeout=timeout,
|
131
|
+
)
|
132
|
+
|
133
|
+
lsof_pids: ta.Set[int] = set()
|
134
|
+
for li in lsof_output:
|
135
|
+
if li.pid is None:
|
136
|
+
continue
|
137
|
+
try:
|
138
|
+
li_pid = int(li.pid)
|
139
|
+
except ValueError:
|
140
|
+
continue
|
141
|
+
lsof_pids.add(li_pid)
|
142
|
+
|
143
|
+
if initial_pid not in lsof_pids:
|
144
|
+
return None
|
145
|
+
|
146
|
+
if (reread_pid := pf.read()) is None or reread_pid != initial_pid:
|
147
|
+
return None
|
148
|
+
|
149
|
+
return reread_pid
|
150
|
+
|
151
|
+
@contextlib.contextmanager
|
152
|
+
def _pin_pidfile_owner(self, pidfile: Pidfile, timeout: Timeout) -> ta.Iterator[int]:
|
153
|
+
while (pid := self._try_read_and_verify(pidfile, timeout)) is None:
|
154
|
+
time.sleep(self._sleep_s)
|
155
|
+
timeout()
|
156
|
+
|
157
|
+
yield pid
|
158
|
+
|
159
|
+
|
160
|
+
##
|
161
|
+
|
162
|
+
|
163
|
+
class LslocksPidfdPidfilePinner(PidfilePinner):
|
164
|
+
"""
|
165
|
+
Finds the locking pid via `lslocks`, opens a pidfd, then re-runs `lslocks` and rechecks the locking pid is the same.
|
166
|
+
"""
|
167
|
+
|
168
|
+
@classmethod
|
169
|
+
def is_available(cls) -> bool:
|
170
|
+
return sys.platform == 'linux' and shutil.which('lslocks') is not None
|
171
|
+
|
172
|
+
def _read_locking_pid(self, path: str, timeout: Timeout) -> int:
|
173
|
+
lsl_output = LslocksCommand().run(timeout=timeout)
|
174
|
+
|
175
|
+
lsl_pids = {
|
176
|
+
li.pid
|
177
|
+
for li in lsl_output
|
178
|
+
if li.path == path
|
179
|
+
and li.type == 'FLOCK'
|
180
|
+
}
|
181
|
+
if not lsl_pids:
|
182
|
+
raise self.NoOwnerError
|
183
|
+
if len(lsl_pids) != 1:
|
184
|
+
raise RuntimeError(f'Multiple locks on file: {path}')
|
185
|
+
|
186
|
+
[pid] = lsl_pids
|
187
|
+
return pid
|
188
|
+
|
189
|
+
class _Result(ta.NamedTuple):
|
190
|
+
pid: int
|
191
|
+
pidfd: int
|
192
|
+
|
193
|
+
def _try_read_and_verify(
|
194
|
+
self,
|
195
|
+
pidfile: Pidfile,
|
196
|
+
timeout: Timeout,
|
197
|
+
) -> ta.Optional[_Result]:
|
198
|
+
path = os.path.abspath(pidfile.path)
|
199
|
+
initial_pid = self._read_locking_pid(path, timeout)
|
200
|
+
|
201
|
+
try:
|
202
|
+
pidfd = os.open(f'/proc/{initial_pid}', os.O_RDONLY)
|
203
|
+
except FileNotFoundError:
|
204
|
+
raise self.NoOwnerError from None
|
205
|
+
|
206
|
+
try:
|
207
|
+
reread_pid = self._read_locking_pid(path, timeout)
|
208
|
+
if reread_pid != initial_pid:
|
209
|
+
os.close(pidfd)
|
210
|
+
return None
|
211
|
+
|
212
|
+
return self._Result(initial_pid, pidfd)
|
213
|
+
|
214
|
+
except BaseException:
|
215
|
+
os.close(pidfd)
|
216
|
+
raise
|
217
|
+
|
218
|
+
@contextlib.contextmanager
|
219
|
+
def _pin_pidfile_owner(
|
220
|
+
self,
|
221
|
+
pidfile: Pidfile,
|
222
|
+
timeout: Timeout,
|
223
|
+
) -> ta.Iterator[int]:
|
224
|
+
while (res := self._try_read_and_verify(pidfile, timeout)) is None:
|
225
|
+
time.sleep(self._sleep_s)
|
226
|
+
timeout()
|
227
|
+
|
228
|
+
try:
|
229
|
+
yield res.pid
|
230
|
+
finally:
|
231
|
+
os.close(res.pidfd)
|
232
|
+
|
233
|
+
|
234
|
+
##
|
235
|
+
|
236
|
+
|
237
|
+
if __name__ == '__main__':
|
238
|
+
def _main() -> None:
|
239
|
+
argparse = __import__('argparse')
|
240
|
+
parser = argparse.ArgumentParser()
|
241
|
+
parser.add_argument('file')
|
242
|
+
args = parser.parse_args()
|
243
|
+
|
244
|
+
with PidfilePinner.default_impl()().pin_pidfile_owner(
|
245
|
+
args.file,
|
246
|
+
timeout=5.,
|
247
|
+
) as pid:
|
248
|
+
print(pid)
|
249
|
+
|
250
|
+
_main()
|
omlish/sockets/bind.py
CHANGED
@@ -15,10 +15,10 @@ import socket as socket_
|
|
15
15
|
import stat
|
16
16
|
import typing as ta
|
17
17
|
|
18
|
-
from
|
19
|
-
from
|
20
|
-
from
|
21
|
-
from
|
18
|
+
from ..lite.check import check
|
19
|
+
from ..lite.dataclasses import dataclass_maybe_post_init
|
20
|
+
from .addresses import SocketAddress
|
21
|
+
from .addresses import SocketAndAddress
|
22
22
|
|
23
23
|
|
24
24
|
SocketBinderT = ta.TypeVar('SocketBinderT', bound='SocketBinder')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: omlish
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev228
|
4
4
|
Summary: omlish
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -32,7 +32,7 @@ Requires-Dist: cbor2~=5.6; extra == "all"
|
|
32
32
|
Requires-Dist: cloudpickle~=3.1; extra == "all"
|
33
33
|
Requires-Dist: httpx[http2]~=0.28; extra == "all"
|
34
34
|
Requires-Dist: wrapt~=1.17; extra == "all"
|
35
|
-
Requires-Dist: cryptography~=
|
35
|
+
Requires-Dist: cryptography~=44.0; extra == "all"
|
36
36
|
Requires-Dist: sqlalchemy[asyncio]~=2.0; extra == "all"
|
37
37
|
Requires-Dist: pg8000~=1.31; extra == "all"
|
38
38
|
Requires-Dist: pymysql~=1.1; extra == "all"
|
@@ -76,7 +76,7 @@ Requires-Dist: httpx[http2]~=0.28; extra == "http"
|
|
76
76
|
Provides-Extra: misc
|
77
77
|
Requires-Dist: wrapt~=1.17; extra == "misc"
|
78
78
|
Provides-Extra: secrets
|
79
|
-
Requires-Dist: cryptography~=
|
79
|
+
Requires-Dist: cryptography~=44.0; extra == "secrets"
|
80
80
|
Provides-Extra: sqlalchemy
|
81
81
|
Requires-Dist: sqlalchemy[asyncio]~=2.0; extra == "sqlalchemy"
|
82
82
|
Provides-Extra: sqldrivers
|
@@ -1,5 +1,5 @@
|
|
1
1
|
omlish/.manifests.json,sha256=YGmAnUBszmosQQ_7Hh2wwtDiYdYZ4unNKYzOtALuels,7968
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=7YnXltr9so9p-_7zMJK4FLVkWPEZyjsuxoimC7Jjpb4,3380
|
3
3
|
omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
|
4
4
|
omlish/c3.py,sha256=ubu7lHwss5V4UznbejAI0qXhXahrU01MysuHOZI9C4U,8116
|
5
5
|
omlish/cached.py,sha256=UI-XTFBwA6YXWJJJeBn-WkwBkfzDjLBBaZf4nIJA9y0,510
|
@@ -203,11 +203,11 @@ omlish/dataclasses/impl/utils.py,sha256=aER2iL3UAtgS1BdLuEvTr9Tr2wC28wk1kiOeO-jI
|
|
203
203
|
omlish/diag/__init__.py,sha256=4S8v0myJM4Zld6_FV6cPe_nSv0aJb6kXftEit0HkiGE,1141
|
204
204
|
omlish/diag/asts.py,sha256=BveUUNUcaAm4Hg55f4ZxGSI313E4L8cCZ5XjHpEkKVI,3325
|
205
205
|
omlish/diag/debug.py,sha256=ClED7kKXeVMyKrjGIxcq14kXk9kvUJfytBQwK9y7c4Q,1637
|
206
|
-
omlish/diag/lslocks.py,sha256=
|
207
|
-
omlish/diag/lsof.py,sha256=
|
206
|
+
omlish/diag/lslocks.py,sha256=fWI3SZwgEkhipVfSqvzVzREJRShcDYmlYByHBT0LToc,1744
|
207
|
+
omlish/diag/lsof.py,sha256=DnowqvKYah-WCuBHS3DAcZCvlsWJdM9kYNFq97UZDDA,9127
|
208
208
|
omlish/diag/procfs.py,sha256=KaGTAA2Gj8eEEp7MjClRe4aimwzd-HDABThFzvq2cBQ,9684
|
209
209
|
omlish/diag/procstats.py,sha256=UkqxREqfd-38xPYZ9T1SIJISz5ARQCEhTtOZrxtm2dE,777
|
210
|
-
omlish/diag/ps.py,sha256=
|
210
|
+
omlish/diag/ps.py,sha256=b7ai9O4mGZliNFvBu6PdQfMmct4qpcMTygEf1ISHBLQ,1666
|
211
211
|
omlish/diag/pycharm.py,sha256=7-r_F-whXt8v-0dehxAX-MeMFPM3iZXX9IfeL0GfUtk,4643
|
212
212
|
omlish/diag/pydevd.py,sha256=UN55ZjkWLCVyHxE2CNRRYamuvSKfzWsn0D5oczRTXO4,7536
|
213
213
|
omlish/diag/threads.py,sha256=1-x02VCDZ407gfbtXm1pWK-ubqhqfePm9PMqkHCVoqk,3642
|
@@ -433,7 +433,7 @@ omlish/lite/resources.py,sha256=YNSmX1Ohck1aoWRs55a-o5ChVbFJIQhtbqE-XwF55Oc,326
|
|
433
433
|
omlish/lite/runtime.py,sha256=XQo408zxTdJdppUZqOWHyeUR50VlCpNIExNGHz4U6O4,459
|
434
434
|
omlish/lite/secrets.py,sha256=3Mz3V2jf__XU9qNHcH56sBSw95L3U2UPL24bjvobG0c,816
|
435
435
|
omlish/lite/strings.py,sha256=QGxT1Yh4oI8ycsfeobxnjEhvDob_GiAKLeIhZwo1j24,1986
|
436
|
-
omlish/lite/timeouts.py,sha256=
|
436
|
+
omlish/lite/timeouts.py,sha256=wZ6PP1D3B8jpAI7-cQm7wkGTh2sE366XIn6FSMH6DZ4,4959
|
437
437
|
omlish/lite/timing.py,sha256=aVu3hEDB_jyTF_ryZI7iU-xg4q8CNwqpp9Apfru_iwY,196
|
438
438
|
omlish/lite/types.py,sha256=fP5EMyBdEp2LmDxcHjUDtwAMdR06ISr9lKOL7smWfHM,140
|
439
439
|
omlish/lite/typing.py,sha256=U3-JaEnkDSYxK4tsu_MzUn3RP6qALBe5FXQXpD-licE,1090
|
@@ -455,37 +455,45 @@ omlish/logs/utils.py,sha256=mzHrZ9ji75p5A8qR29eUr05CBAHMb8J753MSkID_VaQ,393
|
|
455
455
|
omlish/manifests/__init__.py,sha256=P2B0dpT8D7l5lJwRGPA92IcQj6oeXfd90X5-q9BJrKg,51
|
456
456
|
omlish/manifests/load.py,sha256=LrWAvBfdzDkFdLuVwfw2RwFvLjxx-rvfkpU9eBsWeIc,5626
|
457
457
|
omlish/manifests/types.py,sha256=d8bv5tknCJqclRfxCpao_8XxHo2yofhLpVHQTB-MfNw,260
|
458
|
-
omlish/marshal/__init__.py,sha256=
|
459
|
-
omlish/marshal/any.py,sha256=e82OyYK3Emm1P1ClnsnxP7fIWC2iNVyW0H5nK4mLmWM,779
|
458
|
+
omlish/marshal/__init__.py,sha256=o7EtBHbciL3OLz6zsMny-UGjyAfFXO1zRGIqVOPEKw0,2591
|
460
459
|
omlish/marshal/base.py,sha256=HEzfby-PgGzIhiRpBkFrkw5-hKacRSC5W_jwLjT8aYw,6740
|
461
|
-
omlish/marshal/base64.py,sha256=F-3ogJdcFCtWINRgJgWT0rErqgx6f4qahhcg8OrkqhE,1089
|
462
|
-
omlish/marshal/dataclasses.py,sha256=ZpfNaIdhKwWouWkoQGuequKwrEeehbz9QSQoW3acyPo,7756
|
463
|
-
omlish/marshal/datetimes.py,sha256=0ffg8cEvx9SMKIXZGD9b7MqpLfmgw0uKKdn6YTfoqok,3714
|
464
|
-
omlish/marshal/enums.py,sha256=CMAbx6RI2EcQoo7SoD-5q2l-3DFKreWMiOxs6mFpl_4,1472
|
465
460
|
omlish/marshal/exceptions.py,sha256=jwQWn4LcPnadT2KRI_1JJCOSkwWh0yHnYK9BmSkNN4U,302
|
466
461
|
omlish/marshal/factories.py,sha256=Q926jSVjaQLEmStnHLhm_c_vqEysN1LnDCwAsFLIzXw,2970
|
467
462
|
omlish/marshal/forbidden.py,sha256=NDe828hqCQw-AgxcEm8MiDZNxWoBwf3o7sTyvQsSsQ0,867
|
468
463
|
omlish/marshal/global_.py,sha256=K76wB1-pdg4VWgiqR7wyxRNYr-voJApexYW2nV-R4DM,1127
|
469
|
-
omlish/marshal/helpers.py,sha256=-SOgYJmrURILHpPK6Wu3cCvhj8RJrqfJxuKhh9UMs7o,1102
|
470
|
-
omlish/marshal/iterables.py,sha256=H9FoCB5RlJW0SVSi3SBD6sxOXN9XRTOUkHRwCYSqRb8,2632
|
471
|
-
omlish/marshal/literals.py,sha256=m92biF9-PwHGVBx3zG3s2YvklLeOQ7T5IOdgwBJr-NU,1599
|
472
|
-
omlish/marshal/mappings.py,sha256=XcNOaV708ZHeuIrWiFHC6F1O6U9NyyTKUurvXwIryJo,2789
|
473
|
-
omlish/marshal/maybes.py,sha256=i-gOQJ-7tdt6sOazAeyCh4N71SK3jWv-BKlkx-fZm-s,2200
|
474
|
-
omlish/marshal/namedtuples.py,sha256=H0icxcE5FrqgfI9dRc8LlXJy430g_yuILTCVD0Zvfd0,2799
|
475
464
|
omlish/marshal/naming.py,sha256=lIklR_Od4x1ghltAgOzqcKhHs-leeSv2YmFhCHO7GIs,613
|
476
|
-
omlish/marshal/newtypes.py,sha256=fRpXLoCpoiaqcvl7v92I1_Qt7udn4vsPc1P3UfcBu-8,841
|
477
465
|
omlish/marshal/nop.py,sha256=2mWve_dicFAiUQ2Y5asKkUW-XGmEE9Qi2ClIasFad0c,461
|
478
|
-
omlish/marshal/numbers.py,sha256=kFRIX9l1yofiYzafV6SnYfEg0PiCsAqeRHOeT6BSxlM,1672
|
479
|
-
omlish/marshal/objects.py,sha256=74tUmMymimSqgd4a6kyMh_owJe6J7YQXwCXEF-JWt1c,8419
|
480
|
-
omlish/marshal/optionals.py,sha256=r0XB5rqfasvgZJNrKYd6Unq2U4nHt3JURi26j0dYHlw,1499
|
481
|
-
omlish/marshal/polymorphism.py,sha256=2SxrfneA9QdhNdxieEGFnHDHpUo3ftETA9dMbCbmbWY,6511
|
482
|
-
omlish/marshal/primitives.py,sha256=f_6m24Cb-FDGsZpYSas11nLt3xCCEUXugw3Hv4-aNhg,1291
|
483
466
|
omlish/marshal/registries.py,sha256=FvC6qXHCizNB2QmU_N3orxW7iqfGYkiUXYYdTRWS6HA,2353
|
484
|
-
omlish/marshal/standard.py,sha256
|
485
|
-
omlish/marshal/unions.py,sha256=tT4W-mxuPi7s_kdl25_AUltsurYPO_0mQl2CiVmNonY,4357
|
467
|
+
omlish/marshal/standard.py,sha256=ncaoD_OyCzS5H8bt3WAp5z7k1mWPFeOgAYBVaBLq4Sg,3783
|
486
468
|
omlish/marshal/utils.py,sha256=puKJpwPpuDlMOIrKMcLTRLJyMiL6n_Xs-p59AuDEymA,543
|
487
|
-
omlish/marshal/uuids.py,sha256=H4B7UX_EPNmP2tC8bubcKrPLTS4aQu98huvbXQ3Zv2g,910
|
488
469
|
omlish/marshal/values.py,sha256=ssHiWdg_L6M17kAn8GiGdPW7UeQOm3RDikWkvwblf5I,263
|
470
|
+
omlish/marshal/composite/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
471
|
+
omlish/marshal/composite/iterables.py,sha256=tOMjJ-nyYBrRnAGAlT2scV3iR9QSic8La-1qFcy9yNk,2642
|
472
|
+
omlish/marshal/composite/literals.py,sha256=0fTwQVSQJe9L17grcLq5hMuoYD7vHRFgdHR5-Teq0g8,1608
|
473
|
+
omlish/marshal/composite/mappings.py,sha256=92oAqYzzTdRNhFDtmukpJd8anoi3pt2nX5XhLTlM_Dg,2799
|
474
|
+
omlish/marshal/composite/maybes.py,sha256=4rxTv769Uk4gQGAnE6urVnMscF1vhcnwqP_lm5QzSoM,2211
|
475
|
+
omlish/marshal/composite/newtypes.py,sha256=lYCacdR2BlLWMT1kc8o08UjsmJ6aYlAHkrzG8BozWCM,849
|
476
|
+
omlish/marshal/composite/optionals.py,sha256=iQgSrb9Xyb_IP81YREAZ0xKYXImLgMILGLBnYL2lFWw,1508
|
477
|
+
omlish/marshal/objects/__init__.py,sha256=F4wej8L_tedC8ETYxAnmKfdPR9TjsqIus9Z3nZofYuc,182
|
478
|
+
omlish/marshal/objects/dataclasses.py,sha256=Fo15maLrWICq4H3YlZpa0PjnJTC4eqG1IF0C-88qCKs,7780
|
479
|
+
omlish/marshal/objects/helpers.py,sha256=85GZp4h3Yo0GYGmnZpKgNxkWnSk8h2R21nfDLU2DtM0,1110
|
480
|
+
omlish/marshal/objects/marshal.py,sha256=rdZsDWKgLBZxV0ZQlwHTJv9iUg0lC57trJHBOFKvuLo,2636
|
481
|
+
omlish/marshal/objects/metadata.py,sha256=QVD7DRhXbLda_Edgpc3OD1xT9fthmeaaj6l_nTE1PMM,3307
|
482
|
+
omlish/marshal/objects/namedtuples.py,sha256=ENWyiYZhTwDRqUkkWrHeNcoHGEo5GW634jMuBUc3654,2815
|
483
|
+
omlish/marshal/objects/unmarshal.py,sha256=-83sSgL6WX6C3JfXZr64ZLYi3SsJC9kyiGAbEQbVHQI,3620
|
484
|
+
omlish/marshal/polymorphism/__init__.py,sha256=e2UTrSL0qp7w_1vkdxDWd7sXlWhep2KPV49-BB64ma8,130
|
485
|
+
omlish/marshal/polymorphism/marshal.py,sha256=Lraih0Dhkcwu6Bb6QkrYOWoMIubh46VQkXxJQWisA8Y,1827
|
486
|
+
omlish/marshal/polymorphism/metadata.py,sha256=hbXqkYKXhfJeMllzI0Ubeeqbq201khVN8uprgVhMpHM,3046
|
487
|
+
omlish/marshal/polymorphism/unions.py,sha256=YwsK9T3okGiHj88LTFNdUvuH7VkCsD-aTnZseKzhpdA,4350
|
488
|
+
omlish/marshal/polymorphism/unmarshal.py,sha256=gdWTgpl4hXBqac1gHmg_23VMb7x42CE2x-3oRpCaLwU,2047
|
489
|
+
omlish/marshal/singular/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
490
|
+
omlish/marshal/singular/any.py,sha256=42XmUbX_AaiHGFwS2QmA-huPCcZ1_jzVyrnBUYVm21U,787
|
491
|
+
omlish/marshal/singular/base64.py,sha256=gQIkFN60lNEuSiu3MDQFoHwMZTtzDbrBRtNpFZ2HXew,1098
|
492
|
+
omlish/marshal/singular/datetimes.py,sha256=1PDVFF6TGkGxGUno8TaFGRof0DQUookYf_X2Nl8T4V0,3723
|
493
|
+
omlish/marshal/singular/enums.py,sha256=0FSRj8fiM9LrRrFtlWrMsjG-ualfirGNSP0H-36J4sA,1481
|
494
|
+
omlish/marshal/singular/numbers.py,sha256=12a8HxjDHMTgtJTxO7VY_h5llaPyYB-QEPY09dUFOec,1680
|
495
|
+
omlish/marshal/singular/primitives.py,sha256=EZi2AIi_Onw1pekAiL4ujz4w-ASuOGWCu4MUIE_dCnk,1299
|
496
|
+
omlish/marshal/singular/uuids.py,sha256=rZoE6NE5z6x_ZRmVMjjR2iK7CR8ijfDOvhMKgmm8Mgk,918
|
489
497
|
omlish/math/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
490
498
|
omlish/math/bits.py,sha256=yip1l8agOYzT7bFyMGc0RR3XlnGCfHMpjw_SECLLh1I,3477
|
491
499
|
omlish/math/floats.py,sha256=UimhOT7KRl8LXTzOI5cQWoX_9h6WNWe_3vcOuO7-h_8,327
|
@@ -495,18 +503,20 @@ omlish/multiprocessing/proxies.py,sha256=bInhGds2rv6xT9q3qRMlZuSXFAjwfspkiohXZ36
|
|
495
503
|
omlish/multiprocessing/spawn.py,sha256=sTvPLIJGYnjjI6ASqhFzHF-97tCnaOXX7u7s-33SUMw,1875
|
496
504
|
omlish/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
497
505
|
omlish/os/atomics.py,sha256=KhWNeh4mzU3M-TF0v8uR6hUqMfZJW42MeyIK9Jl6R0k,5246
|
498
|
-
omlish/os/death.py,sha256=
|
506
|
+
omlish/os/death.py,sha256=kxcAWw91zvvWT5qxXbKVg-YEOJXxx658VCdkCTNPTag,4825
|
499
507
|
omlish/os/deathsig.py,sha256=hk9Yq2kyDdI-cI7OQH7mOfpRbOKzY_TfPKEqgrjVYbA,641
|
500
|
-
omlish/os/fcntl.py,sha256=
|
501
|
-
omlish/os/files.py,sha256=
|
508
|
+
omlish/os/fcntl.py,sha256=riQf9iEEEIC28lJp8ud06MU56w2XJHJ9nBFtck_hdhc,1501
|
509
|
+
omlish/os/files.py,sha256=WJ_42vsZIZukQURN3TTccp-n74ZNhbux_ps3TLbHj18,1106
|
510
|
+
omlish/os/forkhooks.py,sha256=PbcMrPF_7D0QBm73e55I_XIk4yQzsdj-L6rpe_eyAFM,5024
|
502
511
|
omlish/os/journald.py,sha256=2nI8Res1poXkbLc31--MPUlzYMESnCcPUkIxDOCjZW0,3903
|
503
512
|
omlish/os/linux.py,sha256=whJ6scwMKSFBdXiVhJW0BCpJV4jOGMr-a_a3Bhwz6Ls,18938
|
504
513
|
omlish/os/paths.py,sha256=hqPiyg_eYaRoIVPdAeX4oeLEV4Kpln_XsH0tHvbOf8Q,844
|
505
514
|
omlish/os/sizes.py,sha256=ohkALLvqSqBX4iR-7DMKJ4pfOCRdZXV8htH4QywUNM0,152
|
506
515
|
omlish/os/temp.py,sha256=P97KiVeNB7rfGn4tlgU5ro86JUxAsiphLMlxsjQgfB0,1198
|
507
516
|
omlish/os/pidfiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
508
|
-
omlish/os/pidfiles/manager.py,sha256=
|
509
|
-
omlish/os/pidfiles/pidfile.py,sha256=
|
517
|
+
omlish/os/pidfiles/manager.py,sha256=XP_0ynjWDG2wjRN3sIKjmFafpf-er3AYm8E7aXs16fA,3209
|
518
|
+
omlish/os/pidfiles/pidfile.py,sha256=WmZt_c8fvztPgZQnYHhcQCKWgHqAEsaI3Ggz6Wqgkc8,3748
|
519
|
+
omlish/os/pidfiles/pinning.py,sha256=_AwYjJc1UGX7mdCOk4mItJJcsOJo3RW2ebBOm2noW5Y,6359
|
510
520
|
omlish/reflect/__init__.py,sha256=JBWwxKwP4IEaomkK0PTju02STU1BVXT14SCrShT1Sm0,769
|
511
521
|
omlish/reflect/inspect.py,sha256=veJ424-9oZrqyvhVpvxOi7hcKW-PDBkdYL2yjrFlk4o,495
|
512
522
|
omlish/reflect/ops.py,sha256=RJ6jzrM4ieFsXzWyNXWV43O_WgzEaUvlHSc5N2ezW2A,2044
|
@@ -525,7 +535,7 @@ omlish/secrets/subprocesses.py,sha256=ffjfbgPbEE_Pwb_87vG4yYR2CGZy3I31mHNCo_0JtH
|
|
525
535
|
omlish/secrets/tempssl.py,sha256=tlwRrbHHvgKJtNAC31I5sDKryya4fagqN6kGt-tV4Qg,1874
|
526
536
|
omlish/sockets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
527
537
|
omlish/sockets/addresses.py,sha256=vbVeQBkzI513H4vRv-JS89QtRbr9U8v5zqkm3oODl_s,1869
|
528
|
-
omlish/sockets/bind.py,sha256=
|
538
|
+
omlish/sockets/bind.py,sha256=uRHZJvBxWXadd3Qt7deDEJ1rWzjC-lVodRgPA6VMwNU,8025
|
529
539
|
omlish/sockets/handlers.py,sha256=Gj6xZoo4vommge8XvkehYw3B7O4aql2P4qzZIIa0p24,462
|
530
540
|
omlish/sockets/io.py,sha256=lfhTkB7NnAIx9kuQhAkwgsEUXY78Mp1_WtYrIQNS_k8,1408
|
531
541
|
omlish/sockets/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -679,9 +689,9 @@ omlish/text/indent.py,sha256=YjtJEBYWuk8--b9JU_T6q4yxV85_TR7VEVr5ViRCFwk,1336
|
|
679
689
|
omlish/text/minja.py,sha256=jZC-fp3Xuhx48ppqsf2Sf1pHbC0t8XBB7UpUUoOk2Qw,5751
|
680
690
|
omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
|
681
691
|
omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
|
682
|
-
omlish-0.0.0.
|
683
|
-
omlish-0.0.0.
|
684
|
-
omlish-0.0.0.
|
685
|
-
omlish-0.0.0.
|
686
|
-
omlish-0.0.0.
|
687
|
-
omlish-0.0.0.
|
692
|
+
omlish-0.0.0.dev228.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
693
|
+
omlish-0.0.0.dev228.dist-info/METADATA,sha256=-HhLcpKh_NMYQIcIENf1Dyen3kQU2vxd2nAe_weG7wk,4176
|
694
|
+
omlish-0.0.0.dev228.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
695
|
+
omlish-0.0.0.dev228.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
696
|
+
omlish-0.0.0.dev228.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
697
|
+
omlish-0.0.0.dev228.dist-info/RECORD,,
|