omextra 0.0.0.dev488__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 (159) hide show
  1. omextra-0.0.0.dev488/LICENSE +21 -0
  2. omextra-0.0.0.dev488/MANIFEST.in +1 -0
  3. omextra-0.0.0.dev488/PKG-INFO +33 -0
  4. omextra-0.0.0.dev488/README.md +14 -0
  5. omextra-0.0.0.dev488/omextra/.omlish-manifests.json +14 -0
  6. omextra-0.0.0.dev488/omextra/__about__.py +31 -0
  7. omextra-0.0.0.dev488/omextra/__init__.py +0 -0
  8. omextra-0.0.0.dev488/omextra/asyncs/__init__.py +0 -0
  9. omextra-0.0.0.dev488/omextra/asyncs/bluelet/LICENSE +6 -0
  10. omextra-0.0.0.dev488/omextra/asyncs/bluelet/__init__.py +0 -0
  11. omextra-0.0.0.dev488/omextra/asyncs/bluelet/all.py +67 -0
  12. omextra-0.0.0.dev488/omextra/asyncs/bluelet/api.py +23 -0
  13. omextra-0.0.0.dev488/omextra/asyncs/bluelet/core.py +179 -0
  14. omextra-0.0.0.dev488/omextra/asyncs/bluelet/events.py +79 -0
  15. omextra-0.0.0.dev488/omextra/asyncs/bluelet/files.py +81 -0
  16. omextra-0.0.0.dev488/omextra/asyncs/bluelet/runner.py +419 -0
  17. omextra-0.0.0.dev488/omextra/asyncs/bluelet/sockets.py +217 -0
  18. omextra-0.0.0.dev488/omextra/asyncs/bridge.py +359 -0
  19. omextra-0.0.0.dev488/omextra/collections/__init__.py +0 -0
  20. omextra-0.0.0.dev488/omextra/collections/hamt/LICENSE +35 -0
  21. omextra-0.0.0.dev488/omextra/collections/hamt/__init__.py +0 -0
  22. omextra-0.0.0.dev488/omextra/collections/hamt/_hamt.c +3621 -0
  23. omextra-0.0.0.dev488/omextra/defs.py +216 -0
  24. omextra-0.0.0.dev488/omextra/dynamic.py +219 -0
  25. omextra-0.0.0.dev488/omextra/formats/__init__.py +0 -0
  26. omextra-0.0.0.dev488/omextra/formats/goyaml/LICENSE +16 -0
  27. omextra-0.0.0.dev488/omextra/formats/goyaml/__init__.py +29 -0
  28. omextra-0.0.0.dev488/omextra/formats/goyaml/ast.py +2217 -0
  29. omextra-0.0.0.dev488/omextra/formats/goyaml/errors.py +49 -0
  30. omextra-0.0.0.dev488/omextra/formats/goyaml/parsing.py +2332 -0
  31. omextra-0.0.0.dev488/omextra/formats/goyaml/scanning.py +1888 -0
  32. omextra-0.0.0.dev488/omextra/formats/goyaml/tokens.py +998 -0
  33. omextra-0.0.0.dev488/omextra/formats/json/Json.g4 +77 -0
  34. omextra-0.0.0.dev488/omextra/formats/json/__init__.py +0 -0
  35. omextra-0.0.0.dev488/omextra/formats/json/_antlr/JsonLexer.py +109 -0
  36. omextra-0.0.0.dev488/omextra/formats/json/_antlr/JsonListener.py +61 -0
  37. omextra-0.0.0.dev488/omextra/formats/json/_antlr/JsonParser.py +457 -0
  38. omextra-0.0.0.dev488/omextra/formats/json/_antlr/JsonVisitor.py +42 -0
  39. omextra-0.0.0.dev488/omextra/formats/json/_antlr/__init__.py +0 -0
  40. omextra-0.0.0.dev488/omextra/formats/json5/Json5.g4 +168 -0
  41. omextra-0.0.0.dev488/omextra/formats/json5/__init__.py +0 -0
  42. omextra-0.0.0.dev488/omextra/formats/json5/_antlr/Json5Lexer.py +354 -0
  43. omextra-0.0.0.dev488/omextra/formats/json5/_antlr/Json5Listener.py +79 -0
  44. omextra-0.0.0.dev488/omextra/formats/json5/_antlr/Json5Parser.py +617 -0
  45. omextra-0.0.0.dev488/omextra/formats/json5/_antlr/Json5Visitor.py +52 -0
  46. omextra-0.0.0.dev488/omextra/formats/json5/_antlr/__init__.py +0 -0
  47. omextra-0.0.0.dev488/omextra/formats/json5/parsing.py +101 -0
  48. omextra-0.0.0.dev488/omextra/io/__init__.py +0 -0
  49. omextra-0.0.0.dev488/omextra/io/trampoline.py +289 -0
  50. omextra-0.0.0.dev488/omextra/specs/__init__.py +0 -0
  51. omextra-0.0.0.dev488/omextra/specs/proto/Protobuf3.g4 +396 -0
  52. omextra-0.0.0.dev488/omextra/specs/proto/__init__.py +0 -0
  53. omextra-0.0.0.dev488/omextra/specs/proto/_antlr/Protobuf3Lexer.py +340 -0
  54. omextra-0.0.0.dev488/omextra/specs/proto/_antlr/Protobuf3Listener.py +448 -0
  55. omextra-0.0.0.dev488/omextra/specs/proto/_antlr/Protobuf3Parser.py +3909 -0
  56. omextra-0.0.0.dev488/omextra/specs/proto/_antlr/Protobuf3Visitor.py +257 -0
  57. omextra-0.0.0.dev488/omextra/specs/proto/_antlr/__init__.py +0 -0
  58. omextra-0.0.0.dev488/omextra/specs/proto/nodes.py +54 -0
  59. omextra-0.0.0.dev488/omextra/specs/proto/parsing.py +98 -0
  60. omextra-0.0.0.dev488/omextra/sql/__init__.py +0 -0
  61. omextra-0.0.0.dev488/omextra/sql/parsing/Minisql.g4 +292 -0
  62. omextra-0.0.0.dev488/omextra/sql/parsing/__init__.py +0 -0
  63. omextra-0.0.0.dev488/omextra/sql/parsing/_antlr/MinisqlLexer.py +322 -0
  64. omextra-0.0.0.dev488/omextra/sql/parsing/_antlr/MinisqlListener.py +511 -0
  65. omextra-0.0.0.dev488/omextra/sql/parsing/_antlr/MinisqlParser.py +3763 -0
  66. omextra-0.0.0.dev488/omextra/sql/parsing/_antlr/MinisqlVisitor.py +292 -0
  67. omextra-0.0.0.dev488/omextra/sql/parsing/_antlr/__init__.py +0 -0
  68. omextra-0.0.0.dev488/omextra/sql/parsing/parsing.py +120 -0
  69. omextra-0.0.0.dev488/omextra/text/__init__.py +0 -0
  70. omextra-0.0.0.dev488/omextra/text/abnf/LICENSE +16 -0
  71. omextra-0.0.0.dev488/omextra/text/abnf/__init__.py +79 -0
  72. omextra-0.0.0.dev488/omextra/text/abnf/base.py +313 -0
  73. omextra-0.0.0.dev488/omextra/text/abnf/core.py +141 -0
  74. omextra-0.0.0.dev488/omextra/text/abnf/errors.py +10 -0
  75. omextra-0.0.0.dev488/omextra/text/abnf/meta.py +583 -0
  76. omextra-0.0.0.dev488/omextra/text/abnf/parsers.py +343 -0
  77. omextra-0.0.0.dev488/omextra/text/abnf/utils.py +76 -0
  78. omextra-0.0.0.dev488/omextra/text/abnf/visitors.py +55 -0
  79. omextra-0.0.0.dev488/omextra/text/antlr/__init__.py +3 -0
  80. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/BufferedTokenStream.py +305 -0
  81. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/CommonTokenFactory.py +64 -0
  82. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/CommonTokenStream.py +90 -0
  83. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/FileStream.py +30 -0
  84. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/InputStream.py +90 -0
  85. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/IntervalSet.py +183 -0
  86. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/LICENSE.txt +28 -0
  87. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/LL1Analyzer.py +176 -0
  88. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/Lexer.py +332 -0
  89. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/ListTokenSource.py +147 -0
  90. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/Parser.py +583 -0
  91. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/ParserInterpreter.py +173 -0
  92. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/ParserRuleContext.py +189 -0
  93. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/PredictionContext.py +632 -0
  94. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/Recognizer.py +150 -0
  95. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/RuleContext.py +230 -0
  96. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/StdinStream.py +14 -0
  97. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/Token.py +158 -0
  98. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/TokenStreamRewriter.py +258 -0
  99. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/Utils.py +36 -0
  100. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/__init__.py +2 -0
  101. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/_all.py +24 -0
  102. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/_pygrun.py +174 -0
  103. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/ATN.py +135 -0
  104. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/ATNConfig.py +162 -0
  105. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/ATNConfigSet.py +215 -0
  106. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/ATNDeserializationOptions.py +27 -0
  107. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/ATNDeserializer.py +449 -0
  108. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/ATNSimulator.py +50 -0
  109. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/ATNState.py +267 -0
  110. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/ATNType.py +20 -0
  111. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/LexerATNSimulator.py +573 -0
  112. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/LexerAction.py +301 -0
  113. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/LexerActionExecutor.py +146 -0
  114. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/ParserATNSimulator.py +1664 -0
  115. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/PredictionMode.py +502 -0
  116. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/SemanticContext.py +333 -0
  117. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/Transition.py +271 -0
  118. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/atn/__init__.py +4 -0
  119. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/dfa/DFA.py +136 -0
  120. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/dfa/DFASerializer.py +76 -0
  121. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/dfa/DFAState.py +129 -0
  122. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/dfa/__init__.py +4 -0
  123. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/error/DiagnosticErrorListener.py +111 -0
  124. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/error/ErrorListener.py +75 -0
  125. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/error/ErrorStrategy.py +712 -0
  126. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/error/Errors.py +176 -0
  127. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/error/__init__.py +4 -0
  128. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/tree/Chunk.py +33 -0
  129. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/tree/ParseTreeMatch.py +121 -0
  130. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/tree/ParseTreePattern.py +75 -0
  131. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/tree/ParseTreePatternMatcher.py +377 -0
  132. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/tree/RuleTagToken.py +53 -0
  133. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/tree/TokenTagToken.py +50 -0
  134. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/tree/Tree.py +194 -0
  135. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/tree/Trees.py +114 -0
  136. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/tree/__init__.py +2 -0
  137. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/xpath/XPath.py +278 -0
  138. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/xpath/XPathLexer.py +98 -0
  139. omextra-0.0.0.dev488/omextra/text/antlr/_runtime/xpath/__init__.py +4 -0
  140. omextra-0.0.0.dev488/omextra/text/antlr/cli/__init__.py +0 -0
  141. omextra-0.0.0.dev488/omextra/text/antlr/cli/__main__.py +11 -0
  142. omextra-0.0.0.dev488/omextra/text/antlr/cli/cli.py +62 -0
  143. omextra-0.0.0.dev488/omextra/text/antlr/cli/consts.py +7 -0
  144. omextra-0.0.0.dev488/omextra/text/antlr/cli/gen.py +193 -0
  145. omextra-0.0.0.dev488/omextra/text/antlr/delimit.py +110 -0
  146. omextra-0.0.0.dev488/omextra/text/antlr/dot.py +42 -0
  147. omextra-0.0.0.dev488/omextra/text/antlr/errors.py +14 -0
  148. omextra-0.0.0.dev488/omextra/text/antlr/input.py +96 -0
  149. omextra-0.0.0.dev488/omextra/text/antlr/parsing.py +55 -0
  150. omextra-0.0.0.dev488/omextra/text/antlr/runtime.py +102 -0
  151. omextra-0.0.0.dev488/omextra/text/antlr/utils.py +38 -0
  152. omextra-0.0.0.dev488/omextra.egg-info/PKG-INFO +33 -0
  153. omextra-0.0.0.dev488/omextra.egg-info/SOURCES.txt +157 -0
  154. omextra-0.0.0.dev488/omextra.egg-info/dependency_links.txt +1 -0
  155. omextra-0.0.0.dev488/omextra.egg-info/entry_points.txt +2 -0
  156. omextra-0.0.0.dev488/omextra.egg-info/requires.txt +1 -0
  157. omextra-0.0.0.dev488/omextra.egg-info/top_level.txt +1 -0
  158. omextra-0.0.0.dev488/pyproject.toml +58 -0
  159. omextra-0.0.0.dev488/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ Copyright 2023- wrmsr
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
4
+ following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
7
+ disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
10
+ disclaimer in the documentation and/or other materials provided with the distribution.
11
+
12
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ global-exclude **/conftest.py
@@ -0,0 +1,33 @@
1
+ Metadata-Version: 2.4
2
+ Name: omextra
3
+ Version: 0.0.0.dev488
4
+ Summary: omextra
5
+ Author: wrmsr
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: source, https://github.com/wrmsr/omlish
8
+ Classifier: Development Status :: 2 - Pre-Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Operating System :: POSIX
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Requires-Python: >=3.13
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: omlish==0.0.0.dev488
18
+ Dynamic: license-file
19
+
20
+ # Overview
21
+
22
+ Core-like code not appropriate for inclusion in `omlish` for one reason or another. A bit like
23
+ [`golang.org/x`](https://pkg.go.dev/golang.org/x) but even less suitable for production use.
24
+
25
+ Code here is usually in the process of either moving out of or moving into `omlish` proper, or being demoted to the
26
+ unpublished `x` root dir, or just being deleted.
27
+
28
+ # Notable packages
29
+
30
+ - **[text.antlr](https://github.com/wrmsr/omlish/blob/master/omextra/text/antlr)** -
31
+ [ANTLR](https://www.antlr.org/)-related code. The codebase is generally moving away from antlr in favor of an internal
32
+ [abnf engine](https://github.com/wrmsr/omlish/blob/master/omextra/text/abnf), but I have other projects that need the
33
+ full power of antlr, so it may remain as an optional dep for utility code (much like sqlalchemy).
@@ -0,0 +1,14 @@
1
+ # Overview
2
+
3
+ Core-like code not appropriate for inclusion in `omlish` for one reason or another. A bit like
4
+ [`golang.org/x`](https://pkg.go.dev/golang.org/x) but even less suitable for production use.
5
+
6
+ Code here is usually in the process of either moving out of or moving into `omlish` proper, or being demoted to the
7
+ unpublished `x` root dir, or just being deleted.
8
+
9
+ # Notable packages
10
+
11
+ - **[text.antlr](https://github.com/wrmsr/omlish/blob/master/omextra/text/antlr)** -
12
+ [ANTLR](https://www.antlr.org/)-related code. The codebase is generally moving away from antlr in favor of an internal
13
+ [abnf engine](https://github.com/wrmsr/omlish/blob/master/omextra/text/abnf), but I have other projects that need the
14
+ full power of antlr, so it may remain as an optional dep for utility code (much like sqlalchemy).
@@ -0,0 +1,14 @@
1
+ [
2
+ {
3
+ "module": ".text.antlr.cli.__main__",
4
+ "attr": "_CLI_MODULE",
5
+ "file": "omextra/text/antlr/cli/__main__.py",
6
+ "line": 1,
7
+ "value": {
8
+ "!omdev.cli.types.CliModule": {
9
+ "name": "antlr",
10
+ "module": "omextra.text.antlr.cli.__main__"
11
+ }
12
+ }
13
+ }
14
+ ]
@@ -0,0 +1,31 @@
1
+ from omlish.__about__ import ProjectBase
2
+ from omlish.__about__ import SetuptoolsBase
3
+ from omlish.__about__ import __version__
4
+
5
+
6
+ class Project(ProjectBase):
7
+ name = 'omextra'
8
+ description = 'omextra'
9
+
10
+ dependencies = [
11
+ # FIXME: text.antlr.cli deps omdev.cache.data, yet this lib is 'under' omdev.
12
+ # f'omdev == {__version__}',
13
+
14
+ f'omlish == {__version__}',
15
+ ]
16
+
17
+ optional_dependencies: dict = {
18
+ }
19
+
20
+ entry_points = {
21
+ 'omlish.manifests': {name: name},
22
+ }
23
+
24
+
25
+ class Setuptools(SetuptoolsBase):
26
+ cext = True
27
+
28
+ find_packages = {
29
+ 'include': [Project.name, f'{Project.name}.*'],
30
+ 'exclude': [*SetuptoolsBase.find_packages['exclude']],
31
+ }
File without changes
File without changes
@@ -0,0 +1,6 @@
1
+ Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
2
+
3
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
4
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
5
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
6
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,67 @@
1
+ # ruff: noqa: I001
2
+ from .api import ( # noqa
3
+ bluelet,
4
+ )
5
+
6
+ from .core import ( # noqa
7
+ BlueletCoro as Coro,
8
+ BlueletExcInfo as ExcInfo,
9
+ CoreBlueletEvent as CoreEvent,
10
+ DelegationBlueletEvent as DelegationEvent,
11
+ ExceptionBlueletEvent as ExceptionEvent,
12
+ JoinBlueletEvent as JoinEvent,
13
+ KillBlueletEvent as KillEvent,
14
+ ReturnBlueletEvent as ReturnEvent,
15
+ SleepBlueletEvent as SleepEvent,
16
+ SpawnBlueletEvent as SpawnEvent,
17
+ ValueBlueletEvent as ValueEvent,
18
+ )
19
+
20
+ from .events import ( # noqa
21
+ BlueletEvent as Event,
22
+ BlueletFuture as Future,
23
+ BlueletHasFileno as HasFileno,
24
+ BlueletWaitable as Waitable,
25
+ BlueletWaitables as Waitables,
26
+ WaitableBlueletEvent as WaitableEvent,
27
+ )
28
+
29
+ from .files import ( # noqa
30
+ FileBlueletEvent as FileEvent,
31
+ ReadBlueletEvent as ReadEvent,
32
+ WriteBlueletEvent as WriteEvent,
33
+ )
34
+
35
+ from .runner import ( # noqa
36
+ BlueletCoroException as CoroException,
37
+ )
38
+
39
+ from .sockets import ( # noqa
40
+ AcceptBlueletEvent as AcceptEvent,
41
+ BlueletConnection as Connection,
42
+ BlueletListener as Listener,
43
+ ReceiveBlueletEvent as ReceiveEvent,
44
+ SendBlueletEvent as SendEvent,
45
+ SocketBlueletEvent as SocketEvent,
46
+ SocketClosedBlueletError as SocketClosedError,
47
+ )
48
+
49
+
50
+ ##
51
+
52
+
53
+ call = bluelet.call
54
+ end = bluelet.end
55
+ join = bluelet.join
56
+ kill = bluelet.kill
57
+ null = bluelet.null
58
+ sleep = bluelet.sleep
59
+ spawn = bluelet.spawn
60
+
61
+ read = bluelet.read
62
+ write = bluelet.write
63
+
64
+ run = bluelet.run
65
+
66
+ connect = bluelet.connect
67
+ server = bluelet.server
@@ -0,0 +1,23 @@
1
+ # ruff: noqa: UP006 UP007 UP045
2
+ # @omlish-lite
3
+ # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+ from .core import _CoreBlueletApi
9
+ from .files import _FilesBlueletApi
10
+ from .runner import _RunnerBlueletApi
11
+ from .sockets import _SocketsBlueletApi
12
+
13
+
14
+ class BlueletApi(
15
+ _RunnerBlueletApi,
16
+ _SocketsBlueletApi,
17
+ _FilesBlueletApi,
18
+ _CoreBlueletApi,
19
+ ):
20
+ pass
21
+
22
+
23
+ bluelet = BlueletApi()
@@ -0,0 +1,179 @@
1
+ # ruff: noqa: UP006 UP007 UP043 UP045
2
+ # @omlish-lite
3
+ # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+ import dataclasses as dc
9
+ import time
10
+ import types
11
+ import typing as ta
12
+
13
+ from omlish.lite.abstract import Abstract
14
+
15
+ from .events import BlueletEvent
16
+ from .events import BlueletFuture
17
+ from .events import WaitableBlueletEvent
18
+
19
+
20
+ T = ta.TypeVar('T')
21
+
22
+ BlueletExcInfo = ta.Tuple[ta.Type[BaseException], BaseException, types.TracebackType] # ta.TypeAlias
23
+
24
+ BlueletCoro = ta.Generator[ta.Union['BlueletEvent', 'BlueletCoro'], ta.Any, None] # ta.TypeAlias
25
+
26
+ BlueletSpawnable = ta.Union[BlueletCoro, ta.Awaitable] # ta.TypeAlias
27
+
28
+
29
+ ##
30
+
31
+
32
+ @dc.dataclass(frozen=True, eq=False)
33
+ class _BlueletAwaitableDriver:
34
+ a: ta.Awaitable
35
+
36
+ def __call__(self) -> BlueletCoro:
37
+ g = self.a.__await__()
38
+ gi = iter(g)
39
+ while True:
40
+ try:
41
+ f = gi.send(None)
42
+ except StopIteration as e:
43
+ yield ReturnBlueletEvent(e.value)
44
+ break
45
+ else:
46
+ if not isinstance(f, BlueletFuture):
47
+ raise TypeError(f)
48
+ res = yield f.event
49
+ f.done = True
50
+ f.result = res
51
+
52
+
53
+ ##
54
+
55
+
56
+ class CoreBlueletEvent(BlueletEvent, Abstract):
57
+ pass
58
+
59
+
60
+ @dc.dataclass(frozen=True, eq=False)
61
+ class ValueBlueletEvent(CoreBlueletEvent, ta.Generic[T]):
62
+ """An event that does nothing but return a fixed value."""
63
+
64
+ value: T
65
+
66
+
67
+ @dc.dataclass(frozen=True, eq=False)
68
+ class ExceptionBlueletEvent(CoreBlueletEvent):
69
+ """Raise an exception at the yield point. Used internally."""
70
+
71
+ exc_info: BlueletExcInfo
72
+
73
+
74
+ @dc.dataclass(frozen=True, eq=False)
75
+ class SpawnBlueletEvent(CoreBlueletEvent):
76
+ """Add a new coroutine coro to the scheduler."""
77
+
78
+ spawned: BlueletSpawnable
79
+
80
+
81
+ @dc.dataclass(frozen=True, eq=False)
82
+ class JoinBlueletEvent(CoreBlueletEvent):
83
+ """Suspend the coro until the specified child coro has completed."""
84
+
85
+ child: BlueletCoro
86
+
87
+
88
+ @dc.dataclass(frozen=True, eq=False)
89
+ class KillBlueletEvent(CoreBlueletEvent):
90
+ """Unschedule a child coro."""
91
+
92
+ child: BlueletCoro
93
+
94
+
95
+ @dc.dataclass(frozen=True, eq=False)
96
+ class DelegationBlueletEvent(CoreBlueletEvent):
97
+ """
98
+ Suspend execution of the current coro, start a new coro and, once the child coro finished, return control to
99
+ the parent coro.
100
+ """
101
+
102
+ spawned: BlueletCoro
103
+
104
+
105
+ @dc.dataclass(frozen=True, eq=False)
106
+ class ReturnBlueletEvent(CoreBlueletEvent, ta.Generic[T]):
107
+ """Return a value the current coro's delegator at the point of delegation. Ends the current (delegate) coro."""
108
+
109
+ value: ta.Optional[T]
110
+
111
+
112
+ @dc.dataclass(frozen=True, eq=False)
113
+ class SleepBlueletEvent(WaitableBlueletEvent, CoreBlueletEvent):
114
+ """Suspend the coro for a given duration."""
115
+
116
+ wakeup_time: float
117
+
118
+ def time_left(self) -> float:
119
+ return max(self.wakeup_time - time.time(), 0.)
120
+
121
+
122
+ ##
123
+
124
+
125
+ class _CoreBlueletApi:
126
+ def value(self, v: T) -> ValueBlueletEvent[T]:
127
+ """Event: yield a value."""
128
+
129
+ return ValueBlueletEvent(v)
130
+
131
+ def null(self) -> ValueBlueletEvent[None]:
132
+ """Event: yield to the scheduler without doing anything special."""
133
+
134
+ return ValueBlueletEvent(None)
135
+
136
+ def spawn(self, spawned: BlueletSpawnable) -> SpawnBlueletEvent:
137
+ """Event: add another coroutine to the scheduler. Both the parent and child coroutines run concurrently."""
138
+
139
+ if isinstance(spawned, types.CoroutineType):
140
+ spawned = _BlueletAwaitableDriver(spawned)()
141
+
142
+ if not isinstance(spawned, types.GeneratorType):
143
+ raise TypeError(f'{spawned} is not spawnable')
144
+
145
+ return SpawnBlueletEvent(spawned)
146
+
147
+ def join(self, coro: BlueletCoro) -> JoinBlueletEvent:
148
+ """Suspend the coro until another, previously `spawn`ed coro completes."""
149
+
150
+ return JoinBlueletEvent(coro)
151
+
152
+ def kill(self, coro: BlueletCoro) -> KillBlueletEvent:
153
+ """Halt the execution of a different `spawn`ed coro."""
154
+
155
+ return KillBlueletEvent(coro)
156
+
157
+ def call(self, spawned: BlueletSpawnable) -> DelegationBlueletEvent:
158
+ """
159
+ Event: delegate to another coroutine. The current coroutine is resumed once the sub-coroutine finishes. If the
160
+ sub-coroutine returns a value using end(), then this event returns that value.
161
+ """
162
+
163
+ if isinstance(spawned, types.CoroutineType):
164
+ spawned = _BlueletAwaitableDriver(spawned)()
165
+
166
+ if not isinstance(spawned, types.GeneratorType):
167
+ raise TypeError(f'{spawned} is not spawnable')
168
+
169
+ return DelegationBlueletEvent(spawned)
170
+
171
+ def end(self, value: ta.Optional[T] = None) -> ReturnBlueletEvent[T]:
172
+ """Event: ends the coroutine and returns a value to its delegator."""
173
+
174
+ return ReturnBlueletEvent(value)
175
+
176
+ def sleep(self, duration: float) -> SleepBlueletEvent:
177
+ """Event: suspend the coro for ``duration`` seconds."""
178
+
179
+ return SleepBlueletEvent(time.time() + duration)
@@ -0,0 +1,79 @@
1
+ # ruff: noqa: UP007 UP045
2
+ # @omlish-lite
3
+ # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+ import dataclasses as dc
9
+ import typing as ta
10
+
11
+ from omlish.lite.abstract import Abstract
12
+
13
+
14
+ R = ta.TypeVar('R')
15
+
16
+ BlueletEventT = ta.TypeVar('BlueletEventT', bound='BlueletEvent')
17
+
18
+ BlueletWaitable = ta.Union[int, 'BlueletHasFileno'] # ta.TypeAlias
19
+
20
+
21
+ ##
22
+
23
+
24
+ class BlueletEvent(Abstract):
25
+ """
26
+ Just a base class identifying Bluelet events. An event is an object yielded from a Bluelet coro coroutine to
27
+ suspend operation and communicate with the scheduler.
28
+ """
29
+
30
+ def __await__(self):
31
+ return BlueletFuture(self).__await__()
32
+
33
+
34
+ ##
35
+
36
+
37
+ class BlueletHasFileno(ta.Protocol):
38
+ def fileno(self) -> int: ...
39
+
40
+
41
+ @dc.dataclass(frozen=True)
42
+ class BlueletWaitables:
43
+ r: ta.Sequence[BlueletWaitable] = ()
44
+ w: ta.Sequence[BlueletWaitable] = ()
45
+ x: ta.Sequence[BlueletWaitable] = ()
46
+
47
+
48
+ class WaitableBlueletEvent(BlueletEvent, Abstract):
49
+ """
50
+ A waitable event is one encapsulating an action that can be waited for using a select() call. That is, it's an event
51
+ with an associated file descriptor.
52
+ """
53
+
54
+ def waitables(self) -> BlueletWaitables:
55
+ """
56
+ Return "waitable" objects to pass to select(). Should return three iterables for input readiness, output
57
+ readiness, and exceptional conditions (i.e., the three lists passed to select()).
58
+ """
59
+ return BlueletWaitables()
60
+
61
+ def fire(self) -> ta.Any:
62
+ """Called when an associated file descriptor becomes ready (i.e., is returned from a select() call)."""
63
+
64
+
65
+ ##
66
+
67
+
68
+ @dc.dataclass(eq=False)
69
+ class BlueletFuture(ta.Generic[BlueletEventT, R]):
70
+ event: BlueletEventT
71
+ done: bool = False
72
+ result: ta.Optional[R] = None
73
+
74
+ def __await__(self):
75
+ if not self.done:
76
+ yield self
77
+ if not self.done:
78
+ raise RuntimeError("await wasn't used with event future")
79
+ return self.result
@@ -0,0 +1,81 @@
1
+ # ruff: noqa: UP006 UP007 UP045
2
+ # @omlish-lite
3
+ # Based on bluelet ( https://github.com/sampsyo/bluelet ) by Adrian Sampson, original license:
4
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
5
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
6
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
7
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+ import dataclasses as dc
9
+ import typing as ta
10
+
11
+ from omlish.lite.abstract import Abstract
12
+
13
+ from .core import DelegationBlueletEvent
14
+ from .core import ReturnBlueletEvent
15
+ from .events import BlueletEvent
16
+ from .events import BlueletWaitables
17
+ from .events import WaitableBlueletEvent
18
+
19
+
20
+ ##
21
+
22
+
23
+ class FileBlueletEvent(BlueletEvent, Abstract):
24
+ pass
25
+
26
+
27
+ @dc.dataclass(frozen=True, eq=False)
28
+ class ReadBlueletEvent(WaitableBlueletEvent, FileBlueletEvent):
29
+ """Reads from a file-like object."""
30
+
31
+ fd: ta.IO
32
+ bufsize: int
33
+
34
+ def waitables(self) -> BlueletWaitables:
35
+ return BlueletWaitables(r=[self.fd])
36
+
37
+ def fire(self) -> bytes:
38
+ return self.fd.read(self.bufsize)
39
+
40
+
41
+ @dc.dataclass(frozen=True, eq=False)
42
+ class WriteBlueletEvent(WaitableBlueletEvent, FileBlueletEvent):
43
+ """Writes to a file-like object."""
44
+
45
+ fd: ta.IO
46
+ data: bytes
47
+
48
+ def waitables(self) -> BlueletWaitables:
49
+ return BlueletWaitables(w=[self.fd])
50
+
51
+ def fire(self) -> None:
52
+ self.fd.write(self.data)
53
+
54
+
55
+ ##
56
+
57
+
58
+ class _FilesBlueletApi:
59
+ def read(self, fd: ta.IO, bufsize: ta.Optional[int] = None) -> BlueletEvent:
60
+ """Event: read from a file descriptor asynchronously."""
61
+
62
+ if bufsize is None:
63
+ # Read all.
64
+ def reader():
65
+ buf = []
66
+ while True:
67
+ data = yield self.read(fd, 1024)
68
+ if not data:
69
+ break
70
+ buf.append(data)
71
+ yield ReturnBlueletEvent(''.join(buf))
72
+
73
+ return DelegationBlueletEvent(reader())
74
+
75
+ else:
76
+ return ReadBlueletEvent(fd, bufsize)
77
+
78
+ def write(self, fd: ta.IO, data: bytes) -> BlueletEvent:
79
+ """Event: write to a file descriptor asynchronously."""
80
+
81
+ return WriteBlueletEvent(fd, data)