omlish 0.0.0.dev149__py3-none-any.whl → 0.0.0.dev151__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.dev149'
2
- __revision__ = '78e7c7e35dc2bc806db7fd199c1ce42b0f41cbe8'
1
+ __version__ = '0.0.0.dev151'
2
+ __revision__ = '7d978888ef2b04964976a01388376b919ec8bafe'
3
3
 
4
4
 
5
5
  #
omlish/argparse/cli.py CHANGED
@@ -11,16 +11,15 @@ import functools
11
11
  import sys
12
12
  import typing as ta
13
13
 
14
- from ..lite.check import check_arg
15
- from ..lite.check import check_isinstance
16
- from ..lite.check import check_not_empty
17
- from ..lite.check import check_not_in
18
- from ..lite.check import check_not_isinstance
14
+ from ..lite.check import check
19
15
 
20
16
 
21
17
  T = ta.TypeVar('T')
22
18
 
23
19
 
20
+ ArgparseCommandFn = ta.Callable[[], ta.Optional[int]] # ta.TypeAlias
21
+
22
+
24
23
  ##
25
24
 
26
25
 
@@ -43,9 +42,6 @@ def argparse_arg(*args, **kwargs) -> ArgparseArg:
43
42
  #
44
43
 
45
44
 
46
- ArgparseCommandFn = ta.Callable[[], ta.Optional[int]] # ta.TypeAlias
47
-
48
-
49
45
  @dc.dataclass(eq=False)
50
46
  class ArgparseCommand:
51
47
  name: str
@@ -60,18 +56,18 @@ class ArgparseCommand:
60
56
 
61
57
  def __post_init__(self) -> None:
62
58
  def check_name(s: str) -> None:
63
- check_isinstance(s, str)
64
- check_not_in('_', s)
65
- check_not_empty(s)
59
+ check.isinstance(s, str)
60
+ check.not_in('_', s)
61
+ check.not_empty(s)
66
62
  check_name(self.name)
67
- check_not_isinstance(self.aliases, str)
63
+ check.not_isinstance(self.aliases, str)
68
64
  for a in self.aliases or []:
69
65
  check_name(a)
70
66
 
71
- check_arg(callable(self.fn))
72
- check_arg(all(isinstance(a, ArgparseArg) for a in self.args))
73
- check_isinstance(self.parent, (ArgparseCommand, type(None)))
74
- check_isinstance(self.accepts_unknown, bool)
67
+ check.arg(callable(self.fn))
68
+ check.arg(all(isinstance(a, ArgparseArg) for a in self.args))
69
+ check.isinstance(self.parent, (ArgparseCommand, type(None)))
70
+ check.isinstance(self.accepts_unknown, bool)
75
71
 
76
72
  functools.update_wrapper(self, self.fn)
77
73
 
@@ -92,10 +88,10 @@ def argparse_command(
92
88
  accepts_unknown: bool = False,
93
89
  ) -> ta.Any: # ta.Callable[[ArgparseCommandFn], ArgparseCommand]: # FIXME
94
90
  for arg in args:
95
- check_isinstance(arg, ArgparseArg)
96
- check_isinstance(name, (str, type(None)))
97
- check_isinstance(parent, (ArgparseCommand, type(None)))
98
- check_not_isinstance(aliases, str)
91
+ check.isinstance(arg, ArgparseArg)
92
+ check.isinstance(name, (str, type(None)))
93
+ check.isinstance(parent, (ArgparseCommand, type(None)))
94
+ check.not_isinstance(aliases, str)
99
95
 
100
96
  def inner(fn):
101
97
  return ArgparseCommand(
@@ -151,7 +147,7 @@ class ArgparseCli:
151
147
  bseen = set() # type: ignore
152
148
  for k, v in bns.items():
153
149
  if isinstance(v, (ArgparseCommand, ArgparseArg)):
154
- check_not_in(v, bseen)
150
+ check.not_in(v, bseen)
155
151
  bseen.add(v)
156
152
  objs[k] = v
157
153
  elif k in objs:
@@ -163,7 +159,7 @@ class ArgparseCli:
163
159
  }), globalns=ns.get('__globals__', {}))
164
160
 
165
161
  if '_parser' in ns:
166
- parser = check_isinstance(ns['_parser'], argparse.ArgumentParser)
162
+ parser = check.isinstance(ns['_parser'], argparse.ArgumentParser)
167
163
  else:
168
164
  parser = argparse.ArgumentParser()
169
165
  setattr(cls, '_parser', parser)
@@ -179,7 +175,7 @@ class ArgparseCli:
179
175
  if (
180
176
  len(arg.args) == 1 and
181
177
  isinstance(arg.args[0], str) and
182
- not (n := check_isinstance(arg.args[0], str)).startswith('-') and
178
+ not (n := check.isinstance(arg.args[0], str)).startswith('-') and
183
179
  'metavar' not in arg.kwargs
184
180
  ):
185
181
  cparser.add_argument(
omlish/check.py CHANGED
@@ -1,20 +1,13 @@
1
- """
2
- TODO:
3
- - def maybe(v: lang.Maybe[T])
4
- - patch / override lite.check ?
5
- - checker interface?
6
- """
7
- import collections
8
- import threading
9
1
  import typing as ta
10
2
 
3
+ from .lite.check import CheckArgsRenderer as ArgsRenderer # noqa
4
+ from .lite.check import CheckExceptionFactory as ExceptionFactory # noqa
5
+ from .lite.check import CheckLateConfigureFn as LateConfigureFn # noqa
6
+ from .lite.check import CheckMessage as Message # noqa
7
+ from .lite.check import CheckOnRaiseFn as OnRaiseFn # noqa
8
+ from .lite.check import Checks
9
+ from .lite.check import check
11
10
 
12
- T = ta.TypeVar('T')
13
- SizedT = ta.TypeVar('SizedT', bound=ta.Sized)
14
-
15
- Message: ta.TypeAlias = str | ta.Callable[..., str | None] | None
16
-
17
- _NONE_TYPE = type(None)
18
11
 
19
12
  _isinstance = isinstance
20
13
  _issubclass = issubclass
@@ -24,43 +17,21 @@ _callable = callable
24
17
  ##
25
18
 
26
19
 
27
- _CONFIG_LOCK = threading.RLock()
28
-
29
-
30
- OnRaiseFn: ta.TypeAlias = ta.Callable[[Exception], None]
31
- _ON_RAISE: ta.Sequence[OnRaiseFn] = []
32
-
33
-
34
- def register_on_raise(fn: OnRaiseFn) -> None:
35
- global _ON_RAISE
36
- with _CONFIG_LOCK:
37
- _ON_RAISE = [*_ON_RAISE, fn]
38
-
39
-
40
- def unregister_on_raise(fn: OnRaiseFn) -> None:
41
- global _ON_RAISE
42
- with _CONFIG_LOCK:
43
- _ON_RAISE = [e for e in _ON_RAISE if e != fn]
20
+ register_on_raise = check.register_on_raise
21
+ unregister_on_raise = check.unregister_on_raise
44
22
 
45
23
 
46
- #
47
-
48
-
49
- _ARGS_RENDERER: ta.Callable[..., str | None] | None = None
50
-
24
+ ##
51
25
 
52
- def _try_enable_args_rendering() -> bool:
53
- global _ARGS_RENDERER
54
- if _ARGS_RENDERER is not None:
55
- return True
56
26
 
27
+ def _try_get_args_rendering() -> ArgsRenderer | None:
57
28
  try:
58
29
  from .diag.asts import ArgsRenderer
59
30
 
60
31
  ArgsRenderer.smoketest()
61
32
 
62
33
  except Exception: # noqa
63
- return False
34
+ return None
64
35
 
65
36
  def _real_render_args(fmt: str, *args: ta.Any) -> str | None:
66
37
  ra = ArgsRenderer(back=3).render_args(*args)
@@ -69,445 +40,59 @@ def _try_enable_args_rendering() -> bool:
69
40
 
70
41
  return fmt % tuple(str(a) for a in ra)
71
42
 
72
- _ARGS_RENDERER = _real_render_args
73
- return True
74
-
75
-
76
- _TRIED_ENABLED_ARGS_RENDERING: bool | None = None
77
-
78
-
79
- def try_enable_args_rendering() -> bool:
80
- global _TRIED_ENABLED_ARGS_RENDERING
81
- if _TRIED_ENABLED_ARGS_RENDERING is not None:
82
- return _TRIED_ENABLED_ARGS_RENDERING
83
-
84
- with _CONFIG_LOCK:
85
- if _TRIED_ENABLED_ARGS_RENDERING is None:
86
- _TRIED_ENABLED_ARGS_RENDERING = _try_enable_args_rendering()
87
-
88
- return _TRIED_ENABLED_ARGS_RENDERING
89
-
90
-
91
- ##
92
-
93
-
94
- def _default_exception_factory(exc_cls: type[Exception], *args, **kwargs) -> Exception:
95
- return exc_cls(*args, **kwargs) # noqa
96
-
97
-
98
- _EXCEPTION_FACTORY = _default_exception_factory
99
-
100
-
101
- class _ArgsKwargs:
102
- def __init__(self, *args, **kwargs):
103
- self.args = args
104
- self.kwargs = kwargs
105
-
106
-
107
- def _raise(
108
- exception_type: type[Exception],
109
- default_message: str,
110
- message: Message,
111
- ak: _ArgsKwargs = _ArgsKwargs(),
112
- *,
113
- render_fmt: str | None = None,
114
- ) -> ta.NoReturn:
115
- exc_args = ()
116
- if _callable(message):
117
- message = ta.cast(ta.Callable, message)(*ak.args, **ak.kwargs)
118
- if _isinstance(message, tuple):
119
- message, *exc_args = message # type: ignore
120
-
121
- if message is None:
122
- message = default_message
123
-
124
- try_enable_args_rendering()
125
-
126
- if render_fmt is not None and _ARGS_RENDERER is not None:
127
- rendered_args = _ARGS_RENDERER(render_fmt, *ak.args)
128
- if rendered_args is not None:
129
- message = f'{message} : {rendered_args}'
130
-
131
- exc = _EXCEPTION_FACTORY(
132
- exception_type,
133
- message,
134
- *exc_args,
135
- *ak.args,
136
- **ak.kwargs,
137
- )
138
-
139
- for fn in _ON_RAISE:
140
- fn(exc)
141
-
142
- raise exc
143
-
144
-
145
- ##
146
-
147
-
148
- def _unpack_isinstance_spec(spec: ta.Any) -> tuple:
149
- if _isinstance(spec, type):
150
- return (spec,)
151
- if not _isinstance(spec, tuple):
152
- spec = (spec,)
153
- if None in spec:
154
- spec = tuple(filter(None, spec)) + (_NONE_TYPE,) # noqa
155
- if ta.Any in spec:
156
- spec = (object,)
157
- return spec
158
-
159
-
160
- def isinstance(v: ta.Any, spec: type[T] | tuple, msg: Message = None) -> T: # noqa
161
- if not _isinstance(v, _unpack_isinstance_spec(spec)):
162
- _raise(
163
- TypeError,
164
- 'Must be instance',
165
- msg,
166
- _ArgsKwargs(v, spec),
167
- render_fmt='not isinstance(%s, %s)',
168
- )
169
-
170
- return v
171
-
172
-
173
- def of_isinstance(spec: type[T] | tuple, msg: Message = None) -> ta.Callable[[ta.Any], T]:
174
- def inner(v):
175
- return isinstance(v, _unpack_isinstance_spec(spec), msg)
176
-
177
- return inner
178
-
179
-
180
- def cast(v: ta.Any, cls: type[T], msg: Message = None) -> T: # noqa
181
- if not _isinstance(v, cls):
182
- _raise(
183
- TypeError,
184
- 'Must be instance',
185
- msg,
186
- _ArgsKwargs(v, cls),
187
- )
188
-
189
- return v
190
-
191
-
192
- def of_cast(cls: type[T], msg: Message = None) -> ta.Callable[[T], T]:
193
- def inner(v):
194
- return isinstance(v, cls, msg)
195
-
196
- return inner
197
-
198
-
199
- def not_isinstance(v: T, spec: ta.Any, msg: Message = None) -> T: # noqa
200
- if _isinstance(v, _unpack_isinstance_spec(spec)):
201
- _raise(
202
- TypeError,
203
- 'Must not be instance',
204
- msg,
205
- _ArgsKwargs(v, spec),
206
- render_fmt='isinstance(%s, %s)',
207
- )
208
-
209
- return v
210
-
43
+ return _real_render_args
211
44
 
212
- def of_not_isinstance(spec: ta.Any, msg: Message = None) -> ta.Callable[[T], T]:
213
- def inner(v):
214
- return not_isinstance(v, _unpack_isinstance_spec(spec), msg)
215
45
 
216
- return inner
46
+ def _try_enable_args_rendering(c: Checks) -> None:
47
+ if (rf := _try_get_args_rendering()) is not None:
48
+ c.set_args_renderer(rf)
217
49
 
218
50
 
219
- ##
220
-
221
-
222
- def issubclass(v: type[T], spec: ta.Any, msg: Message = None) -> type[T]: # noqa
223
- if not _issubclass(v, spec):
224
- _raise(
225
- TypeError,
226
- 'Must be subclass',
227
- msg,
228
- _ArgsKwargs(v, spec),
229
- render_fmt='not issubclass(%s, %s)',
230
- )
231
-
232
- return v
233
-
234
-
235
- def not_issubclass(v: type[T], spec: ta.Any, msg: Message = None) -> type[T]: # noqa
236
- if _issubclass(v, spec):
237
- _raise(
238
- TypeError,
239
- 'Must not be subclass',
240
- msg,
241
- _ArgsKwargs(v, spec),
242
- render_fmt='issubclass(%s, %s)',
243
- )
244
-
245
- return v
246
-
247
-
248
- ##
249
-
250
-
251
- def in_(v: T, c: ta.Container[T], msg: Message = None) -> T:
252
- if v not in c:
253
- _raise(
254
- ValueError,
255
- 'Must be in',
256
- msg,
257
- _ArgsKwargs(v, c),
258
- render_fmt='%s not in %s',
259
- )
260
-
261
- return v
262
-
263
-
264
- def not_in(v: T, c: ta.Container[T], msg: Message = None) -> T:
265
- if v in c:
266
- _raise(
267
- ValueError,
268
- 'Must not be in',
269
- msg,
270
- _ArgsKwargs(v, c),
271
- render_fmt='%s in %s',
272
- )
273
-
274
- return v
275
-
276
-
277
- def empty(v: SizedT, msg: Message = None) -> SizedT:
278
- if len(v) != 0:
279
- _raise(
280
- ValueError,
281
- 'Must be empty',
282
- msg,
283
- _ArgsKwargs(v),
284
- render_fmt='%s',
285
- )
286
-
287
- return v
288
-
289
-
290
- def iterempty(v: ta.Iterable[T], msg: Message = None) -> ta.Iterable[T]:
291
- it = iter(v)
292
- try:
293
- next(it)
294
- except StopIteration:
295
- pass
296
- else:
297
- _raise(
298
- ValueError,
299
- 'Must be empty',
300
- msg,
301
- _ArgsKwargs(v),
302
- render_fmt='%s',
303
- )
304
-
305
- return v
306
-
307
-
308
- def not_empty(v: SizedT, msg: Message = None) -> SizedT:
309
- if len(v) == 0:
310
- _raise(
311
- ValueError,
312
- 'Must not be empty',
313
- msg,
314
- _ArgsKwargs(v),
315
- render_fmt='%s',
316
- )
317
-
318
- return v
319
-
320
-
321
- def unique(it: ta.Iterable[T], msg: Message = None) -> ta.Iterable[T]:
322
- dupes = [e for e, c in collections.Counter(it).items() if c > 1]
323
- if dupes:
324
- _raise(
325
- ValueError,
326
- 'Must be unique',
327
- msg,
328
- _ArgsKwargs(it, dupes),
329
- )
330
-
331
- return it
332
-
333
-
334
- def single(obj: ta.Iterable[T], message: Message = None) -> T:
335
- try:
336
- [value] = obj
337
- except ValueError:
338
- _raise(
339
- ValueError,
340
- 'Must be single',
341
- message,
342
- _ArgsKwargs(obj),
343
- render_fmt='%s',
344
- )
345
-
346
- return value
347
-
348
-
349
- def opt_single(obj: ta.Iterable[T], message: Message = None) -> T | None:
350
- it = iter(obj)
351
- try:
352
- value = next(it)
353
- except StopIteration:
354
- return None
355
-
356
- try:
357
- next(it)
358
- except StopIteration:
359
- return value # noqa
360
-
361
- _raise(
362
- ValueError,
363
- 'Must be empty or single',
364
- message,
365
- _ArgsKwargs(obj),
366
- render_fmt='%s',
367
- )
51
+ check.register_late_configure(_try_enable_args_rendering)
368
52
 
369
53
 
370
54
  ##
371
55
 
372
56
 
373
- def none(v: ta.Any, msg: Message = None) -> None:
374
- if v is not None:
375
- _raise(
376
- ValueError,
377
- 'Must be None',
378
- msg,
379
- _ArgsKwargs(v),
380
- render_fmt='%s',
381
- )
382
-
383
-
384
- def not_none(v: T | None, msg: Message = None) -> T:
385
- if v is None:
386
- _raise(
387
- ValueError,
388
- 'Must not be None',
389
- msg,
390
- _ArgsKwargs(v),
391
- render_fmt='%s',
392
- )
393
-
394
- return v
395
-
396
-
397
- ##
398
-
399
-
400
- def equal(v: T, o: ta.Any, msg: Message = None) -> T:
401
- if o != v:
402
- _raise(
403
- ValueError,
404
- 'Must be equal',
405
- msg,
406
- _ArgsKwargs(v, o),
407
- render_fmt='%s != %s',
408
- )
409
-
410
- return v
411
-
412
-
413
- def is_(v: T, o: ta.Any, msg: Message = None) -> T:
414
- if o is not v:
415
- _raise(
416
- ValueError,
417
- 'Must be the same',
418
- msg,
419
- _ArgsKwargs(v, o),
420
- render_fmt='%s is not %s',
421
- )
422
-
423
- return v
424
-
425
-
426
- def is_not(v: T, o: ta.Any, msg: Message = None) -> T:
427
- if o is v:
428
- _raise(
429
- ValueError,
430
- 'Must not be the same',
431
- msg,
432
- _ArgsKwargs(v, o),
433
- render_fmt='%s is %s',
434
- )
435
-
436
- return v
437
-
438
-
439
- def callable(v: T, msg: Message = None) -> T: # noqa
440
- if not _callable(v):
441
- _raise(
442
- TypeError,
443
- 'Must be callable',
444
- msg,
445
- _ArgsKwargs(v),
446
- render_fmt='%s',
447
- )
448
-
449
- return v # type: ignore
450
-
451
-
452
- def non_empty_str(v: str | None, msg: Message = None) -> str:
453
- if not _isinstance(v, str) or not v:
454
- _raise(
455
- ValueError,
456
- 'Must be non-empty str',
457
- msg,
458
- _ArgsKwargs(v),
459
- render_fmt='%s',
460
- )
461
-
462
- return v
57
+ isinstance = check.isinstance # noqa
58
+ of_isinstance = check.of_isinstance
59
+ cast = check.cast
60
+ of_cast = check.of_cast
61
+ not_isinstance = check.not_isinstance
62
+ of_not_isinstance = check.of_not_isinstance
463
63
 
64
+ #
464
65
 
465
- def replacing(expected: ta.Any, old: ta.Any, new: T, msg: Message = None) -> T:
466
- if old != expected:
467
- _raise(
468
- ValueError,
469
- 'Must be replacing',
470
- msg,
471
- _ArgsKwargs(expected, old, new),
472
- render_fmt='%s -> %s -> %s',
473
- )
66
+ issubclass = check.issubclass # noqa
67
+ not_issubclass = check.not_issubclass
474
68
 
475
- return new
69
+ #
476
70
 
71
+ in_ = check.in_
72
+ not_in = check.not_in
73
+ empty = check.empty
74
+ iterempty = check.iterempty
75
+ not_empty = check.not_empty
76
+ unique = check.unique
77
+ single = check.single
78
+ opt_single = check.opt_single
477
79
 
478
- def replacing_none(old: ta.Any, new: T, msg: Message = None) -> T:
479
- if old is not None:
480
- _raise(
481
- ValueError,
482
- 'Must be replacing None',
483
- msg,
484
- _ArgsKwargs(old, new),
485
- render_fmt='%s -> %s',
486
- )
80
+ #
487
81
 
488
- return new
82
+ none = check.none
83
+ not_none = check.not_none
489
84
 
85
+ #
490
86
 
491
- ##
87
+ equal = check.equal
88
+ is_ = check.is_
89
+ is_not = check.is_not
90
+ callable = check.callable # noqa
91
+ non_empty_str = check.non_empty_str
92
+ replacing = check.replacing
93
+ replacing_none = check.replacing_none
492
94
 
95
+ #
493
96
 
494
- def arg(v: bool, msg: Message = None) -> None:
495
- if not v:
496
- _raise(
497
- RuntimeError,
498
- 'Argument condition not met',
499
- msg,
500
- _ArgsKwargs(v),
501
- render_fmt='%s',
502
- )
503
-
504
-
505
- def state(v: bool, msg: Message = None) -> None:
506
- if not v:
507
- _raise(
508
- RuntimeError,
509
- 'State condition not met',
510
- msg,
511
- _ArgsKwargs(v),
512
- render_fmt='%s',
513
- )
97
+ arg = check.arg
98
+ state = check.state
omlish/docker/__init__.py CHANGED
@@ -1,37 +0,0 @@
1
- from .cli import ( # noqa
2
- Inspect,
3
- Port,
4
- PsItem,
5
- cli_inspect,
6
- cli_ps,
7
- has_cli,
8
- parse_port,
9
- )
10
-
11
- from .compose import ( # noqa
12
- ComposeConfig,
13
- get_compose_port,
14
- )
15
-
16
- from .helpers import ( # noqa
17
- DOCKER_HOST_PLATFORM_KEY,
18
- get_docker_host_platform,
19
- timebomb_payload,
20
- )
21
-
22
- from .hub import ( # noqa
23
- HubRepoInfo,
24
- get_hub_repo_info,
25
- select_latest_tag,
26
- split_tag_suffix,
27
- )
28
-
29
-
30
- ##
31
-
32
-
33
- from ..lite.docker import ( # noqa
34
- DOCKER_FOR_MAC_HOSTNAME,
35
-
36
- is_likely_in_docker,
37
- )