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
@@ -0,0 +1,56 @@
1
+ # ruff: noqa: UP043 UP045
2
+ # @omlish-lite
3
+ import dataclasses as dc
4
+ import typing as ta
5
+
6
+ from .asyncs import AsyncHttpClient
7
+ from .asyncs import AsyncStreamHttpResponse
8
+ from .base import HttpClientContext
9
+ from .base import HttpRequest
10
+ from .sync import HttpClient
11
+ from .sync import StreamHttpResponse
12
+
13
+
14
+ ##
15
+
16
+
17
+ class ExecutorAsyncHttpClient(AsyncHttpClient):
18
+ def __init__(
19
+ self,
20
+ run_in_executor: ta.Callable[..., ta.Awaitable],
21
+ client: HttpClient,
22
+ ) -> None:
23
+ super().__init__()
24
+
25
+ self._run_in_executor = run_in_executor
26
+ self._client = client
27
+
28
+ @dc.dataclass(frozen=True)
29
+ class _StreamAdapter:
30
+ owner: 'ExecutorAsyncHttpClient'
31
+ resp: StreamHttpResponse
32
+
33
+ async def read1(self, n: int = -1, /) -> bytes:
34
+ return await self.owner._run_in_executor(self.resp.stream.read1, n) # noqa
35
+
36
+ async def read(self, n: int = -1, /) -> bytes:
37
+ return await self.owner._run_in_executor(self.resp.stream.read, n) # noqa
38
+
39
+ async def readall(self) -> bytes:
40
+ return await self.owner._run_in_executor(self.resp.stream.readall) # noqa
41
+
42
+ async def close(self) -> None:
43
+ return await self.owner._run_in_executor(self.resp.close) # noqa
44
+
45
+ async def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> AsyncStreamHttpResponse:
46
+ resp: StreamHttpResponse = await self._run_in_executor(lambda: self._client.stream_request(req, context=ctx))
47
+ return AsyncStreamHttpResponse(
48
+ status=resp.status,
49
+ headers=resp.headers,
50
+ request=req,
51
+ underlying=resp,
52
+ **(dict( # type: ignore
53
+ _stream=(adapter := self._StreamAdapter(self, resp)),
54
+ _closer=adapter.close,
55
+ ) if resp.has_data else {}),
56
+ )
@@ -1,13 +1,22 @@
1
+ """
2
+ TODO:
3
+ - standardize following redirects
4
+ """
5
+ import contextlib
1
6
  import functools
2
7
  import typing as ta
3
8
 
4
9
  from ... import dataclasses as dc
5
10
  from ... import lang
11
+ from ...io.buffers import ReadableListBuffer
6
12
  from ..headers import HttpHeaders
7
- from .base import HttpClient
13
+ from .asyncs import AsyncHttpClient
14
+ from .asyncs import AsyncStreamHttpResponse
15
+ from .base import HttpClientContext
8
16
  from .base import HttpClientError
9
17
  from .base import HttpRequest
10
- from .base import StreamHttpResponse
18
+ from .sync import HttpClient
19
+ from .sync import StreamHttpResponse
11
20
 
12
21
 
13
22
  if ta.TYPE_CHECKING:
@@ -24,16 +33,13 @@ class HttpxHttpClient(HttpClient):
24
33
  class _StreamAdapter:
25
34
  it: ta.Iterator[bytes]
26
35
 
27
- def read(self, /, n: int = -1) -> bytes:
28
- if n < 0:
29
- return b''.join(self.it)
30
- else:
31
- try:
32
- return next(self.it)
33
- except StopIteration:
34
- return b''
36
+ def read1(self, n: int = -1, /) -> bytes:
37
+ try:
38
+ return next(self.it)
39
+ except StopIteration:
40
+ return b''
35
41
 
36
- def _stream_request(self, req: HttpRequest) -> StreamHttpResponse:
42
+ def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> StreamHttpResponse:
37
43
  try:
38
44
  resp_cm = httpx.stream(
39
45
  method=req.method_or_default,
@@ -55,7 +61,7 @@ class HttpxHttpClient(HttpClient):
55
61
  headers=HttpHeaders(resp.headers.raw),
56
62
  request=req,
57
63
  underlying=resp,
58
- stream=self._StreamAdapter(resp.iter_bytes()),
64
+ _stream=ReadableListBuffer().new_buffered_reader(self._StreamAdapter(resp.iter_bytes())),
59
65
  _closer=resp_close, # type: ignore
60
66
  )
61
67
 
@@ -63,6 +69,65 @@ class HttpxHttpClient(HttpClient):
63
69
  resp_close()
64
70
  raise HttpClientError from e
65
71
 
66
- except Exception:
72
+ except BaseException:
67
73
  resp_close()
68
74
  raise
75
+
76
+
77
+ ##
78
+
79
+
80
+ class HttpxAsyncHttpClient(AsyncHttpClient):
81
+ @dc.dataclass(frozen=True)
82
+ class _StreamAdapter:
83
+ it: ta.AsyncIterator[bytes]
84
+
85
+ async def read1(self, n: int = -1, /) -> bytes:
86
+ try:
87
+ return await anext(self.it)
88
+ except StopAsyncIteration:
89
+ return b''
90
+
91
+ async def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> AsyncStreamHttpResponse:
92
+ es = contextlib.AsyncExitStack()
93
+
94
+ try:
95
+ client = await es.enter_async_context(httpx.AsyncClient())
96
+
97
+ resp = await es.enter_async_context(client.stream(
98
+ method=req.method_or_default,
99
+ url=req.url,
100
+ headers=req.headers_ or None, # type: ignore
101
+ content=req.data,
102
+ timeout=req.timeout_s,
103
+ ))
104
+
105
+ it = resp.aiter_bytes()
106
+
107
+ # FIXME:
108
+ # this has a tendency to raise `RuntimeError: async generator ignored GeneratorExit` when all of the
109
+ # following conditions are met:
110
+ # - stopped iterating midway through
111
+ # - shutting down the event loop
112
+ # - debugging under pycharm / pydevd
113
+ # - running under asyncio
114
+ # it does not seem to happen unless all of these conditions are met. see:
115
+ # https://gist.github.com/wrmsr/a0578ee5d5371b53804cfb56aeb84cdf .
116
+ es.push_async_callback(it.aclose) # type: ignore[attr-defined]
117
+
118
+ return AsyncStreamHttpResponse(
119
+ status=resp.status_code,
120
+ headers=HttpHeaders(resp.headers.raw),
121
+ request=req,
122
+ underlying=resp,
123
+ _stream=ReadableListBuffer().new_async_buffered_reader(self._StreamAdapter(it)),
124
+ _closer=es.aclose,
125
+ )
126
+
127
+ except httpx.HTTPError as e:
128
+ await es.aclose()
129
+ raise HttpClientError from e
130
+
131
+ except BaseException:
132
+ await es.aclose()
133
+ raise
@@ -0,0 +1,181 @@
1
+ # ruff: noqa: UP007 UP043 UP045
2
+ # @omlish-lite
3
+ """
4
+ TODO:
5
+ - redirect
6
+ - referrer header?
7
+ - non-forwarded headers, host check, etc lol
8
+ - 'check' kw becomes StatusCheckingMiddleware?
9
+ """
10
+ import dataclasses as dc
11
+ import typing as ta
12
+ import urllib.parse
13
+
14
+ from ...lite.abstract import Abstract
15
+ from ...lite.check import check
16
+ from ..urls import parsed_url_replace
17
+ from .asyncs import AsyncHttpClient
18
+ from .asyncs import AsyncStreamHttpResponse
19
+ from .base import BaseHttpClient
20
+ from .base import BaseHttpResponse
21
+ from .base import HttpClientContext
22
+ from .base import HttpClientError
23
+ from .base import HttpRequest
24
+ from .sync import HttpClient
25
+ from .sync import StreamHttpResponse
26
+ from .sync import close_http_client_response
27
+
28
+
29
+ BaseHttpClientT = ta.TypeVar('BaseHttpClientT', bound=BaseHttpClient)
30
+
31
+
32
+ ##
33
+
34
+
35
+ class HttpClientMiddleware(Abstract):
36
+ def process_request(
37
+ self,
38
+ ctx: HttpClientContext,
39
+ req: HttpRequest,
40
+ ) -> HttpRequest:
41
+ return req
42
+
43
+ def process_response(
44
+ self,
45
+ ctx: HttpClientContext,
46
+ req: HttpRequest,
47
+ resp: BaseHttpResponse,
48
+ ) -> ta.Union[BaseHttpResponse, HttpRequest]:
49
+ return resp
50
+
51
+
52
+ class AbstractMiddlewareHttpClient(Abstract, ta.Generic[BaseHttpClientT]):
53
+ def __init__(
54
+ self,
55
+ client: BaseHttpClientT,
56
+ middlewares: ta.Iterable[HttpClientMiddleware],
57
+ ) -> None:
58
+ super().__init__()
59
+
60
+ self._client = client
61
+ self._middlewares = list(middlewares)
62
+
63
+ def _process_request(
64
+ self,
65
+ ctx: HttpClientContext,
66
+ req: HttpRequest,
67
+ ) -> HttpRequest:
68
+ for mw in self._middlewares:
69
+ req = mw.process_request(ctx, req)
70
+ return req
71
+
72
+ def _process_response(
73
+ self,
74
+ ctx: HttpClientContext,
75
+ req: HttpRequest,
76
+ resp: BaseHttpResponse,
77
+ ) -> ta.Union[BaseHttpResponse, HttpRequest]:
78
+ for mw in self._middlewares:
79
+ nxt = mw.process_response(ctx, req, resp)
80
+ if isinstance(nxt, HttpRequest):
81
+ return nxt
82
+ else:
83
+ resp = nxt
84
+ return resp
85
+
86
+
87
+ #
88
+
89
+
90
+ class MiddlewareHttpClient(AbstractMiddlewareHttpClient[HttpClient], HttpClient):
91
+ def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> StreamHttpResponse:
92
+ while True:
93
+ req = self._process_request(ctx, req)
94
+
95
+ resp = self._client.stream_request(req, context=ctx)
96
+
97
+ try:
98
+ out = self._process_response(ctx, req, resp)
99
+
100
+ if isinstance(out, HttpRequest):
101
+ close_http_client_response(resp)
102
+ req = out
103
+ continue
104
+
105
+ elif isinstance(out, StreamHttpResponse):
106
+ return out
107
+
108
+ else:
109
+ raise TypeError(out) # noqa
110
+
111
+ except Exception:
112
+ close_http_client_response(resp)
113
+ raise
114
+
115
+ raise RuntimeError
116
+
117
+
118
+ class MiddlewareAsyncHttpClient(AbstractMiddlewareHttpClient[AsyncHttpClient], AsyncHttpClient):
119
+ def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> ta.Awaitable[AsyncStreamHttpResponse]:
120
+ return self._client.stream_request(self._process_request(ctx, req))
121
+
122
+
123
+ ##
124
+
125
+
126
+ class TooManyRedirectsHttpClientError(HttpClientError):
127
+ pass
128
+
129
+
130
+ class RedirectHandlingHttpClientMiddleware(HttpClientMiddleware):
131
+ DEFAULT_MAX_REDIRECTS: ta.ClassVar[int] = 5
132
+
133
+ def __init__(
134
+ self,
135
+ *,
136
+ max_redirects: ta.Optional[int] = None,
137
+ ) -> None:
138
+ super().__init__()
139
+
140
+ if max_redirects is None:
141
+ max_redirects = self.DEFAULT_MAX_REDIRECTS
142
+ self._max_redirects = max_redirects
143
+
144
+ @dc.dataclass()
145
+ class _State:
146
+ num_redirects: int = 0
147
+
148
+ def _get_state(self, ctx: HttpClientContext) -> _State:
149
+ try:
150
+ return ctx._dct[self._State] # noqa
151
+ except KeyError:
152
+ ret = ctx._dct[self._State] = self._State() # noqa
153
+ return ret
154
+
155
+ def process_response(
156
+ self,
157
+ ctx: HttpClientContext,
158
+ req: HttpRequest,
159
+ resp: BaseHttpResponse,
160
+ ) -> ta.Union[BaseHttpResponse, HttpRequest]: # noqa
161
+ if resp.status == 302:
162
+ st = self._get_state(ctx)
163
+ if st.num_redirects >= self._max_redirects:
164
+ raise TooManyRedirectsHttpClientError
165
+ st.num_redirects += 1
166
+
167
+ rd_url = check.not_none(resp.headers).single_str_dct['location']
168
+
169
+ rd_purl = urllib.parse.urlparse(rd_url)
170
+ if not rd_purl.netloc:
171
+ rq_purl = urllib.parse.urlparse(req.url)
172
+ rd_purl = parsed_url_replace(
173
+ rd_purl,
174
+ scheme=rq_purl.scheme,
175
+ netloc=rq_purl.netloc,
176
+ )
177
+ rd_url = urllib.parse.urlunparse(rd_purl)
178
+
179
+ return dc.replace(req, url=rd_url)
180
+
181
+ return resp
@@ -0,0 +1,151 @@
1
+ # ruff: noqa: UP045
2
+ # @omlish-lite
3
+ import abc
4
+ import contextlib
5
+ import dataclasses as dc
6
+ import typing as ta
7
+
8
+ from ...io.readers import BufferedBytesReader
9
+ from ...lite.abstract import Abstract
10
+ from ...lite.dataclasses import dataclass_shallow_asdict
11
+ from .base import BaseHttpClient
12
+ from .base import BaseHttpResponse
13
+ from .base import BaseHttpResponseT
14
+ from .base import HttpClientContext
15
+ from .base import HttpRequest
16
+ from .base import HttpResponse
17
+ from .base import HttpStatusError
18
+
19
+
20
+ StreamHttpResponseT = ta.TypeVar('StreamHttpResponseT', bound='StreamHttpResponse')
21
+ HttpClientT = ta.TypeVar('HttpClientT', bound='HttpClient')
22
+
23
+
24
+ ##
25
+
26
+
27
+ @ta.final
28
+ @dc.dataclass(frozen=True) # kw_only=True
29
+ class StreamHttpResponse(BaseHttpResponse):
30
+ _stream: ta.Optional[BufferedBytesReader] = None
31
+
32
+ @property
33
+ def stream(self) -> 'BufferedBytesReader':
34
+ if (st := self._stream) is None:
35
+ raise TypeError('No data')
36
+ return st
37
+
38
+ @property
39
+ def has_data(self) -> bool:
40
+ return self._stream is not None
41
+
42
+ #
43
+
44
+ _closer: ta.Optional[ta.Callable[[], None]] = None
45
+
46
+ def __enter__(self: StreamHttpResponseT) -> StreamHttpResponseT:
47
+ return self
48
+
49
+ def __exit__(self, exc_type, exc_val, exc_tb):
50
+ self.close()
51
+
52
+ def close(self) -> None:
53
+ if (c := self._closer) is not None:
54
+ c() # noqa
55
+
56
+
57
+ #
58
+
59
+
60
+ def close_http_client_response(resp: BaseHttpResponse) -> None:
61
+ if isinstance(resp, HttpResponse):
62
+ pass
63
+
64
+ elif isinstance(resp, StreamHttpResponse):
65
+ resp.close()
66
+
67
+ else:
68
+ raise TypeError(resp)
69
+
70
+
71
+ @contextlib.contextmanager
72
+ def closing_http_client_response(resp: BaseHttpResponseT) -> ta.Iterator[BaseHttpResponseT]:
73
+ if isinstance(resp, HttpResponse):
74
+ yield resp
75
+ return
76
+
77
+ elif isinstance(resp, StreamHttpResponse):
78
+ with contextlib.closing(resp):
79
+ yield resp
80
+
81
+ else:
82
+ raise TypeError(resp)
83
+
84
+
85
+ def read_http_client_response(resp: BaseHttpResponse) -> HttpResponse:
86
+ if isinstance(resp, HttpResponse):
87
+ return resp
88
+
89
+ elif isinstance(resp, StreamHttpResponse):
90
+ return HttpResponse(**{
91
+ **{k: v for k, v in dataclass_shallow_asdict(resp).items() if k not in ('_stream', '_closer')},
92
+ **({'data': resp.stream.readall()} if resp.has_data else {}),
93
+ })
94
+
95
+ else:
96
+ raise TypeError(resp)
97
+
98
+
99
+ ##
100
+
101
+
102
+ class HttpClient(BaseHttpClient, Abstract):
103
+ def __enter__(self: HttpClientT) -> HttpClientT:
104
+ return self
105
+
106
+ def __exit__(self, exc_type, exc_val, exc_tb):
107
+ pass
108
+
109
+ def request(
110
+ self,
111
+ req: HttpRequest,
112
+ *,
113
+ context: ta.Optional[HttpClientContext] = None,
114
+ check: bool = False,
115
+ ) -> HttpResponse:
116
+ with closing_http_client_response(self.stream_request(
117
+ req,
118
+ context=context,
119
+ check=check,
120
+ )) as resp:
121
+ return read_http_client_response(resp)
122
+
123
+ def stream_request(
124
+ self,
125
+ req: HttpRequest,
126
+ *,
127
+ context: ta.Optional[HttpClientContext] = None,
128
+ check: bool = False,
129
+ ) -> StreamHttpResponse:
130
+ if context is None:
131
+ context = HttpClientContext()
132
+
133
+ resp = self._stream_request(context, req)
134
+
135
+ try:
136
+ if check and not resp.is_success:
137
+ if isinstance(resp.underlying, Exception):
138
+ cause = resp.underlying
139
+ else:
140
+ cause = None
141
+ raise HttpStatusError(read_http_client_response(resp)) from cause # noqa
142
+
143
+ except Exception:
144
+ close_http_client_response(resp)
145
+ raise
146
+
147
+ return resp
148
+
149
+ @abc.abstractmethod
150
+ def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> StreamHttpResponse:
151
+ raise NotImplementedError
@@ -0,0 +1,49 @@
1
+ # ruff: noqa: UP043 UP045
2
+ # @omlish-lite
3
+ import dataclasses as dc
4
+
5
+ from .asyncs import AsyncHttpClient
6
+ from .asyncs import AsyncStreamHttpResponse
7
+ from .base import HttpClientContext
8
+ from .base import HttpRequest
9
+ from .sync import HttpClient
10
+ from .sync import StreamHttpResponse
11
+
12
+
13
+ ##
14
+
15
+
16
+ class SyncAsyncHttpClient(AsyncHttpClient):
17
+ def __init__(self, client: HttpClient) -> None:
18
+ super().__init__()
19
+
20
+ self._client = client
21
+
22
+ @dc.dataclass(frozen=True)
23
+ class _StreamAdapter:
24
+ ul: StreamHttpResponse
25
+
26
+ async def read1(self, n: int = -1, /) -> bytes:
27
+ return self.ul.stream.read1(n)
28
+
29
+ async def read(self, n: int = -1, /) -> bytes:
30
+ return self.ul.stream.read(n)
31
+
32
+ async def readall(self) -> bytes:
33
+ return self.ul.stream.readall()
34
+
35
+ async def close(self) -> None:
36
+ self.ul.close()
37
+
38
+ async def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> AsyncStreamHttpResponse:
39
+ resp = self._client.stream_request(req, context=ctx)
40
+ return AsyncStreamHttpResponse(
41
+ status=resp.status,
42
+ headers=resp.headers,
43
+ request=req,
44
+ underlying=resp,
45
+ **(dict( # type: ignore
46
+ _stream=(adapter := self._StreamAdapter(resp)),
47
+ _closer=adapter.close,
48
+ ) if resp.has_data else {}),
49
+ )
@@ -1,14 +1,18 @@
1
+ # ruff: noqa: UP043 UP045
2
+ # @omlish-lite
1
3
  import http.client
2
4
  import typing as ta
3
5
  import urllib.error
4
6
  import urllib.request
5
7
 
8
+ from ...io.buffers import ReadableListBuffer
6
9
  from ..headers import HttpHeaders
7
10
  from .base import DEFAULT_ENCODING
8
- from .base import HttpClient
11
+ from .base import HttpClientContext
9
12
  from .base import HttpClientError
10
13
  from .base import HttpRequest
11
- from .base import StreamHttpResponse
14
+ from .sync import HttpClient
15
+ from .sync import StreamHttpResponse
12
16
 
13
17
 
14
18
  ##
@@ -39,7 +43,7 @@ class UrllibHttpClient(HttpClient):
39
43
  data=d,
40
44
  )
41
45
 
42
- def _stream_request(self, req: HttpRequest) -> StreamHttpResponse:
46
+ def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> StreamHttpResponse:
43
47
  try:
44
48
  resp = urllib.request.urlopen( # noqa
45
49
  self._build_request(req),
@@ -53,7 +57,6 @@ class UrllibHttpClient(HttpClient):
53
57
  headers=HttpHeaders(e.headers.items()),
54
58
  request=req,
55
59
  underlying=e,
56
- stream=e, # noqa
57
60
  _closer=e.close,
58
61
  )
59
62
 
@@ -70,7 +73,7 @@ class UrllibHttpClient(HttpClient):
70
73
  headers=HttpHeaders(resp.headers.items()),
71
74
  request=req,
72
75
  underlying=resp,
73
- stream=resp,
76
+ _stream=ReadableListBuffer().new_buffered_reader(resp),
74
77
  _closer=resp.close,
75
78
  )
76
79