omxtra 0.0.0.dev535__tar.gz → 0.0.0.dev536__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. {omxtra-0.0.0.dev535/omxtra.egg-info → omxtra-0.0.0.dev536}/PKG-INFO +2 -2
  2. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/_amalg.py +2 -2
  3. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/bytes/decoders.py +96 -69
  4. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/core.py +34 -5
  5. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/drivers/asyncio.py +25 -1
  6. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/drivers/sync.py +2 -0
  7. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/errors.py +11 -3
  8. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/flow/types.py +19 -10
  9. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/handlers/decoders.py +1 -8
  10. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/handlers/flatmap.py +24 -4
  11. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/handlers/queues.py +22 -14
  12. omxtra-0.0.0.dev536/omxtra/io/pipelines/http/aggregators.py +257 -0
  13. omxtra-0.0.0.dev536/omxtra/io/pipelines/http/client/requests.py +18 -0
  14. omxtra-0.0.0.dev536/omxtra/io/pipelines/http/client/responses.py +50 -0
  15. omxtra-0.0.0.dev535/omxtra/io/pipelines/http/decoders2/objects.py → omxtra-0.0.0.dev536/omxtra/io/pipelines/http/decoders.py +98 -81
  16. omxtra-0.0.0.dev535/omxtra/io/pipelines/http/client/responses.py → omxtra-0.0.0.dev536/omxtra/io/pipelines/http/decompressors.py +118 -179
  17. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/http/encoders.py +54 -64
  18. omxtra-0.0.0.dev536/omxtra/io/pipelines/http/objects.py +165 -0
  19. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/http/requests.py +66 -3
  20. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/http/responses.py +66 -3
  21. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/http/server/apps/asgi.py +13 -2
  22. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/http/server/apps/wsgi.py +10 -0
  23. omxtra-0.0.0.dev536/omxtra/io/pipelines/http/server/requests.py +50 -0
  24. omxtra-0.0.0.dev536/omxtra/io/pipelines/http/server/responses.py +18 -0
  25. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/http/sse.py +1 -1
  26. omxtra-0.0.0.dev536/omxtra/io/pipelines/http/transferencoding.py +48 -0
  27. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/ssl/handlers.py +4 -1
  28. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/scripts/lib/io/pipelines.py +1721 -1290
  29. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536/omxtra.egg-info}/PKG-INFO +2 -2
  30. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra.egg-info/SOURCES.txt +3 -6
  31. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra.egg-info/requires.txt +1 -1
  32. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/pyproject.toml +2 -2
  33. omxtra-0.0.0.dev535/omxtra/io/pipelines/_old/flow/flow.py +0 -268
  34. omxtra-0.0.0.dev535/omxtra/io/pipelines/bytes/decoders2.py +0 -234
  35. omxtra-0.0.0.dev535/omxtra/io/pipelines/http/client/requests.py +0 -54
  36. omxtra-0.0.0.dev535/omxtra/io/pipelines/http/decoders.py +0 -527
  37. omxtra-0.0.0.dev535/omxtra/io/pipelines/http/objects.py +0 -80
  38. omxtra-0.0.0.dev535/omxtra/io/pipelines/http/server/requests.py +0 -318
  39. omxtra-0.0.0.dev535/omxtra/io/pipelines/http/server/responses.py +0 -54
  40. omxtra-0.0.0.dev535/omxtra/sql/parsing/_antlr/__init__.py +0 -0
  41. omxtra-0.0.0.dev535/omxtra/text/__init__.py +0 -0
  42. omxtra-0.0.0.dev535/omxtra/text/antlr/cli/__init__.py +0 -0
  43. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/LICENSE +0 -0
  44. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/MANIFEST.in +0 -0
  45. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/README.md +0 -0
  46. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/.omlish-manifests.json +0 -0
  47. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/README.md +0 -0
  48. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/__about__.py +0 -0
  49. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/__init__.py +0 -0
  50. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/__init__.py +0 -0
  51. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/all.py +0 -0
  52. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bluelet/LICENSE +0 -0
  53. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bluelet/__init__.py +0 -0
  54. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bluelet/all.py +0 -0
  55. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bluelet/api.py +0 -0
  56. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bluelet/core.py +0 -0
  57. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bluelet/events.py +0 -0
  58. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bluelet/files.py +0 -0
  59. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bluelet/runner.py +0 -0
  60. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bluelet/sockets.py +0 -0
  61. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/bridge.py +0 -0
  62. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/asyncs/flavors.py +0 -0
  63. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/concurrent/__init__.py +0 -0
  64. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/concurrent/threadlets.py +0 -0
  65. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/defs.py +0 -0
  66. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/dynamic.py +0 -0
  67. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/__init__.py +0 -0
  68. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json/Json.g4 +0 -0
  69. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json/__init__.py +0 -0
  70. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json/_antlr/JsonLexer.py +0 -0
  71. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json/_antlr/JsonListener.py +0 -0
  72. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json/_antlr/JsonParser.py +0 -0
  73. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json/_antlr/JsonVisitor.py +0 -0
  74. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json/_antlr/__init__.py +0 -0
  75. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json5/Json5.g4 +0 -0
  76. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json5/__init__.py +0 -0
  77. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json5/_antlr/Json5Lexer.py +0 -0
  78. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json5/_antlr/Json5Listener.py +0 -0
  79. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json5/_antlr/Json5Parser.py +0 -0
  80. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json5/_antlr/Json5Visitor.py +0 -0
  81. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json5/_antlr/__init__.py +0 -0
  82. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/formats/json5/parsing.py +0 -0
  83. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/__init__.py +0 -0
  84. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/__init__.py +0 -0
  85. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/asyncs.py +0 -0
  86. {omxtra-0.0.0.dev535/omxtra/io/pipelines/_old → omxtra-0.0.0.dev536/omxtra/io/pipelines/bytes}/__init__.py +0 -0
  87. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/bytes/buffering.py +0 -0
  88. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/bytes/queues.py +0 -0
  89. {omxtra-0.0.0.dev535/omxtra/io/pipelines/_old/flow → omxtra-0.0.0.dev536/omxtra/io/pipelines/drivers}/__init__.py +0 -0
  90. {omxtra-0.0.0.dev535/omxtra/io/pipelines/bytes → omxtra-0.0.0.dev536/omxtra/io/pipelines/flow}/__init__.py +0 -0
  91. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/flow/stub.py +0 -0
  92. {omxtra-0.0.0.dev535/omxtra/io/pipelines/drivers → omxtra-0.0.0.dev536/omxtra/io/pipelines/handlers}/__init__.py +0 -0
  93. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/handlers/feedback.py +0 -0
  94. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/handlers/fns.py +0 -0
  95. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/handlers/logs.py +0 -0
  96. {omxtra-0.0.0.dev535/omxtra/io/pipelines/flow → omxtra-0.0.0.dev536/omxtra/io/pipelines/http}/__init__.py +0 -0
  97. {omxtra-0.0.0.dev535/omxtra/io/pipelines/handlers → omxtra-0.0.0.dev536/omxtra/io/pipelines/http/client}/__init__.py +0 -0
  98. {omxtra-0.0.0.dev535/omxtra/io/pipelines/http → omxtra-0.0.0.dev536/omxtra/io/pipelines/http/server}/__init__.py +0 -0
  99. {omxtra-0.0.0.dev535/omxtra/io/pipelines/http/client → omxtra-0.0.0.dev536/omxtra/io/pipelines/http/server/apps}/__init__.py +0 -0
  100. {omxtra-0.0.0.dev535/omxtra/io/pipelines/http/decoders2 → omxtra-0.0.0.dev536/omxtra/io/pipelines/sched}/__init__.py +0 -0
  101. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/pipelines/sched/types.py +0 -0
  102. {omxtra-0.0.0.dev535/omxtra/io/pipelines/http/server → omxtra-0.0.0.dev536/omxtra/io/pipelines/ssl}/__init__.py +0 -0
  103. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/io/trampoline.py +0 -0
  104. {omxtra-0.0.0.dev535/omxtra/io/pipelines/http/server/apps → omxtra-0.0.0.dev536/omxtra/scripts}/__init__.py +0 -0
  105. {omxtra-0.0.0.dev535/omxtra/io/pipelines/sched → omxtra-0.0.0.dev536/omxtra/scripts/lib}/__init__.py +0 -0
  106. {omxtra-0.0.0.dev535/omxtra/io/pipelines/ssl → omxtra-0.0.0.dev536/omxtra/scripts/lib/io}/__init__.py +0 -0
  107. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/LICENSE +0 -0
  108. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/__init__.py +0 -0
  109. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/config.py +0 -0
  110. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/debug.py +0 -0
  111. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/default.py +0 -0
  112. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/events.py +0 -0
  113. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/headers.py +0 -0
  114. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/inject.py +0 -0
  115. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/lifespans.py +0 -0
  116. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/listener.py +0 -0
  117. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/multiprocess.py +0 -0
  118. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/protocols/__init__.py +0 -0
  119. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/protocols/h11.py +0 -0
  120. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/protocols/h2.py +0 -0
  121. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/protocols/protocols.py +0 -0
  122. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/protocols/types.py +0 -0
  123. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/resources/__init__.py +0 -0
  124. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/resources/favicon.ico +0 -0
  125. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/server.py +0 -0
  126. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/sockets.py +0 -0
  127. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/ssl.py +0 -0
  128. {omxtra-0.0.0.dev535/omxtra/scripts → omxtra-0.0.0.dev536/omxtra/server/streams}/__init__.py +0 -0
  129. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/streams/httpstream.py +0 -0
  130. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/streams/utils.py +0 -0
  131. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/streams/wsstream.py +0 -0
  132. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/taskspawner.py +0 -0
  133. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/types.py +0 -0
  134. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/server/workercontext.py +0 -0
  135. {omxtra-0.0.0.dev535/omxtra/scripts/lib → omxtra-0.0.0.dev536/omxtra/specs}/__init__.py +0 -0
  136. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/specs/proto/Protobuf3.g4 +0 -0
  137. {omxtra-0.0.0.dev535/omxtra/scripts/lib/io → omxtra-0.0.0.dev536/omxtra/specs/proto}/__init__.py +0 -0
  138. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/specs/proto/_antlr/Protobuf3Lexer.py +0 -0
  139. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/specs/proto/_antlr/Protobuf3Listener.py +0 -0
  140. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/specs/proto/_antlr/Protobuf3Parser.py +0 -0
  141. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/specs/proto/_antlr/Protobuf3Visitor.py +0 -0
  142. {omxtra-0.0.0.dev535/omxtra/server/streams → omxtra-0.0.0.dev536/omxtra/specs/proto/_antlr}/__init__.py +0 -0
  143. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/specs/proto/nodes.py +0 -0
  144. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/specs/proto/parsing.py +0 -0
  145. {omxtra-0.0.0.dev535/omxtra/specs → omxtra-0.0.0.dev536/omxtra/sql}/__init__.py +0 -0
  146. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/sql/alchemy/__init__.py +0 -0
  147. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/sql/alchemy/asyncs.py +0 -0
  148. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/sql/parsing/Minisql.g4 +0 -0
  149. {omxtra-0.0.0.dev535/omxtra/specs/proto → omxtra-0.0.0.dev536/omxtra/sql/parsing}/__init__.py +0 -0
  150. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/sql/parsing/_antlr/MinisqlLexer.py +0 -0
  151. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/sql/parsing/_antlr/MinisqlListener.py +0 -0
  152. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/sql/parsing/_antlr/MinisqlParser.py +0 -0
  153. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/sql/parsing/_antlr/MinisqlVisitor.py +0 -0
  154. {omxtra-0.0.0.dev535/omxtra/specs/proto → omxtra-0.0.0.dev536/omxtra/sql/parsing}/_antlr/__init__.py +0 -0
  155. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/sql/parsing/parsing.py +0 -0
  156. {omxtra-0.0.0.dev535/omxtra/sql → omxtra-0.0.0.dev536/omxtra/text}/__init__.py +0 -0
  157. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/__init__.py +0 -0
  158. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/BufferedTokenStream.py +0 -0
  159. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/CommonTokenFactory.py +0 -0
  160. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/CommonTokenStream.py +0 -0
  161. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/FileStream.py +0 -0
  162. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/InputStream.py +0 -0
  163. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/IntervalSet.py +0 -0
  164. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/LICENSE.txt +0 -0
  165. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/LL1Analyzer.py +0 -0
  166. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/Lexer.py +0 -0
  167. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/ListTokenSource.py +0 -0
  168. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/Parser.py +0 -0
  169. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/ParserInterpreter.py +0 -0
  170. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/ParserRuleContext.py +0 -0
  171. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/PredictionContext.py +0 -0
  172. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/Recognizer.py +0 -0
  173. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/RuleContext.py +0 -0
  174. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/StdinStream.py +0 -0
  175. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/Token.py +0 -0
  176. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/TokenStreamRewriter.py +0 -0
  177. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/Utils.py +0 -0
  178. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/__init__.py +0 -0
  179. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/_all.py +0 -0
  180. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/_pygrun.py +0 -0
  181. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/ATN.py +0 -0
  182. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/ATNConfig.py +0 -0
  183. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/ATNConfigSet.py +0 -0
  184. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/ATNDeserializationOptions.py +0 -0
  185. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/ATNDeserializer.py +0 -0
  186. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/ATNSimulator.py +0 -0
  187. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/ATNState.py +0 -0
  188. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/ATNType.py +0 -0
  189. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/LexerATNSimulator.py +0 -0
  190. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/LexerAction.py +0 -0
  191. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/LexerActionExecutor.py +0 -0
  192. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/ParserATNSimulator.py +0 -0
  193. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/PredictionMode.py +0 -0
  194. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/SemanticContext.py +0 -0
  195. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/Transition.py +0 -0
  196. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/atn/__init__.py +0 -0
  197. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/dfa/DFA.py +0 -0
  198. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/dfa/DFASerializer.py +0 -0
  199. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/dfa/DFAState.py +0 -0
  200. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/dfa/__init__.py +0 -0
  201. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/error/DiagnosticErrorListener.py +0 -0
  202. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/error/ErrorListener.py +0 -0
  203. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/error/ErrorStrategy.py +0 -0
  204. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/error/Errors.py +0 -0
  205. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/error/__init__.py +0 -0
  206. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/tree/Chunk.py +0 -0
  207. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/tree/ParseTreeMatch.py +0 -0
  208. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/tree/ParseTreePattern.py +0 -0
  209. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/tree/ParseTreePatternMatcher.py +0 -0
  210. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/tree/RuleTagToken.py +0 -0
  211. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/tree/TokenTagToken.py +0 -0
  212. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/tree/Tree.py +0 -0
  213. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/tree/Trees.py +0 -0
  214. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/tree/__init__.py +0 -0
  215. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/xpath/XPath.py +0 -0
  216. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/xpath/XPathLexer.py +0 -0
  217. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/_runtime/xpath/__init__.py +0 -0
  218. {omxtra-0.0.0.dev535/omxtra/sql/parsing → omxtra-0.0.0.dev536/omxtra/text/antlr/cli}/__init__.py +0 -0
  219. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/cli/__main__.py +0 -0
  220. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/cli/cli.py +0 -0
  221. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/cli/consts.py +0 -0
  222. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/cli/gen.py +0 -0
  223. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/delimit.py +0 -0
  224. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/dot.py +0 -0
  225. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/errors.py +0 -0
  226. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/input.py +0 -0
  227. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/parsing.py +0 -0
  228. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/runtime.py +0 -0
  229. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra/text/antlr/utils.py +0 -0
  230. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra.egg-info/dependency_links.txt +0 -0
  231. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra.egg-info/entry_points.txt +0 -0
  232. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/omxtra.egg-info/top_level.txt +0 -0
  233. {omxtra-0.0.0.dev535 → omxtra-0.0.0.dev536}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omxtra
3
- Version: 0.0.0.dev535
3
+ Version: 0.0.0.dev536
4
4
  Summary: omxtra
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.13
14
14
  Requires-Python: >=3.13
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
- Requires-Dist: omlish==0.0.0.dev535
17
+ Requires-Dist: omlish==0.0.0.dev536
18
18
  Provides-Extra: all
19
19
  Requires-Dist: h11~=0.16; extra == "all"
20
20
  Requires-Dist: h2~=4.3; extra == "all"
@@ -9,8 +9,8 @@ from .handlers.flatmap import FlatMapChannelPipelineHandler # noqa
9
9
  from .handlers.fns import FnChannelPipelineHandler # noqa
10
10
  from .handlers.queues import QueueChannelPipelineHandler # noqa
11
11
  from .http.client.requests import PipelineHttpRequestEncoder # noqa
12
- from .http.client.responses import PipelineHttpResponseHeadDecoder # noqa
13
- from .http.server.requests import PipelineHttpRequestHeadDecoder # noqa
12
+ from .http.client.responses import PipelineHttpResponseDecoder # noqa
13
+ from .http.server.requests import PipelineHttpRequestDecoder # noqa
14
14
  from .http.server.responses import PipelineHttpResponseEncoder # noqa
15
15
 
16
16
 
@@ -14,13 +14,13 @@ from omlish.io.streams.segmented import SegmentedByteStreamBuffer
14
14
  from omlish.io.streams.types import ByteStreamBuffer
15
15
  from omlish.io.streams.types import MutableByteStreamBuffer
16
16
  from omlish.io.streams.utils import ByteStreamBuffers
17
+ from omlish.io.streams.utils import CanByteStreamBuffer
17
18
  from omlish.lite.abstract import Abstract
18
19
  from omlish.lite.check import check
19
20
 
20
21
  from ..core import ChannelPipelineHandler
21
22
  from ..core import ChannelPipelineHandlerContext
22
23
  from ..core import ChannelPipelineMessages
23
- from ..errors import DecodingChannelPipelineError
24
24
  from ..errors import IncompleteDecodingChannelPipelineError
25
25
  from ..flow.types import ChannelPipelineFlow
26
26
  from ..flow.types import ChannelPipelineFlowMessages
@@ -46,7 +46,7 @@ class UnicodeDecoderChannelPipelineHandler(ChannelPipelineHandler):
46
46
 
47
47
  def inbound(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any) -> None:
48
48
  if ByteStreamBuffers.can_bytes(msg):
49
- b = ByteStreamBuffers.any_to_bytes(msg)
49
+ b = ByteStreamBuffers.to_bytes(msg)
50
50
 
51
51
  msg = b.decode(self._encoding, errors=self._errors)
52
52
 
@@ -126,30 +126,12 @@ class DelimiterFrameDecoderChannelPipelineHandler(InboundBytesBufferingChannelPi
126
126
  ##
127
127
 
128
128
 
129
- class BytesToMessageDecoderChannelPipelineHandler(InboundBytesBufferingChannelPipelineHandler, Abstract):
130
- def __init__(
131
- self,
132
- *,
133
- max_buffer_size: ta.Optional[int] = None,
134
- buffer_chunk_size: int = 64 * 1024,
135
- scanning_buffer: bool = False,
136
- ) -> None:
137
- super().__init__()
138
-
139
- self._max_buffer_size = max_buffer_size
140
- self._buffer_chunk_size = buffer_chunk_size
141
- self._scanning_buffer = scanning_buffer
142
-
143
- def inbound_buffered_bytes(self) -> int:
144
- if (buf := self._buf) is None:
145
- return 0
146
- return len(buf)
147
-
129
+ class BytesToMessageDecoderChannelPipelineHandler(ChannelPipelineHandler, Abstract):
148
130
  @abc.abstractmethod
149
131
  def _decode(
150
132
  self,
151
133
  ctx: ChannelPipelineHandlerContext,
152
- buf: ByteStreamBuffer,
134
+ data: CanByteStreamBuffer,
153
135
  out: ta.List[ta.Any],
154
136
  *,
155
137
  final: bool = False,
@@ -158,40 +140,20 @@ class BytesToMessageDecoderChannelPipelineHandler(InboundBytesBufferingChannelPi
158
140
 
159
141
  #
160
142
 
161
- _buf: ta.Optional[MutableByteStreamBuffer] = None
162
-
163
- def _new_buf(self) -> MutableByteStreamBuffer:
164
- buf: MutableByteStreamBuffer = SegmentedByteStreamBuffer(
165
- max_size=self._max_buffer_size,
166
- chunk_size=self._buffer_chunk_size,
167
- )
168
-
169
- if self._scanning_buffer:
170
- buf = ScanningByteStreamBuffer(buf)
171
-
172
- return buf
173
-
174
- #
175
-
176
143
  _called_decode: bool = False # ~ `selfFiredChannelRead`
177
144
  _produced_messages: bool = False # ~ `firedChannelRead`
178
145
 
179
146
  def _call_decode(
180
147
  self,
181
148
  ctx: ChannelPipelineHandlerContext,
182
- buf: ByteStreamBuffer,
149
+ data: CanByteStreamBuffer,
183
150
  *,
184
151
  final: bool = False,
185
152
  ) -> None:
186
153
  self._called_decode = True
187
154
 
188
155
  out: ta.List[ta.Any] = []
189
- try:
190
- self._decode(ctx, buf, out, final=final)
191
- except DecodingChannelPipelineError:
192
- raise
193
- except Exception as e:
194
- raise DecodingChannelPipelineError from e
156
+ self._decode(ctx, data, out, final=final)
195
157
 
196
158
  if not out:
197
159
  return
@@ -203,6 +165,11 @@ class BytesToMessageDecoderChannelPipelineHandler(InboundBytesBufferingChannelPi
203
165
 
204
166
  #
205
167
 
168
+ def _on_bytes_input(self, ctx: ChannelPipelineHandlerContext, data: CanByteStreamBuffer) -> None:
169
+ check.arg(len(data) > 0)
170
+
171
+ self._call_decode(ctx, data)
172
+
206
173
  def _on_flush_input(self, ctx: ChannelPipelineHandlerContext) -> None:
207
174
  if (
208
175
  self._called_decode and
@@ -217,27 +184,10 @@ class BytesToMessageDecoderChannelPipelineHandler(InboundBytesBufferingChannelPi
217
184
  ctx.feed_in(ChannelPipelineFlowMessages.FlushInput())
218
185
 
219
186
  def _on_final_input(self, ctx: ChannelPipelineHandlerContext, msg: ChannelPipelineMessages.FinalInput) -> None:
220
- dec_buf: ByteStreamBuffer
221
- if self._buf is not None:
222
- dec_buf = self._buf
223
- else:
224
- dec_buf = DirectByteStreamBuffer(b'')
225
-
226
- self._call_decode(ctx, dec_buf, final=True)
187
+ self._call_decode(ctx, DirectByteStreamBuffer(b''), final=True)
227
188
 
228
189
  ctx.feed_in(msg)
229
190
 
230
- def _on_bytes_input(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any) -> None:
231
- check.arg(len(msg) > 0)
232
-
233
- if self._buf is None:
234
- self._buf = self._new_buf()
235
-
236
- for seg in ByteStreamBuffers.iter_segments(msg):
237
- self._buf.write(seg)
238
-
239
- self._call_decode(ctx, self._buf)
240
-
241
191
  #
242
192
 
243
193
  def inbound(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any) -> None:
@@ -263,7 +213,7 @@ class FnBytesToMessageDecoderChannelPipelineHandler(BytesToMessageDecoderChannel
263
213
  def __call__(
264
214
  self,
265
215
  ctx: ChannelPipelineHandlerContext,
266
- buf: ByteStreamBuffer,
216
+ data: CanByteStreamBuffer,
267
217
  out: ta.List[ta.Any],
268
218
  *,
269
219
  final: bool = False,
@@ -273,20 +223,97 @@ class FnBytesToMessageDecoderChannelPipelineHandler(BytesToMessageDecoderChannel
273
223
  def __init__(
274
224
  self,
275
225
  decode_fn: DecodeFn,
226
+ ) -> None:
227
+ super().__init__()
228
+
229
+ self._decode_fn = decode_fn
230
+
231
+ def _decode(
232
+ self,
233
+ ctx: ChannelPipelineHandlerContext,
234
+ buf: CanByteStreamBuffer,
235
+ out: ta.List[ta.Any],
236
+ *,
237
+ final: bool = False,
238
+ ) -> None:
239
+ self._decode_fn(ctx, buf, out, final=final)
240
+
241
+
242
+ ##
243
+
244
+
245
+ class BufferedBytesToMessageDecoderChannelPipelineHandler(
246
+ InboundBytesBufferingChannelPipelineHandler,
247
+ BytesToMessageDecoderChannelPipelineHandler,
248
+ Abstract,
249
+ ):
250
+ def __init__(
251
+ self,
276
252
  *,
277
253
  max_buffer_size: ta.Optional[int] = None,
278
254
  buffer_chunk_size: int = 64 * 1024,
279
255
  scanning_buffer: bool = False,
280
256
  ) -> None:
281
- super().__init__(
282
- max_buffer_size=max_buffer_size,
283
- buffer_chunk_size=buffer_chunk_size,
284
- scanning_buffer=scanning_buffer,
257
+ super().__init__()
258
+
259
+ self._max_buffer_size = max_buffer_size
260
+ self._buffer_chunk_size = buffer_chunk_size
261
+ self._scanning_buffer = scanning_buffer
262
+
263
+ #
264
+
265
+ def inbound_buffered_bytes(self) -> int:
266
+ if (buf := self._buf) is None:
267
+ return 0
268
+ return len(buf)
269
+
270
+ _buf: ta.Optional[MutableByteStreamBuffer] = None
271
+
272
+ def _new_buf(self) -> MutableByteStreamBuffer:
273
+ buf: MutableByteStreamBuffer = SegmentedByteStreamBuffer(
274
+ max_size=self._max_buffer_size,
275
+ chunk_size=self._buffer_chunk_size,
285
276
  )
286
277
 
287
- self._decode_fn = decode_fn
278
+ if self._scanning_buffer:
279
+ buf = ScanningByteStreamBuffer(buf)
280
+
281
+ return buf
282
+
283
+ #
288
284
 
289
285
  def _decode(
286
+ self,
287
+ ctx: ChannelPipelineHandlerContext,
288
+ data: CanByteStreamBuffer,
289
+ out: ta.List[ta.Any],
290
+ *,
291
+ final: bool = False,
292
+ ) -> None:
293
+ if final:
294
+ check.arg(len(data) == 0)
295
+
296
+ if not isinstance(data, ByteStreamBuffer):
297
+ data = DirectByteStreamBuffer(b'')
298
+
299
+ self._decode_buffer(ctx, data, out, final=final)
300
+
301
+ return
302
+
303
+ check.arg(len(data) > 0)
304
+
305
+ if (buf := self._buf) is None:
306
+ buf = self._buf = self._new_buf()
307
+
308
+ for seg in ByteStreamBuffers.iter_segments(data):
309
+ buf.write(seg)
310
+
311
+ self._decode_buffer(ctx, buf, out, final=final)
312
+
313
+ #
314
+
315
+ @abc.abstractmethod
316
+ def _decode_buffer(
290
317
  self,
291
318
  ctx: ChannelPipelineHandlerContext,
292
319
  buf: ByteStreamBuffer,
@@ -294,4 +321,4 @@ class FnBytesToMessageDecoderChannelPipelineHandler(BytesToMessageDecoderChannel
294
321
  *,
295
322
  final: bool = False,
296
323
  ) -> None:
297
- self._decode_fn(ctx, buf, out, final=final)
324
+ raise NotImplementedError
@@ -11,10 +11,11 @@ from omlish.lite.check import check
11
11
  from omlish.lite.namespaces import NamespaceClass
12
12
 
13
13
  from .errors import ContextInvalidatedChannelPipelineError
14
- from .errors import FinalOutputChannelPipelineError
15
14
  from .errors import MessageNotPropagatedChannelPipelineError
16
15
  from .errors import MessageReachedTerminalChannelPipelineError
17
16
  from .errors import SawFinalInputChannelPipelineError
17
+ from .errors import SawFinalOutputChannelPipelineError
18
+ from .errors import SawInitialInputChannelPipelineError
18
19
  from .errors import UnhandleableChannelPipelineError
19
20
 
20
21
 
@@ -60,6 +61,14 @@ class ChannelPipelineMessages(NamespaceClass):
60
61
 
61
62
  #
62
63
 
64
+ @ta.final
65
+ @dc.dataclass(frozen=True, eq=False)
66
+ class InitialInput(NeverOutbound, MustPropagate): # ~ Netty `ChannelInboundHandler::channelActive`
67
+ """Signals that the inbound stream has begun producing input (`connected`)."""
68
+
69
+ def __repr__(self) -> str:
70
+ return f'{type(self).__name__}@{id(self):x}()'
71
+
63
72
  @ta.final
64
73
  @dc.dataclass(frozen=True, eq=False)
65
74
  class FinalInput(NeverOutbound, MustPropagate): # ~ Netty `ChannelInboundHandler::channelInactive`
@@ -1216,6 +1225,8 @@ class PipelineChannel:
1216
1225
 
1217
1226
  self._output: ta.Final[PipelineChannel._Output] = PipelineChannel._Output()
1218
1227
 
1228
+ self._saw_any_input = False
1229
+ self._saw_initial_input = False
1219
1230
  self._saw_final_input = False
1220
1231
  self._saw_final_output = False
1221
1232
 
@@ -1275,6 +1286,14 @@ class PipelineChannel:
1275
1286
 
1276
1287
  #
1277
1288
 
1289
+ @property
1290
+ def saw_any_input(self) -> bool:
1291
+ return self._saw_any_input
1292
+
1293
+ @property
1294
+ def saw_initial_input(self) -> bool:
1295
+ return self._saw_initial_input
1296
+
1278
1297
  @property
1279
1298
  def saw_final_input(self) -> bool:
1280
1299
  return self._saw_final_input # Note: only 'channel-level'
@@ -1506,10 +1525,17 @@ class PipelineChannel:
1506
1525
  self._step_in()
1507
1526
  try:
1508
1527
  for msg in msgs:
1509
- if isinstance(msg, ChannelPipelineMessages.FinalInput):
1528
+ if self._saw_final_input:
1529
+ raise SawFinalInputChannelPipelineError
1530
+ elif isinstance(msg, ChannelPipelineMessages.FinalInput):
1510
1531
  self._saw_final_input = True
1511
- elif self._saw_final_input:
1512
- raise SawFinalInputChannelPipelineError # noqa
1532
+
1533
+ if isinstance(msg, ChannelPipelineMessages.InitialInput):
1534
+ if self._saw_any_input:
1535
+ raise SawInitialInputChannelPipelineError
1536
+ check.state(not self._saw_initial_input)
1537
+ self._saw_initial_input = True
1538
+ self._saw_any_input = True
1513
1539
 
1514
1540
  ctx._inbound(msg) # noqa
1515
1541
 
@@ -1525,6 +1551,9 @@ class PipelineChannel:
1525
1551
  def feed_in(self, *msgs: ta.Any) -> None:
1526
1552
  self._feed_in_to(self._pipeline._outermost, msgs) # noqa
1527
1553
 
1554
+ def feed_initial_input(self) -> None:
1555
+ self._feed_in_to(self._pipeline._outermost, (ChannelPipelineMessages.InitialInput(),)) # noqa
1556
+
1528
1557
  def feed_final_input(self) -> None:
1529
1558
  self._feed_in_to(self._pipeline._outermost, (ChannelPipelineMessages.FinalInput(),)) # noqa
1530
1559
 
@@ -1590,7 +1619,7 @@ class PipelineChannel:
1590
1619
  if isinstance(msg, ChannelPipelineMessages.FinalOutput):
1591
1620
  self._saw_final_output = True
1592
1621
  elif self._saw_final_output:
1593
- raise FinalOutputChannelPipelineError
1622
+ raise SawFinalOutputChannelPipelineError
1594
1623
 
1595
1624
  self._output._q.append(msg) # noqa
1596
1625
 
@@ -8,6 +8,7 @@ TODO:
8
8
  - dedicated read_task, flush_task, sched_task
9
9
  - read_task toggles back and forth between reading and waiting
10
10
  - main task only reads from command queue
11
+ - asynclite?
11
12
  """
12
13
  import abc
13
14
  import asyncio
@@ -169,6 +170,8 @@ class AsyncioStreamPipelineChannelDriver(Abstract):
169
170
  class _FeedInCommand(_Command):
170
171
  msgs: ta.Sequence[ta.Any]
171
172
 
173
+ fut: ta.Optional['asyncio.Future[None]'] = None
174
+
172
175
  def __repr__(self) -> str:
173
176
  return f'{self.__class__.__name__}([{", ".join(map(repr, self.msgs))}])'
174
177
 
@@ -176,11 +179,27 @@ class AsyncioStreamPipelineChannelDriver(Abstract):
176
179
  async def _inner() -> None:
177
180
  self._channel.feed_in(*cmd.msgs) # noqa
178
181
 
179
- await self._do_with_channel(_inner)
182
+ if (fut := cmd.fut) is None:
183
+ await self._do_with_channel(_inner)
184
+ return
185
+
186
+ try:
187
+ await self._do_with_channel(_inner)
188
+ fut.set_result(None)
189
+ except BaseException as e: # noqa
190
+ fut.set_exception(e)
191
+ raise
180
192
 
181
193
  async def feed_in(self, *msgs: ta.Any) -> None:
182
194
  check.state(not self._shutdown_event.is_set())
183
195
 
196
+ fut: asyncio.Future[None] = asyncio.Future()
197
+ self._command_queue.put_nowait(AsyncioStreamPipelineChannelDriver._FeedInCommand(msgs, fut=fut))
198
+ await fut
199
+
200
+ def feed_in_nowait(self, *msgs: ta.Any) -> None:
201
+ check.state(not self._shutdown_event.is_set())
202
+
184
203
  self._command_queue.put_nowait(AsyncioStreamPipelineChannelDriver._FeedInCommand(msgs))
185
204
 
186
205
  ##
@@ -566,6 +585,11 @@ class SimpleAsyncioStreamPipelineChannelDriver(AsyncioStreamPipelineChannelDrive
566
585
  command_queue_task: ta.Optional[asyncio.Task[AsyncioStreamPipelineChannelDriver._Command]] = None
567
586
 
568
587
  try:
588
+ if not self._shutdown_event.is_set():
589
+ await self._handle_command(AsyncioStreamPipelineChannelDriver._FeedInCommand([ # noqa
590
+ ChannelPipelineMessages.InitialInput(),
591
+ ]))
592
+
569
593
  while not self._shutdown_event.is_set():
570
594
  if command_queue_task is None:
571
595
  command_queue_task = asyncio.create_task(self._command_queue.get())
@@ -84,6 +84,8 @@ class SyncSocketPipelineChannelDriver:
84
84
  self._channel = PipelineChannel(self._spec)
85
85
 
86
86
  try:
87
+ self._channel.feed_initial_input()
88
+
87
89
  while True:
88
90
  if in_msgs:
89
91
  self._channel.feed_in(*in_msgs)
@@ -22,15 +22,23 @@ class UnhandleableChannelPipelineError(ChannelPipelineError):
22
22
  # state
23
23
 
24
24
 
25
- class ContextInvalidatedChannelPipelineError(ChannelPipelineError):
25
+ class StateChannelPipelineError(ChannelPipelineError):
26
26
  pass
27
27
 
28
28
 
29
- class SawFinalInputChannelPipelineError(ChannelPipelineError):
29
+ class ContextInvalidatedChannelPipelineError(StateChannelPipelineError):
30
30
  pass
31
31
 
32
32
 
33
- class FinalOutputChannelPipelineError(ChannelPipelineError):
33
+ class SawInitialInputChannelPipelineError(StateChannelPipelineError):
34
+ pass
35
+
36
+
37
+ class SawFinalInputChannelPipelineError(StateChannelPipelineError):
38
+ pass
39
+
40
+
41
+ class SawFinalOutputChannelPipelineError(StateChannelPipelineError):
34
42
  pass
35
43
 
36
44
 
@@ -6,6 +6,7 @@ import typing as ta
6
6
  from omlish.lite.abstract import Abstract
7
7
  from omlish.lite.namespaces import NamespaceClass
8
8
 
9
+ from ..core import ChannelPipelineHandlerContext
9
10
  from ..core import ChannelPipelineMessages
10
11
  from ..core import ChannelPipelineService
11
12
 
@@ -26,16 +27,6 @@ class ChannelPipelineFlowMessages(NamespaceClass):
26
27
  class FlushInput(ChannelPipelineMessages.NeverOutbound): # ~ Netty `ChannelInboundInvoker::fireChannelReadComplete` # noqa
27
28
  pass
28
29
 
29
- @ta.final
30
- @dc.dataclass(frozen=True)
31
- class ReadyForOutput(ChannelPipelineMessages.NeverOutbound): # ~ Netty `ChannelOutboundInvoker::fireChannelWritabilityChanged` # noqa
32
- pass
33
-
34
- @ta.final
35
- @dc.dataclass(frozen=True)
36
- class PauseOutput(ChannelPipelineMessages.NeverOutbound): # ~ Netty `ChannelOutboundInvoker::fireChannelWritabilityChanged` # noqa
37
- pass
38
-
39
30
  #
40
31
 
41
32
  @ta.final
@@ -48,6 +39,20 @@ class ChannelPipelineFlowMessages(NamespaceClass):
48
39
  class ReadyForInput(ChannelPipelineMessages.NeverInbound): # ~ Netty `ChannelOutboundInvoker::read`
49
40
  pass
50
41
 
42
+ #
43
+
44
+ # # TODO:
45
+ # @ta.final
46
+ # @dc.dataclass(frozen=True)
47
+ # class ReadyForOutput(ChannelPipelineMessages.NeverOutbound): # ~ Netty `ChannelOutboundInvoker::fireChannelWritabilityChanged` # noqa
48
+ # pass
49
+
50
+ # # TODO:
51
+ # @ta.final
52
+ # @dc.dataclass(frozen=True)
53
+ # class PauseOutput(ChannelPipelineMessages.NeverOutbound): # ~ Netty `ChannelOutboundInvoker::fireChannelWritabilityChanged` # noqa
54
+ # pass
55
+
51
56
 
52
57
  ##
53
58
 
@@ -56,3 +61,7 @@ class ChannelPipelineFlow(ChannelPipelineService, Abstract):
56
61
  @abc.abstractmethod
57
62
  def is_auto_read(self) -> bool:
58
63
  raise NotImplementedError
64
+
65
+ @staticmethod
66
+ def is_auto_read_context(ctx: ChannelPipelineHandlerContext) -> bool:
67
+ return (fc := ctx.services.find(ChannelPipelineFlow)) is None or fc.is_auto_read()
@@ -9,7 +9,6 @@ from ..core import ChannelPipelineHandler
9
9
  from ..core import ChannelPipelineHandlerContext
10
10
  from ..core import ChannelPipelineHandlerFn
11
11
  from ..core import ShareableChannelPipelineHandler
12
- from ..errors import DecodingChannelPipelineError
13
12
  from ..flow.types import ChannelPipelineFlow
14
13
  from ..flow.types import ChannelPipelineFlowMessages
15
14
 
@@ -51,13 +50,7 @@ class MessageToMessageDecoderChannelPipelineHandler(ChannelPipelineHandler, Abst
51
50
 
52
51
  self._called_decode = True
53
52
 
54
- try:
55
- out = list(self._decode(ctx, msg))
56
-
57
- except DecodingChannelPipelineError:
58
- raise
59
- except Exception as e:
60
- raise DecodingChannelPipelineError from e
53
+ out = list(self._decode(ctx, msg))
61
54
 
62
55
  if not out:
63
56
  return
@@ -55,6 +55,15 @@ class FlatMapChannelPipelineHandlerFns(NamespaceClass):
55
55
  ) -> FlatMapChannelPipelineHandlerFn:
56
56
  return cls.Filter(pred, fn, else_fn)
57
57
 
58
+ @classmethod
59
+ def filter_type(
60
+ cls,
61
+ ty: ta.Union[type, ta.Tuple[type, ...]],
62
+ fn: FlatMapChannelPipelineHandlerFn,
63
+ else_fn: ta.Optional[FlatMapChannelPipelineHandlerFn] = None,
64
+ ) -> FlatMapChannelPipelineHandlerFn:
65
+ return cls.filter(ChannelPipelineHandlerFns.isinstance(ty), fn, else_fn)
66
+
58
67
  #
59
68
 
60
69
  @dc.dataclass(frozen=True)
@@ -217,6 +226,20 @@ class FlatMapChannelPipelineHandlerFns(NamespaceClass):
217
226
  def drop(cls) -> FlatMapChannelPipelineHandlerFn:
218
227
  return cls.Drop()
219
228
 
229
+ #
230
+
231
+ @dc.dataclass(frozen=True)
232
+ class Nop:
233
+ def __repr__(self) -> str:
234
+ return f'{type(self).__name__}()'
235
+
236
+ def __call__(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any) -> ta.Iterable[ta.Any]:
237
+ return (msg,)
238
+
239
+ @classmethod
240
+ def nop(cls) -> FlatMapChannelPipelineHandlerFn:
241
+ return cls.Nop()
242
+
220
243
 
221
244
  #
222
245
 
@@ -295,10 +318,7 @@ class FlatMapChannelPipelineHandlers(NamespaceClass):
295
318
  fn = FlatMapChannelPipelineHandlerFns.filter(filter, fn)
296
319
 
297
320
  if filter_type is not None:
298
- fn = FlatMapChannelPipelineHandlerFns.filter(
299
- ChannelPipelineHandlerFns.isinstance(filter_type),
300
- fn,
301
- )
321
+ fn = FlatMapChannelPipelineHandlerFns.filter_type(filter_type, fn)
302
322
 
303
323
  fn = FlatMapChannelPipelineHandlerFns.filter(cls._NOT_MUST_PROPAGATE, fn)
304
324
 
@@ -23,11 +23,13 @@ class QueueChannelPipelineHandler(ChannelPipelineHandler, Abstract):
23
23
  self,
24
24
  *,
25
25
  filter: ta.Optional[ChannelPipelineHandlerFn[ta.Any, bool]] = None, # noqa
26
+ filter_type: ta.Optional[ta.Union[type, ta.Tuple[type, ...]]] = None,
26
27
  passthrough: ta.Union[bool, ta.Literal['must_propagate']] = 'must_propagate',
27
28
  ) -> None:
28
29
  super().__init__()
29
30
 
30
31
  self._filter = filter
32
+ self._filter_type = filter_type
31
33
  self._passthrough = passthrough
32
34
 
33
35
  self._q: collections.deque[ta.Any] = collections.deque()
@@ -39,6 +41,7 @@ class QueueChannelPipelineHandler(ChannelPipelineHandler, Abstract):
39
41
  '(',
40
42
  ', '.join([
41
43
  *([f'filter={self._filter!r}'] if self._filter is not None else []),
44
+ *([f'filter_type={self._filter_type!r}'] if self._filter_type is not None else []),
42
45
  *([f'passthrough={self._passthrough!r}'] if self._passthrough else []),
43
46
  ]),
44
47
  ')',
@@ -68,6 +71,15 @@ class QueueChannelPipelineHandler(ChannelPipelineHandler, Abstract):
68
71
 
69
72
  #
70
73
 
74
+ def _should_enqueue(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any) -> bool:
75
+ if self._filter is not None and not self._filter(ctx, msg):
76
+ return False
77
+
78
+ if self._filter_type is not None and not isinstance(msg, self._filter_type):
79
+ return False
80
+
81
+ return True
82
+
71
83
  def _should_passthrough(self, msg: ta.Any) -> bool:
72
84
  if isinstance(pt := self._passthrough, bool):
73
85
  return pt
@@ -78,29 +90,25 @@ class QueueChannelPipelineHandler(ChannelPipelineHandler, Abstract):
78
90
  else:
79
91
  raise RuntimeError(f'Unknown passthrough mode {self._passthrough!r} for {self!r}')
80
92
 
81
-
82
- class InboundQueueChannelPipelineHandler(QueueChannelPipelineHandler):
83
- def inbound(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any) -> None:
84
- if (self._filter is not None and not self._filter(ctx, msg)):
85
- ctx.feed_in(msg)
93
+ def _handle(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any, feed: ta.Callable[[ta.Any], None]) -> None:
94
+ if not self._should_enqueue(ctx, msg):
95
+ feed(msg)
86
96
  return
87
97
 
88
98
  self._append(msg)
89
99
 
90
100
  if self._should_passthrough(msg):
91
- ctx.feed_in(msg)
101
+ feed(msg)
92
102
 
93
103
 
94
- class OutboundQueueChannelPipelineHandler(QueueChannelPipelineHandler):
95
- def outbound(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any) -> None:
96
- if (self._filter is not None and not self._filter(ctx, msg)):
97
- ctx.feed_out(msg)
98
- return
104
+ class InboundQueueChannelPipelineHandler(QueueChannelPipelineHandler):
105
+ def inbound(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any) -> None:
106
+ self._handle(ctx, msg, ctx.feed_in)
99
107
 
100
- self._append(msg)
101
108
 
102
- if self._should_passthrough(msg):
103
- ctx.feed_out(msg)
109
+ class OutboundQueueChannelPipelineHandler(QueueChannelPipelineHandler):
110
+ def outbound(self, ctx: ChannelPipelineHandlerContext, msg: ta.Any) -> None:
111
+ self._handle(ctx, msg, ctx.feed_out)
104
112
 
105
113
 
106
114
  class DuplexQueueChannelPipelineHandler(