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
@@ -1,18 +1,20 @@
1
+ # ruff: noqa: UP006 UP007 UP045
2
+ # @omlish-lite
1
3
  """
2
4
  TODO:
5
+ - ?? lite ?? whole point is an async client in lite code
3
6
  - stream
4
7
  - chunk size - httpx interface is awful, punch through?
5
8
  - httpx catch
6
9
  - return non-200 HttpResponses
7
10
  - async
8
11
  """
9
- import abc
10
- import contextlib
12
+ import dataclasses as dc
11
13
  import typing as ta
12
14
 
13
- from ... import cached
14
- from ... import dataclasses as dc
15
- from ... import lang
15
+ from ...lite.abstract import Abstract
16
+ from ...lite.attrops import AttrOps
17
+ from ...lite.cached import cached_property
16
18
  from ..headers import CanHttpHeaders
17
19
  from ..headers import HttpHeaders
18
20
 
@@ -33,17 +35,28 @@ def is_success_status(status: int) -> bool:
33
35
  ##
34
36
 
35
37
 
38
+ @ta.final
36
39
  @dc.dataclass(frozen=True)
37
- class HttpRequest(lang.Final):
40
+ class HttpRequest:
38
41
  url: str
39
- method: str | None = None # noqa
42
+ method: ta.Optional[str] = None # noqa
40
43
 
41
- _: dc.KW_ONLY
44
+ # _: dc.KW_ONLY
42
45
 
43
- headers: CanHttpHeaders | None = dc.xfield(None, repr=dc.truthy_repr)
44
- data: bytes | str | None = dc.xfield(None, repr_fn=lambda v: '...' if v is not None else None)
46
+ headers: ta.Optional[CanHttpHeaders] = None
47
+ data: ta.Union[bytes, str, None] = None
45
48
 
46
- timeout_s: float | None = None
49
+ timeout_s: ta.Optional[float] = None
50
+
51
+ #
52
+
53
+ __repr__ = AttrOps['HttpRequest'](lambda o: (
54
+ o.url,
55
+ o.method,
56
+ (o.headers, dict(repr_fn=AttrOps.truthy_repr)),
57
+ (o.data, dict(repr_fn=lambda v: '...' if v is not None else None)),
58
+ (o.timeout_s, dict(repr_fn=AttrOps.opt_repr)),
59
+ )).repr
47
60
 
48
61
  #
49
62
 
@@ -55,151 +68,79 @@ class HttpRequest(lang.Final):
55
68
  return 'POST'
56
69
  return 'GET'
57
70
 
58
- @cached.property
59
- def headers_(self) -> HttpHeaders | None:
71
+ @cached_property
72
+ def headers_(self) -> ta.Optional[HttpHeaders]:
60
73
  return HttpHeaders(self.headers) if self.headers is not None else None
61
74
 
62
75
 
63
76
  #
64
77
 
65
78
 
66
- @dc.dataclass(frozen=True, kw_only=True)
67
- class BaseHttpResponse(lang.Abstract):
68
- status: int
69
-
70
- headers: HttpHeaders | None = dc.xfield(None, repr=dc.truthy_repr)
71
-
79
+ @dc.dataclass(frozen=True) # kw_only=True
80
+ class BaseHttpResponse(Abstract):
72
81
  request: HttpRequest
73
- underlying: ta.Any = dc.field(default=None, repr=False)
74
-
75
- @property
76
- def is_success(self) -> bool:
77
- return is_success_status(self.status)
78
-
79
-
80
- @dc.dataclass(frozen=True, kw_only=True)
81
- class HttpResponse(BaseHttpResponse, lang.Final):
82
- data: bytes | None = dc.xfield(None, repr_fn=lambda v: '...' if v is not None else None)
83
-
84
-
85
- @dc.dataclass(frozen=True, kw_only=True)
86
- class StreamHttpResponse(BaseHttpResponse, lang.Final):
87
- class Stream(ta.Protocol):
88
- def read(self, /, n: int = -1) -> bytes: ...
89
-
90
- stream: Stream
91
82
 
92
- _closer: ta.Callable[[], None] | None = dc.field(default=None, repr=False)
93
-
94
- def __enter__(self) -> ta.Self:
95
- return self
83
+ status: int
96
84
 
97
- def __exit__(self, exc_type, exc_val, exc_tb):
98
- self.close()
85
+ headers: ta.Optional[HttpHeaders] = None
99
86
 
100
- def close(self) -> None:
101
- if (c := self._closer) is not None:
102
- c()
87
+ underlying: ta.Any = None
103
88
 
89
+ #
104
90
 
105
- def close_response(resp: BaseHttpResponse) -> None:
106
- if isinstance(resp, HttpResponse):
107
- pass
91
+ __repr__ = AttrOps['BaseHttpResponse'](lambda o: (
92
+ o.status,
93
+ (o.headers, dict(repr_fn=AttrOps.truthy_repr)),
94
+ o.request,
95
+ )).repr
108
96
 
109
- elif isinstance(resp, StreamHttpResponse):
110
- resp.close()
97
+ #
111
98
 
112
- else:
113
- raise TypeError(resp)
99
+ @property
100
+ def is_success(self) -> bool:
101
+ return is_success_status(self.status)
114
102
 
115
103
 
116
- @contextlib.contextmanager
117
- def closing_response(resp: BaseHttpResponseT) -> ta.Iterator[BaseHttpResponseT]:
118
- if isinstance(resp, HttpResponse):
119
- yield resp
120
- return
104
+ @ta.final
105
+ @dc.dataclass(frozen=True) # kw_only=True
106
+ class HttpResponse(BaseHttpResponse):
107
+ data: ta.Optional[bytes] = None
121
108
 
122
- elif isinstance(resp, StreamHttpResponse):
123
- with contextlib.closing(resp):
124
- yield resp
109
+ #
125
110
 
126
- else:
127
- raise TypeError(resp)
111
+ __repr__ = AttrOps['HttpResponse'](lambda o: (
112
+ o.status,
113
+ (o.headers, dict(repr_fn=AttrOps.truthy_repr)),
114
+ (o.data, dict(repr_fn=lambda v: '...' if v is not None else None)),
115
+ o.request,
116
+ )).repr
128
117
 
129
118
 
130
- def read_response(resp: BaseHttpResponse) -> HttpResponse:
131
- if isinstance(resp, HttpResponse):
132
- return resp
119
+ ##
133
120
 
134
- elif isinstance(resp, StreamHttpResponse):
135
- data = resp.stream.read()
136
- return HttpResponse(**{
137
- **{k: v for k, v in dc.shallow_asdict(resp).items() if k not in ('stream', '_closer')},
138
- 'data': data,
139
- })
140
121
 
141
- else:
142
- raise TypeError(resp)
122
+ @ta.final
123
+ class HttpClientContext:
124
+ def __init__(self) -> None:
125
+ self._dct: dict = {}
143
126
 
144
127
 
145
- #
128
+ ##
146
129
 
147
130
 
148
131
  class HttpClientError(Exception):
149
132
  @property
150
- def cause(self) -> BaseException | None:
133
+ def cause(self) -> ta.Optional[BaseException]:
151
134
  return self.__cause__
152
135
 
153
136
 
154
- @dc.dataclass(frozen=True)
137
+ @dc.dataclass()
155
138
  class HttpStatusError(HttpClientError):
156
139
  response: HttpResponse
157
140
 
158
141
 
159
- #
142
+ ##
160
143
 
161
144
 
162
- class HttpClient(lang.Abstract):
163
- def __enter__(self) -> ta.Self:
164
- return self
165
-
166
- def __exit__(self, exc_type, exc_val, exc_tb):
167
- pass
168
-
169
- def request(
170
- self,
171
- req: HttpRequest,
172
- *,
173
- check: bool = False,
174
- ) -> HttpResponse:
175
- with closing_response(self.stream_request(
176
- req,
177
- check=check,
178
- )) as resp:
179
- return read_response(resp)
180
-
181
- def stream_request(
182
- self,
183
- req: HttpRequest,
184
- *,
185
- check: bool = False,
186
- ) -> StreamHttpResponse:
187
- resp = self._stream_request(req)
188
-
189
- try:
190
- if check and not resp.is_success:
191
- if isinstance(resp.underlying, Exception):
192
- cause = resp.underlying
193
- else:
194
- cause = None
195
- raise HttpStatusError(read_response(resp)) from cause # noqa
196
-
197
- except Exception:
198
- close_response(resp)
199
- raise
200
-
201
- return resp
202
-
203
- @abc.abstractmethod
204
- def _stream_request(self, req: HttpRequest) -> StreamHttpResponse:
205
- raise NotImplementedError
145
+ class BaseHttpClient(Abstract):
146
+ pass
@@ -0,0 +1,171 @@
1
+ # @omlish-lite
2
+ # ruff: noqa: UP045
3
+ import errno
4
+ import socket
5
+ import typing as ta
6
+ import urllib.parse
7
+
8
+ from ....io.buffers import ReadableListBuffer
9
+ from ....lite.check import check
10
+ from ...coro.client.connection import CoroHttpClientConnection
11
+ from ...coro.client.response import CoroHttpClientResponse
12
+ from ...coro.io import CoroHttpIo
13
+ from ...headers import HttpHeaders
14
+ from ...urls import unparse_url_request_path
15
+ from ..base import HttpClientContext
16
+ from ..base import HttpClientError
17
+ from ..base import HttpRequest
18
+ from ..sync import HttpClient
19
+ from ..sync import StreamHttpResponse
20
+
21
+
22
+ T = ta.TypeVar('T')
23
+
24
+
25
+ ##
26
+
27
+
28
+ class CoroHttpClient(HttpClient):
29
+ class _Connection:
30
+ def __init__(self, req: HttpRequest) -> None:
31
+ super().__init__()
32
+
33
+ self._req = req
34
+ self._ups = urllib.parse.urlparse(req.url)
35
+
36
+ self._ssl = self._ups.scheme == 'https'
37
+
38
+ _cc: ta.Optional[CoroHttpClientConnection] = None
39
+ _resp: ta.Optional[CoroHttpClientResponse] = None
40
+
41
+ _sock: ta.Optional[socket.socket] = None
42
+ _sock_file: ta.Optional[ta.BinaryIO] = None
43
+
44
+ _ssl_context: ta.Any = None
45
+
46
+ #
47
+
48
+ def _create_https_context(self, http_version: int) -> ta.Any:
49
+ # https://github.com/python/cpython/blob/a7160912274003672dc116d918260c0a81551c21/Lib/http/client.py#L809
50
+ import ssl
51
+
52
+ # Function also used by urllib.request to be able to set the check_hostname attribute on a context object.
53
+ context = ssl.create_default_context()
54
+
55
+ # Send ALPN extension to indicate HTTP/1.1 protocol.
56
+ if http_version == 11:
57
+ context.set_alpn_protocols(['http/1.1'])
58
+
59
+ # Enable PHA for TLS 1.3 connections if available.
60
+ if context.post_handshake_auth is not None:
61
+ context.post_handshake_auth = True
62
+
63
+ return context
64
+
65
+ #
66
+
67
+ def setup(self) -> StreamHttpResponse:
68
+ check.none(self._sock)
69
+ check.none(self._ssl_context)
70
+
71
+ self._cc = cc = CoroHttpClientConnection(
72
+ check.not_none(self._ups.hostname),
73
+ default_port=CoroHttpClientConnection.HTTPS_PORT if self._ssl else CoroHttpClientConnection.HTTP_PORT,
74
+ )
75
+
76
+ if self._ssl:
77
+ self._ssl_context = self._create_https_context(self._cc.http_version)
78
+
79
+ try:
80
+ self._run_coro(cc.connect())
81
+
82
+ self._run_coro(cc.request(
83
+ self._req.method or 'GET',
84
+ unparse_url_request_path(self._ups) or '/',
85
+ self._req.data,
86
+ hh.single_str_dct if (hh := self._req.headers_) is not None else {},
87
+ ))
88
+
89
+ self._resp = resp = self._run_coro(cc.get_response())
90
+
91
+ return StreamHttpResponse(
92
+ status=resp._state.status, # noqa
93
+ headers=HttpHeaders(resp._state.headers.items()), # noqa
94
+ request=self._req,
95
+ underlying=self,
96
+ _stream=ReadableListBuffer().new_buffered_reader(self),
97
+ _closer=self.close,
98
+ )
99
+
100
+ except Exception:
101
+ self.close()
102
+ raise
103
+
104
+ def _run_coro(self, g: ta.Generator[ta.Any, ta.Any, T]) -> T:
105
+ i = None
106
+
107
+ while True:
108
+ try:
109
+ o = g.send(i)
110
+ except StopIteration as e:
111
+ return e.value
112
+
113
+ try:
114
+ i = self._handle_io(o)
115
+ except OSError as e:
116
+ raise HttpClientError from e
117
+
118
+ def _handle_io(self, o: CoroHttpIo.Io) -> ta.Any:
119
+ if isinstance(o, CoroHttpIo.ConnectIo):
120
+ check.none(self._sock)
121
+ self._sock = socket.create_connection(*o.args, **(o.kwargs or {}))
122
+
123
+ if self._ssl_context is not None:
124
+ self._sock = self._ssl_context.wrap_socket(
125
+ self._sock,
126
+ server_hostname=check.not_none(o.server_hostname),
127
+ )
128
+
129
+ # Might fail in OSs that don't implement TCP_NODELAY
130
+ try:
131
+ self._sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
132
+ except OSError as e:
133
+ if e.errno != errno.ENOPROTOOPT:
134
+ raise
135
+
136
+ self._sock_file = self._sock.makefile('rb')
137
+
138
+ return None
139
+
140
+ elif isinstance(o, CoroHttpIo.CloseIo):
141
+ check.not_none(self._sock).close()
142
+ return None
143
+
144
+ elif isinstance(o, CoroHttpIo.WriteIo):
145
+ check.not_none(self._sock).sendall(o.data)
146
+ return None
147
+
148
+ elif isinstance(o, CoroHttpIo.ReadIo):
149
+ if (sz := o.sz) is not None:
150
+ return check.not_none(self._sock_file).read(sz)
151
+ else:
152
+ return check.not_none(self._sock_file).read()
153
+
154
+ elif isinstance(o, CoroHttpIo.ReadLineIo):
155
+ return check.not_none(self._sock_file).readline(o.sz)
156
+
157
+ else:
158
+ raise TypeError(o)
159
+
160
+ def read1(self, n: int = -1, /) -> bytes:
161
+ return self._run_coro(check.not_none(self._resp).read(n if n >= 0 else None))
162
+
163
+ def close(self) -> None:
164
+ if self._resp is not None:
165
+ self._resp.close()
166
+ if self._sock is not None:
167
+ self._sock.close()
168
+
169
+ def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> StreamHttpResponse:
170
+ conn = CoroHttpClient._Connection(req)
171
+ return conn.setup()
@@ -1,60 +1,239 @@
1
+ import abc
2
+ import contextlib
1
3
  import typing as ta
2
4
 
5
+ from ... import lang
3
6
  from ..headers import CanHttpHeaders
4
- from .base import HttpClient
7
+ from .asyncs import AsyncHttpClient
8
+ from .base import HttpClientContext
5
9
  from .base import HttpRequest
6
10
  from .base import HttpResponse
7
- from .urllib import UrllibHttpClient
11
+ from .sync import HttpClient
12
+
13
+
14
+ with lang.auto_proxy_import(globals()):
15
+ from . import httpx as _httpx
16
+ from . import urllib as _urllib
17
+
18
+
19
+ C = ta.TypeVar('C')
20
+ R = ta.TypeVar('R')
21
+
22
+
23
+ ##
24
+
25
+
26
+ class _DefaultRequester(lang.Abstract, ta.Generic[C, R]):
27
+ def __call__(
28
+ self,
29
+ url: str,
30
+ method: str | None = None,
31
+ *,
32
+ headers: CanHttpHeaders | None = None,
33
+ data: bytes | str | None = None,
34
+
35
+ timeout_s: float | None = None,
36
+
37
+ context: HttpClientContext | None = None,
38
+ check: bool = False,
39
+ client: C | None = None, # noqa
40
+
41
+ **kwargs: ta.Any,
42
+ ) -> R:
43
+ request = HttpRequest( # noqa
44
+ url,
45
+ method=method,
46
+
47
+ headers=headers,
48
+ data=data,
49
+
50
+ timeout_s=timeout_s,
51
+
52
+ **kwargs,
53
+ )
54
+
55
+ return self._do(
56
+ request,
57
+ context=context,
58
+ check=check,
59
+ client=client,
60
+ )
61
+
62
+ @abc.abstractmethod
63
+ def _do(
64
+ self,
65
+ request: HttpRequest, # noqa
66
+ *,
67
+ context: HttpClientContext | None = None,
68
+ check: bool = False,
69
+ client: C | None = None, # noqa
70
+ ) -> R:
71
+ raise NotImplementedError
8
72
 
9
73
 
10
74
  ##
11
75
 
12
76
 
13
77
  def _default_client() -> HttpClient:
14
- return UrllibHttpClient()
78
+ return _urllib.UrllibHttpClient()
15
79
 
16
80
 
17
81
  def client() -> HttpClient:
18
82
  return _default_client()
19
83
 
20
84
 
21
- def request(
22
- url: str,
23
- method: str | None = None,
24
- *,
25
- headers: CanHttpHeaders | None = None,
26
- data: bytes | str | None = None,
85
+ @contextlib.contextmanager
86
+ def manage_client(client: HttpClient | None = None) -> ta.Generator[HttpClient]: # noqa
87
+ if client is not None:
88
+ yield client
89
+
90
+ else:
91
+ with _default_client() as client: # noqa
92
+ yield client
93
+
94
+
95
+ #
96
+
97
+
98
+ class _BaseSyncDefaultRequester(_DefaultRequester[HttpClient, R], lang.Abstract, ta.Generic[R]):
99
+ def _do(
100
+ self,
101
+ request: HttpRequest, # noqa
102
+ *,
103
+ context: HttpClientContext | None = None,
104
+ check: bool = False,
105
+ client: HttpClient | None = None, # noqa
106
+ ) -> R:
107
+ if context is None:
108
+ context = HttpClientContext()
109
+
110
+ if client is not None:
111
+ return self._do_(
112
+ client,
113
+ context,
114
+ request,
115
+ check=check,
116
+ )
117
+
118
+ else:
119
+ with _default_client() as client: # noqa
120
+ return self._do_(
121
+ client,
122
+ context,
123
+ request,
124
+ check=check,
125
+ )
126
+
127
+ @abc.abstractmethod
128
+ def _do_(
129
+ self,
130
+ client: HttpClient, # noqa
131
+ context: HttpClientContext,
132
+ request: HttpRequest, # noqa
133
+ *,
134
+ check: bool = False, # noqa
135
+ ) -> R:
136
+ raise NotImplementedError
137
+
138
+
139
+ class _SyncDefaultRequester(_BaseSyncDefaultRequester[HttpResponse]):
140
+ def _do_(
141
+ self,
142
+ client: HttpClient, # noqa
143
+ context: HttpClientContext,
144
+ request: HttpRequest, # noqa
145
+ *,
146
+ check: bool = False, # noqa
147
+ ) -> HttpResponse:
148
+ return client.request(
149
+ request,
150
+ context=context,
151
+ check=check,
152
+ )
153
+
154
+
155
+ request = _SyncDefaultRequester()
27
156
 
28
- timeout_s: float | None = None,
29
157
 
30
- check: bool = False,
158
+ ##
31
159
 
32
- client: HttpClient | None = None, # noqa
33
160
 
34
- **kwargs: ta.Any,
35
- ) -> HttpResponse:
36
- req = HttpRequest(
37
- url,
38
- method=method,
161
+ def _default_async_client() -> AsyncHttpClient:
162
+ return _httpx.HttpxAsyncHttpClient()
39
163
 
40
- headers=headers,
41
- data=data,
42
164
 
43
- timeout_s=timeout_s,
165
+ def async_client() -> AsyncHttpClient:
166
+ return _default_async_client()
44
167
 
45
- **kwargs,
46
- )
47
168
 
48
- def do(cli: HttpClient) -> HttpResponse:
49
- return cli.request(
50
- req,
169
+ @contextlib.asynccontextmanager
170
+ async def manage_async_client(client: AsyncHttpClient | None = None) -> ta.AsyncGenerator[AsyncHttpClient]: # noqa
171
+ if client is not None:
172
+ yield client
51
173
 
174
+ else:
175
+ async with _default_async_client() as client: # noqa
176
+ yield client
177
+
178
+
179
+ #
180
+
181
+
182
+ class _BaseAsyncDefaultRequester(_DefaultRequester[AsyncHttpClient, ta.Awaitable[R]], lang.Abstract, ta.Generic[R]):
183
+ async def _do(
184
+ self,
185
+ request: HttpRequest, # noqa
186
+ *,
187
+ context: HttpClientContext | None = None,
188
+ check: bool = False,
189
+ client: AsyncHttpClient | None = None, # noqa
190
+ ) -> R:
191
+ if context is None:
192
+ context = HttpClientContext()
193
+
194
+ if client is not None:
195
+ return await self._do_(
196
+ client,
197
+ context,
198
+ request,
199
+ check=check,
200
+ )
201
+
202
+ else:
203
+ async with _default_async_client() as client: # noqa
204
+ return await self._do_(
205
+ client,
206
+ context,
207
+ request,
208
+ check=check,
209
+ )
210
+
211
+ @abc.abstractmethod
212
+ def _do_(
213
+ self,
214
+ client: AsyncHttpClient, # noqa
215
+ context: HttpClientContext,
216
+ request: HttpRequest, # noqa
217
+ *,
218
+ check: bool = False, # noqa
219
+ ) -> ta.Awaitable[R]:
220
+ raise NotImplementedError
221
+
222
+
223
+ class _AsyncDefaultRequester(_BaseAsyncDefaultRequester[HttpResponse]):
224
+ async def _do_(
225
+ self,
226
+ client: AsyncHttpClient, # noqa
227
+ context: HttpClientContext,
228
+ request: HttpRequest, # noqa
229
+ *,
230
+ check: bool = False,
231
+ ) -> HttpResponse: # noqa
232
+ return await client.request(
233
+ request,
234
+ context=context,
52
235
  check=check,
53
236
  )
54
237
 
55
- if client is not None:
56
- return do(client)
57
238
 
58
- else:
59
- with _default_client() as cli:
60
- return do(cli)
239
+ async_request = _AsyncDefaultRequester()