omlish 0.0.0.dev22__tar.gz → 0.0.0.dev24__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 (314) hide show
  1. {omlish-0.0.0.dev22/omlish.egg-info → omlish-0.0.0.dev24}/PKG-INFO +1 -1
  2. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/__about__.py +10 -3
  3. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/asyncs/bridge.py +3 -0
  4. omlish-0.0.0.dev24/omlish/bootstrap/__init__.py +42 -0
  5. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/bootstrap/base.py +3 -1
  6. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/bootstrap/diag.py +48 -1
  7. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/bootstrap/main.py +2 -1
  8. omlish-0.0.0.dev24/omlish/bootstrap/marshal.py +18 -0
  9. omlish-0.0.0.dev24/omlish/check.py +499 -0
  10. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/__init__.py +2 -2
  11. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/utils.py +3 -3
  12. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/concurrent/threadlets.py +5 -0
  13. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/__init__.py +1 -0
  14. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/init.py +10 -2
  15. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/metadata.py +3 -3
  16. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/reflect.py +1 -1
  17. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/utils.py +16 -3
  18. omlish-0.0.0.dev24/omlish/diag/asts.py +132 -0
  19. omlish-0.0.0.dev24/omlish/diag/pycharm.py +139 -0
  20. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/docker.py +19 -11
  21. omlish-0.0.0.dev24/omlish/genmachine.py +59 -0
  22. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/graphs/trees.py +1 -1
  23. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/__init__.py +13 -1
  24. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/cached.py +5 -2
  25. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/descriptors.py +33 -16
  26. omlish-0.0.0.dev24/omlish/lang/resources.py +60 -0
  27. omlish-0.0.0.dev24/omlish/lite/logs.py +250 -0
  28. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/logs/__init__.py +17 -2
  29. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/logs/configs.py +13 -1
  30. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/logs/formatters.py +0 -1
  31. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/__init__.py +6 -0
  32. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/base64.py +4 -0
  33. omlish-0.0.0.dev24/omlish/marshal/helpers.py +49 -0
  34. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/primitives.py +6 -0
  35. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/standard.py +4 -0
  36. omlish-0.0.0.dev24/omlish/marshal/unions.py +101 -0
  37. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/matchfns.py +3 -3
  38. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/keywords/base.py +2 -2
  39. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/keywords/parse.py +1 -1
  40. omlish-0.0.0.dev24/omlish/sql/__init__.py +27 -0
  41. omlish-0.0.0.dev24/omlish/sql/qualifiedname.py +82 -0
  42. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/stats.py +1 -0
  43. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24/omlish.egg-info}/PKG-INFO +1 -1
  44. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish.egg-info/SOURCES.txt +7 -0
  45. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/pyproject.toml +1 -1
  46. omlish-0.0.0.dev22/omlish/bootstrap/__init__.py +0 -3
  47. omlish-0.0.0.dev22/omlish/check.py +0 -231
  48. omlish-0.0.0.dev22/omlish/lite/logs.py +0 -121
  49. omlish-0.0.0.dev22/omlish/marshal/helpers.py +0 -22
  50. omlish-0.0.0.dev22/omlish/sql/__init__.py +0 -9
  51. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/LICENSE +0 -0
  52. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/MANIFEST.in +0 -0
  53. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/README.rst +0 -0
  54. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/__init__.py +0 -0
  55. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/argparse.py +0 -0
  56. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/asyncs/__init__.py +0 -0
  57. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/asyncs/anyio.py +0 -0
  58. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/asyncs/asyncio.py +0 -0
  59. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/asyncs/asyncs.py +0 -0
  60. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/asyncs/flavors.py +0 -0
  61. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/asyncs/trio.py +0 -0
  62. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/asyncs/trio_asyncio.py +0 -0
  63. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/bootstrap/__main__.py +0 -0
  64. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/bootstrap/harness.py +0 -0
  65. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/bootstrap/sys.py +0 -0
  66. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/c3.py +0 -0
  67. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/cached.py +0 -0
  68. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/_abc.py +0 -0
  69. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/_io_abc.py +0 -0
  70. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/cache/__init__.py +0 -0
  71. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/cache/descriptor.py +0 -0
  72. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/cache/impl.py +0 -0
  73. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/cache/types.py +0 -0
  74. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/coerce.py +0 -0
  75. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/exceptions.py +0 -0
  76. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/frozen.py +0 -0
  77. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/identity.py +0 -0
  78. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/indexed.py +0 -0
  79. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/mappings.py +0 -0
  80. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/ordered.py +0 -0
  81. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/persistent.py +0 -0
  82. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/skiplist.py +0 -0
  83. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/sorted.py +0 -0
  84. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/treap.py +0 -0
  85. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/treapmap.py +0 -0
  86. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/collections/unmodifiable.py +0 -0
  87. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/concurrent/__init__.py +0 -0
  88. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/concurrent/executors.py +0 -0
  89. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/concurrent/futures.py +0 -0
  90. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/configs/__init__.py +0 -0
  91. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/configs/classes.py +0 -0
  92. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/configs/flattening.py +0 -0
  93. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/configs/strings.py +0 -0
  94. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/__init__.py +0 -0
  95. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/api.py +0 -0
  96. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/as_.py +0 -0
  97. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/copy.py +0 -0
  98. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/descriptors.py +0 -0
  99. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/exceptions.py +0 -0
  100. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/fields.py +0 -0
  101. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/frozen.py +0 -0
  102. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/hashing.py +0 -0
  103. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/internals.py +0 -0
  104. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/main.py +0 -0
  105. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/metaclass.py +0 -0
  106. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/order.py +0 -0
  107. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/params.py +0 -0
  108. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/processing.py +0 -0
  109. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/replace.py +0 -0
  110. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/repr.py +0 -0
  111. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/simple.py +0 -0
  112. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/slots.py +0 -0
  113. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dataclasses/impl/utils.py +0 -0
  114. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/datetimes.py +0 -0
  115. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/defs.py +0 -0
  116. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/__init__.py +0 -0
  117. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/procfs.py +0 -0
  118. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/procstats.py +0 -0
  119. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/ps.py +0 -0
  120. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/pydevd.py +0 -0
  121. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/replserver/__init__.py +0 -0
  122. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/replserver/__main__.py +0 -0
  123. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/replserver/console.py +0 -0
  124. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/replserver/server.py +0 -0
  125. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/diag/threads.py +0 -0
  126. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dispatch/__init__.py +0 -0
  127. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dispatch/_dispatch2.py +0 -0
  128. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dispatch/_dispatch3.py +0 -0
  129. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dispatch/dispatch.py +0 -0
  130. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dispatch/functions.py +0 -0
  131. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dispatch/methods.py +0 -0
  132. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/dynamic.py +0 -0
  133. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/fnpairs.py +0 -0
  134. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/formats/__init__.py +0 -0
  135. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/formats/dotenv.py +0 -0
  136. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/formats/json.py +0 -0
  137. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/formats/props.py +0 -0
  138. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/formats/yaml.py +0 -0
  139. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/graphs/__init__.py +0 -0
  140. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/graphs/dags.py +0 -0
  141. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/graphs/domination.py +0 -0
  142. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/graphs/dot/__init__.py +0 -0
  143. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/graphs/dot/items.py +0 -0
  144. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/graphs/dot/rendering.py +0 -0
  145. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/graphs/dot/utils.py +0 -0
  146. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/__init__.py +0 -0
  147. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/asgi.py +0 -0
  148. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/collections.py +0 -0
  149. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/consts.py +0 -0
  150. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/cookies.py +0 -0
  151. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/dates.py +0 -0
  152. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/encodings.py +0 -0
  153. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/json.py +0 -0
  154. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/sessions.py +0 -0
  155. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/http/wsgi.py +0 -0
  156. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/__init__.py +0 -0
  157. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/binder.py +0 -0
  158. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/bindings.py +0 -0
  159. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/eagers.py +0 -0
  160. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/elements.py +0 -0
  161. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/exceptions.py +0 -0
  162. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/__init__.py +0 -0
  163. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/bindings.py +0 -0
  164. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/elements.py +0 -0
  165. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/injector.py +0 -0
  166. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/inspect.py +0 -0
  167. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/multis.py +0 -0
  168. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/origins.py +0 -0
  169. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/privates.py +0 -0
  170. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/providers.py +0 -0
  171. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/proxy.py +0 -0
  172. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/impl/scopes.py +0 -0
  173. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/injector.py +0 -0
  174. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/inspect.py +0 -0
  175. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/keys.py +0 -0
  176. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/listeners.py +0 -0
  177. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/managed.py +0 -0
  178. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/multis.py +0 -0
  179. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/origins.py +0 -0
  180. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/overrides.py +0 -0
  181. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/privates.py +0 -0
  182. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/providers.py +0 -0
  183. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/scopes.py +0 -0
  184. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/types.py +0 -0
  185. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/inject/utils.py +0 -0
  186. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/iterators.py +0 -0
  187. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/classes/__init__.py +0 -0
  188. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/classes/abstract.py +0 -0
  189. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/classes/restrict.py +0 -0
  190. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/classes/simple.py +0 -0
  191. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/classes/virtual.py +0 -0
  192. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/clsdct.py +0 -0
  193. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/cmp.py +0 -0
  194. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/contextmanagers.py +0 -0
  195. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/exceptions.py +0 -0
  196. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/functions.py +0 -0
  197. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/imports.py +0 -0
  198. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/iterables.py +0 -0
  199. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/maybes.py +0 -0
  200. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/objects.py +0 -0
  201. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/resolving.py +0 -0
  202. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/strings.py +0 -0
  203. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/sys.py +0 -0
  204. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/timeouts.py +0 -0
  205. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lang/typing.py +0 -0
  206. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/libc.py +0 -0
  207. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lifecycles/__init__.py +0 -0
  208. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lifecycles/abstract.py +0 -0
  209. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lifecycles/base.py +0 -0
  210. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lifecycles/contextmanagers.py +0 -0
  211. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lifecycles/controller.py +0 -0
  212. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lifecycles/manager.py +0 -0
  213. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lifecycles/states.py +0 -0
  214. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lifecycles/transitions.py +0 -0
  215. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/__init__.py +0 -0
  216. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/cached.py +0 -0
  217. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/check.py +0 -0
  218. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/contextmanagers.py +0 -0
  219. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/json.py +0 -0
  220. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/marshal.py +0 -0
  221. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/reflect.py +0 -0
  222. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/runtime.py +0 -0
  223. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/secrets.py +0 -0
  224. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/strings.py +0 -0
  225. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/lite/subprocesses.py +0 -0
  226. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/logs/_abc.py +0 -0
  227. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/logs/handlers.py +0 -0
  228. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/logs/noisy.py +0 -0
  229. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/logs/utils.py +0 -0
  230. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/any.py +0 -0
  231. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/base.py +0 -0
  232. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/dataclasses.py +0 -0
  233. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/datetimes.py +0 -0
  234. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/enums.py +0 -0
  235. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/exceptions.py +0 -0
  236. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/factories.py +0 -0
  237. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/forbidden.py +0 -0
  238. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/global_.py +0 -0
  239. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/iterables.py +0 -0
  240. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/mappings.py +0 -0
  241. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/maybes.py +0 -0
  242. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/naming.py +0 -0
  243. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/numbers.py +0 -0
  244. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/objects.py +0 -0
  245. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/optionals.py +0 -0
  246. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/polymorphism.py +0 -0
  247. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/registries.py +0 -0
  248. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/utils.py +0 -0
  249. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/uuids.py +0 -0
  250. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/marshal/values.py +0 -0
  251. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/math.py +0 -0
  252. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/multiprocessing.py +0 -0
  253. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/os.py +0 -0
  254. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/reflect/__init__.py +0 -0
  255. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/reflect/isinstance.py +0 -0
  256. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/reflect/ops.py +0 -0
  257. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/reflect/subst.py +0 -0
  258. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/reflect/types.py +0 -0
  259. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/runmodule.py +0 -0
  260. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/secrets/__init__.py +0 -0
  261. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/secrets/crypto.py +0 -0
  262. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/secrets/marshal.py +0 -0
  263. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/secrets/openssl.py +0 -0
  264. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/secrets/passwords.py +0 -0
  265. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/secrets/secrets.py +0 -0
  266. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/secrets/subprocesses.py +0 -0
  267. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/__init__.py +0 -0
  268. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/__init__.py +0 -0
  269. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/keywords/__init__.py +0 -0
  270. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/keywords/core.py +0 -0
  271. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/keywords/metadata.py +0 -0
  272. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/keywords/render.py +0 -0
  273. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/keywords/validation.py +0 -0
  274. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/schemas/__init__.py +0 -0
  275. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/schemas/draft202012/__init__.py +0 -0
  276. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/__init__.py +0 -0
  277. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/specs/jsonschema/types.py +0 -0
  278. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/sql/_abc.py +0 -0
  279. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/sql/asyncs.py +0 -0
  280. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/sql/dbs.py +0 -0
  281. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/sql/duckdb.py +0 -0
  282. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/sql/exprs.py +0 -0
  283. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/sql/secrets.py +0 -0
  284. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/sql/sqlean.py +0 -0
  285. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/sync.py +0 -0
  286. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/term.py +0 -0
  287. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/__init__.py +0 -0
  288. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/__init__.py +0 -0
  289. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/helpers.py +0 -0
  290. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/inject/__init__.py +0 -0
  291. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/inject/harness.py +0 -0
  292. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/marks.py +0 -0
  293. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/__init__.py +0 -0
  294. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/_registry.py +0 -0
  295. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/asyncs.py +0 -0
  296. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/depskip.py +0 -0
  297. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/logging.py +0 -0
  298. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/managermarks.py +0 -0
  299. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/pydevd.py +0 -0
  300. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/repeat.py +0 -0
  301. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/skips.py +0 -0
  302. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/spacing.py +0 -0
  303. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/switches.py +0 -0
  304. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/pytest/plugins/utils.py +0 -0
  305. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/testing/testing.py +0 -0
  306. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/text/__init__.py +0 -0
  307. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/text/delimit.py +0 -0
  308. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/text/glyphsplit.py +0 -0
  309. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/text/indent.py +0 -0
  310. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish/text/parts.py +0 -0
  311. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish.egg-info/dependency_links.txt +0 -0
  312. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish.egg-info/requires.txt +0 -0
  313. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/omlish.egg-info/top_level.txt +0 -0
  314. {omlish-0.0.0.dev22 → omlish-0.0.0.dev24}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev22
3
+ Version: 0.0.0.dev24
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev22'
2
- __revision__ = '3d902899000237758f62e46319a8da3bccd2d447'
1
+ __version__ = '0.0.0.dev24'
2
+ __revision__ = '4ab439ef967fda27804fe7d241924c6f08757b54'
3
3
 
4
4
 
5
5
  #
@@ -80,7 +80,11 @@ class Project(ProjectBase):
80
80
  'sqlalchemy[asyncio] ~= 2.0',
81
81
 
82
82
  'pg8000 ~= 1.31',
83
+ # 'psycopg2 ~= 2.9',
84
+
83
85
  'pymysql ~= 1.1',
86
+ # 'mysql-connector-python ~= 9.0',
87
+ # 'mysqlclient ~= 2.2',
84
88
 
85
89
  'aiomysql ~= 0.2',
86
90
  'aiosqlite ~= 0.20',
@@ -110,7 +114,10 @@ class SetuptoolsBase:
110
114
  include_package_data = False
111
115
 
112
116
  find_packages = {
113
- 'exclude': ['*.tests', '*.tests.*'],
117
+ 'exclude': [
118
+ '*.tests',
119
+ '*.tests.*',
120
+ ],
114
121
  }
115
122
 
116
123
 
@@ -8,6 +8,9 @@ KEEP THE SPACE SHUTTLE FLYING.
8
8
 
9
9
  TODO:
10
10
  - reuse greenlet if nested somehow?
11
+
12
+ See:
13
+ - https://greenback.readthedocs.io/en/latest/
11
14
  """
12
15
  import itertools
13
16
  import sys
@@ -0,0 +1,42 @@
1
+ from .base import ( # noqa
2
+ Bootstrap,
3
+ ContextBootstrap,
4
+ SimpleBootstrap,
5
+ )
6
+
7
+ from .diag import ( # noqa
8
+ CheckBootstrap,
9
+ CprofileBootstrap,
10
+ PycharmBootstrap,
11
+ ThreadDumpBootstrap,
12
+ TimebombBootstrap,
13
+ )
14
+
15
+ from .harness import ( # noqa
16
+ bootstrap,
17
+ )
18
+
19
+ from .sys import ( # noqa
20
+ CwdBootstrap,
21
+ EnvBootstrap,
22
+ FaulthandlerBootstrap,
23
+ FdsBootstrap,
24
+ GcBootstrap,
25
+ GcDebugFlag,
26
+ ImportBootstrap,
27
+ LogBootstrap,
28
+ NiceBootstrap,
29
+ PidfileBootstrap,
30
+ PrctlBootstrap,
31
+ PrintPidBootstrap,
32
+ RlimitBootstrap,
33
+ SetuidBootstrap,
34
+ )
35
+
36
+
37
+ ##
38
+
39
+
40
+ from ..lang.imports import _register_conditional_import # noqa
41
+
42
+ _register_conditional_import('..marshal', '.marshal', __package__)
@@ -2,6 +2,8 @@ import abc
2
2
  import dataclasses as dc
3
3
  import typing as ta
4
4
 
5
+ from omlish import lang
6
+
5
7
 
6
8
  BootstrapConfigT = ta.TypeVar('BootstrapConfigT', bound='Bootstrap.Config')
7
9
 
@@ -9,7 +11,7 @@ BootstrapConfigT = ta.TypeVar('BootstrapConfigT', bound='Bootstrap.Config')
9
11
  ##
10
12
 
11
13
 
12
- class Bootstrap(abc.ABC, ta.Generic[BootstrapConfigT]):
14
+ class Bootstrap(abc.ABC, lang.PackageSealed, ta.Generic[BootstrapConfigT]):
13
15
  @dc.dataclass(frozen=True)
14
16
  class Config(abc.ABC): # noqa
15
17
  pass
@@ -5,28 +5,56 @@ import signal
5
5
  import sys
6
6
  import typing as ta
7
7
 
8
+ from .. import check
8
9
  from .. import lang
9
10
  from .base import Bootstrap
10
11
  from .base import ContextBootstrap
12
+ from .base import SimpleBootstrap
11
13
 
12
14
 
13
15
  if ta.TYPE_CHECKING:
14
16
  import cProfile # noqa
15
17
  import pstats
16
18
 
19
+ from ..diag import pycharm as diagpc
17
20
  from ..diag import threads as diagt
18
21
 
19
22
  else:
20
23
  cProfile = lang.proxy_import('cProfile') # noqa
21
24
  pstats = lang.proxy_import('pstats')
22
25
 
26
+ diagpc = lang.proxy_import('..diag.pycharm', __package__)
23
27
  diagt = lang.proxy_import('..diag.threads', __package__)
24
28
 
25
29
 
26
30
  ##
27
31
 
28
32
 
29
- class ProfilingBootstrap(ContextBootstrap['ProfilingBootstrap.Config']):
33
+ class CheckBootstrap(ContextBootstrap['CheckBootstrap.Config']):
34
+ @dc.dataclass(frozen=True)
35
+ class Config(Bootstrap.Config):
36
+ breakpoint: bool = False
37
+
38
+ @staticmethod
39
+ def _breakpoint(exc: Exception) -> None: # noqa
40
+ breakpoint() # noqa
41
+
42
+ @contextlib.contextmanager
43
+ def enter(self) -> ta.Iterator[None]:
44
+ if not self._config.breakpoint:
45
+ return
46
+
47
+ check.register_on_raise(CheckBootstrap._breakpoint)
48
+ try:
49
+ yield
50
+ finally:
51
+ check.unregister_on_raise(CheckBootstrap._breakpoint)
52
+
53
+
54
+ ##
55
+
56
+
57
+ class CprofileBootstrap(ContextBootstrap['CprofileBootstrap.Config']):
30
58
  @dc.dataclass(frozen=True)
31
59
  class Config(Bootstrap.Config):
32
60
  enable: bool = False
@@ -128,3 +156,22 @@ class TimebombBootstrap(ContextBootstrap['TimebombBootstrap.Config']):
128
156
  yield
129
157
  finally:
130
158
  tbt.stop_nowait()
159
+
160
+
161
+ ##
162
+
163
+
164
+ class PycharmBootstrap(SimpleBootstrap['PycharmBootstrap.Config']):
165
+ @dc.dataclass(frozen=True)
166
+ class Config(Bootstrap.Config):
167
+ debug_host: ta.Optional[str] = None
168
+ debug_port: ta.Optional[int] = None
169
+ version: ta.Optional[str] = None
170
+
171
+ def run(self) -> None:
172
+ if self._config.debug_port is not None:
173
+ diagpc.pycharm_remote_debugger_attach(
174
+ self._config.debug_host,
175
+ self._config.debug_port,
176
+ version=self._config.version,
177
+ )
@@ -156,8 +156,9 @@ def _main() -> int:
156
156
  with bootstrap(*cfgs):
157
157
  tgt = args.target
158
158
 
159
+ sys.argv = [tgt, *(args.args or ())]
160
+
159
161
  if args.module:
160
- sys.argv = [tgt, *(args.args or ())]
161
162
  runpy._run_module_as_main(tgt) # type: ignore # noqa
162
163
 
163
164
  else:
@@ -0,0 +1,18 @@
1
+ from .. import lang
2
+ from .. import marshal as msh
3
+ from .base import Bootstrap
4
+ from .harness import BOOTSTRAP_TYPES_BY_NAME
5
+
6
+
7
+ @lang.cached_function
8
+ def _install_standard_marshalling() -> None:
9
+ cfgs_poly = msh.Polymorphism(
10
+ Bootstrap.Config,
11
+ [msh.Impl(b.Config, n) for n, b in BOOTSTRAP_TYPES_BY_NAME.items()],
12
+ )
13
+
14
+ msh.STANDARD_MARSHALER_FACTORIES[0:0] = [msh.PolymorphismMarshalerFactory(cfgs_poly)]
15
+ msh.STANDARD_UNMARSHALER_FACTORIES[0:0] = [msh.PolymorphismUnmarshalerFactory(cfgs_poly)]
16
+
17
+
18
+ _install_standard_marshalling()
@@ -0,0 +1,499 @@
1
+ """
2
+ TODO:
3
+ - def maybe(v: lang.Maybe[T])
4
+ """
5
+ import collections
6
+ import threading
7
+ import typing as ta
8
+
9
+
10
+ T = ta.TypeVar('T')
11
+ SizedT = ta.TypeVar('SizedT', bound=ta.Sized)
12
+
13
+ Message: ta.TypeAlias = str | ta.Callable[..., str | None] | None
14
+
15
+ _NONE_TYPE = type(None)
16
+
17
+ _isinstance = isinstance
18
+ _issubclass = issubclass
19
+ _callable = callable
20
+
21
+
22
+ ##
23
+
24
+
25
+ _CONFIG_LOCK = threading.RLock()
26
+
27
+
28
+ OnRaiseFn: ta.TypeAlias = ta.Callable[[Exception], None]
29
+ _ON_RAISE: ta.Sequence[OnRaiseFn] = []
30
+
31
+
32
+ def register_on_raise(fn: OnRaiseFn) -> None:
33
+ global _ON_RAISE
34
+ with _CONFIG_LOCK:
35
+ _ON_RAISE = [*_ON_RAISE, fn]
36
+
37
+
38
+ def unregister_on_raise(fn: OnRaiseFn) -> None:
39
+ global _ON_RAISE
40
+ with _CONFIG_LOCK:
41
+ _ON_RAISE = [e for e in _ON_RAISE if e != fn]
42
+
43
+
44
+ #
45
+
46
+
47
+ _render_args: ta.Callable[..., str | None] | None = None
48
+
49
+
50
+ def enable_args_rendering() -> bool:
51
+ global _render_args
52
+ if _render_args is not None:
53
+ return True
54
+
55
+ with _CONFIG_LOCK:
56
+ if _render_args is not None:
57
+ return True # type: ignore
58
+
59
+ try:
60
+ from .diag.asts import ArgsRenderer
61
+
62
+ ArgsRenderer.smoketest()
63
+
64
+ except Exception: # noqa
65
+ return False
66
+
67
+ def _real_render_args(fmt: str, *args: ta.Any) -> str | None:
68
+ ra = ArgsRenderer(back=3).render_args(*args)
69
+ if ra is None:
70
+ return None
71
+
72
+ return fmt % tuple(str(a) for a in ra)
73
+
74
+ _render_args = _real_render_args
75
+ return True
76
+
77
+
78
+ enable_args_rendering()
79
+
80
+
81
+ #
82
+
83
+
84
+ def _default_exception_factory(exc_cls: type[Exception], *args, **kwargs) -> Exception:
85
+ return exc_cls(*args, **kwargs) # noqa
86
+
87
+
88
+ _EXCEPTION_FACTORY = _default_exception_factory
89
+
90
+
91
+ class _Args:
92
+ def __init__(self, *args, **kwargs):
93
+ self.args = args
94
+ self.kwargs = kwargs
95
+
96
+
97
+ def _raise(
98
+ exception_type: type[Exception],
99
+ default_message: str,
100
+ message: Message,
101
+ ak: _Args = _Args(),
102
+ *,
103
+ render_fmt: str | None = None,
104
+ ) -> ta.NoReturn:
105
+ exc_args = ()
106
+ if _callable(message):
107
+ message = ta.cast(ta.Callable, message)(*ak.args, **ak.kwargs)
108
+ if _isinstance(message, tuple):
109
+ message, *exc_args = message # type: ignore
110
+
111
+ if message is None:
112
+ message = default_message
113
+
114
+ if render_fmt is not None and _render_args is not None:
115
+ rendered_args = _render_args(render_fmt, *ak.args)
116
+ if rendered_args is not None:
117
+ message = f'{message} : {rendered_args}'
118
+
119
+ exc = _EXCEPTION_FACTORY(
120
+ exception_type,
121
+ message,
122
+ *exc_args,
123
+ *ak.args,
124
+ **ak.kwargs,
125
+ )
126
+
127
+ for fn in _ON_RAISE:
128
+ fn(exc)
129
+
130
+ raise exc
131
+
132
+
133
+ ##
134
+
135
+
136
+ def _unpack_isinstance_spec(spec: ta.Any) -> tuple:
137
+ if not _isinstance(spec, tuple):
138
+ spec = (spec,)
139
+ if None in spec:
140
+ spec = tuple(filter(None, spec)) + (_NONE_TYPE,) # noqa
141
+ if ta.Any in spec:
142
+ spec = (object,)
143
+ return spec
144
+
145
+
146
+ def isinstance(v: ta.Any, spec: type[T] | tuple, msg: Message = None) -> T: # noqa
147
+ if not _isinstance(v, _unpack_isinstance_spec(spec)):
148
+ _raise(
149
+ TypeError,
150
+ 'Must be instance',
151
+ msg,
152
+ _Args(v, spec),
153
+ render_fmt='not isinstance(%s, %s)',
154
+ )
155
+
156
+ return v
157
+
158
+
159
+ def of_isinstance(spec: type[T] | tuple, msg: Message = None) -> ta.Callable[[ta.Any], T]:
160
+ def inner(v):
161
+ return isinstance(v, _unpack_isinstance_spec(spec), msg)
162
+
163
+ return inner
164
+
165
+
166
+ def cast(v: ta.Any, cls: type[T], msg: Message = None) -> T: # noqa
167
+ if not _isinstance(v, cls):
168
+ _raise(
169
+ TypeError,
170
+ 'Must be instance',
171
+ msg,
172
+ _Args(v, cls),
173
+ )
174
+
175
+ return v
176
+
177
+
178
+ def of_cast(cls: type[T], msg: Message = None) -> ta.Callable[[T], T]:
179
+ def inner(v):
180
+ return isinstance(v, cls, msg)
181
+
182
+ return inner
183
+
184
+
185
+ def not_isinstance(v: T, spec: ta.Any, msg: Message = None) -> T: # noqa
186
+ if _isinstance(v, _unpack_isinstance_spec(spec)):
187
+ _raise(
188
+ TypeError,
189
+ 'Must not be instance',
190
+ msg,
191
+ _Args(v, spec),
192
+ render_fmt='isinstance(%s, %s)',
193
+ )
194
+
195
+ return v
196
+
197
+
198
+ def of_not_isinstance(spec: ta.Any, msg: Message = None) -> ta.Callable[[T], T]:
199
+ def inner(v):
200
+ return not_isinstance(v, _unpack_isinstance_spec(spec), msg)
201
+
202
+ return inner
203
+
204
+
205
+ ##
206
+
207
+
208
+ def issubclass(v: type[T], spec: ta.Any, msg: Message = None) -> type[T]: # noqa
209
+ if not _issubclass(v, spec):
210
+ _raise(
211
+ TypeError,
212
+ 'Must be subclass',
213
+ msg,
214
+ _Args(v, spec),
215
+ render_fmt='not issubclass(%s, %s)',
216
+ )
217
+
218
+ return v
219
+
220
+
221
+ def not_issubclass(v: type[T], spec: ta.Any, msg: Message = None) -> type[T]: # noqa
222
+ if _issubclass(v, spec):
223
+ _raise(
224
+ TypeError,
225
+ 'Must not be subclass',
226
+ msg,
227
+ _Args(v, spec),
228
+ render_fmt='issubclass(%s, %s)',
229
+ )
230
+
231
+ return v
232
+
233
+
234
+ ##
235
+
236
+
237
+ def in_(v: T, c: ta.Container[T], msg: Message = None) -> T:
238
+ if v not in c:
239
+ _raise(
240
+ ValueError,
241
+ 'Must be in',
242
+ msg,
243
+ _Args(v, c),
244
+ render_fmt='%s not in %s',
245
+ )
246
+
247
+ return v
248
+
249
+
250
+ def not_in(v: T, c: ta.Container[T], msg: Message = None) -> T:
251
+ if v in c:
252
+ _raise(
253
+ ValueError,
254
+ 'Must not be in',
255
+ msg,
256
+ _Args(v, c),
257
+ render_fmt='%s in %s',
258
+ )
259
+
260
+ return v
261
+
262
+
263
+ def empty(v: SizedT, msg: Message = None) -> SizedT:
264
+ if len(v) != 0:
265
+ _raise(
266
+ ValueError,
267
+ 'Must be empty',
268
+ msg,
269
+ _Args(v),
270
+ render_fmt='%s',
271
+ )
272
+
273
+ return v
274
+
275
+
276
+ def iterempty(v: ta.Iterable[T], msg: Message = None) -> ta.Iterable[T]:
277
+ it = iter(v)
278
+ try:
279
+ next(it)
280
+ except StopIteration:
281
+ pass
282
+ else:
283
+ _raise(
284
+ ValueError,
285
+ 'Must be empty',
286
+ msg,
287
+ _Args(v),
288
+ render_fmt='%s',
289
+ )
290
+
291
+ return v
292
+
293
+
294
+ def not_empty(v: SizedT, msg: Message = None) -> SizedT:
295
+ if len(v) == 0:
296
+ _raise(
297
+ ValueError,
298
+ 'Must not be empty',
299
+ msg,
300
+ _Args(v),
301
+ render_fmt='%s',
302
+ )
303
+
304
+ return v
305
+
306
+
307
+ def unique(it: ta.Iterable[T], msg: Message = None) -> ta.Iterable[T]:
308
+ dupes = [e for e, c in collections.Counter(it).items() if c > 1]
309
+ if dupes:
310
+ _raise(
311
+ ValueError,
312
+ 'Must be unique',
313
+ msg,
314
+ _Args(it, dupes),
315
+ )
316
+
317
+ return it
318
+
319
+
320
+ def single(obj: ta.Iterable[T], message: Message = None) -> T:
321
+ try:
322
+ [value] = obj
323
+ except ValueError:
324
+ _raise(
325
+ ValueError,
326
+ 'Must be single',
327
+ message,
328
+ _Args(obj),
329
+ render_fmt='%s',
330
+ )
331
+
332
+ return value
333
+
334
+
335
+ def optional_single(obj: ta.Iterable[T], message: Message = None) -> T | None:
336
+ it = iter(obj)
337
+ try:
338
+ value = next(it)
339
+ except StopIteration:
340
+ return None
341
+
342
+ try:
343
+ next(it)
344
+ except StopIteration:
345
+ return value # noqa
346
+
347
+ _raise(
348
+ ValueError,
349
+ 'Must be empty or single',
350
+ message,
351
+ _Args(obj),
352
+ render_fmt='%s',
353
+ )
354
+
355
+
356
+ ##
357
+
358
+
359
+ def none(v: ta.Any, msg: Message = None) -> None:
360
+ if v is not None:
361
+ _raise(
362
+ ValueError,
363
+ 'Must be None',
364
+ msg,
365
+ _Args(v),
366
+ render_fmt='%s',
367
+ )
368
+
369
+
370
+ def not_none(v: T | None, msg: Message = None) -> T:
371
+ if v is None:
372
+ _raise(
373
+ ValueError,
374
+ 'Must not be None',
375
+ msg,
376
+ _Args(v),
377
+ render_fmt='%s',
378
+ )
379
+
380
+ return v
381
+
382
+
383
+ ##
384
+
385
+
386
+ def equal(v: T, o: ta.Any, msg: Message = None) -> T:
387
+ if o != v:
388
+ _raise(
389
+ ValueError,
390
+ 'Must be equal',
391
+ msg,
392
+ _Args(v, o),
393
+ render_fmt='%s != %s',
394
+ )
395
+
396
+ return v
397
+
398
+
399
+ def is_(v: T, o: ta.Any, msg: Message = None) -> T:
400
+ if o is not v:
401
+ _raise(
402
+ ValueError,
403
+ 'Must be the same',
404
+ msg,
405
+ _Args(v, o),
406
+ render_fmt='%s is not %s',
407
+ )
408
+
409
+ return v
410
+
411
+
412
+ def is_not(v: T, o: ta.Any, msg: Message = None) -> T:
413
+ if o is v:
414
+ _raise(
415
+ ValueError,
416
+ 'Must not be the same',
417
+ msg,
418
+ _Args(v, o),
419
+ render_fmt='%s is %s',
420
+ )
421
+
422
+ return v
423
+
424
+
425
+ def callable(v: T, msg: Message = None) -> T: # noqa
426
+ if not _callable(v):
427
+ _raise(
428
+ TypeError,
429
+ 'Must be callable',
430
+ msg,
431
+ _Args(v),
432
+ render_fmt='%s',
433
+ )
434
+
435
+ return v # type: ignore
436
+
437
+
438
+ def non_empty_str(v: str | None, msg: Message = None) -> str:
439
+ if not _isinstance(v, str) or not v:
440
+ _raise(
441
+ ValueError,
442
+ 'Must be non-empty str',
443
+ msg,
444
+ _Args(v),
445
+ render_fmt='%s',
446
+ )
447
+
448
+ return v
449
+
450
+
451
+ def replacing(expected: ta.Any, old: ta.Any, new: T, msg: Message = None) -> T:
452
+ if old != expected:
453
+ _raise(
454
+ ValueError,
455
+ 'Must be replacing',
456
+ msg,
457
+ _Args(expected, old, new),
458
+ render_fmt='%s -> %s -> %s',
459
+ )
460
+
461
+ return new
462
+
463
+
464
+ def replacing_none(old: ta.Any, new: T, msg: Message = None) -> T:
465
+ if old is not None:
466
+ _raise(
467
+ ValueError,
468
+ 'Must be replacing None',
469
+ msg,
470
+ _Args(old, new),
471
+ render_fmt='%s -> %s',
472
+ )
473
+
474
+ return new
475
+
476
+
477
+ ##
478
+
479
+
480
+ def arg(v: bool, msg: Message = None) -> None:
481
+ if not v:
482
+ _raise(
483
+ RuntimeError,
484
+ 'Argument condition not met',
485
+ msg,
486
+ _Args(v),
487
+ render_fmt='%s',
488
+ )
489
+
490
+
491
+ def state(v: bool, msg: Message = None) -> None:
492
+ if not v:
493
+ _raise(
494
+ RuntimeError,
495
+ 'State condition not met',
496
+ msg,
497
+ _Args(v),
498
+ render_fmt='%s',
499
+ )