omlish 0.0.0.dev88__py3-none-any.whl → 0.0.0.dev90__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 +2 -2
- omlish/bootstrap/sys.py +3 -3
- omlish/fnpairs.py +2 -3
- omlish/formats/json/cli/cli.py +22 -3
- omlish/lite/pidfile.py +68 -0
- omlish/os.py +0 -63
- {omlish-0.0.0.dev88.dist-info → omlish-0.0.0.dev90.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev88.dist-info → omlish-0.0.0.dev90.dist-info}/RECORD +12 -11
- {omlish-0.0.0.dev88.dist-info → omlish-0.0.0.dev90.dist-info}/WHEEL +1 -1
- {omlish-0.0.0.dev88.dist-info → omlish-0.0.0.dev90.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev88.dist-info → omlish-0.0.0.dev90.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev88.dist-info → omlish-0.0.0.dev90.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/bootstrap/sys.py
CHANGED
@@ -22,14 +22,14 @@ from .base import SimpleBootstrap
|
|
22
22
|
if ta.TYPE_CHECKING:
|
23
23
|
from .. import libc
|
24
24
|
from .. import logs
|
25
|
-
from .. import os as osu
|
26
25
|
from ..formats import dotenv
|
26
|
+
from ..lite import pidfile
|
27
27
|
|
28
28
|
else:
|
29
29
|
libc = lang.proxy_import('..libc', __package__)
|
30
30
|
logs = lang.proxy_import('..logs', __package__)
|
31
|
-
osu = lang.proxy_import('..os', __package__)
|
32
31
|
dotenv = lang.proxy_import('..formats.dotenv', __package__)
|
32
|
+
pidfile = lang.proxy_import('..lite.pidfile', __package__)
|
33
33
|
|
34
34
|
|
35
35
|
##
|
@@ -317,7 +317,7 @@ class PidfileBootstrap(ContextBootstrap['PidfileBootstrap.Config']):
|
|
317
317
|
yield
|
318
318
|
return
|
319
319
|
|
320
|
-
with
|
320
|
+
with pidfile.Pidfile(self._config.path) as pf:
|
321
321
|
pf.write()
|
322
322
|
yield
|
323
323
|
|
omlish/fnpairs.py
CHANGED
@@ -3,11 +3,10 @@ TODO:
|
|
3
3
|
- objects
|
4
4
|
- csv
|
5
5
|
- csvloader
|
6
|
-
- cbor
|
7
|
-
- alt json backends
|
8
6
|
- wrapped (wait for usecase)
|
9
|
-
- streams
|
7
|
+
- streams / incremental
|
10
8
|
- fileobj -> fileobj?
|
9
|
+
- swap zstandard for zstd
|
11
10
|
|
12
11
|
Compression choice:
|
13
12
|
- lzma if-available minimal-space
|
omlish/formats/json/cli/cli.py
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
- -I/-Ogz, lz4, etc - fnpairs
|
4
|
+
- read from http
|
5
|
+
"""
|
1
6
|
import argparse
|
2
7
|
import codecs
|
3
8
|
import contextlib
|
@@ -11,6 +16,7 @@ import typing as ta
|
|
11
16
|
from .... import check
|
12
17
|
from .... import lang
|
13
18
|
from .... import term
|
19
|
+
from ....lite.io import DelimitingBuffer
|
14
20
|
from ..render import JsonRenderer
|
15
21
|
from ..stream.build import JsonObjectBuilder
|
16
22
|
from ..stream.lex import JsonStreamLexer
|
@@ -45,7 +51,10 @@ def _main() -> None:
|
|
45
51
|
|
46
52
|
parser.add_argument('--stream', action='store_true')
|
47
53
|
parser.add_argument('--stream-build', action='store_true')
|
48
|
-
|
54
|
+
|
55
|
+
parser.add_argument('-l', '--lines', action='store_true')
|
56
|
+
|
57
|
+
parser.add_argument('--read-buffer-size', type=int, default=0x4000)
|
49
58
|
|
50
59
|
parser.add_argument('-f', '--format')
|
51
60
|
|
@@ -58,7 +67,7 @@ def _main() -> None:
|
|
58
67
|
|
59
68
|
parser.add_argument('-c', '--color', action='store_true')
|
60
69
|
|
61
|
-
parser.add_argument('-
|
70
|
+
parser.add_argument('-L', '--less', action='store_true')
|
62
71
|
|
63
72
|
args = parser.parse_args()
|
64
73
|
|
@@ -175,7 +184,7 @@ def _main() -> None:
|
|
175
184
|
build = None
|
176
185
|
|
177
186
|
while True:
|
178
|
-
buf = os.read(fd, args.
|
187
|
+
buf = os.read(fd, args.read_buffer_size)
|
179
188
|
|
180
189
|
for s in decoder.decode(buf, not buf):
|
181
190
|
n = 0
|
@@ -200,6 +209,16 @@ def _main() -> None:
|
|
200
209
|
if renderer is not None:
|
201
210
|
out.write('\n')
|
202
211
|
|
212
|
+
elif args.lines:
|
213
|
+
fd = in_file.fileno()
|
214
|
+
db = DelimitingBuffer()
|
215
|
+
|
216
|
+
while buf := os.read(fd, args.read_buffer_size):
|
217
|
+
for chunk in db.feed(buf):
|
218
|
+
s = check.isinstance(chunk, bytes).decode('utf-8')
|
219
|
+
v = fmt.load(io.StringIO(s))
|
220
|
+
print(render_one(v), file=out)
|
221
|
+
|
203
222
|
else:
|
204
223
|
with io.TextIOWrapper(in_file) as tw:
|
205
224
|
v = fmt.load(tw)
|
omlish/lite/pidfile.py
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# ruff: noqa: UP007
|
2
|
+
import fcntl
|
3
|
+
import os
|
4
|
+
import signal
|
5
|
+
import typing as ta
|
6
|
+
|
7
|
+
|
8
|
+
class Pidfile:
|
9
|
+
def __init__(self, path: str) -> None:
|
10
|
+
super().__init__()
|
11
|
+
self._path = path
|
12
|
+
|
13
|
+
_f: ta.TextIO
|
14
|
+
|
15
|
+
def __repr__(self) -> str:
|
16
|
+
return f'{self.__class__.__name__}({self._path!r})'
|
17
|
+
|
18
|
+
def __enter__(self) -> 'Pidfile':
|
19
|
+
fd = os.open(self._path, os.O_RDWR | os.O_CREAT, 0o600)
|
20
|
+
try:
|
21
|
+
os.set_inheritable(fd, True)
|
22
|
+
f = os.fdopen(fd, 'r+')
|
23
|
+
except Exception:
|
24
|
+
try:
|
25
|
+
os.close(fd)
|
26
|
+
except Exception: # noqa
|
27
|
+
pass
|
28
|
+
raise
|
29
|
+
self._f = f
|
30
|
+
return self
|
31
|
+
|
32
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
33
|
+
if self._f is not None:
|
34
|
+
self._f.close()
|
35
|
+
del self._f
|
36
|
+
|
37
|
+
def try_lock(self) -> bool:
|
38
|
+
try:
|
39
|
+
fcntl.flock(self._f, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
40
|
+
return True
|
41
|
+
except OSError:
|
42
|
+
return False
|
43
|
+
|
44
|
+
def ensure_locked(self) -> None:
|
45
|
+
if not self.try_lock():
|
46
|
+
raise RuntimeError('Could not get lock')
|
47
|
+
|
48
|
+
def write(self, pid: ta.Optional[int] = None) -> None:
|
49
|
+
self.ensure_locked()
|
50
|
+
if pid is None:
|
51
|
+
pid = os.getpid()
|
52
|
+
self._f.write(f'{pid}\n')
|
53
|
+
self._f.flush()
|
54
|
+
|
55
|
+
def clear(self) -> None:
|
56
|
+
self.ensure_locked()
|
57
|
+
self._f.seek(0)
|
58
|
+
self._f.truncate()
|
59
|
+
|
60
|
+
def read(self) -> int:
|
61
|
+
if self.try_lock():
|
62
|
+
raise RuntimeError('Got lock')
|
63
|
+
self._f.seek(0)
|
64
|
+
return int(self._f.read())
|
65
|
+
|
66
|
+
def kill(self, sig: int = signal.SIGTERM) -> None:
|
67
|
+
pid = self.read()
|
68
|
+
os.kill(pid, sig) # FIXME: Still racy
|
omlish/os.py
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
import contextlib
|
2
|
-
import fcntl
|
3
2
|
import os
|
4
3
|
import resource
|
5
4
|
import shutil
|
6
|
-
import signal
|
7
5
|
import tempfile
|
8
6
|
import typing as ta
|
9
7
|
|
@@ -44,67 +42,6 @@ def tmp_file(
|
|
44
42
|
shutil.rmtree(f.name, ignore_errors=True)
|
45
43
|
|
46
44
|
|
47
|
-
class Pidfile:
|
48
|
-
def __init__(self, path: str) -> None:
|
49
|
-
super().__init__()
|
50
|
-
self._path = path
|
51
|
-
|
52
|
-
_f: ta.TextIO
|
53
|
-
|
54
|
-
def __repr__(self) -> str:
|
55
|
-
return f'{self.__class__.__name__}({self._path!r})'
|
56
|
-
|
57
|
-
def __enter__(self) -> ta.Self:
|
58
|
-
fd = os.open(self._path, os.O_RDWR | os.O_CREAT, 0o600)
|
59
|
-
try:
|
60
|
-
os.set_inheritable(fd, True)
|
61
|
-
f = os.fdopen(fd, 'r+')
|
62
|
-
except Exception:
|
63
|
-
try:
|
64
|
-
os.close(fd)
|
65
|
-
except Exception: # noqa
|
66
|
-
pass
|
67
|
-
raise
|
68
|
-
self._f = f
|
69
|
-
return self
|
70
|
-
|
71
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
72
|
-
if self._f is not None:
|
73
|
-
self._f.close()
|
74
|
-
del self._f
|
75
|
-
|
76
|
-
def try_lock(self) -> bool:
|
77
|
-
try:
|
78
|
-
fcntl.flock(self._f, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
79
|
-
return True
|
80
|
-
except OSError:
|
81
|
-
return False
|
82
|
-
|
83
|
-
def write(self, pid: int | None = None) -> None:
|
84
|
-
if not self.try_lock():
|
85
|
-
raise RuntimeError('Could not get lock')
|
86
|
-
if pid is None:
|
87
|
-
pid = os.getpid()
|
88
|
-
self._f.write(f'{pid}\n')
|
89
|
-
self._f.flush()
|
90
|
-
|
91
|
-
def clear(self) -> None:
|
92
|
-
if not self.try_lock():
|
93
|
-
raise RuntimeError('Could not get lock')
|
94
|
-
self._f.seek(0)
|
95
|
-
self._f.truncate()
|
96
|
-
|
97
|
-
def read(self) -> int:
|
98
|
-
if self.try_lock():
|
99
|
-
raise RuntimeError('Got lock')
|
100
|
-
self._f.seek(0)
|
101
|
-
return int(self._f.read())
|
102
|
-
|
103
|
-
def kill(self, sig: int = signal.SIGTERM) -> None:
|
104
|
-
pid = self.read()
|
105
|
-
os.kill(pid, sig) # Still racy
|
106
|
-
|
107
|
-
|
108
45
|
def touch(self, mode: int = 0o666, exist_ok: bool = True) -> None:
|
109
46
|
if exist_ok:
|
110
47
|
# First try to bump modification time
|
@@ -1,5 +1,5 @@
|
|
1
1
|
omlish/.manifests.json,sha256=hTFp9tvE72BxKloIq1s1SS0LRQlIsvMtO69Sbc47rKg,1704
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=znvMoN-IBoaUZ4OXaaRoHANiPt5KtchQBS7qSqRRoLI,3345
|
3
3
|
omlish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
omlish/argparse.py,sha256=Dc73G8lyoQBLvXhMYUbzQUh4SJu_OTvKUXjSUxq_ang,7499
|
5
5
|
omlish/c3.py,sha256=4vogWgwPb8TbNS2KkZxpoWbwjj7MuHG2lQG-hdtkvjI,8062
|
@@ -8,14 +8,14 @@ omlish/check.py,sha256=rZFEn6IHiMq4KGCYxlUGcUCJP12pPPUs_-AG0aouPM8,10540
|
|
8
8
|
omlish/datetimes.py,sha256=HajeM1kBvwlTa-uR1TTZHmZ3zTPnnUr1uGGQhiO1XQ0,2152
|
9
9
|
omlish/defs.py,sha256=T3bq_7h_tO3nDB5RAFBn7DkdeQgqheXzkFColbOHZko,4890
|
10
10
|
omlish/dynamic.py,sha256=35C_cCX_Vq2HrHzGk5T-zbrMvmUdiIiwDzDNixczoDo,6541
|
11
|
-
omlish/fnpairs.py,sha256=
|
11
|
+
omlish/fnpairs.py,sha256=wHm1AUt-bwDCGnWrKrE2ppJav5OBm39lTyeHGaMTLBo,10885
|
12
12
|
omlish/fnpipes.py,sha256=AJkgz9nvRRm7oqw7ZgYyz21klu276LWi54oYCLg-vOg,2196
|
13
13
|
omlish/genmachine.py,sha256=RlU-y_dt2nRdvoo7Z3HsUELlBn3KuyI4qUnqLVbChRI,2450
|
14
14
|
omlish/iterators.py,sha256=GGLC7RIT86uXMjhIIIqnff_Iu5SI_b9rXYywYGFyzmo,7292
|
15
15
|
omlish/libc.py,sha256=8r7Ejyhttk9ruCfBkxNTrlzir5WPbDE2vmY7VPlceMA,15362
|
16
16
|
omlish/matchfns.py,sha256=I1IlQGfEyk_AcFSy6ulVS3utC-uwyZM2YfUXYHc9Bw0,6152
|
17
17
|
omlish/multiprocessing.py,sha256=QZT4C7I-uThCAjaEY3xgUYb-5GagUlnE4etN01LDyU4,5186
|
18
|
-
omlish/os.py,sha256=
|
18
|
+
omlish/os.py,sha256=5nJ-a9JKSMoaZVZ1eOa5BAbfL7o7CF7ue_PyJwufnwY,1460
|
19
19
|
omlish/runmodule.py,sha256=PWvuAaJ9wQQn6bx9ftEL3_d04DyotNn8dR_twm2pgw0,700
|
20
20
|
omlish/sync.py,sha256=AqwIfIuCMVHLwlJUa7dmaSjfA4sM5AYPCD5-nsz3XVQ,1516
|
21
21
|
omlish/term.py,sha256=NEmxqAhicyInGtmFamZAizI2xdu819MzFYPEp0Fx97M,6111
|
@@ -93,7 +93,7 @@ omlish/bootstrap/diag.py,sha256=LADLhusbJ1tKxVD8-gmia1HShX1VeszRO1OApIQhSpI,5507
|
|
93
93
|
omlish/bootstrap/harness.py,sha256=VW8YP-yENGyXIuJ8GL_xintArF13nafwpz-iAghPt34,1967
|
94
94
|
omlish/bootstrap/main.py,sha256=yZhOHDDlj4xB5a89dRdT8z58FsqqnpoBg1-tvY2CJe4,5903
|
95
95
|
omlish/bootstrap/marshal.py,sha256=ZxdAeMNd2qXRZ1HUK89HmEhz8tqlS9OduW34QBscKw0,516
|
96
|
-
omlish/bootstrap/sys.py,sha256=
|
96
|
+
omlish/bootstrap/sys.py,sha256=iLHUNIuIPv-k-Mc6aHj5sSET78olCVt7t0HquFDO4iQ,8762
|
97
97
|
omlish/collections/__init__.py,sha256=tGUzvS_ZjiqALsLRy7JX3h4KZRQX2CmtdAfTRD7UwMk,1677
|
98
98
|
omlish/collections/_abc.py,sha256=sP7BpTVhx6s6C59mTFeosBi4rHOWC6tbFBYbxdZmvh0,2365
|
99
99
|
omlish/collections/_io_abc.py,sha256=Cxs8KB1B_69rxpUYxI-MTsilAmNooJJn3w07DKqYKkE,1255
|
@@ -197,7 +197,7 @@ omlish/formats/json/backends/std.py,sha256=PM00Kh9ZR2XzollHMEvdo35Eml1N-zFfRW-LO
|
|
197
197
|
omlish/formats/json/backends/ujson.py,sha256=BNJCU4kluGHdqTUKLJEuHhE2m2TmqR7HEN289S0Eokg,2278
|
198
198
|
omlish/formats/json/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
199
199
|
omlish/formats/json/cli/__main__.py,sha256=1wxxKZVkj_u7HCcewwMIbGuZj_Wph95yrUbm474Op9M,188
|
200
|
-
omlish/formats/json/cli/cli.py,sha256=
|
200
|
+
omlish/formats/json/cli/cli.py,sha256=Ka-S-_L79HjaqbIi1SbGDywbYtEtoo673_DIG9m14jM,6027
|
201
201
|
omlish/formats/json/cli/formats.py,sha256=tqEZKby4HeafGcaUs-m8B-2ZV12dRo40rzL-V99cp00,1714
|
202
202
|
omlish/formats/json/stream/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
203
203
|
omlish/formats/json/stream/build.py,sha256=6deXBxTx1toFAPShz2Jo5OiXxH5Y4ppG8gDPRFoUgjA,2461
|
@@ -296,6 +296,7 @@ omlish/lite/io.py,sha256=lcpI1cS_Kn90tvYMg8ZWkSlYloS4RFqXCk-rKyclhdg,3148
|
|
296
296
|
omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
|
297
297
|
omlish/lite/logs.py,sha256=vkFkSX0Izb2P-NNMqqNLSec0BzeLOtHoQWgdXwQuDPU,6007
|
298
298
|
omlish/lite/marshal.py,sha256=kZtfIiFfmxEi8ZKne3fT0R8g8kLmJ-Q5nq4kOvwhiqk,8656
|
299
|
+
omlish/lite/pidfile.py,sha256=ymcr6JhEt33caZMsay_auQI0Ok-OTc6qpn49Zena5KQ,1723
|
299
300
|
omlish/lite/reflect.py,sha256=9QYJwdINraq1JNMEgvoqeSlVvRRgOXpxAkpgX8EgRXc,1307
|
300
301
|
omlish/lite/runtime.py,sha256=VUhmNQvwf8QzkWSKj4Q0ReieJA_PzHaJNRBivfTseow,452
|
301
302
|
omlish/lite/secrets.py,sha256=3Mz3V2jf__XU9qNHcH56sBSw95L3U2UPL24bjvobG0c,816
|
@@ -456,9 +457,9 @@ omlish/text/delimit.py,sha256=ubPXcXQmtbOVrUsNh5gH1mDq5H-n1y2R4cPL5_DQf68,4928
|
|
456
457
|
omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,3296
|
457
458
|
omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
|
458
459
|
omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
|
459
|
-
omlish-0.0.0.
|
460
|
-
omlish-0.0.0.
|
461
|
-
omlish-0.0.0.
|
462
|
-
omlish-0.0.0.
|
463
|
-
omlish-0.0.0.
|
464
|
-
omlish-0.0.0.
|
460
|
+
omlish-0.0.0.dev90.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
461
|
+
omlish-0.0.0.dev90.dist-info/METADATA,sha256=uCP2bxca0LjGBfKIwCeIh1WdZI5H-s5zLynGvdIgQXk,3987
|
462
|
+
omlish-0.0.0.dev90.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
463
|
+
omlish-0.0.0.dev90.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
464
|
+
omlish-0.0.0.dev90.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
465
|
+
omlish-0.0.0.dev90.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|