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 CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev88'
2
- __revision__ = 'ccf0f3b0ac6cc9e9ca522c8c4a9c8e6a4151bd7b'
1
+ __version__ = '0.0.0.dev90'
2
+ __revision__ = 'ed1c5d0c10d318c251ce6e44e500d805bb6f059a'
3
3
 
4
4
 
5
5
  #
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 osu.Pidfile(self._config.path) as pf:
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
@@ -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
- parser.add_argument('--stream-buffer-size', type=int, default=0x4000)
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('-l', '--less', action='store_true')
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.stream_buffer_size)
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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev88
3
+ Version: 0.0.0.dev90
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=hTFp9tvE72BxKloIq1s1SS0LRQlIsvMtO69Sbc47rKg,1704
2
- omlish/__about__.py,sha256=_pr15t5ifEAY1adRq4S8Fp21jhhRHPNo6mJlHz7_xBo,3345
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=Sl8CMFNyDS-1JYAjSWqnT5FmUm9Lj6o7FxSRo7g4jww,10875
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=vO1sZCzAhVxo46tDFLrD52q2KuMFWQwu5MPJgSsnliI,3107
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=i6veZeE83wO0HTl9b6ykj_pEN05fqu0enoAv4sw5Ayc,8742
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=a_Ak3x8U1ulK2EkG4DQ4XbfsV_4gz5YAigv43Ah_XlY,5491
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.dev88.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
460
- omlish-0.0.0.dev88.dist-info/METADATA,sha256=_sR0eXqLj64VXjpIND0FJ_jFD56oVh9f7QXetS_XP0g,3987
461
- omlish-0.0.0.dev88.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
462
- omlish-0.0.0.dev88.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
463
- omlish-0.0.0.dev88.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
464
- omlish-0.0.0.dev88.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5