omlish 0.0.0.dev6__py3-none-any.whl → 0.0.0.dev8__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.
Files changed (108) hide show
  1. omlish/__about__.py +109 -5
  2. omlish/__init__.py +0 -8
  3. omlish/asyncs/__init__.py +0 -9
  4. omlish/asyncs/anyio.py +40 -0
  5. omlish/bootstrap.py +737 -0
  6. omlish/check.py +1 -1
  7. omlish/collections/__init__.py +4 -0
  8. omlish/collections/exceptions.py +2 -0
  9. omlish/collections/utils.py +38 -9
  10. omlish/configs/strings.py +2 -0
  11. omlish/dataclasses/__init__.py +7 -0
  12. omlish/dataclasses/impl/descriptors.py +95 -0
  13. omlish/dataclasses/impl/reflect.py +1 -1
  14. omlish/dataclasses/utils.py +23 -0
  15. omlish/{lang/datetimes.py → datetimes.py} +8 -4
  16. omlish/diag/procfs.py +1 -1
  17. omlish/diag/threads.py +131 -48
  18. omlish/docker.py +16 -1
  19. omlish/fnpairs.py +0 -4
  20. omlish/{serde → formats}/dotenv.py +3 -0
  21. omlish/{serde → formats}/yaml.py +2 -2
  22. omlish/graphs/trees.py +1 -1
  23. omlish/http/consts.py +6 -0
  24. omlish/http/sessions.py +2 -2
  25. omlish/inject/__init__.py +4 -0
  26. omlish/inject/binder.py +3 -3
  27. omlish/inject/elements.py +1 -1
  28. omlish/inject/impl/injector.py +57 -27
  29. omlish/inject/impl/origins.py +2 -0
  30. omlish/inject/origins.py +3 -0
  31. omlish/inject/utils.py +18 -0
  32. omlish/iterators.py +69 -2
  33. omlish/lang/__init__.py +16 -7
  34. omlish/lang/classes/restrict.py +10 -0
  35. omlish/lang/contextmanagers.py +1 -1
  36. omlish/lang/descriptors.py +3 -3
  37. omlish/lang/imports.py +67 -0
  38. omlish/lang/iterables.py +40 -0
  39. omlish/lang/maybes.py +3 -0
  40. omlish/lang/objects.py +38 -0
  41. omlish/lang/strings.py +25 -0
  42. omlish/lang/sys.py +9 -0
  43. omlish/lang/typing.py +37 -0
  44. omlish/lite/__init__.py +1 -0
  45. omlish/lite/cached.py +18 -0
  46. omlish/lite/check.py +29 -0
  47. omlish/lite/contextmanagers.py +18 -0
  48. omlish/lite/json.py +30 -0
  49. omlish/lite/logs.py +121 -0
  50. omlish/lite/marshal.py +318 -0
  51. omlish/lite/reflect.py +49 -0
  52. omlish/lite/runtime.py +18 -0
  53. omlish/lite/secrets.py +19 -0
  54. omlish/lite/strings.py +25 -0
  55. omlish/lite/subprocesses.py +112 -0
  56. omlish/logs/__init__.py +13 -9
  57. omlish/logs/configs.py +17 -22
  58. omlish/logs/formatters.py +3 -48
  59. omlish/marshal/__init__.py +28 -0
  60. omlish/marshal/any.py +5 -5
  61. omlish/marshal/base.py +27 -11
  62. omlish/marshal/base64.py +24 -9
  63. omlish/marshal/dataclasses.py +34 -28
  64. omlish/marshal/datetimes.py +74 -18
  65. omlish/marshal/enums.py +14 -8
  66. omlish/marshal/exceptions.py +11 -1
  67. omlish/marshal/factories.py +59 -74
  68. omlish/marshal/forbidden.py +35 -0
  69. omlish/marshal/global_.py +11 -4
  70. omlish/marshal/iterables.py +21 -24
  71. omlish/marshal/mappings.py +23 -26
  72. omlish/marshal/numbers.py +51 -0
  73. omlish/marshal/optionals.py +11 -12
  74. omlish/marshal/polymorphism.py +86 -21
  75. omlish/marshal/primitives.py +4 -5
  76. omlish/marshal/standard.py +13 -8
  77. omlish/marshal/uuids.py +4 -5
  78. omlish/matchfns.py +218 -0
  79. omlish/os.py +64 -0
  80. omlish/reflect/__init__.py +39 -0
  81. omlish/reflect/isinstance.py +38 -0
  82. omlish/reflect/ops.py +84 -0
  83. omlish/reflect/subst.py +110 -0
  84. omlish/reflect/types.py +275 -0
  85. omlish/secrets/__init__.py +18 -2
  86. omlish/secrets/crypto.py +132 -0
  87. omlish/secrets/marshal.py +36 -7
  88. omlish/secrets/openssl.py +207 -0
  89. omlish/secrets/secrets.py +260 -8
  90. omlish/secrets/subprocesses.py +42 -0
  91. omlish/sql/dbs.py +6 -5
  92. omlish/sql/exprs.py +12 -0
  93. omlish/sql/secrets.py +10 -0
  94. omlish/term.py +1 -1
  95. omlish/testing/pytest/plugins/switches.py +54 -19
  96. omlish/text/glyphsplit.py +5 -0
  97. omlish-0.0.0.dev8.dist-info/METADATA +50 -0
  98. {omlish-0.0.0.dev6.dist-info → omlish-0.0.0.dev8.dist-info}/RECORD +105 -78
  99. {omlish-0.0.0.dev6.dist-info → omlish-0.0.0.dev8.dist-info}/WHEEL +1 -1
  100. omlish/logs/filters.py +0 -11
  101. omlish/reflect.py +0 -470
  102. omlish-0.0.0.dev6.dist-info/METADATA +0 -34
  103. /omlish/{asyncs/futures.py → concurrent.py} +0 -0
  104. /omlish/{serde → formats}/__init__.py +0 -0
  105. /omlish/{serde → formats}/json.py +0 -0
  106. /omlish/{serde → formats}/props.py +0 -0
  107. {omlish-0.0.0.dev6.dist-info → omlish-0.0.0.dev8.dist-info}/LICENSE +0 -0
  108. {omlish-0.0.0.dev6.dist-info → omlish-0.0.0.dev8.dist-info}/top_level.txt +0 -0
omlish/__about__.py CHANGED
@@ -1,6 +1,110 @@
1
- __author__ = 'wrmsr'
2
- __url__ = 'https://github.com/wrmsr/omlish'
3
- __license__ = 'BSD-3-Clause'
4
- __requires_python__ = '>=3.12'
1
+ __version__ = '0.0.0.dev8'
5
2
 
6
- __version__ = '0.0.0.dev6'
3
+
4
+ #
5
+
6
+
7
+ class ProjectBase:
8
+ name: str | None = None
9
+ authors = [{'name': 'wrmsr'}]
10
+ urls = {'source': 'https://github.com/wrmsr/omlish'}
11
+ license = {'text': 'BSD-3-Clause'}
12
+ requires_python = '>=3.12'
13
+
14
+ version = __version__
15
+
16
+ classifiers = [
17
+ 'License :: OSI Approved :: BSD License',
18
+ 'Development Status :: 2 - Pre-Alpha',
19
+ 'Intended Audience :: Developers',
20
+
21
+ 'Operating System :: OS Independent',
22
+ 'Operating System :: POSIX',
23
+ ]
24
+
25
+
26
+ class Project(ProjectBase):
27
+ name = 'omlish'
28
+ description = 'omlish'
29
+
30
+ optional_dependencies = {
31
+ 'async': [
32
+ 'anyio >= 4.4',
33
+ 'sniffio >= 1.3',
34
+
35
+ 'greenlet >= 3; python_version < "3.13"',
36
+
37
+ 'trio >= 0.26',
38
+ 'trio-asyncio >= 0.15; python_version < "3.13"',
39
+ ],
40
+
41
+ 'compression': [
42
+ 'lz4 >= 4',
43
+ 'python-snappy >= 0.7; python_version < "3.13"',
44
+ 'zstd >= 1.5',
45
+ ],
46
+
47
+ 'formats': [
48
+ 'orjson > 3.10',
49
+ 'cloudpickle >= 3',
50
+ 'pyyaml >= 5',
51
+ ],
52
+
53
+ 'http': [
54
+ 'httpx[http2] >= 0.27',
55
+ ],
56
+
57
+ 'misc': [
58
+ 'jinja2 >= 3.1',
59
+ 'psutil >= 6',
60
+ 'wrapt >= 1.14',
61
+ ],
62
+
63
+ 'secrets': [
64
+ 'cryptography >= 43',
65
+ ],
66
+
67
+ 'sql': [
68
+ 'sqlalchemy >= 2; python_version >= "3.13"',
69
+ 'sqlalchemy[asyncio] >= 2; python_version < "3.13"',
70
+
71
+ 'pg8000 >= 1.31',
72
+ 'pymysql >= 1.1',
73
+
74
+ 'aiomysql >= 0.2',
75
+ 'aiosqlite >= 0.20',
76
+ 'asyncpg >= 0.29; python_version < "3.13"',
77
+ ],
78
+
79
+ 'sqlx': [
80
+ "sqlean.py >= 3.45; python_version < '3.13'",
81
+
82
+ 'duckdb >= 1',
83
+ ],
84
+
85
+ 'testing': [
86
+ 'pytest >= 8',
87
+ ],
88
+ }
89
+
90
+
91
+ #
92
+
93
+
94
+ class SetuptoolsBase:
95
+ manifest_in = [
96
+ 'global-exclude **/conftest.py',
97
+ ]
98
+
99
+ include_package_data = False
100
+
101
+ find_packages = {
102
+ 'exclude': ['*.tests', '*.tests.*'],
103
+ }
104
+
105
+
106
+ class Setuptools(SetuptoolsBase):
107
+ find_packages = {
108
+ 'include': [Project.name, f'{Project.name}.*'],
109
+ 'exclude': [*SetuptoolsBase.find_packages['exclude']],
110
+ }
omlish/__init__.py CHANGED
@@ -1,8 +0,0 @@
1
- import sys as _sys
2
-
3
-
4
- REQUIRED_PYTHON_VERSION = (3, 12)
5
-
6
-
7
- if _sys.version_info < REQUIRED_PYTHON_VERSION:
8
- raise RuntimeError(f'Python version {_sys.version_info=} < {REQUIRED_PYTHON_VERSION}')
omlish/asyncs/__init__.py CHANGED
@@ -33,12 +33,3 @@ from .flavors import ( # noqa
33
33
  mark_trio,
34
34
  with_adapter_loop,
35
35
  )
36
-
37
- from .futures import ( # noqa
38
- FutureError,
39
- FutureTimeoutError,
40
- ImmediateExecutor,
41
- new_thread_or_immediate_executor,
42
- wait_dependent_futures,
43
- wait_futures,
44
- )
omlish/asyncs/anyio.py CHANGED
@@ -13,9 +13,20 @@ lookit:
13
13
  - https://github.com/M-o-a-T/aevent
14
14
  - https://github.com/florimondmanca/aiometer
15
15
  - https://github.com/sanitizers/octomachinery/blob/b36c3d3d49da813ac46e361424132955a4e99ac8/octomachinery/utils/asynctools.py
16
+
17
+ ==
18
+
19
+ async def killer(shutdown: anyio.Event, sleep_s: float) -> None:
20
+ log.warning('Killing in %d seconds', sleep_s)
21
+ await anyio.sleep(sleep_s)
22
+ log.warning('Killing')
23
+ shutdown.set()
24
+
16
25
  """ # noqa
26
+ import signal
17
27
  import typing as ta
18
28
 
29
+ import anyio.abc
19
30
  import anyio.streams.memory
20
31
  import anyio.streams.stapled
21
32
  import sniffio
@@ -214,3 +225,32 @@ class LazyFn(ta.Generic[T]):
214
225
  self._v = lang.just(await self._fn())
215
226
  await self._once.do(do)
216
227
  return self._v.must()
228
+
229
+
230
+ ##
231
+
232
+
233
+ async def install_shutdown_signal_handler(
234
+ tg: anyio.abc.TaskGroup,
235
+ event: anyio.Event | None = None,
236
+ *,
237
+ signals: ta.Iterable[int] = (signal.SIGINT, signal.SIGTERM),
238
+ echo: bool = False,
239
+ ) -> ta.Callable[..., ta.Awaitable[None]] | None:
240
+ if event is None:
241
+ event = anyio.Event()
242
+
243
+ async def _handler(*, task_status=anyio.TASK_STATUS_IGNORED):
244
+ with anyio.open_signal_receiver(*signals) as it: # type: ignore
245
+ task_status.started()
246
+ async for signum in it:
247
+ if echo:
248
+ if signum == signal.SIGINT:
249
+ print('Ctrl+C pressed!')
250
+ else:
251
+ print('Terminated!')
252
+ event.set()
253
+ return
254
+
255
+ await tg.start(_handler)
256
+ return event.wait