omlish 0.0.0.dev423__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 (464) hide show
  1. omlish/{.manifests.json → .omlish-manifests.json} +12 -0
  2. omlish/__about__.py +21 -18
  3. omlish/argparse/all.py +17 -9
  4. omlish/argparse/cli.py +16 -3
  5. omlish/argparse/utils.py +21 -0
  6. omlish/asyncs/all.py +0 -13
  7. omlish/asyncs/asyncio/rlock.py +110 -0
  8. omlish/asyncs/asyncio/subprocesses.py +2 -2
  9. omlish/asyncs/asyncio/sync.py +43 -0
  10. omlish/asyncs/asyncio/utils.py +2 -0
  11. omlish/asyncs/ioproxy/proxy.py +1 -1
  12. omlish/asyncs/sync.py +25 -0
  13. omlish/bootstrap/_marshal.py +1 -1
  14. omlish/bootstrap/diag.py +12 -21
  15. omlish/bootstrap/main.py +2 -5
  16. omlish/bootstrap/sys.py +27 -28
  17. omlish/c3.py +4 -1
  18. omlish/cexts/include/omlish/omlish.hh +1 -0
  19. omlish/collections/__init__.py +13 -1
  20. omlish/collections/attrregistry.py +210 -0
  21. omlish/collections/cache/impl.py +3 -2
  22. omlish/collections/identity.py +1 -0
  23. omlish/collections/mappings.py +28 -0
  24. omlish/collections/trie.py +5 -1
  25. omlish/collections/utils.py +77 -0
  26. omlish/concurrent/__init__.py +0 -11
  27. omlish/concurrent/all.py +18 -0
  28. omlish/concurrent/futures.py +25 -0
  29. omlish/concurrent/threadlets.py +1 -1
  30. omlish/configs/processing/flattening.py +1 -1
  31. omlish/configs/processing/merging.py +8 -6
  32. omlish/configs/types.py +1 -1
  33. omlish/daemons/__init__.py +70 -0
  34. omlish/daemons/daemon.py +2 -2
  35. omlish/daemons/launching.py +2 -2
  36. omlish/daemons/reparent.py +2 -3
  37. omlish/daemons/spawning.py +2 -3
  38. omlish/dataclasses/__init__.py +5 -5
  39. omlish/dataclasses/errors.py +1 -1
  40. omlish/dataclasses/impl/api/classes/decorator.py +3 -0
  41. omlish/dataclasses/impl/api/classes/make.py +4 -1
  42. omlish/dataclasses/impl/concerns/doc.py +1 -1
  43. omlish/dataclasses/impl/concerns/repr.py +15 -2
  44. omlish/dataclasses/impl/configs.py +97 -36
  45. omlish/dataclasses/impl/generation/compilation.py +21 -19
  46. omlish/dataclasses/impl/generation/globals.py +1 -0
  47. omlish/dataclasses/impl/generation/ops.py +1 -0
  48. omlish/dataclasses/impl/generation/processor.py +105 -24
  49. omlish/dataclasses/impl/processing/base.py +8 -0
  50. omlish/dataclasses/impl/processing/driving.py +8 -8
  51. omlish/dataclasses/specs.py +34 -2
  52. omlish/dataclasses/tools/as_.py +0 -12
  53. omlish/dataclasses/tools/modifiers.py +5 -0
  54. omlish/dataclasses/tools/static.py +1 -1
  55. omlish/diag/_pycharm/runhack.py +1 -1
  56. omlish/diag/{lslocks.py → cmds/lslocks.py} +6 -6
  57. omlish/diag/{lsof.py → cmds/lsof.py} +6 -6
  58. omlish/diag/{ps.py → cmds/ps.py} +6 -6
  59. omlish/diag/procfs.py +4 -4
  60. omlish/diag/pycharm.py +16 -2
  61. omlish/diag/pydevd.py +58 -40
  62. omlish/diag/replserver/console.py +3 -3
  63. omlish/diag/replserver/server.py +2 -2
  64. omlish/dispatch/__init__.py +18 -12
  65. omlish/dispatch/methods.py +50 -140
  66. omlish/dom/rendering.py +1 -1
  67. omlish/formats/dotenv.py +8 -8
  68. omlish/formats/json/stream/__init__.py +18 -3
  69. omlish/formats/json/stream/building.py +2 -2
  70. omlish/formats/json/stream/lexing.py +401 -67
  71. omlish/formats/json/stream/parsing.py +32 -10
  72. omlish/formats/json/stream/rendering.py +6 -6
  73. omlish/formats/json/stream/utils.py +132 -30
  74. omlish/formats/json5/literals.py +7 -4
  75. omlish/formats/json5/parsing.py +33 -79
  76. omlish/formats/json5/stream.py +77 -0
  77. omlish/formats/logfmt.py +8 -2
  78. omlish/funcs/genmachine.py +2 -2
  79. omlish/funcs/guard.py +225 -0
  80. omlish/graphs/dot/rendering.py +1 -1
  81. omlish/http/all.py +122 -53
  82. omlish/http/asgi.py +2 -2
  83. omlish/http/clients/__init__.py +0 -34
  84. omlish/http/clients/asyncs.py +153 -0
  85. omlish/http/clients/base.py +63 -122
  86. omlish/http/clients/coro/sync.py +171 -0
  87. omlish/http/clients/default.py +209 -30
  88. omlish/http/clients/executor.py +56 -0
  89. omlish/http/clients/httpx.py +78 -13
  90. omlish/http/clients/middleware.py +181 -0
  91. omlish/http/clients/sync.py +151 -0
  92. omlish/http/clients/syncasync.py +49 -0
  93. omlish/http/clients/urllib.py +8 -5
  94. omlish/http/coro/client/{client.py → connection.py} +43 -37
  95. omlish/http/coro/client/headers.py +5 -5
  96. omlish/http/coro/client/response.py +37 -38
  97. omlish/http/coro/client/status.py +4 -4
  98. omlish/http/coro/{client/io.py → io.py} +19 -2
  99. omlish/http/coro/server/fdio.py +10 -9
  100. omlish/http/coro/server/server.py +14 -41
  101. omlish/http/coro/server/sockets.py +7 -6
  102. omlish/http/flasky/__init__.py +40 -0
  103. omlish/http/flasky/_compat.py +2 -0
  104. omlish/http/flasky/api.py +82 -0
  105. omlish/http/flasky/app.py +203 -0
  106. omlish/http/flasky/cvs.py +59 -0
  107. omlish/http/flasky/requests.py +20 -0
  108. omlish/http/flasky/responses.py +23 -0
  109. omlish/http/flasky/routes.py +23 -0
  110. omlish/http/flasky/types.py +15 -0
  111. omlish/http/handlers.py +3 -2
  112. omlish/http/headers.py +69 -35
  113. omlish/http/sse.py +1 -1
  114. omlish/http/urls.py +67 -0
  115. omlish/inject/__init__.py +173 -126
  116. omlish/inject/_dataclasses.py +4986 -0
  117. omlish/inject/binder.py +10 -49
  118. omlish/inject/elements.py +27 -0
  119. omlish/inject/{utils.py → helpers/constfn.py} +3 -3
  120. omlish/inject/{tags.py → helpers/id.py} +2 -2
  121. omlish/inject/helpers/multis.py +143 -0
  122. omlish/inject/helpers/wrappers.py +54 -0
  123. omlish/inject/impl/elements.py +52 -22
  124. omlish/inject/impl/injector.py +76 -49
  125. omlish/inject/impl/inspect.py +11 -1
  126. omlish/inject/impl/maysync.py +43 -0
  127. omlish/inject/impl/multis.py +10 -7
  128. omlish/inject/impl/privates.py +8 -8
  129. omlish/inject/impl/providers.py +23 -34
  130. omlish/inject/impl/providersmap.py +43 -0
  131. omlish/inject/impl/proxy.py +0 -2
  132. omlish/inject/impl/scopes.py +19 -23
  133. omlish/inject/impl/sync.py +41 -0
  134. omlish/inject/injector.py +37 -8
  135. omlish/inject/inspect.py +35 -0
  136. omlish/inject/listeners.py +4 -4
  137. omlish/inject/managed.py +54 -18
  138. omlish/inject/maysync.py +27 -0
  139. omlish/inject/multis.py +8 -0
  140. omlish/inject/overrides.py +3 -3
  141. omlish/inject/privates.py +6 -0
  142. omlish/inject/providers.py +8 -1
  143. omlish/inject/scopes.py +40 -12
  144. omlish/inject/sync.py +49 -0
  145. omlish/io/buffers.py +119 -1
  146. omlish/io/readers.py +29 -0
  147. omlish/iterators/__init__.py +28 -20
  148. omlish/iterators/transforms.py +204 -0
  149. omlish/lang/__init__.py +240 -129
  150. omlish/lang/_asyncs.cc +186 -0
  151. omlish/lang/asyncs.py +67 -43
  152. omlish/lang/{attrs.py → attrstorage.py} +15 -15
  153. omlish/lang/cached/property.py +2 -2
  154. omlish/lang/casing.py +11 -0
  155. omlish/lang/classes/bindable.py +2 -3
  156. omlish/lang/classes/restrict.py +8 -0
  157. omlish/lang/classes/simple.py +26 -4
  158. omlish/lang/collections.py +1 -1
  159. omlish/lang/contextmanagers.py +59 -9
  160. omlish/lang/functions.py +31 -33
  161. omlish/lang/imports/_capture.cc +103 -0
  162. omlish/lang/imports/capture.py +902 -0
  163. omlish/lang/imports/lazy.py +0 -25
  164. omlish/lang/imports/proxy.py +559 -0
  165. omlish/lang/iterables.py +2 -2
  166. omlish/lang/lazyglobals.py +49 -14
  167. omlish/lang/maybes.py +2 -1
  168. omlish/lang/maysync.py +2 -2
  169. omlish/lang/params.py +17 -0
  170. omlish/lang/recursion.py +0 -1
  171. omlish/lang/resources.py +1 -1
  172. omlish/lang/sequences.py +124 -0
  173. omlish/lifecycles/contextmanagers.py +1 -2
  174. omlish/lifecycles/controller.py +1 -2
  175. omlish/lite/abstract.py +54 -24
  176. omlish/lite/asyncs.py +146 -0
  177. omlish/lite/attrops.py +415 -0
  178. omlish/lite/cached.py +57 -1
  179. omlish/lite/contextmanagers.py +4 -4
  180. omlish/lite/dataclasses.py +55 -0
  181. omlish/lite/inject.py +5 -4
  182. omlish/lite/marshal.py +1 -0
  183. omlish/lite/maybes.py +10 -2
  184. omlish/lite/maysync.py +22 -5
  185. omlish/lite/pycharm.py +1 -1
  186. omlish/lite/strings.py +0 -7
  187. omlish/lite/timing.py +6 -3
  188. omlish/lite/typing.py +6 -0
  189. omlish/logs/_amalg.py +8 -0
  190. omlish/logs/all.py +59 -31
  191. omlish/logs/base.py +204 -0
  192. omlish/logs/contexts.py +171 -0
  193. omlish/logs/formatters.py +13 -0
  194. omlish/logs/infos.py +377 -0
  195. omlish/logs/levels.py +97 -0
  196. omlish/logs/modules.py +13 -0
  197. omlish/logs/protocols.py +32 -0
  198. omlish/logs/standard.py +20 -15
  199. omlish/logs/std/configs.py +29 -0
  200. omlish/logs/{filters.py → std/filters.py} +1 -1
  201. omlish/logs/std/formatters.py +25 -0
  202. omlish/logs/std/handlers.py +19 -0
  203. omlish/logs/{json.py → std/json.py} +2 -2
  204. omlish/logs/std/loggers.py +48 -0
  205. omlish/logs/{proxy.py → std/proxy.py} +3 -3
  206. omlish/logs/std/records.py +671 -0
  207. omlish/logs/typed/bindings.py +108 -37
  208. omlish/logs/typed/types.py +17 -1
  209. omlish/logs/typed/values.py +2 -2
  210. omlish/logs/utils.py +60 -4
  211. omlish/logs/warnings.py +8 -0
  212. omlish/manifests/loading.py +8 -1
  213. omlish/marshal/__init__.py +54 -22
  214. omlish/marshal/_dataclasses.py +2774 -0
  215. omlish/marshal/base/configs.py +12 -0
  216. omlish/marshal/base/contexts.py +36 -21
  217. omlish/marshal/base/funcs.py +8 -11
  218. omlish/marshal/base/options.py +8 -0
  219. omlish/marshal/base/registries.py +146 -44
  220. omlish/marshal/base/types.py +40 -16
  221. omlish/marshal/composite/iterables.py +33 -20
  222. omlish/marshal/composite/literals.py +20 -18
  223. omlish/marshal/composite/mappings.py +36 -23
  224. omlish/marshal/composite/maybes.py +29 -19
  225. omlish/marshal/composite/newtypes.py +16 -16
  226. omlish/marshal/composite/optionals.py +14 -14
  227. omlish/marshal/composite/special.py +15 -15
  228. omlish/marshal/composite/unions/literals.py +93 -0
  229. omlish/marshal/composite/unions/primitives.py +103 -0
  230. omlish/marshal/factories/invalidate.py +18 -68
  231. omlish/marshal/factories/method.py +26 -0
  232. omlish/marshal/factories/moduleimport/factories.py +22 -65
  233. omlish/marshal/factories/multi.py +13 -25
  234. omlish/marshal/factories/recursive.py +42 -56
  235. omlish/marshal/factories/typecache.py +29 -74
  236. omlish/marshal/factories/typemap.py +42 -43
  237. omlish/marshal/objects/dataclasses.py +129 -106
  238. omlish/marshal/objects/marshal.py +18 -14
  239. omlish/marshal/objects/namedtuples.py +48 -42
  240. omlish/marshal/objects/unmarshal.py +19 -15
  241. omlish/marshal/polymorphism/marshal.py +9 -11
  242. omlish/marshal/polymorphism/metadata.py +16 -5
  243. omlish/marshal/polymorphism/standard.py +13 -1
  244. omlish/marshal/polymorphism/unions.py +15 -105
  245. omlish/marshal/polymorphism/unmarshal.py +9 -10
  246. omlish/marshal/singular/enums.py +14 -18
  247. omlish/marshal/standard.py +10 -6
  248. omlish/marshal/trivial/any.py +1 -1
  249. omlish/marshal/trivial/forbidden.py +21 -26
  250. omlish/math/fixed.py +2 -2
  251. omlish/metadata.py +23 -1
  252. omlish/os/atomics.py +2 -2
  253. omlish/os/forkhooks.py +4 -0
  254. omlish/os/journald.py +3 -3
  255. omlish/os/pidfiles/pinning.py +2 -2
  256. omlish/reflect/ops.py +9 -0
  257. omlish/reflect/types.py +44 -8
  258. omlish/secrets/marshal.py +1 -1
  259. omlish/secrets/secrets.py +6 -3
  260. omlish/sockets/addresses.py +1 -1
  261. omlish/sockets/server/handlers.py +2 -2
  262. omlish/sockets/server/server.py +4 -3
  263. omlish/sockets/server/ssl.py +2 -2
  264. omlish/specs/jmespath/__init__.py +12 -3
  265. omlish/specs/jmespath/_dataclasses.py +2893 -0
  266. omlish/specs/jmespath/ast.py +1 -1
  267. omlish/specs/jsonrpc/__init__.py +13 -0
  268. omlish/specs/jsonrpc/_marshal.py +32 -23
  269. omlish/specs/jsonrpc/conns.py +10 -7
  270. omlish/specs/jsonschema/_marshal.py +1 -1
  271. omlish/specs/jsonschema/keywords/__init__.py +7 -0
  272. omlish/specs/jsonschema/keywords/_dataclasses.py +1644 -0
  273. omlish/specs/openapi/_marshal.py +31 -22
  274. omlish/sql/__init__.py +15 -20
  275. omlish/sql/{tabledefs/alchemy.py → alchemy/tabledefs.py} +2 -2
  276. omlish/sql/queries/_marshal.py +3 -3
  277. omlish/sql/queries/params.py +1 -1
  278. omlish/sql/queries/rendering.py +1 -1
  279. omlish/sql/tabledefs/_marshal.py +1 -1
  280. omlish/subprocesses/all.py +135 -0
  281. omlish/subprocesses/base.py +8 -3
  282. omlish/subprocesses/editor.py +1 -1
  283. omlish/sync.py +181 -20
  284. omlish/term/alt.py +60 -0
  285. omlish/term/confirm.py +8 -8
  286. omlish/term/pager.py +235 -0
  287. omlish/term/terminfo.py +935 -0
  288. omlish/term/termstate.py +67 -0
  289. omlish/term/vt100/terminal.py +0 -3
  290. omlish/testing/pytest/plugins/asyncs/fixtures.py +4 -1
  291. omlish/testing/pytest/plugins/skips.py +2 -5
  292. omlish/testing/unittest/main.py +3 -3
  293. omlish/text/docwrap/__init__.py +3 -0
  294. omlish/text/docwrap/__main__.py +11 -0
  295. omlish/text/docwrap/api.py +83 -0
  296. omlish/text/docwrap/cli.py +86 -0
  297. omlish/text/docwrap/groups.py +84 -0
  298. omlish/text/docwrap/lists.py +167 -0
  299. omlish/text/docwrap/parts.py +146 -0
  300. omlish/text/docwrap/reflowing.py +106 -0
  301. omlish/text/docwrap/rendering.py +151 -0
  302. omlish/text/docwrap/utils.py +11 -0
  303. omlish/text/docwrap/wrapping.py +59 -0
  304. omlish/text/filecache.py +2 -2
  305. omlish/text/lorem.py +6 -0
  306. omlish/text/parts.py +2 -2
  307. omlish/text/textwrap.py +51 -0
  308. omlish/typedvalues/__init__.py +1 -1
  309. omlish/typedvalues/marshal.py +85 -59
  310. omlish/typedvalues/values.py +2 -1
  311. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/METADATA +36 -38
  312. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/RECORD +323 -385
  313. omlish/asyncs/bluelet/LICENSE +0 -6
  314. omlish/asyncs/bluelet/all.py +0 -67
  315. omlish/asyncs/bluelet/api.py +0 -23
  316. omlish/asyncs/bluelet/core.py +0 -178
  317. omlish/asyncs/bluelet/events.py +0 -79
  318. omlish/asyncs/bluelet/files.py +0 -80
  319. omlish/asyncs/bluelet/runner.py +0 -417
  320. omlish/asyncs/bluelet/sockets.py +0 -216
  321. omlish/asyncs/bridge.py +0 -359
  322. omlish/asyncs/utils.py +0 -18
  323. omlish/dataclasses/impl/generation/mangling.py +0 -18
  324. omlish/defs.py +0 -216
  325. omlish/dispatch/_dispatch2.py +0 -69
  326. omlish/dispatch/_dispatch3.py +0 -108
  327. omlish/dynamic.py +0 -219
  328. omlish/formats/json/Json.g4 +0 -77
  329. omlish/formats/json/_antlr/JsonLexer.py +0 -109
  330. omlish/formats/json/_antlr/JsonListener.py +0 -61
  331. omlish/formats/json/_antlr/JsonParser.py +0 -457
  332. omlish/formats/json/_antlr/JsonVisitor.py +0 -42
  333. omlish/formats/json5/Json5.g4 +0 -168
  334. omlish/formats/json5/_antlr/Json5Lexer.py +0 -354
  335. omlish/formats/json5/_antlr/Json5Listener.py +0 -79
  336. omlish/formats/json5/_antlr/Json5Parser.py +0 -617
  337. omlish/formats/json5/_antlr/Json5Visitor.py +0 -52
  338. omlish/funcs/match.py +0 -227
  339. omlish/io/trampoline.py +0 -289
  340. omlish/lang/imports/proxyinit.py +0 -665
  341. omlish/lite/logs.py +0 -4
  342. omlish/lite/reprs.py +0 -85
  343. omlish/logs/abc.py +0 -319
  344. omlish/logs/callers.py +0 -67
  345. omlish/logs/color.py +0 -27
  346. omlish/logs/configs.py +0 -29
  347. omlish/logs/handlers.py +0 -17
  348. omlish/logs/protocol.py +0 -218
  349. omlish/logs/timing.py +0 -58
  350. omlish/marshal/factories/match.py +0 -34
  351. omlish/marshal/factories/simple.py +0 -28
  352. omlish/specs/irc/messages/base.py +0 -49
  353. omlish/specs/irc/messages/formats.py +0 -92
  354. omlish/specs/irc/messages/messages.py +0 -774
  355. omlish/specs/irc/messages/parsing.py +0 -98
  356. omlish/specs/irc/numerics/formats.py +0 -97
  357. omlish/specs/irc/numerics/numerics.py +0 -865
  358. omlish/specs/irc/numerics/types.py +0 -59
  359. omlish/specs/irc/protocol/LICENSE +0 -11
  360. omlish/specs/irc/protocol/__init__.py +0 -61
  361. omlish/specs/irc/protocol/consts.py +0 -6
  362. omlish/specs/irc/protocol/errors.py +0 -30
  363. omlish/specs/irc/protocol/message.py +0 -21
  364. omlish/specs/irc/protocol/nuh.py +0 -55
  365. omlish/specs/irc/protocol/parsing.py +0 -158
  366. omlish/specs/irc/protocol/rendering.py +0 -153
  367. omlish/specs/irc/protocol/tags.py +0 -102
  368. omlish/specs/irc/protocol/utils.py +0 -30
  369. omlish/specs/proto/Protobuf3.g4 +0 -396
  370. omlish/specs/proto/__init__.py +0 -0
  371. omlish/specs/proto/_antlr/Protobuf3Lexer.py +0 -340
  372. omlish/specs/proto/_antlr/Protobuf3Listener.py +0 -448
  373. omlish/specs/proto/_antlr/Protobuf3Parser.py +0 -3909
  374. omlish/specs/proto/_antlr/Protobuf3Visitor.py +0 -257
  375. omlish/specs/proto/_antlr/__init__.py +0 -0
  376. omlish/specs/proto/nodes.py +0 -54
  377. omlish/specs/proto/parsing.py +0 -97
  378. omlish/sql/parsing/Minisql.g4 +0 -292
  379. omlish/sql/parsing/__init__.py +0 -0
  380. omlish/sql/parsing/_antlr/MinisqlLexer.py +0 -322
  381. omlish/sql/parsing/_antlr/MinisqlListener.py +0 -511
  382. omlish/sql/parsing/_antlr/MinisqlParser.py +0 -3763
  383. omlish/sql/parsing/_antlr/MinisqlVisitor.py +0 -292
  384. omlish/sql/parsing/_antlr/__init__.py +0 -0
  385. omlish/sql/parsing/parsing.py +0 -119
  386. omlish/text/antlr/__init__.py +0 -3
  387. omlish/text/antlr/_runtime/BufferedTokenStream.py +0 -305
  388. omlish/text/antlr/_runtime/CommonTokenFactory.py +0 -64
  389. omlish/text/antlr/_runtime/CommonTokenStream.py +0 -90
  390. omlish/text/antlr/_runtime/FileStream.py +0 -30
  391. omlish/text/antlr/_runtime/InputStream.py +0 -90
  392. omlish/text/antlr/_runtime/IntervalSet.py +0 -183
  393. omlish/text/antlr/_runtime/LICENSE.txt +0 -28
  394. omlish/text/antlr/_runtime/LL1Analyzer.py +0 -176
  395. omlish/text/antlr/_runtime/Lexer.py +0 -332
  396. omlish/text/antlr/_runtime/ListTokenSource.py +0 -147
  397. omlish/text/antlr/_runtime/Parser.py +0 -583
  398. omlish/text/antlr/_runtime/ParserInterpreter.py +0 -173
  399. omlish/text/antlr/_runtime/ParserRuleContext.py +0 -189
  400. omlish/text/antlr/_runtime/PredictionContext.py +0 -632
  401. omlish/text/antlr/_runtime/Recognizer.py +0 -150
  402. omlish/text/antlr/_runtime/RuleContext.py +0 -230
  403. omlish/text/antlr/_runtime/StdinStream.py +0 -14
  404. omlish/text/antlr/_runtime/Token.py +0 -158
  405. omlish/text/antlr/_runtime/TokenStreamRewriter.py +0 -258
  406. omlish/text/antlr/_runtime/Utils.py +0 -36
  407. omlish/text/antlr/_runtime/__init__.py +0 -2
  408. omlish/text/antlr/_runtime/_all.py +0 -24
  409. omlish/text/antlr/_runtime/_pygrun.py +0 -174
  410. omlish/text/antlr/_runtime/atn/ATN.py +0 -135
  411. omlish/text/antlr/_runtime/atn/ATNConfig.py +0 -162
  412. omlish/text/antlr/_runtime/atn/ATNConfigSet.py +0 -215
  413. omlish/text/antlr/_runtime/atn/ATNDeserializationOptions.py +0 -27
  414. omlish/text/antlr/_runtime/atn/ATNDeserializer.py +0 -449
  415. omlish/text/antlr/_runtime/atn/ATNSimulator.py +0 -50
  416. omlish/text/antlr/_runtime/atn/ATNState.py +0 -267
  417. omlish/text/antlr/_runtime/atn/ATNType.py +0 -20
  418. omlish/text/antlr/_runtime/atn/LexerATNSimulator.py +0 -573
  419. omlish/text/antlr/_runtime/atn/LexerAction.py +0 -301
  420. omlish/text/antlr/_runtime/atn/LexerActionExecutor.py +0 -146
  421. omlish/text/antlr/_runtime/atn/ParserATNSimulator.py +0 -1664
  422. omlish/text/antlr/_runtime/atn/PredictionMode.py +0 -502
  423. omlish/text/antlr/_runtime/atn/SemanticContext.py +0 -333
  424. omlish/text/antlr/_runtime/atn/Transition.py +0 -271
  425. omlish/text/antlr/_runtime/atn/__init__.py +0 -4
  426. omlish/text/antlr/_runtime/dfa/DFA.py +0 -136
  427. omlish/text/antlr/_runtime/dfa/DFASerializer.py +0 -76
  428. omlish/text/antlr/_runtime/dfa/DFAState.py +0 -129
  429. omlish/text/antlr/_runtime/dfa/__init__.py +0 -4
  430. omlish/text/antlr/_runtime/error/DiagnosticErrorListener.py +0 -111
  431. omlish/text/antlr/_runtime/error/ErrorListener.py +0 -75
  432. omlish/text/antlr/_runtime/error/ErrorStrategy.py +0 -712
  433. omlish/text/antlr/_runtime/error/Errors.py +0 -176
  434. omlish/text/antlr/_runtime/error/__init__.py +0 -4
  435. omlish/text/antlr/_runtime/tree/Chunk.py +0 -33
  436. omlish/text/antlr/_runtime/tree/ParseTreeMatch.py +0 -121
  437. omlish/text/antlr/_runtime/tree/ParseTreePattern.py +0 -75
  438. omlish/text/antlr/_runtime/tree/ParseTreePatternMatcher.py +0 -377
  439. omlish/text/antlr/_runtime/tree/RuleTagToken.py +0 -53
  440. omlish/text/antlr/_runtime/tree/TokenTagToken.py +0 -50
  441. omlish/text/antlr/_runtime/tree/Tree.py +0 -194
  442. omlish/text/antlr/_runtime/tree/Trees.py +0 -114
  443. omlish/text/antlr/_runtime/tree/__init__.py +0 -2
  444. omlish/text/antlr/_runtime/xpath/XPath.py +0 -278
  445. omlish/text/antlr/_runtime/xpath/XPathLexer.py +0 -98
  446. omlish/text/antlr/_runtime/xpath/__init__.py +0 -4
  447. omlish/text/antlr/delimit.py +0 -109
  448. omlish/text/antlr/dot.py +0 -41
  449. omlish/text/antlr/errors.py +0 -14
  450. omlish/text/antlr/input.py +0 -96
  451. omlish/text/antlr/parsing.py +0 -54
  452. omlish/text/antlr/runtime.py +0 -102
  453. omlish/text/antlr/utils.py +0 -38
  454. /omlish/{asyncs/bluelet → cexts}/__init__.py +0 -0
  455. /omlish/{formats/json/_antlr → diag/cmds}/__init__.py +0 -0
  456. /omlish/{formats/json5/_antlr → http/clients/coro}/__init__.py +0 -0
  457. /omlish/{specs/irc → inject/helpers}/__init__.py +0 -0
  458. /omlish/{specs/irc/messages → logs/std}/__init__.py +0 -0
  459. /omlish/logs/{noisy.py → std/noisy.py} +0 -0
  460. /omlish/{specs/irc/numerics → marshal/composite/unions}/__init__.py +0 -0
  461. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/WHEEL +0 -0
  462. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/entry_points.txt +0 -0
  463. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/licenses/LICENSE +0 -0
  464. {omlish-0.0.0.dev423.dist-info → omlish-0.0.0.dev484.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,6 @@ from ... import dataclasses as dc
5
5
  from ... import lang
6
6
  from ... import marshal as msh
7
7
  from ... import reflect as rfl
8
- from ...funcs import match as mfs
9
8
  from .. import jsonschema as jsch
10
9
  from .openapi import Reference
11
10
  from .openapi import Schema
@@ -36,10 +35,14 @@ class _ReferenceUnionMarshaler(msh.Marshaler):
36
35
  return self.m.marshal(ctx, o)
37
36
 
38
37
 
39
- class _ReferenceUnionMarshalerFactory(msh.MarshalerFactoryMatchClass):
40
- @mfs.simple(lambda _, ctx, rty: _reference_union_arg(rty) is not None)
41
- def _build(self, ctx: msh.MarshalContext, rty: rfl.Type) -> msh.Marshaler:
42
- return _ReferenceUnionMarshaler(ctx.make(check.not_none(_reference_union_arg(rty))), ctx.make(Reference))
38
+ class _ReferenceUnionMarshalerFactory(msh.MarshalerFactory):
39
+ def make_marshaler(self, ctx: msh.MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Marshaler] | None:
40
+ if (rua := _reference_union_arg(rty)) is None:
41
+ return None
42
+ return lambda: _ReferenceUnionMarshaler(
43
+ ctx.make_marshaler(check.not_none(rua)),
44
+ ctx.make_marshaler(Reference),
45
+ )
43
46
 
44
47
 
45
48
  #
@@ -59,10 +62,14 @@ class _ReferenceUnionUnmarshaler(msh.Unmarshaler):
59
62
  return self.u.unmarshal(ctx, v) # noqa
60
63
 
61
64
 
62
- class _ReferenceUnionUnmarshalerFactory(msh.UnmarshalerFactoryMatchClass):
63
- @mfs.simple(lambda _, ctx, rty: _reference_union_arg(rty) is not None)
64
- def _build(self, ctx: msh.UnmarshalContext, rty: rfl.Type) -> msh.Unmarshaler:
65
- return _ReferenceUnionUnmarshaler(ctx.make(check.not_none(_reference_union_arg(rty))), ctx.make(Reference))
65
+ class _ReferenceUnionUnmarshalerFactory(msh.UnmarshalerFactory):
66
+ def make_unmarshaler(self, ctx: msh.UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Unmarshaler] | None: # noqa
67
+ if (rua := _reference_union_arg(rty)) is None:
68
+ return None
69
+ return lambda: _ReferenceUnionUnmarshaler(
70
+ ctx.make_unmarshaler(check.not_none(rua)),
71
+ ctx.make_unmarshaler(Reference),
72
+ )
66
73
 
67
74
 
68
75
  ##
@@ -86,16 +93,17 @@ class _SchemaMarshaler(msh.Marshaler):
86
93
  return dct
87
94
 
88
95
 
89
- class _SchemaMarshalerFactory(msh.MarshalerFactoryMatchClass):
90
- @mfs.simple(lambda _, ctx, rty: rty is Schema)
91
- def _build(self, ctx: msh.MarshalContext, rty: rfl.Type) -> msh.Marshaler:
92
- return _SchemaMarshaler(
96
+ class _SchemaMarshalerFactory(msh.MarshalerFactory):
97
+ def make_marshaler(self, ctx: msh.MarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Marshaler] | None:
98
+ if rty is not Schema:
99
+ return None
100
+ return lambda: _SchemaMarshaler(
93
101
  {
94
- f: (msh.translate_name(f, msh.Naming.LOW_CAMEL), ctx.make(rfl.type_(a)))
102
+ f: (msh.translate_name(f, msh.Naming.LOW_CAMEL), ctx.make_marshaler(rfl.type_(a)))
95
103
  for f, a in dc.reflect(Schema).field_annotations.items()
96
104
  if f != 'keywords'
97
105
  },
98
- ctx.make(jsch.Keywords),
106
+ ctx.make_marshaler(jsch.Keywords),
99
107
  )
100
108
 
101
109
 
@@ -121,16 +129,17 @@ class _SchemaUnmarshaler(msh.Unmarshaler):
121
129
  return Schema(**kw)
122
130
 
123
131
 
124
- class _SchemaUnmarshalerFactory(msh.UnmarshalerFactoryMatchClass):
125
- @mfs.simple(lambda _, ctx, rty: rty is Schema)
126
- def _build(self, ctx: msh.UnmarshalContext, rty: rfl.Type) -> msh.Unmarshaler:
127
- return _SchemaUnmarshaler(
132
+ class _SchemaUnmarshalerFactory(msh.UnmarshalerFactory):
133
+ def make_unmarshaler(self, ctx: msh.UnmarshalFactoryContext, rty: rfl.Type) -> ta.Callable[[], msh.Unmarshaler] | None: # noqa
134
+ if rty is not Schema:
135
+ return None
136
+ return lambda: _SchemaUnmarshaler(
128
137
  {
129
- msh.translate_name(f, msh.Naming.LOW_CAMEL): (f, ctx.make(rfl.type_(a)))
138
+ msh.translate_name(f, msh.Naming.LOW_CAMEL): (f, ctx.make_unmarshaler(rfl.type_(a)))
130
139
  for f, a in dc.reflect(Schema).field_annotations.items()
131
140
  if f != 'keywords'
132
141
  },
133
- ctx.make(jsch.Keywords),
142
+ ctx.make_unmarshaler(jsch.Keywords),
134
143
  )
135
144
 
136
145
 
@@ -138,7 +147,7 @@ class _SchemaUnmarshalerFactory(msh.UnmarshalerFactoryMatchClass):
138
147
 
139
148
 
140
149
  @lang.static_init
141
- def _install_standard_marshalling() -> None:
150
+ def _install_standard_marshaling() -> None:
142
151
  msh.install_standard_factories(
143
152
  _ReferenceUnionMarshalerFactory(),
144
153
  _ReferenceUnionUnmarshalerFactory(),
omlish/sql/__init__.py CHANGED
@@ -1,29 +1,24 @@
1
1
  # ruff: noqa: I001
2
- import typing as _ta
3
-
4
2
  from .. import lang as _lang
5
3
 
6
4
 
7
- if _ta.TYPE_CHECKING:
5
+ with _lang.auto_proxy_init(globals()):
6
+ ##
7
+
8
8
  from . import api # noqa
9
- else:
10
- globals()['api'] = _lang.proxy_import('.api', __package__)
11
9
 
12
- from .dbs import ( # noqa
13
- DbLoc,
14
- DbSpec,
15
- DbType,
16
- DbTypes,
17
- HostDbLoc,
18
- UrlDbLoc,
19
- )
10
+ from .dbs import ( # noqa
11
+ DbLoc,
12
+ DbSpec,
13
+ DbType,
14
+ DbTypes,
15
+ HostDbLoc,
16
+ UrlDbLoc,
17
+ )
20
18
 
21
- from .qualifiedname import ( # noqa
22
- QualifiedName,
23
- qn,
24
- )
19
+ from .qualifiedname import ( # noqa
20
+ QualifiedName,
21
+ qn,
22
+ )
25
23
 
26
- if _ta.TYPE_CHECKING:
27
24
  from . import queries # noqa
28
- else:
29
- globals()['queries'] = _lang.proxy_import('.queries', __package__)
@@ -7,13 +7,13 @@ import typing as ta
7
7
  import sqlalchemy as sa
8
8
  import sqlalchemy.sql.schema
9
9
 
10
- from .tabledefs import TableDef
10
+ from ..tabledefs import TableDef
11
11
 
12
12
 
13
13
  ##
14
14
 
15
15
 
16
- def build_sa_table(
16
+ def build_td_table(
17
17
  td: TableDef,
18
18
  *,
19
19
  metadata: sa.MetaData | None = None,
@@ -40,7 +40,7 @@ class OpMarshalerUnmarshaler(msh.Marshaler, msh.Unmarshaler):
40
40
  return col.make_map(((o.name, o) for _, o in self.ns), strict=True)
41
41
 
42
42
  def marshal(self, ctx: msh.MarshalContext, o: ta.Any) -> msh.Value:
43
- return check.isinstance(o, self.ty).name # type: ignore # noqa
43
+ return check.isinstance(o, self.ty).name
44
44
 
45
45
  def unmarshal(self, ctx: msh.UnmarshalContext, v: msh.Value) -> ta.Any:
46
46
  return self.by_name[check.isinstance(v, str)]
@@ -63,7 +63,7 @@ class LowerEnumMarshaler(msh.Marshaler, msh.Unmarshaler):
63
63
 
64
64
 
65
65
  @lang.static_init
66
- def _install_standard_marshalling() -> None:
66
+ def _install_standard_marshaling() -> None:
67
67
  for ty, ns in [
68
68
  (BinaryOp, BinaryOps),
69
69
  (UnaryOp, UnaryOps),
@@ -92,7 +92,7 @@ def _install_standard_marshalling() -> None:
92
92
  p = msh.polymorphism_from_subclasses(
93
93
  cls,
94
94
  naming=msh.Naming.SNAKE,
95
- strip_suffix='auto',
95
+ strip_suffix=msh.AutoStripSuffix,
96
96
  )
97
97
  msh.install_standard_factories(
98
98
  msh.PolymorphismMarshalerFactory(p),
@@ -16,7 +16,7 @@ class Param(lang.Final):
16
16
  if self.n is not None:
17
17
  return f'{self.__class__.__name__}({self.n!r})'
18
18
  else:
19
- return f'{self.__class__.__name__}(@{hex(id(self))[2:]})'
19
+ return f'{self.__class__.__name__}(@{id(self):x})'
20
20
 
21
21
  def __eq__(self, other):
22
22
  if not isinstance(other, Param):
@@ -81,7 +81,7 @@ class Renderer(lang.Abstract):
81
81
  def args(self) -> lang.Args:
82
82
  return self._params_preparer.prepare()
83
83
 
84
- @dispatch.method
84
+ @dispatch.method(instance_cache=True)
85
85
  def render(self, o: ta.Any) -> tp.Part:
86
86
  raise TypeError(o)
87
87
 
@@ -16,6 +16,6 @@ def _install_poly(cls: type) -> None:
16
16
 
17
17
 
18
18
  @lang.static_init
19
- def _install_standard_marshalling() -> None:
19
+ def _install_standard_marshaling() -> None:
20
20
  _install_poly(Dtype)
21
21
  _install_poly(Element)
@@ -0,0 +1,135 @@
1
+ import sys as _sys
2
+ import typing as _ta
3
+
4
+ from .. import lang as _lang # noqa
5
+
6
+
7
+ with _lang.auto_proxy_init(globals()):
8
+ ##
9
+
10
+ from .asyncs import ( # noqa
11
+ AbstractAsyncSubprocesses,
12
+ )
13
+
14
+ from .base import ( # noqa
15
+ SubprocessChannelOption,
16
+
17
+ VerboseCalledProcessError,
18
+ BaseSubprocesses,
19
+ )
20
+
21
+ from .maysync import ( # noqa
22
+ MaysyncSubprocesses,
23
+ )
24
+
25
+ from .run import ( # noqa
26
+ SubprocessRunOutput,
27
+ SubprocessRun,
28
+ SubprocessRunnable,
29
+ )
30
+
31
+ from .sync import ( # noqa
32
+ AbstractSubprocesses,
33
+
34
+ Subprocesses,
35
+
36
+ subprocesses,
37
+ )
38
+
39
+ from .utils import ( # noqa
40
+ subprocess_close as close,
41
+ )
42
+
43
+ from .wrap import ( # noqa
44
+ subprocess_shell_wrap_exec as shell_wrap_exec,
45
+ subprocess_maybe_shell_wrap_exec as maybe_shell_wrap_exec,
46
+ )
47
+
48
+
49
+ ##
50
+
51
+
52
+ if _ta.TYPE_CHECKING:
53
+ from . import sync as _sync # noqa
54
+ else:
55
+ _sync = _lang.proxy_import('.sync', __package__)
56
+
57
+
58
+ def run(
59
+ *cmd: str,
60
+ input: _ta.Any = None, # noqa
61
+ timeout: '_lang.TimeoutLike' = None,
62
+ check: bool = False,
63
+ capture_output: bool | None = None,
64
+ **kwargs: _ta.Any,
65
+ ) -> 'SubprocessRunOutput':
66
+ return _sync.subprocesses.run(
67
+ *cmd,
68
+ input=input,
69
+ timeout=timeout,
70
+ check=check,
71
+ capture_output=capture_output,
72
+ **kwargs,
73
+ )
74
+
75
+
76
+ def check_call(
77
+ *cmd: str,
78
+ stdout: _ta.Any = _sys.stderr,
79
+ **kwargs: _ta.Any,
80
+ ) -> None:
81
+ return _sync.subprocesses.check_call(
82
+ *cmd,
83
+ stdout=stdout,
84
+ **kwargs,
85
+ )
86
+
87
+
88
+ def check_output(
89
+ *cmd: str,
90
+ **kwargs: _ta.Any,
91
+ ) -> bytes:
92
+ return _sync.subprocesses.check_output(
93
+ *cmd,
94
+ **kwargs,
95
+ )
96
+
97
+
98
+ def check_output_str(
99
+ *cmd: str,
100
+ **kwargs: _ta.Any,
101
+ ) -> str:
102
+ return _sync.subprocesses.check_output_str(
103
+ *cmd,
104
+ **kwargs,
105
+ )
106
+
107
+
108
+ def try_call(
109
+ *cmd: str,
110
+ **kwargs: _ta.Any,
111
+ ) -> bool:
112
+ return _sync.subprocesses.try_call(
113
+ *cmd,
114
+ **kwargs,
115
+ )
116
+
117
+
118
+ def try_output(
119
+ *cmd: str,
120
+ **kwargs: _ta.Any,
121
+ ) -> bytes | None:
122
+ return _sync.subprocesses.try_output(
123
+ *cmd,
124
+ **kwargs,
125
+ )
126
+
127
+
128
+ def try_output_str(
129
+ *cmd: str,
130
+ **kwargs: _ta.Any,
131
+ ) -> str | None:
132
+ return _sync.subprocesses.try_output_str(
133
+ *cmd,
134
+ **kwargs,
135
+ )
@@ -9,6 +9,7 @@ import typing as ta
9
9
 
10
10
  from ..lite.abstract import Abstract
11
11
  from ..lite.timeouts import Timeout
12
+ from ..logs.protocols import LoggerLike
12
13
  from .wrap import subprocess_maybe_shell_wrap_exec
13
14
 
14
15
 
@@ -55,12 +56,16 @@ class VerboseCalledProcessError(subprocess.CalledProcessError):
55
56
 
56
57
 
57
58
  class BaseSubprocesses(Abstract):
58
- DEFAULT_LOGGER: ta.ClassVar[ta.Optional[logging.Logger]] = None
59
+ DEFAULT_LOGGER: ta.ClassVar[ta.Optional[LoggerLike]] = None
60
+
61
+ PIPE: ta.ClassVar[int] = subprocess.PIPE
62
+ STDOUT: ta.ClassVar[int] = subprocess.STDOUT
63
+ DEVNULL: ta.ClassVar[int] = subprocess.DEVNULL
59
64
 
60
65
  def __init__(
61
66
  self,
62
67
  *,
63
- log: ta.Optional[logging.Logger] = None,
68
+ log: ta.Optional[LoggerLike] = None,
64
69
  try_exceptions: ta.Optional[ta.Tuple[ta.Type[Exception], ...]] = None,
65
70
  ) -> None:
66
71
  super().__init__()
@@ -68,7 +73,7 @@ class BaseSubprocesses(Abstract):
68
73
  self._log = log if log is not None else self.DEFAULT_LOGGER
69
74
  self._try_exceptions = try_exceptions if try_exceptions is not None else self.DEFAULT_TRY_EXCEPTIONS
70
75
 
71
- def set_logger(self, log: ta.Optional[logging.Logger]) -> None:
76
+ def set_logger(self, log: ta.Optional[LoggerLike]) -> None:
72
77
  self._log = log
73
78
 
74
79
  #
@@ -32,7 +32,7 @@ def get_user_text_editor(default: ta.Optional[str] = None) -> str:
32
32
  ##
33
33
 
34
34
 
35
- class EditTextWithUserEditor(SubprocessRunnable, ExitStacked):
35
+ class EditTextWithUserEditor(SubprocessRunnable[ta.Optional[str]], ExitStacked):
36
36
  def __init__(self, initial_text: str = '') -> None:
37
37
  super().__init__()
38
38
 
omlish/sync.py CHANGED
@@ -1,3 +1,5 @@
1
+ # ruff: noqa: UP006 UP043 UP045
2
+ # @omlish-lite
1
3
  """
2
4
  TODO:
3
5
  - sync (lol) w/ asyncs.anyio
@@ -5,19 +7,21 @@ TODO:
5
7
  - Once poison=False, PoisonedError
6
8
  """
7
9
  import collections
10
+ import contextlib
8
11
  import threading
9
12
  import typing as ta
10
13
 
11
- from . import lang
14
+ from .lite.maybes import Maybe
12
15
 
13
16
 
14
17
  T = ta.TypeVar('T')
18
+ U = ta.TypeVar('U')
15
19
 
16
20
 
17
21
  ##
18
22
 
19
23
 
20
- class Once:
24
+ class SyncOnce:
21
25
  def __init__(self) -> None:
22
26
  super().__init__()
23
27
 
@@ -40,43 +44,43 @@ class Once:
40
44
  ##
41
45
 
42
46
 
43
- class Lazy(ta.Generic[T]):
47
+ class SyncLazy(ta.Generic[T]):
44
48
  def __init__(self) -> None:
45
49
  super().__init__()
46
50
 
47
- self._once = Once()
48
- self._v: lang.Maybe[T] = lang.empty()
51
+ self._once = SyncOnce()
52
+ self._v: Maybe[T] = Maybe.empty()
49
53
 
50
- def peek(self) -> lang.Maybe[T]:
54
+ def peek(self) -> Maybe[T]:
51
55
  return self._v
52
56
 
53
57
  def set(self, v: T) -> None:
54
- self._v = lang.just(v)
58
+ self._v = Maybe.just(v)
55
59
 
56
60
  def get(self, fn: ta.Callable[[], T]) -> T:
57
61
  def do():
58
- self._v = lang.just(fn())
62
+ self._v = Maybe.just(fn())
59
63
  self._once.do(do)
60
64
  return self._v.must()
61
65
 
62
66
 
63
- class LazyFn(ta.Generic[T]):
67
+ class SyncLazyFn(ta.Generic[T]):
64
68
  def __init__(self, fn: ta.Callable[[], T]) -> None:
65
69
  super().__init__()
66
70
 
67
71
  self._fn = fn
68
- self._once = Once()
69
- self._v: lang.Maybe[T] = lang.empty()
72
+ self._once = SyncOnce()
73
+ self._v: Maybe[T] = Maybe.empty()
70
74
 
71
- def peek(self) -> lang.Maybe[T]:
75
+ def peek(self) -> Maybe[T]:
72
76
  return self._v
73
77
 
74
78
  def set(self, v: T) -> None:
75
- self._v = lang.just(v)
79
+ self._v = Maybe.just(v)
76
80
 
77
81
  def get(self) -> T:
78
82
  def do():
79
- self._v = lang.just(self._fn())
83
+ self._v = Maybe.just(self._fn())
80
84
  self._once.do(do)
81
85
  return self._v.must()
82
86
 
@@ -89,11 +93,11 @@ class ConditionDeque(ta.Generic[T]):
89
93
  self,
90
94
  *,
91
95
  cond: ta.Optional['threading.Condition'] = None,
92
- deque: collections.deque[T] | None = None,
96
+ deque: ta.Optional[ta.Deque[T]] = None,
93
97
 
94
98
  lock: ta.Optional['threading.RLock'] = None,
95
- maxlen: int | None = None,
96
- init: ta.Iterable[T] | None = None,
99
+ maxlen: ta.Optional[int] = None,
100
+ init: ta.Optional[ta.Iterable[T]] = None,
97
101
  ) -> None:
98
102
  super().__init__()
99
103
 
@@ -112,7 +116,7 @@ class ConditionDeque(ta.Generic[T]):
112
116
  return self._cond
113
117
 
114
118
  @property
115
- def deque(self) -> collections.deque[T]:
119
+ def deque(self) -> ta.Deque[T]:
116
120
  return self._deque
117
121
 
118
122
  def push(
@@ -126,9 +130,9 @@ class ConditionDeque(ta.Generic[T]):
126
130
 
127
131
  def pop(
128
132
  self,
129
- timeout: float | None = None,
133
+ timeout: ta.Optional[float] = None,
130
134
  *,
131
- if_empty: ta.Callable[[], None] | None = None,
135
+ if_empty: ta.Optional[ta.Callable[[], None]] = None,
132
136
  ) -> T:
133
137
  with self.cond:
134
138
  if not self.deque and if_empty is not None:
@@ -136,3 +140,160 @@ class ConditionDeque(ta.Generic[T]):
136
140
  while not self.deque:
137
141
  self.cond.wait(timeout)
138
142
  return self.deque.popleft()
143
+
144
+
145
+ ##
146
+
147
+
148
+ class SyncBufferRelay(ta.Generic[T]):
149
+ def __init__(
150
+ self,
151
+ *,
152
+ wake_fn: ta.Callable[[], None],
153
+ ) -> None:
154
+ super().__init__()
155
+
156
+ self._wake_fn = wake_fn
157
+
158
+ self._lock = threading.Lock()
159
+ self._buffer: SyncBufferRelay._Buffer = SyncBufferRelay._Buffer()
160
+
161
+ class _Buffer:
162
+ def __init__(self) -> None:
163
+ self.lst: list = []
164
+ self.age = 0
165
+
166
+ def __repr__(self) -> str:
167
+ return f'{self.__class__.__qualname__}({self.lst!r}, age={self.age!r})'
168
+
169
+ def push(self, *vs: T) -> None:
170
+ with self._lock:
171
+ buf = self._buffer
172
+ needs_wake = not buf.age
173
+ buf.lst.extend(vs)
174
+ buf.age += 1
175
+ if needs_wake:
176
+ self._wake_fn()
177
+
178
+ def swap(self) -> ta.Sequence[T]:
179
+ with self._lock:
180
+ buf, self._buffer = self._buffer, SyncBufferRelay._Buffer()
181
+ return buf.lst
182
+
183
+
184
+ ##
185
+
186
+
187
+ class CountDownLatch:
188
+ def __init__(self, count: int) -> None:
189
+ super().__init__()
190
+
191
+ self._count = count
192
+ self._cond = threading.Condition()
193
+
194
+ def count_down(self) -> None:
195
+ with self._cond:
196
+ self._count -= 1
197
+ if self._count <= 0:
198
+ self._cond.notify_all()
199
+
200
+ def wait(
201
+ self,
202
+ timeout: ta.Optional[float] = None,
203
+ ) -> bool:
204
+ with self._cond:
205
+ return self._cond.wait_for(
206
+ lambda: self._count < 1,
207
+ timeout,
208
+ )
209
+
210
+
211
+ ##
212
+
213
+
214
+ class ObjectPool(ta.Generic[T]):
215
+ def __init__(self, new: ta.Optional[ta.Callable[[], T]] = None) -> None:
216
+ super().__init__()
217
+
218
+ self._new = new
219
+
220
+ self._lock = threading.Lock()
221
+ self._pool: ta.List[T] = []
222
+ self._closed: bool = False
223
+
224
+ #
225
+
226
+ class ClosedError(Exception):
227
+ pass
228
+
229
+ def _check_not_closed(self) -> None:
230
+ if self._closed:
231
+ raise ObjectPool.ClosedError
232
+
233
+ def close(self) -> None:
234
+ with self._lock:
235
+ self._closed = True
236
+
237
+ #
238
+
239
+ class EmptyError(Exception):
240
+ pass
241
+
242
+ def get(self, new: ta.Optional[ta.Callable[[], T]] = None) -> T:
243
+ with self._lock:
244
+ self._check_not_closed()
245
+ if self._pool:
246
+ return self._pool.pop()
247
+
248
+ if new is None:
249
+ new = self._new
250
+ if new is not None:
251
+ return new()
252
+
253
+ raise ObjectPool.EmptyError
254
+
255
+ def put(self, obj: T) -> None:
256
+ with self._lock:
257
+ self._check_not_closed()
258
+ self._pool.append(obj)
259
+
260
+ def acquire(self, new: ta.Optional[ta.Callable[[], T]] = None) -> ta.ContextManager[T]:
261
+ @contextlib.contextmanager
262
+ def inner():
263
+ o = self.get(new)
264
+ try:
265
+ yield o
266
+ finally:
267
+ self.put(o)
268
+
269
+ return inner()
270
+
271
+ def drain(self) -> ta.List[T]:
272
+ with self._lock:
273
+ out = self._pool
274
+ self._pool = []
275
+
276
+ return out
277
+
278
+ #
279
+
280
+ def manage(
281
+ self,
282
+ drain: ta.Optional[ta.Callable[[T], None]] = None,
283
+ ) -> ta.ContextManager['ObjectPool[T]']:
284
+ @contextlib.contextmanager
285
+ def inner():
286
+ with self._lock:
287
+ self._check_not_closed()
288
+
289
+ try:
290
+ yield self
291
+
292
+ finally:
293
+ self.close()
294
+
295
+ if drain is not None:
296
+ for o in self.drain():
297
+ drain(o)
298
+
299
+ return inner()