omlish 0.0.0.dev447__py3-none-any.whl → 0.0.0.dev484__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.

Potentially problematic release.


This version of omlish might be problematic. Click here for more details.

Files changed (226) hide show
  1. omlish/.omlish-manifests.json +12 -0
  2. omlish/__about__.py +15 -15
  3. omlish/argparse/all.py +17 -9
  4. omlish/argparse/cli.py +16 -3
  5. omlish/argparse/utils.py +21 -0
  6. omlish/asyncs/asyncio/rlock.py +110 -0
  7. omlish/asyncs/asyncio/sync.py +43 -0
  8. omlish/asyncs/asyncio/utils.py +2 -0
  9. omlish/asyncs/sync.py +25 -0
  10. omlish/bootstrap/_marshal.py +1 -1
  11. omlish/bootstrap/diag.py +12 -21
  12. omlish/bootstrap/main.py +2 -5
  13. omlish/bootstrap/sys.py +27 -28
  14. omlish/cexts/__init__.py +0 -0
  15. omlish/cexts/include/omlish/omlish.hh +1 -0
  16. omlish/collections/__init__.py +13 -1
  17. omlish/collections/attrregistry.py +210 -0
  18. omlish/collections/cache/impl.py +1 -0
  19. omlish/collections/identity.py +1 -0
  20. omlish/collections/mappings.py +28 -0
  21. omlish/collections/trie.py +5 -1
  22. omlish/collections/utils.py +77 -0
  23. omlish/concurrent/all.py +2 -1
  24. omlish/concurrent/futures.py +25 -0
  25. omlish/concurrent/threadlets.py +1 -1
  26. omlish/daemons/reparent.py +2 -3
  27. omlish/daemons/spawning.py +2 -3
  28. omlish/dataclasses/__init__.py +2 -0
  29. omlish/dataclasses/impl/api/classes/decorator.py +3 -0
  30. omlish/dataclasses/impl/api/classes/make.py +3 -0
  31. omlish/dataclasses/impl/concerns/repr.py +15 -2
  32. omlish/dataclasses/impl/configs.py +97 -37
  33. omlish/dataclasses/impl/generation/compilation.py +21 -19
  34. omlish/dataclasses/impl/generation/globals.py +1 -0
  35. omlish/dataclasses/impl/generation/ops.py +1 -0
  36. omlish/dataclasses/impl/generation/processor.py +105 -24
  37. omlish/dataclasses/impl/processing/base.py +8 -0
  38. omlish/dataclasses/impl/processing/driving.py +8 -8
  39. omlish/dataclasses/specs.py +1 -0
  40. omlish/dataclasses/tools/modifiers.py +5 -0
  41. omlish/diag/cmds/__init__.py +0 -0
  42. omlish/diag/{lslocks.py → cmds/lslocks.py} +6 -6
  43. omlish/diag/{lsof.py → cmds/lsof.py} +6 -6
  44. omlish/diag/{ps.py → cmds/ps.py} +6 -6
  45. omlish/diag/pycharm.py +16 -2
  46. omlish/diag/pydevd.py +58 -40
  47. omlish/diag/replserver/console.py +1 -1
  48. omlish/dispatch/__init__.py +18 -12
  49. omlish/dispatch/methods.py +50 -140
  50. omlish/dom/rendering.py +1 -1
  51. omlish/formats/dotenv.py +1 -1
  52. omlish/formats/json/stream/__init__.py +13 -0
  53. omlish/funcs/guard.py +225 -0
  54. omlish/graphs/dot/rendering.py +1 -1
  55. omlish/http/all.py +44 -4
  56. omlish/http/clients/asyncs.py +33 -27
  57. omlish/http/clients/base.py +17 -1
  58. omlish/http/clients/coro/__init__.py +0 -0
  59. omlish/http/clients/coro/sync.py +171 -0
  60. omlish/http/clients/default.py +208 -29
  61. omlish/http/clients/executor.py +56 -0
  62. omlish/http/clients/httpx.py +72 -11
  63. omlish/http/clients/middleware.py +181 -0
  64. omlish/http/clients/sync.py +33 -27
  65. omlish/http/clients/syncasync.py +49 -0
  66. omlish/http/clients/urllib.py +6 -3
  67. omlish/http/coro/client/connection.py +15 -6
  68. omlish/http/coro/io.py +2 -0
  69. omlish/http/flasky/__init__.py +40 -0
  70. omlish/http/flasky/_compat.py +2 -0
  71. omlish/http/flasky/api.py +82 -0
  72. omlish/http/flasky/app.py +203 -0
  73. omlish/http/flasky/cvs.py +59 -0
  74. omlish/http/flasky/requests.py +20 -0
  75. omlish/http/flasky/responses.py +23 -0
  76. omlish/http/flasky/routes.py +23 -0
  77. omlish/http/flasky/types.py +15 -0
  78. omlish/http/urls.py +67 -0
  79. omlish/inject/__init__.py +38 -18
  80. omlish/inject/_dataclasses.py +4986 -0
  81. omlish/inject/binder.py +4 -48
  82. omlish/inject/elements.py +27 -0
  83. omlish/inject/helpers/__init__.py +0 -0
  84. omlish/inject/{utils.py → helpers/constfn.py} +3 -3
  85. omlish/inject/{tags.py → helpers/id.py} +2 -2
  86. omlish/inject/helpers/multis.py +143 -0
  87. omlish/inject/helpers/wrappers.py +54 -0
  88. omlish/inject/impl/elements.py +47 -17
  89. omlish/inject/impl/injector.py +20 -19
  90. omlish/inject/impl/inspect.py +10 -1
  91. omlish/inject/impl/maysync.py +3 -4
  92. omlish/inject/impl/multis.py +3 -0
  93. omlish/inject/impl/sync.py +3 -4
  94. omlish/inject/injector.py +31 -2
  95. omlish/inject/inspect.py +35 -0
  96. omlish/inject/maysync.py +2 -4
  97. omlish/inject/multis.py +8 -0
  98. omlish/inject/overrides.py +3 -3
  99. omlish/inject/privates.py +6 -0
  100. omlish/inject/providers.py +3 -2
  101. omlish/inject/sync.py +5 -4
  102. omlish/io/buffers.py +118 -0
  103. omlish/io/readers.py +29 -0
  104. omlish/iterators/transforms.py +2 -2
  105. omlish/lang/__init__.py +178 -97
  106. omlish/lang/_asyncs.cc +186 -0
  107. omlish/lang/asyncs.py +17 -0
  108. omlish/lang/casing.py +11 -0
  109. omlish/lang/contextmanagers.py +28 -4
  110. omlish/lang/functions.py +31 -22
  111. omlish/lang/imports/_capture.cc +11 -9
  112. omlish/lang/imports/capture.py +363 -170
  113. omlish/lang/imports/proxy.py +455 -152
  114. omlish/lang/lazyglobals.py +22 -9
  115. omlish/lang/params.py +17 -0
  116. omlish/lang/recursion.py +0 -1
  117. omlish/lang/sequences.py +124 -0
  118. omlish/lite/abstract.py +54 -24
  119. omlish/lite/asyncs.py +2 -2
  120. omlish/lite/attrops.py +2 -0
  121. omlish/lite/contextmanagers.py +4 -4
  122. omlish/lite/dataclasses.py +44 -0
  123. omlish/lite/maybes.py +8 -0
  124. omlish/lite/maysync.py +1 -5
  125. omlish/lite/pycharm.py +1 -1
  126. omlish/lite/typing.py +6 -0
  127. omlish/logs/all.py +1 -1
  128. omlish/logs/utils.py +1 -1
  129. omlish/manifests/loading.py +2 -1
  130. omlish/marshal/__init__.py +33 -13
  131. omlish/marshal/_dataclasses.py +2774 -0
  132. omlish/marshal/base/configs.py +12 -0
  133. omlish/marshal/base/contexts.py +36 -21
  134. omlish/marshal/base/funcs.py +8 -11
  135. omlish/marshal/base/options.py +8 -0
  136. omlish/marshal/base/registries.py +146 -44
  137. omlish/marshal/base/types.py +40 -16
  138. omlish/marshal/composite/iterables.py +33 -20
  139. omlish/marshal/composite/literals.py +20 -18
  140. omlish/marshal/composite/mappings.py +36 -23
  141. omlish/marshal/composite/maybes.py +29 -19
  142. omlish/marshal/composite/newtypes.py +16 -16
  143. omlish/marshal/composite/optionals.py +14 -14
  144. omlish/marshal/composite/special.py +15 -15
  145. omlish/marshal/composite/unions/__init__.py +0 -0
  146. omlish/marshal/composite/unions/literals.py +93 -0
  147. omlish/marshal/composite/unions/primitives.py +103 -0
  148. omlish/marshal/factories/invalidate.py +18 -68
  149. omlish/marshal/factories/method.py +26 -0
  150. omlish/marshal/factories/moduleimport/factories.py +22 -65
  151. omlish/marshal/factories/multi.py +13 -25
  152. omlish/marshal/factories/recursive.py +42 -56
  153. omlish/marshal/factories/typecache.py +29 -74
  154. omlish/marshal/factories/typemap.py +42 -43
  155. omlish/marshal/objects/dataclasses.py +129 -106
  156. omlish/marshal/objects/marshal.py +18 -14
  157. omlish/marshal/objects/namedtuples.py +48 -42
  158. omlish/marshal/objects/unmarshal.py +19 -15
  159. omlish/marshal/polymorphism/marshal.py +9 -11
  160. omlish/marshal/polymorphism/metadata.py +16 -5
  161. omlish/marshal/polymorphism/standard.py +13 -1
  162. omlish/marshal/polymorphism/unions.py +15 -105
  163. omlish/marshal/polymorphism/unmarshal.py +9 -10
  164. omlish/marshal/singular/enums.py +14 -18
  165. omlish/marshal/standard.py +10 -6
  166. omlish/marshal/trivial/any.py +1 -1
  167. omlish/marshal/trivial/forbidden.py +21 -26
  168. omlish/metadata.py +23 -1
  169. omlish/os/forkhooks.py +4 -0
  170. omlish/os/pidfiles/pinning.py +2 -2
  171. omlish/reflect/types.py +1 -0
  172. omlish/secrets/marshal.py +1 -1
  173. omlish/specs/jmespath/__init__.py +12 -3
  174. omlish/specs/jmespath/_dataclasses.py +2893 -0
  175. omlish/specs/jmespath/ast.py +1 -1
  176. omlish/specs/jsonrpc/__init__.py +13 -0
  177. omlish/specs/jsonrpc/_marshal.py +32 -23
  178. omlish/specs/jsonrpc/conns.py +10 -7
  179. omlish/specs/jsonschema/_marshal.py +1 -1
  180. omlish/specs/jsonschema/keywords/__init__.py +7 -0
  181. omlish/specs/jsonschema/keywords/_dataclasses.py +1644 -0
  182. omlish/specs/openapi/_marshal.py +31 -22
  183. omlish/sql/{tabledefs/alchemy.py → alchemy/tabledefs.py} +2 -2
  184. omlish/sql/queries/_marshal.py +2 -2
  185. omlish/sql/queries/rendering.py +1 -1
  186. omlish/sql/tabledefs/_marshal.py +1 -1
  187. omlish/subprocesses/base.py +4 -0
  188. omlish/subprocesses/editor.py +1 -1
  189. omlish/sync.py +155 -21
  190. omlish/term/alt.py +60 -0
  191. omlish/term/confirm.py +8 -8
  192. omlish/term/pager.py +235 -0
  193. omlish/term/terminfo.py +935 -0
  194. omlish/term/termstate.py +67 -0
  195. omlish/term/vt100/terminal.py +0 -3
  196. omlish/testing/pytest/plugins/asyncs/fixtures.py +4 -1
  197. omlish/testing/pytest/plugins/skips.py +2 -1
  198. omlish/testing/unittest/main.py +3 -3
  199. omlish/text/docwrap/__init__.py +3 -0
  200. omlish/text/docwrap/__main__.py +11 -0
  201. omlish/text/docwrap/api.py +83 -0
  202. omlish/text/docwrap/cli.py +86 -0
  203. omlish/text/docwrap/groups.py +84 -0
  204. omlish/text/docwrap/lists.py +167 -0
  205. omlish/text/docwrap/parts.py +146 -0
  206. omlish/text/docwrap/reflowing.py +106 -0
  207. omlish/text/docwrap/rendering.py +151 -0
  208. omlish/text/docwrap/utils.py +11 -0
  209. omlish/text/docwrap/wrapping.py +59 -0
  210. omlish/text/filecache.py +2 -2
  211. omlish/text/lorem.py +6 -0
  212. omlish/text/parts.py +2 -2
  213. omlish/text/textwrap.py +51 -0
  214. omlish/typedvalues/marshal.py +85 -59
  215. omlish/typedvalues/values.py +2 -1
  216. {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev484.dist-info}/METADATA +29 -28
  217. {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev484.dist-info}/RECORD +222 -171
  218. omlish/dataclasses/impl/generation/mangling.py +0 -18
  219. omlish/funcs/match.py +0 -227
  220. omlish/marshal/factories/match.py +0 -34
  221. omlish/marshal/factories/simple.py +0 -28
  222. /omlish/inject/impl/{providers2.py → providersmap.py} +0 -0
  223. {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev484.dist-info}/WHEEL +0 -0
  224. {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev484.dist-info}/entry_points.txt +0 -0
  225. {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev484.dist-info}/licenses/LICENSE +0 -0
  226. {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev484.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,59 @@
1
+ import contextlib
2
+ import contextvars
3
+ import typing as ta
4
+
5
+ from ... import dataclasses as dc
6
+ from ... import lang
7
+
8
+
9
+ if ta.TYPE_CHECKING:
10
+ from .app import AppRunner
11
+ from .requests import Request
12
+
13
+
14
+ T = ta.TypeVar('T')
15
+
16
+
17
+ ##
18
+
19
+
20
+ @dc.dataclass()
21
+ class CvLookupError(LookupError):
22
+ cv: 'Cv'
23
+
24
+
25
+ @ta.final
26
+ class Cv(ta.Generic[T]):
27
+ def __init__(self, name: str) -> None:
28
+ self._name = name
29
+ self._var: contextvars.ContextVar[T] = contextvars.ContextVar(name)
30
+
31
+ def __repr__(self) -> str:
32
+ return f'{self.__class__.__name__}({self._name!r})'
33
+
34
+ def get(self) -> T:
35
+ try:
36
+ return self._var.get()
37
+ except LookupError:
38
+ raise CvLookupError(self) from None
39
+
40
+ @contextlib.contextmanager
41
+ def set(self, new: T) -> ta.Iterator[None]:
42
+ tok = self._var.set(new)
43
+ try:
44
+ yield
45
+ finally:
46
+ self._var.reset(tok)
47
+
48
+
49
+ ##
50
+
51
+
52
+ def _cv(name: str) -> Cv:
53
+ return Cv(f'{__name__}.Cvs.{name}')
54
+
55
+
56
+ class Cvs(lang.Namespace, lang.Final):
57
+ APP_RUNNER: Cv['AppRunner'] = _cv('APP_RUNNER')
58
+
59
+ REQUEST: Cv['Request'] = _cv('REQUEST')
@@ -0,0 +1,20 @@
1
+ import typing as ta
2
+
3
+ from ... import dataclasses as dc
4
+ from ._compat import compat
5
+ from .types import ImmutableMultiDict
6
+
7
+
8
+ ##
9
+
10
+
11
+ @compat
12
+ @dc.dataclass(frozen=True, kw_only=True)
13
+ class Request:
14
+ path: str
15
+ method: str
16
+
17
+ form: ImmutableMultiDict[str, str] | None = None
18
+
19
+ def get_json(self) -> ta.Any:
20
+ raise NotImplementedError
@@ -0,0 +1,23 @@
1
+ import http
2
+ import typing as ta
3
+
4
+ from ... import dataclasses as dc
5
+ from ._compat import compat
6
+
7
+
8
+ ResponseData: ta.TypeAlias = str | ta.Iterable[str] | bytes | ta.Iterable[bytes]
9
+ ResponseStatus: ta.TypeAlias = int | str | http.HTTPStatus
10
+ ResponseHeaders: ta.TypeAlias = ta.Mapping[str, str | ta.Iterable[str]] | ta.Iterable[tuple[str, str]]
11
+
12
+
13
+ ##
14
+
15
+
16
+ @compat
17
+ @dc.dataclass(frozen=True)
18
+ class Response:
19
+ response: ResponseData | None = None
20
+ status: ResponseStatus | None = None
21
+ headers: ResponseHeaders | None = None
22
+ mimetype: str | None = None
23
+ content_type: str | None = None
@@ -0,0 +1,23 @@
1
+ import typing as ta
2
+
3
+ from ... import cached
4
+ from ... import dataclasses as dc
5
+
6
+
7
+ ##
8
+
9
+
10
+ class RouteKey(ta.NamedTuple):
11
+ rule: str
12
+ method: str
13
+
14
+
15
+ @dc.dataclass(frozen=True, kw_only=True)
16
+ class Route:
17
+ rule: str
18
+ endpoint: str
19
+ methods: frozenset[str]
20
+
21
+ @cached.property
22
+ def keys(self) -> frozenset[RouteKey]:
23
+ return frozenset(RouteKey(self.rule, m) for m in self.methods)
@@ -0,0 +1,15 @@
1
+ import typing as ta
2
+
3
+ from ._compat import compat
4
+
5
+
6
+ K = ta.TypeVar('K')
7
+ V = ta.TypeVar('V')
8
+
9
+
10
+ ##
11
+
12
+
13
+ @compat
14
+ class ImmutableMultiDict(ta.Mapping[K, V]):
15
+ pass
omlish/http/urls.py ADDED
@@ -0,0 +1,67 @@
1
+ # ruff: noqa: UP006 UP007 UP045
2
+ # @omlish-lite
3
+ import re
4
+ import typing as ta
5
+ import urllib.parse
6
+
7
+ from ..lite.cached import cached_nullary
8
+
9
+
10
+ ##
11
+
12
+
13
+ @cached_nullary
14
+ def _url_split_host_pat() -> re.Pattern:
15
+ return re.compile('//([^/#?]*)(.*)', re.DOTALL)
16
+
17
+
18
+ def url_split_host(url: str) -> ta.Tuple[ta.Optional[str], str]:
19
+ """splithost('//host[:port]/path') --> 'host[:port]', '/path'."""
20
+
21
+ # https://github.com/python/cpython/blob/364ae607d8035db8ba92486ebebd8225446c1a90/Lib/urllib/parse.py#L1143
22
+ if not (m := _url_split_host_pat().match(url)):
23
+ return None, url
24
+
25
+ host_port, path = m.groups()
26
+ if path and path[0] != '/':
27
+ path = '/' + path
28
+ return host_port, path
29
+
30
+
31
+ ##
32
+
33
+
34
+ def unparse_url_request_path(url: ta.Union[str, urllib.parse.ParseResult]) -> str:
35
+ if isinstance(url, urllib.parse.ParseResult):
36
+ ups = url
37
+ else:
38
+ ups = urllib.parse.urlparse(url)
39
+
40
+ return urllib.parse.urlunparse((
41
+ '',
42
+ '',
43
+ ups.path,
44
+ ups.params,
45
+ ups.query,
46
+ ups.fragment,
47
+ ))
48
+
49
+
50
+ def parsed_url_replace(
51
+ url: urllib.parse.ParseResult,
52
+ *,
53
+ scheme: ta.Optional[str] = None,
54
+ netloc: ta.Optional[str] = None,
55
+ path: ta.Optional[str] = None,
56
+ params: ta.Optional[str] = None,
57
+ query: ta.Optional[str] = None,
58
+ fragment: ta.Optional[str] = None,
59
+ ) -> urllib.parse.ParseResult:
60
+ return urllib.parse.ParseResult(
61
+ scheme if scheme is not None else url.scheme,
62
+ netloc if netloc is not None else url.netloc,
63
+ path if path is not None else url.path,
64
+ params if params is not None else url.params,
65
+ query if query is not None else url.query,
66
+ fragment if fragment is not None else url.fragment,
67
+ )
omlish/inject/__init__.py CHANGED
@@ -19,11 +19,30 @@ from .. import lang as _lang # noqa
19
19
  with _lang.auto_proxy_init(globals()):
20
20
  ##
21
21
 
22
+ from .helpers.constfn import ( # noqa
23
+ ConstFn,
24
+ )
25
+
26
+ from .helpers.id import ( # noqa
27
+ Id,
28
+ )
29
+
30
+ from .helpers.multis import ( # noqa
31
+ bind_map_entry_const,
32
+ bind_set_entry_const,
33
+
34
+ ItemsBinderHelper,
35
+ items_binder_helper,
36
+ )
37
+
38
+ from .helpers.wrappers import ( # noqa
39
+ WrapperBinderHelper,
40
+ wrapper_binder_helper,
41
+ )
42
+
22
43
  from .binder import ( # noqa
23
44
  bind,
24
45
  bind_as_fn,
25
- bind_map_entry_const,
26
- bind_set_entry_const,
27
46
  )
28
47
 
29
48
  from .bindings import ( # noqa
@@ -36,9 +55,14 @@ with _lang.auto_proxy_init(globals()):
36
55
 
37
56
  from .elements import ( # noqa
38
57
  Element,
39
- Elemental,
40
58
  Elements,
59
+ Elemental,
60
+
41
61
  as_elements,
62
+ iter_elements,
63
+
64
+ CollectedElements,
65
+ collect_elements,
42
66
  )
43
67
 
44
68
  from .errors import ( # noqa
@@ -91,15 +115,19 @@ with _lang.auto_proxy_init(globals()):
91
115
  )
92
116
 
93
117
  from .multis import ( # noqa
94
- MapBinding,
95
- MapProvider,
118
+ is_set_multi_key,
96
119
  SetBinding,
97
120
  SetProvider,
98
- MapBinder,
121
+
122
+ is_map_multi_key,
123
+ MapBinding,
124
+ MapProvider,
125
+
99
126
  SetBinder,
127
+ set_binder,
100
128
 
101
- MapBinder as map_binder, # noqa
102
- SetBinder as set_binder, # noqa
129
+ MapBinder,
130
+ map_binder,
103
131
  )
104
132
 
105
133
 
@@ -116,10 +144,10 @@ with _lang.auto_proxy_init(globals()):
116
144
 
117
145
  from .privates import ( # noqa
118
146
  Expose,
147
+ expose,
148
+
119
149
  Private,
120
150
  private,
121
-
122
- Expose as expose, # noqa
123
151
  )
124
152
 
125
153
  from .providers import ( # noqa
@@ -153,16 +181,8 @@ with _lang.auto_proxy_init(globals()):
153
181
  create_injector,
154
182
  )
155
183
 
156
- from .tags import ( # noqa
157
- Id,
158
- )
159
-
160
184
  from .types import ( # noqa
161
185
  Scope,
162
186
  Tag,
163
187
  Unscoped,
164
188
  )
165
-
166
- from .utils import ( # noqa
167
- ConstFn,
168
- )