omxtra 0.0.0.dev545__tar.gz → 0.0.0.dev547__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 (181) hide show
  1. {omxtra-0.0.0.dev545/omxtra.egg-info → omxtra-0.0.0.dev547}/PKG-INFO +10 -2
  2. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/__about__.py +10 -0
  3. omxtra-0.0.0.dev547/omxtra/commands/runners.py +88 -0
  4. omxtra-0.0.0.dev547/omxtra/commands/ssh.py +194 -0
  5. omxtra-0.0.0.dev547/omxtra/specs/proto/abnf.py +23 -0
  6. omxtra-0.0.0.dev547/omxtra/specs/proto/proto3.abnf +280 -0
  7. omxtra-0.0.0.dev547/omxtra/sql/parsing/abnf.py +15 -0
  8. omxtra-0.0.0.dev547/omxtra/sql/parsing/minisql.abnf +338 -0
  9. omxtra-0.0.0.dev547/omxtra/text/antlr/cli/__init__.py +0 -0
  10. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547/omxtra.egg-info}/PKG-INFO +10 -2
  11. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra.egg-info/SOURCES.txt +7 -0
  12. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra.egg-info/requires.txt +11 -1
  13. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/pyproject.toml +14 -3
  14. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/LICENSE +0 -0
  15. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/MANIFEST.in +0 -0
  16. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/README.md +0 -0
  17. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/.omlish-manifests.json +0 -0
  18. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/README.md +0 -0
  19. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/__init__.py +0 -0
  20. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/__init__.py +0 -0
  21. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/all.py +0 -0
  22. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bluelet/LICENSE +0 -0
  23. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bluelet/__init__.py +0 -0
  24. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bluelet/all.py +0 -0
  25. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bluelet/api.py +0 -0
  26. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bluelet/core.py +0 -0
  27. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bluelet/events.py +0 -0
  28. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bluelet/files.py +0 -0
  29. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bluelet/runner.py +0 -0
  30. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bluelet/sockets.py +0 -0
  31. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/bridge.py +0 -0
  32. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/asyncs/flavors.py +0 -0
  33. {omxtra-0.0.0.dev545/omxtra/concurrent → omxtra-0.0.0.dev547/omxtra/commands}/__init__.py +0 -0
  34. {omxtra-0.0.0.dev545/omxtra/formats → omxtra-0.0.0.dev547/omxtra/concurrent}/__init__.py +0 -0
  35. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/concurrent/threadlets.py +0 -0
  36. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/defs.py +0 -0
  37. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/dynamic.py +0 -0
  38. {omxtra-0.0.0.dev545/omxtra/formats/json → omxtra-0.0.0.dev547/omxtra/formats}/__init__.py +0 -0
  39. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json/Json.g4 +0 -0
  40. {omxtra-0.0.0.dev545/omxtra/formats/json/_antlr → omxtra-0.0.0.dev547/omxtra/formats/json}/__init__.py +0 -0
  41. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json/_antlr/JsonLexer.py +0 -0
  42. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json/_antlr/JsonListener.py +0 -0
  43. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json/_antlr/JsonParser.py +0 -0
  44. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json/_antlr/JsonVisitor.py +0 -0
  45. {omxtra-0.0.0.dev545/omxtra/formats/json5 → omxtra-0.0.0.dev547/omxtra/formats/json/_antlr}/__init__.py +0 -0
  46. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json5/Json5.g4 +0 -0
  47. {omxtra-0.0.0.dev545/omxtra/formats/json5/_antlr → omxtra-0.0.0.dev547/omxtra/formats/json5}/__init__.py +0 -0
  48. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json5/_antlr/Json5Lexer.py +0 -0
  49. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json5/_antlr/Json5Listener.py +0 -0
  50. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json5/_antlr/Json5Parser.py +0 -0
  51. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json5/_antlr/Json5Visitor.py +0 -0
  52. {omxtra-0.0.0.dev545/omxtra/io → omxtra-0.0.0.dev547/omxtra/formats/json5/_antlr}/__init__.py +0 -0
  53. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/formats/json5/parsing.py +0 -0
  54. {omxtra-0.0.0.dev545/omxtra/server/streams → omxtra-0.0.0.dev547/omxtra/io}/__init__.py +0 -0
  55. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/io/trampoline.py +0 -0
  56. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/LICENSE +0 -0
  57. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/__init__.py +0 -0
  58. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/config.py +0 -0
  59. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/debug.py +0 -0
  60. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/default.py +0 -0
  61. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/events.py +0 -0
  62. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/headers.py +0 -0
  63. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/inject.py +0 -0
  64. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/lifespans.py +0 -0
  65. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/listener.py +0 -0
  66. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/multiprocess.py +0 -0
  67. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/protocols/__init__.py +0 -0
  68. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/protocols/h11.py +0 -0
  69. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/protocols/h2.py +0 -0
  70. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/protocols/protocols.py +0 -0
  71. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/protocols/types.py +0 -0
  72. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/resources/__init__.py +0 -0
  73. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/resources/favicon.ico +0 -0
  74. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/server.py +0 -0
  75. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/sockets.py +0 -0
  76. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/ssl.py +0 -0
  77. {omxtra-0.0.0.dev545/omxtra/specs → omxtra-0.0.0.dev547/omxtra/server/streams}/__init__.py +0 -0
  78. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/streams/httpstream.py +0 -0
  79. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/streams/utils.py +0 -0
  80. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/streams/wsstream.py +0 -0
  81. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/taskspawner.py +0 -0
  82. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/types.py +0 -0
  83. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/server/workercontext.py +0 -0
  84. {omxtra-0.0.0.dev545/omxtra/specs/proto → omxtra-0.0.0.dev547/omxtra/specs}/__init__.py +0 -0
  85. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/specs/proto/Protobuf3.g4 +0 -0
  86. {omxtra-0.0.0.dev545/omxtra/specs/proto/_antlr → omxtra-0.0.0.dev547/omxtra/specs/proto}/__init__.py +0 -0
  87. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/specs/proto/_antlr/Protobuf3Lexer.py +0 -0
  88. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/specs/proto/_antlr/Protobuf3Listener.py +0 -0
  89. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/specs/proto/_antlr/Protobuf3Parser.py +0 -0
  90. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/specs/proto/_antlr/Protobuf3Visitor.py +0 -0
  91. {omxtra-0.0.0.dev545/omxtra/sql → omxtra-0.0.0.dev547/omxtra/specs/proto/_antlr}/__init__.py +0 -0
  92. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/specs/proto/nodes.py +0 -0
  93. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/specs/proto/parsing.py +0 -0
  94. {omxtra-0.0.0.dev545/omxtra/sql/parsing → omxtra-0.0.0.dev547/omxtra/sql}/__init__.py +0 -0
  95. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/sql/alchemy/__init__.py +0 -0
  96. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/sql/alchemy/asyncs.py +0 -0
  97. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/sql/parsing/Minisql.g4 +0 -0
  98. {omxtra-0.0.0.dev545/omxtra/sql/parsing/_antlr → omxtra-0.0.0.dev547/omxtra/sql/parsing}/__init__.py +0 -0
  99. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/sql/parsing/_antlr/MinisqlLexer.py +0 -0
  100. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/sql/parsing/_antlr/MinisqlListener.py +0 -0
  101. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/sql/parsing/_antlr/MinisqlParser.py +0 -0
  102. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/sql/parsing/_antlr/MinisqlVisitor.py +0 -0
  103. {omxtra-0.0.0.dev545/omxtra/text → omxtra-0.0.0.dev547/omxtra/sql/parsing/_antlr}/__init__.py +0 -0
  104. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/sql/parsing/parsing.py +0 -0
  105. {omxtra-0.0.0.dev545/omxtra/text/antlr/cli → omxtra-0.0.0.dev547/omxtra/text}/__init__.py +0 -0
  106. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/__init__.py +0 -0
  107. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/BufferedTokenStream.py +0 -0
  108. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/CommonTokenFactory.py +0 -0
  109. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/CommonTokenStream.py +0 -0
  110. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/FileStream.py +0 -0
  111. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/InputStream.py +0 -0
  112. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/IntervalSet.py +0 -0
  113. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/LICENSE.txt +0 -0
  114. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/LL1Analyzer.py +0 -0
  115. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/Lexer.py +0 -0
  116. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/ListTokenSource.py +0 -0
  117. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/Parser.py +0 -0
  118. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/ParserInterpreter.py +0 -0
  119. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/ParserRuleContext.py +0 -0
  120. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/PredictionContext.py +0 -0
  121. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/Recognizer.py +0 -0
  122. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/RuleContext.py +0 -0
  123. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/StdinStream.py +0 -0
  124. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/Token.py +0 -0
  125. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/TokenStreamRewriter.py +0 -0
  126. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/Utils.py +0 -0
  127. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/__init__.py +0 -0
  128. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/_all.py +0 -0
  129. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/_pygrun.py +0 -0
  130. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/ATN.py +0 -0
  131. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/ATNConfig.py +0 -0
  132. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/ATNConfigSet.py +0 -0
  133. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/ATNDeserializationOptions.py +0 -0
  134. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/ATNDeserializer.py +0 -0
  135. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/ATNSimulator.py +0 -0
  136. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/ATNState.py +0 -0
  137. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/ATNType.py +0 -0
  138. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/LexerATNSimulator.py +0 -0
  139. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/LexerAction.py +0 -0
  140. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/LexerActionExecutor.py +0 -0
  141. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/ParserATNSimulator.py +0 -0
  142. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/PredictionMode.py +0 -0
  143. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/SemanticContext.py +0 -0
  144. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/Transition.py +0 -0
  145. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/atn/__init__.py +0 -0
  146. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/dfa/DFA.py +0 -0
  147. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/dfa/DFASerializer.py +0 -0
  148. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/dfa/DFAState.py +0 -0
  149. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/dfa/__init__.py +0 -0
  150. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/error/DiagnosticErrorListener.py +0 -0
  151. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/error/ErrorListener.py +0 -0
  152. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/error/ErrorStrategy.py +0 -0
  153. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/error/Errors.py +0 -0
  154. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/error/__init__.py +0 -0
  155. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/tree/Chunk.py +0 -0
  156. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/tree/ParseTreeMatch.py +0 -0
  157. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/tree/ParseTreePattern.py +0 -0
  158. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/tree/ParseTreePatternMatcher.py +0 -0
  159. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/tree/RuleTagToken.py +0 -0
  160. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/tree/TokenTagToken.py +0 -0
  161. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/tree/Tree.py +0 -0
  162. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/tree/Trees.py +0 -0
  163. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/tree/__init__.py +0 -0
  164. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/xpath/XPath.py +0 -0
  165. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/xpath/XPathLexer.py +0 -0
  166. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/_runtime/xpath/__init__.py +0 -0
  167. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/cli/__main__.py +0 -0
  168. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/cli/cli.py +0 -0
  169. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/cli/consts.py +0 -0
  170. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/cli/gen.py +0 -0
  171. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/delimit.py +0 -0
  172. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/dot.py +0 -0
  173. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/errors.py +0 -0
  174. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/input.py +0 -0
  175. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/parsing.py +0 -0
  176. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/runtime.py +0 -0
  177. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra/text/antlr/utils.py +0 -0
  178. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra.egg-info/dependency_links.txt +0 -0
  179. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra.egg-info/entry_points.txt +0 -0
  180. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/omxtra.egg-info/top_level.txt +0 -0
  181. {omxtra-0.0.0.dev545 → omxtra-0.0.0.dev547}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omxtra
3
- Version: 0.0.0.dev545
3
+ Version: 0.0.0.dev547
4
4
  Summary: omxtra
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -14,18 +14,26 @@ 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.dev545
17
+ Requires-Dist: omlish==0.0.0.dev547
18
18
  Provides-Extra: all
19
+ Requires-Dist: omdev==0.0.0.dev547; extra == "all"
19
20
  Requires-Dist: h11~=0.16; extra == "all"
20
21
  Requires-Dist: h2~=4.3; extra == "all"
21
22
  Requires-Dist: priority~=2.0; extra == "all"
22
23
  Requires-Dist: wsproto~=1.3; extra == "all"
24
+ Requires-Dist: paramiko~=4.0; extra == "all"
25
+ Requires-Dist: asyncssh~=2.22; extra == "all"
23
26
  Requires-Dist: jinja2~=3.1; extra == "all"
27
+ Provides-Extra: omdev
28
+ Requires-Dist: omdev==0.0.0.dev547; extra == "omdev"
24
29
  Provides-Extra: server
25
30
  Requires-Dist: h11~=0.16; extra == "server"
26
31
  Requires-Dist: h2~=4.3; extra == "server"
27
32
  Requires-Dist: priority~=2.0; extra == "server"
28
33
  Requires-Dist: wsproto~=1.3; extra == "server"
34
+ Provides-Extra: ssh
35
+ Requires-Dist: paramiko~=4.0; extra == "ssh"
36
+ Requires-Dist: asyncssh~=2.22; extra == "ssh"
29
37
  Provides-Extra: templates
30
38
  Requires-Dist: jinja2~=3.1; extra == "templates"
31
39
  Dynamic: license-file
@@ -15,6 +15,10 @@ class Project(ProjectBase):
15
15
  ]
16
16
 
17
17
  optional_dependencies: dict = {
18
+ 'omdev': [
19
+ f'omdev == {__version__}',
20
+ ],
21
+
18
22
  'server': [
19
23
  'h11 ~= 0.16',
20
24
  'h2 ~= 4.3',
@@ -22,6 +26,12 @@ class Project(ProjectBase):
22
26
  'wsproto ~= 1.3',
23
27
  ],
24
28
 
29
+ 'ssh': [
30
+ 'paramiko ~= 4.0', # !! LGPL
31
+
32
+ 'asyncssh ~= 2.22', # cffi
33
+ ],
34
+
25
35
  'templates': [
26
36
  'jinja2 ~= 3.1',
27
37
  ],
@@ -0,0 +1,88 @@
1
+ """
2
+ TODO:
3
+ - timeout
4
+ - stream in/out/err
5
+ - *sessions*
6
+ - anyio
7
+ """
8
+ import abc
9
+ import asyncio
10
+ import io
11
+ import typing as ta
12
+
13
+ from omlish import check
14
+ from omlish import dataclasses as dc
15
+ from omlish import lang
16
+
17
+
18
+ ##
19
+
20
+
21
+ class CommandRunner(lang.Abstract):
22
+ @dc.dataclass(frozen=True)
23
+ class Command:
24
+ args: ta.Sequence[str]
25
+ in_: bytes | None = None
26
+
27
+ @dc.dataclass(frozen=True)
28
+ class Result:
29
+ rc: int
30
+ out: bytes
31
+ err: bytes
32
+
33
+ def check(self) -> ta.Self:
34
+ if self.rc != 0:
35
+ raise CommandRunner.ReturnCodeError(self)
36
+ return self
37
+
38
+ class ReturnCodeError(Exception):
39
+ def __init__(self, result: 'CommandRunner.Result') -> None:
40
+ super().__init__(f'Bad return code: {result.rc}', result)
41
+
42
+ self.result = result
43
+
44
+ @abc.abstractmethod
45
+ async def run_command(self, cmd: Command) -> Result:
46
+ raise NotImplementedError
47
+
48
+
49
+ class LocalCommandRunner(CommandRunner):
50
+ @dc.dataclass(frozen=True)
51
+ class Config:
52
+ cwd: str | None = None
53
+
54
+ def __init__(self, cfg: Config = Config()) -> None:
55
+ super().__init__()
56
+
57
+ self._cfg = check.isinstance(cfg, LocalCommandRunner.Config)
58
+
59
+ async def run_command(self, cmd: CommandRunner.Command) -> CommandRunner.Result:
60
+ proc = await asyncio.create_subprocess_exec(
61
+ *cmd.args,
62
+ stdin=io.BytesIO(cmd.in_) if cmd.in_ is not None else None,
63
+ stdout=asyncio.subprocess.PIPE,
64
+ stderr=asyncio.subprocess.PIPE,
65
+ **(dict(cwd=self._cfg.cwd) if self._cfg.cwd is not None else {}), # type: ignore
66
+ )
67
+
68
+ out, err = await proc.communicate()
69
+
70
+ return CommandRunner.Result(
71
+ rc=check.not_none(proc.returncode),
72
+ out=out,
73
+ err=err,
74
+ )
75
+
76
+
77
+ async def _a_main() -> None:
78
+ cmd = CommandRunner.Command(
79
+ ['ls', '-al'],
80
+ )
81
+
82
+ rc = await LocalCommandRunner().run_command(cmd)
83
+ check.equal(rc.rc, 0)
84
+ print(rc.out.decode())
85
+
86
+
87
+ if __name__ == '__main__':
88
+ asyncio.run(_a_main())
@@ -0,0 +1,194 @@
1
+ """
2
+ TODO:
3
+ - sessionized
4
+ - streamed
5
+ - actual timeout
6
+
7
+ bcrypt
8
+ fido2
9
+ gssapi
10
+ libnacl
11
+ pkcs11
12
+ pyOpenSSL
13
+
14
+ asyncssh[bcrypt,fido2,gssapi,libnacl,pkcs11,pyOpenSSL]
15
+ """
16
+ import asyncio
17
+ import contextlib
18
+ import shlex
19
+ import typing as ta
20
+
21
+ from omdev.home.secrets import load_secrets
22
+ from omlish import check
23
+ from omlish import dataclasses as dc
24
+ from omlish import lang
25
+
26
+ from .runners import CommandRunner
27
+ from .runners import LocalCommandRunner
28
+
29
+
30
+ if ta.TYPE_CHECKING:
31
+ import asyncssh
32
+ import paramiko
33
+ else:
34
+ asyncssh = lang.proxy_import('asyncssh')
35
+ paramiko = lang.proxy_import('paramiko')
36
+
37
+
38
+ ##
39
+
40
+
41
+ @dc.dataclass(frozen=True)
42
+ class SshConfig:
43
+ host: str | None = None
44
+ port: int | None = None
45
+
46
+ username: str | None = None
47
+ password: str | None = None
48
+
49
+ key_file_path: str | None = None
50
+
51
+
52
+ class SshSubprocessCommandRunner(CommandRunner):
53
+ def __init__(
54
+ self,
55
+ cfg: SshConfig,
56
+ lcr: LocalCommandRunner | None = None,
57
+ ) -> None:
58
+ super().__init__()
59
+
60
+ self._cfg = check.isinstance(cfg, SshConfig)
61
+ self._lcr = check.isinstance(lcr, LocalCommandRunner) if lcr is not None else LocalCommandRunner()
62
+
63
+ async def run_command(self, cmd: CommandRunner.Command) -> CommandRunner.Result:
64
+ args = ['ssh']
65
+
66
+ if self._cfg.key_file_path is not None:
67
+ args.extend(['-i', self._cfg.key_file_path])
68
+
69
+ if self._cfg.port is not None:
70
+ args.extend(['-p', str(self._cfg.port)])
71
+
72
+ dst = check.non_empty_str(self._cfg.host)
73
+ if self._cfg.username is not None:
74
+ dst = f'{self._cfg.username}@{dst}'
75
+ if self._cfg.password is not None:
76
+ raise NotImplementedError
77
+
78
+ args.append(dst)
79
+ args.extend(cmd.args)
80
+ lcmd = CommandRunner.Command(
81
+ args=args,
82
+ in_=cmd.in_,
83
+ )
84
+ return await self._lcr.run_command(lcmd)
85
+
86
+
87
+ class AsyncsshSshCommandRunner(CommandRunner):
88
+ def __init__(
89
+ self,
90
+ cfg: SshConfig,
91
+ ) -> None:
92
+ super().__init__()
93
+
94
+ self._cfg = check.isinstance(cfg, SshConfig)
95
+
96
+ async def run_command(self, cmd: CommandRunner.Command) -> CommandRunner.Result:
97
+ arg = ' '.join(map(shlex.quote, cmd.args))
98
+
99
+ async with asyncssh.connect(
100
+ self._cfg.host,
101
+ encoding=None,
102
+ **(dict(port=int(self._cfg.port)) if self._cfg.port is not None else {}),
103
+ **(dict(username=self._cfg.username) if self._cfg.username is not None else {}),
104
+ **(dict(password=self._cfg.password) if self._cfg.password is not None else {}),
105
+ **(dict(client_keys=[self._cfg.key_file_path]) if self._cfg.key_file_path is not None else {}),
106
+ known_hosts=None,
107
+ ) as conn:
108
+ proc: asyncssh.SSHClientProcess
109
+ async with await conn.create_process(arg) as proc:
110
+ checkw = False
111
+ timeout = None
112
+ res = await proc.wait(checkw, timeout)
113
+
114
+ return CommandRunner.Result(
115
+ rc=check.not_none(res.returncode),
116
+ out=check.isinstance(res.stdout, bytes),
117
+ err=check.isinstance(res.stderr, bytes),
118
+ )
119
+
120
+
121
+ class ParamikoSshCommandRunner(CommandRunner):
122
+ def __init__(
123
+ self,
124
+ cfg: SshConfig,
125
+ ) -> None:
126
+ super().__init__()
127
+
128
+ self._cfg = check.isinstance(cfg, SshConfig)
129
+
130
+ def _run_command(self, cmd: CommandRunner.Command) -> CommandRunner.Result:
131
+ arg = ' '.join(map(shlex.quote, cmd.args))
132
+
133
+ kw: dict[str, ta.Any] = {}
134
+ if self._cfg.port is not None:
135
+ kw.update(port=int(self._cfg.port))
136
+ if self._cfg.username is not None:
137
+ kw.update(username=self._cfg.username)
138
+ if self._cfg.password is not None:
139
+ kw.update(password=self._cfg.password)
140
+ if self._cfg.key_file_path is not None:
141
+ kw.update(key_filename=self._cfg.key_file_path)
142
+
143
+ client: paramiko.client.SSHClient
144
+ with contextlib.closing(paramiko.client.SSHClient()) as client:
145
+ client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
146
+
147
+ client.connect(
148
+ check.not_none(self._cfg.host),
149
+ **kw,
150
+ )
151
+
152
+ si, so, se = client.exec_command(arg)
153
+ # https://stackoverflow.com/questions/60037299/attributeerror-nonetype-object-has-no-attribute-time-paramiko
154
+ si.close()
155
+
156
+ rc = so.channel.recv_exit_status()
157
+ out = so.read()
158
+ err = se.read()
159
+
160
+ return CommandRunner.Result(
161
+ rc=rc,
162
+ out=out,
163
+ err=err,
164
+ )
165
+
166
+ async def run_command(self, cmd: CommandRunner.Command) -> CommandRunner.Result:
167
+ return await asyncio.to_thread(self._run_command, cmd)
168
+
169
+
170
+ async def _a_main() -> None:
171
+ cmd = CommandRunner.Command(
172
+ ['ls', '-al'],
173
+ )
174
+
175
+ cfg = load_secrets()
176
+
177
+ sc = SshConfig(
178
+ host=cfg.get('ec2_ssh_host').reveal(),
179
+ username=cfg.get('ec2_ssh_user').reveal(),
180
+ key_file_path=cfg.get('ec2_ssh_key_file').reveal(),
181
+ )
182
+
183
+ for scr in [
184
+ SshSubprocessCommandRunner(sc),
185
+ AsyncsshSshCommandRunner(sc),
186
+ ParamikoSshCommandRunner(sc),
187
+ ]:
188
+ rc = await scr.run_command(cmd)
189
+ check.equal(rc.rc, 0)
190
+ print(rc.out.decode())
191
+
192
+
193
+ if __name__ == '__main__':
194
+ asyncio.run(_a_main())
@@ -0,0 +1,23 @@
1
+ import os.path
2
+
3
+ from omlish import check
4
+ from omlish.text import abnf
5
+
6
+
7
+ def _main() -> None:
8
+ with open(os.path.join(os.path.dirname(__file__), 'proto3.abnf')) as f:
9
+ gram_src = f.read()
10
+
11
+ gram = abnf.parse_grammar(gram_src, root='proto-file')
12
+
13
+ with open(os.path.join(os.path.dirname(__file__), 'tests', 'examples', 'addressbook.proto')) as f:
14
+ addressbook_src = f.read()
15
+
16
+ addressbook = check.not_none(gram.parse(addressbook_src))
17
+ addressbook = abnf.only_match_rules(addressbook)
18
+
19
+ print(addressbook.render(indent=2))
20
+
21
+
22
+ if __name__ == '__main__':
23
+ _main()
@@ -0,0 +1,280 @@
1
+ ; Proto3 source grammar in ABNF
2
+ ; RFC 5234 core rules plus RFC 7405 case-sensitive strings (%s"...").
3
+ ; This version uses:
4
+ ; SKIP = whitespace-or-comment token
5
+ ; S = zero or more SKIP
6
+ ; R = one or more SKIP
7
+ ;
8
+ ; It is still a character-level grammar, not a true lexer/parser split.
9
+
10
+ ; ------------------------------------------------------------------------------
11
+ ; File
12
+ ; ------------------------------------------------------------------------------
13
+
14
+ proto-file = S syntax-stmt S *(file-item S)
15
+
16
+ file-item = import-stmt
17
+ / package-stmt
18
+ / option-stmt
19
+ / top-level-def
20
+ / empty-stmt
21
+
22
+ top-level-def = message-def / enum-def / service-def
23
+
24
+ ; ------------------------------------------------------------------------------
25
+ ; Whitespace / comments
26
+ ; ------------------------------------------------------------------------------
27
+
28
+ SKIP = WS / comment
29
+ S = *SKIP
30
+ R = 1*SKIP
31
+
32
+ WS = SP / HTAB / CR / LF
33
+
34
+ comment = line-comment / block-comment
35
+ line-comment = "//" *not-eol
36
+ not-eol = %x00-09 / %x0B-0C / %x0E-FF
37
+
38
+ ; Non-nested C-style block comment.
39
+ block-comment = "/*" *block-comment-item "*/"
40
+ block-comment-item = block-comment-safe / ("*" block-comment-not-slash)
41
+ block-comment-safe = %x00-29 / %x2B-FF
42
+ block-comment-not-slash
43
+ = %x00-2E / %x30-FF
44
+
45
+ ; ------------------------------------------------------------------------------
46
+ ; Lexical items
47
+ ; ------------------------------------------------------------------------------
48
+
49
+ squote = %x27
50
+ OCTDIG = %x30-37
51
+ NZDIGIT = %x31-39
52
+
53
+ ident = ALPHA *(ALPHA / DIGIT / "_")
54
+ full-ident = ident *("." ident)
55
+
56
+ message-name = ident
57
+ enum-name = ident
58
+ field-name = ident
59
+ oneof-name = ident
60
+ map-name = ident
61
+ service-name = ident
62
+ rpc-name = ident
63
+
64
+ message-type = ["." ] full-ident
65
+ enum-type = ["." ] full-ident
66
+
67
+ int-lit = decimal-lit / octal-lit / hex-lit
68
+ decimal-lit = ["-"] NZDIGIT *DIGIT
69
+ octal-lit = ["-"] "0" *OCTDIG
70
+ hex-lit = ["-"] "0" (%s"x" / %s"X") 1*HEXDIG
71
+
72
+ float-lit = ( ["-"] float-number ) / %s"inf" / %s"nan"
73
+ float-number = ( digits "." [digits] [exponent] )
74
+ / ( digits exponent )
75
+ / ( "." digits [exponent] )
76
+ digits = 1*DIGIT
77
+ exponent = (%s"e" / %s"E") ["+" / "-"] digits
78
+
79
+ bool-lit = %s"true" / %s"false"
80
+
81
+ str-lit = str-lit-single *(S str-lit-single)
82
+ str-lit-single = squote *sq-char squote / DQUOTE *dq-char DQUOTE
83
+
84
+ sq-char = hex-escape / oct-escape / char-escape / unicode-escape
85
+ / unicode-long-escape / sq-unescaped
86
+ dq-char = hex-escape / oct-escape / char-escape / unicode-escape
87
+ / unicode-long-escape / dq-unescaped
88
+
89
+ sq-unescaped = %x01-09 / %x0B-0C / %x0D / %x0E-26 / %x28-5B / %x5D-FF
90
+ dq-unescaped = %x01-09 / %x0B-0C / %x0D / %x0E-21 / %x23-5B / %x5D-FF
91
+
92
+ hex-escape = %x5C (%s"x" / %s"X") HEXDIG [HEXDIG]
93
+ oct-escape = %x5C OCTDIG [OCTDIG [OCTDIG]]
94
+ char-escape = %x5C (%s"a" / %s"b" / %s"f" / %s"n" / %s"r" / %s"t" / %s"v"
95
+ / %x5C / squote / DQUOTE)
96
+ unicode-escape = %x5C %s"u" 4HEXDIG
97
+ unicode-long-escape
98
+ = %x5C %s"U" ( %s"000" 5HEXDIG / %s"0010" 4HEXDIG )
99
+
100
+ empty-stmt = ";"
101
+
102
+ constant = full-ident
103
+ / (["+" / "-"] S int-lit)
104
+ / (["+" / "-"] S float-lit)
105
+ / str-lit
106
+ / bool-lit
107
+ / message-value
108
+
109
+ ; ------------------------------------------------------------------------------
110
+ ; File-level declarations
111
+ ; ------------------------------------------------------------------------------
112
+
113
+ syntax-stmt = %s"syntax" S "=" S (squote %s"proto3" squote / DQUOTE %s"proto3" DQUOTE) S ";"
114
+
115
+ import-stmt = %s"import" R [(%s"weak" / %s"public") R] str-lit S ";"
116
+
117
+ package-stmt = %s"package" R full-ident S ";"
118
+
119
+ option-stmt = %s"option" R option-name S "=" S constant S ";"
120
+
121
+ option-name = option-name-part *("." option-name-part)
122
+ option-name-part = ident / braced-full-ident
123
+ braced-full-ident = "(" S ["." ] full-ident S ")"
124
+
125
+ ; ------------------------------------------------------------------------------
126
+ ; Types / fields
127
+ ; ------------------------------------------------------------------------------
128
+
129
+ type = scalar-type / message-type / enum-type
130
+
131
+ scalar-type = %s"double" / %s"float"
132
+ / %s"int32" / %s"int64"
133
+ / %s"uint32" / %s"uint64"
134
+ / %s"sint32" / %s"sint64"
135
+ / %s"fixed32" / %s"fixed64"
136
+ / %s"sfixed32" / %s"sfixed64"
137
+ / %s"bool" / %s"string" / %s"bytes"
138
+
139
+ field-number = int-lit
140
+
141
+ field = [(%s"repeated" / %s"optional") R]
142
+ type R field-name S "=" S field-number
143
+ [S "[" S field-options S "]"]
144
+ S ";"
145
+
146
+ field-options = field-option *(S "," S field-option)
147
+ field-option = option-name S "=" S constant
148
+
149
+ oneof-def = %s"oneof" R oneof-name S "{"
150
+ S *(option-stmt S / oneof-field S)
151
+ "}"
152
+
153
+ oneof-field = type R field-name S "=" S field-number
154
+ [S "[" S field-options S "]"]
155
+ S ";"
156
+
157
+ map-field = %s"map" S "<" S key-type S "," S type S ">"
158
+ R map-name S "=" S field-number
159
+ [S "[" S field-options S "]"]
160
+ S ";"
161
+
162
+ key-type = %s"int32" / %s"int64"
163
+ / %s"uint32" / %s"uint64"
164
+ / %s"sint32" / %s"sint64"
165
+ / %s"fixed32" / %s"fixed64"
166
+ / %s"sfixed32" / %s"sfixed64"
167
+ / %s"bool" / %s"string"
168
+
169
+ reserved-stmt = %s"reserved" R (ranges / str-field-names) S ";"
170
+ ranges = range *(S "," S range)
171
+ range = int-lit [R %s"to" R (int-lit / %s"max")]
172
+
173
+ str-field-names = str-field-name *(S "," S str-field-name)
174
+ str-field-name = squote field-name squote / DQUOTE field-name DQUOTE
175
+
176
+ ; ------------------------------------------------------------------------------
177
+ ; Enum definitions
178
+ ; ------------------------------------------------------------------------------
179
+
180
+ enum-def = %s"enum" R enum-name S enum-body
181
+
182
+ enum-body = "{"
183
+ S *(option-stmt S / enum-field S / empty-stmt S / reserved-stmt S)
184
+ "}"
185
+
186
+ enum-field = ident S "=" S ["-" S] int-lit
187
+ [S "[" S enum-value-options S "]"]
188
+ S ";"
189
+
190
+ enum-value-options = enum-value-option *(S "," S enum-value-option)
191
+ enum-value-option = option-name S "=" S constant
192
+
193
+ ; ------------------------------------------------------------------------------
194
+ ; Message definitions
195
+ ; ------------------------------------------------------------------------------
196
+
197
+ message-def = %s"message" R message-name S message-body
198
+
199
+ message-body = "{"
200
+ S *(field S
201
+ / enum-def S
202
+ / message-def S
203
+ / option-stmt S
204
+ / oneof-def S
205
+ / map-field S
206
+ / reserved-stmt S
207
+ / empty-stmt S)
208
+ "}"
209
+
210
+ ; ------------------------------------------------------------------------------
211
+ ; Service definitions
212
+ ; ------------------------------------------------------------------------------
213
+
214
+ service-def = %s"service" R service-name S "{"
215
+ S *(option-stmt S / rpc S / empty-stmt S)
216
+ "}"
217
+
218
+ rpc = %s"rpc" R rpc-name
219
+ S "(" S [ %s"stream" R ] message-type S ")"
220
+ S %s"returns"
221
+ S "(" S [ %s"stream" R ] message-type S ")"
222
+ S ( "{" S *(option-stmt S / empty-stmt S) "}" / ";" )
223
+
224
+ ; ------------------------------------------------------------------------------
225
+ ; MessageValue (from protobuf text format, adapted to use outer S/comment rules)
226
+ ; ------------------------------------------------------------------------------
227
+
228
+ message-value = "{" S text-message S "}"
229
+ / "<" S text-message S ">"
230
+
231
+ text-message = *(text-field S)
232
+
233
+ text-field = text-scalar-field / text-message-field
234
+
235
+ text-message-field = text-field-name
236
+ [S ":"]
237
+ S (message-value / text-message-list)
238
+ [S (";" / ",")]
239
+
240
+ text-scalar-field = text-field-name
241
+ S ":"
242
+ S (text-scalar-value / text-scalar-list)
243
+ [S (";" / ",")]
244
+
245
+ text-message-list = "[" S [message-value *(S "," S message-value)] S "]"
246
+ text-scalar-list = "[" S [text-scalar-value *(S "," S text-scalar-value)] S "]"
247
+
248
+ text-scalar-value = str-lit
249
+ / text-float-value
250
+ / text-signed-ident
251
+ / ident
252
+ / text-signed-int
253
+ / int-lit
254
+
255
+ text-signed-ident = "-" S ident
256
+ text-signed-int = "-" S int-lit
257
+
258
+ text-float-value = text-float-number [("f" / "F")]
259
+ / text-decimal-uint ("f" / "F")
260
+ / %s"inf"
261
+ / %s"nan"
262
+
263
+ text-float-number = digits "." [digits] [exponent]
264
+ / digits exponent
265
+ / "." digits [exponent]
266
+
267
+ text-decimal-uint = "0" / (NZDIGIT *DIGIT)
268
+
269
+ text-field-name = ident / text-extension-name / text-any-name
270
+ text-extension-name
271
+ = "[" S text-type-name S "]"
272
+ text-any-name = "[" S text-url-prefix "/" text-type-name S "]"
273
+
274
+ text-type-name = ident *("." ident)
275
+
276
+ text-url-prefix = text-url-char *(text-url-char / "/")
277
+ text-url-char = ALPHA / DIGIT / "-" / "." / "~" / "_"
278
+ / "!" / "$" / "&" / "(" / ")"
279
+ / "*" / "+" / "," / ";" / "="
280
+ / "%" HEXDIG HEXDIG
@@ -0,0 +1,15 @@
1
+ import os.path
2
+
3
+ from omlish.text import abnf
4
+
5
+
6
+ def _main() -> None:
7
+ with open(os.path.join(os.path.dirname(__file__), 'minisql.abnf')) as f:
8
+ gram = abnf.parse_grammar(f.read(), root='single-stmt')
9
+
10
+ m = gram.parse('select x from y;')
11
+ print(m)
12
+
13
+
14
+ if __name__ == '__main__':
15
+ _main()