omlish 0.0.0.dev29__tar.gz → 0.0.0.dev30__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 (329) hide show
  1. {omlish-0.0.0.dev29/omlish.egg-info → omlish-0.0.0.dev30}/PKG-INFO +15 -15
  2. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/__about__.py +5 -5
  3. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/replserver/server.py +1 -1
  4. omlish-0.0.0.dev30/omlish/fnpipes.py +82 -0
  5. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/sessions.py +2 -2
  6. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/__init__.py +4 -0
  7. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/classes/abstract.py +1 -1
  8. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/contextmanagers.py +35 -0
  9. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/resources.py +1 -0
  10. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/strings.py +49 -1
  11. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/logs.py +20 -5
  12. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/naming.py +5 -0
  13. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/polymorphism.py +20 -10
  14. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/os.py +17 -0
  15. omlish-0.0.0.dev30/omlish/specs/__init__.py +9 -0
  16. omlish-0.0.0.dev30/omlish/sql/__init__.py +13 -0
  17. {omlish-0.0.0.dev29/omlish/sql → omlish-0.0.0.dev30/omlish/sql/alchemy}/__init__.py +0 -14
  18. {omlish-0.0.0.dev29/omlish/sql → omlish-0.0.0.dev30/omlish/sql/alchemy}/asyncs.py +1 -1
  19. {omlish-0.0.0.dev29/omlish/sql → omlish-0.0.0.dev30/omlish/sql/alchemy}/duckdb.py +1 -1
  20. {omlish-0.0.0.dev29/omlish/sql → omlish-0.0.0.dev30/omlish/sql/alchemy}/secrets.py +1 -1
  21. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/asyncs.py +5 -0
  22. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30/omlish.egg-info}/PKG-INFO +15 -15
  23. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish.egg-info/SOURCES.txt +7 -5
  24. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish.egg-info/requires.txt +5 -5
  25. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/pyproject.toml +4 -4
  26. omlish-0.0.0.dev29/omlish/text/__init__.py +0 -0
  27. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/LICENSE +0 -0
  28. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/MANIFEST.in +0 -0
  29. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/README.rst +0 -0
  30. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/.manifests.json +0 -0
  31. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/__init__.py +0 -0
  32. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/argparse.py +0 -0
  33. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/asyncs/__init__.py +0 -0
  34. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/asyncs/anyio.py +0 -0
  35. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/asyncs/asyncio.py +0 -0
  36. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/asyncs/asyncs.py +0 -0
  37. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/asyncs/bridge.py +0 -0
  38. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/asyncs/flavors.py +0 -0
  39. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/asyncs/trio.py +0 -0
  40. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/asyncs/trio_asyncio.py +0 -0
  41. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/bootstrap/__init__.py +0 -0
  42. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/bootstrap/__main__.py +0 -0
  43. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/bootstrap/base.py +0 -0
  44. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/bootstrap/diag.py +0 -0
  45. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/bootstrap/harness.py +0 -0
  46. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/bootstrap/main.py +0 -0
  47. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/bootstrap/marshal.py +0 -0
  48. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/bootstrap/sys.py +0 -0
  49. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/c3.py +0 -0
  50. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/cached.py +0 -0
  51. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/check.py +0 -0
  52. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/__init__.py +0 -0
  53. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/_abc.py +0 -0
  54. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/_io_abc.py +0 -0
  55. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/cache/__init__.py +0 -0
  56. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/cache/descriptor.py +0 -0
  57. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/cache/impl.py +0 -0
  58. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/cache/types.py +0 -0
  59. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/coerce.py +0 -0
  60. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/exceptions.py +0 -0
  61. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/frozen.py +0 -0
  62. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/identity.py +0 -0
  63. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/indexed.py +0 -0
  64. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/mappings.py +0 -0
  65. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/ordered.py +0 -0
  66. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/persistent.py +0 -0
  67. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/skiplist.py +0 -0
  68. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/sorted.py +0 -0
  69. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/treap.py +0 -0
  70. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/treapmap.py +0 -0
  71. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/unmodifiable.py +0 -0
  72. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/collections/utils.py +0 -0
  73. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/concurrent/__init__.py +0 -0
  74. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/concurrent/executors.py +0 -0
  75. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/concurrent/futures.py +0 -0
  76. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/concurrent/threadlets.py +0 -0
  77. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/configs/__init__.py +0 -0
  78. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/configs/classes.py +0 -0
  79. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/configs/flattening.py +0 -0
  80. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/configs/strings.py +0 -0
  81. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/__init__.py +0 -0
  82. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/LICENSE +0 -0
  83. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/__init__.py +0 -0
  84. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/api.py +0 -0
  85. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/as_.py +0 -0
  86. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/copy.py +0 -0
  87. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/descriptors.py +0 -0
  88. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/exceptions.py +0 -0
  89. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/fields.py +0 -0
  90. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/frozen.py +0 -0
  91. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/hashing.py +0 -0
  92. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/init.py +0 -0
  93. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/internals.py +0 -0
  94. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/main.py +0 -0
  95. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/metaclass.py +0 -0
  96. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/metadata.py +0 -0
  97. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/order.py +0 -0
  98. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/params.py +0 -0
  99. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/processing.py +0 -0
  100. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/reflect.py +0 -0
  101. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/replace.py +0 -0
  102. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/repr.py +0 -0
  103. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/simple.py +0 -0
  104. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/slots.py +0 -0
  105. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/impl/utils.py +0 -0
  106. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dataclasses/utils.py +0 -0
  107. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/datetimes.py +0 -0
  108. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/defs.py +0 -0
  109. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/__init__.py +0 -0
  110. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/asts.py +0 -0
  111. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/procfs.py +0 -0
  112. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/procstats.py +0 -0
  113. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/ps.py +0 -0
  114. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/pycharm.py +0 -0
  115. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/pydevd.py +0 -0
  116. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/replserver/__init__.py +0 -0
  117. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/replserver/__main__.py +0 -0
  118. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/replserver/console.py +0 -0
  119. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/diag/threads.py +0 -0
  120. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dispatch/__init__.py +0 -0
  121. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dispatch/_dispatch2.py +0 -0
  122. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dispatch/_dispatch3.py +0 -0
  123. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dispatch/dispatch.py +0 -0
  124. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dispatch/functions.py +0 -0
  125. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dispatch/methods.py +0 -0
  126. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/docker.py +0 -0
  127. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/dynamic.py +0 -0
  128. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/fnpairs.py +0 -0
  129. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/formats/__init__.py +0 -0
  130. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/formats/dotenv.py +0 -0
  131. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/formats/json.py +0 -0
  132. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/formats/props.py +0 -0
  133. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/formats/yaml.py +0 -0
  134. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/genmachine.py +0 -0
  135. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/graphs/__init__.py +0 -0
  136. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/graphs/dags.py +0 -0
  137. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/graphs/domination.py +0 -0
  138. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/graphs/dot/__init__.py +0 -0
  139. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/graphs/dot/items.py +0 -0
  140. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/graphs/dot/make.py +0 -0
  141. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/graphs/dot/rendering.py +0 -0
  142. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/graphs/dot/utils.py +0 -0
  143. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/graphs/trees.py +0 -0
  144. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/__init__.py +0 -0
  145. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/asgi.py +0 -0
  146. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/collections.py +0 -0
  147. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/consts.py +0 -0
  148. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/cookies.py +0 -0
  149. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/dates.py +0 -0
  150. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/encodings.py +0 -0
  151. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/json.py +0 -0
  152. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/http/wsgi.py +0 -0
  153. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/__init__.py +0 -0
  154. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/binder.py +0 -0
  155. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/bindings.py +0 -0
  156. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/eagers.py +0 -0
  157. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/elements.py +0 -0
  158. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/exceptions.py +0 -0
  159. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/__init__.py +0 -0
  160. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/bindings.py +0 -0
  161. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/elements.py +0 -0
  162. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/injector.py +0 -0
  163. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/inspect.py +0 -0
  164. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/multis.py +0 -0
  165. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/origins.py +0 -0
  166. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/privates.py +0 -0
  167. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/providers.py +0 -0
  168. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/proxy.py +0 -0
  169. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/impl/scopes.py +0 -0
  170. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/injector.py +0 -0
  171. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/inspect.py +0 -0
  172. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/keys.py +0 -0
  173. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/listeners.py +0 -0
  174. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/managed.py +0 -0
  175. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/multis.py +0 -0
  176. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/origins.py +0 -0
  177. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/overrides.py +0 -0
  178. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/privates.py +0 -0
  179. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/providers.py +0 -0
  180. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/scopes.py +0 -0
  181. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/types.py +0 -0
  182. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/inject/utils.py +0 -0
  183. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/iterators.py +0 -0
  184. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/cached.py +0 -0
  185. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/classes/__init__.py +0 -0
  186. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/classes/restrict.py +0 -0
  187. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/classes/simple.py +0 -0
  188. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/classes/virtual.py +0 -0
  189. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/clsdct.py +0 -0
  190. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/cmp.py +0 -0
  191. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/datetimes.py +0 -0
  192. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/descriptors.py +0 -0
  193. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/exceptions.py +0 -0
  194. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/functions.py +0 -0
  195. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/imports.py +0 -0
  196. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/iterables.py +0 -0
  197. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/maybes.py +0 -0
  198. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/objects.py +0 -0
  199. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/resolving.py +0 -0
  200. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/sys.py +0 -0
  201. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/timeouts.py +0 -0
  202. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lang/typing.py +0 -0
  203. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/libc.py +0 -0
  204. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lifecycles/__init__.py +0 -0
  205. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lifecycles/abstract.py +0 -0
  206. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lifecycles/base.py +0 -0
  207. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lifecycles/contextmanagers.py +0 -0
  208. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lifecycles/controller.py +0 -0
  209. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lifecycles/manager.py +0 -0
  210. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lifecycles/states.py +0 -0
  211. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lifecycles/transitions.py +0 -0
  212. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/__init__.py +0 -0
  213. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/cached.py +0 -0
  214. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/check.py +0 -0
  215. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/contextmanagers.py +0 -0
  216. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/json.py +0 -0
  217. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/marshal.py +0 -0
  218. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/reflect.py +0 -0
  219. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/runtime.py +0 -0
  220. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/secrets.py +0 -0
  221. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/strings.py +0 -0
  222. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/lite/subprocesses.py +0 -0
  223. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/logs/__init__.py +0 -0
  224. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/logs/_abc.py +0 -0
  225. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/logs/configs.py +0 -0
  226. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/logs/formatters.py +0 -0
  227. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/logs/handlers.py +0 -0
  228. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/logs/noisy.py +0 -0
  229. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/logs/utils.py +0 -0
  230. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/__init__.py +0 -0
  231. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/any.py +0 -0
  232. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/base.py +0 -0
  233. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/base64.py +0 -0
  234. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/dataclasses.py +0 -0
  235. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/datetimes.py +0 -0
  236. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/enums.py +0 -0
  237. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/exceptions.py +0 -0
  238. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/factories.py +0 -0
  239. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/forbidden.py +0 -0
  240. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/global_.py +0 -0
  241. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/helpers.py +0 -0
  242. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/iterables.py +0 -0
  243. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/mappings.py +0 -0
  244. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/maybes.py +0 -0
  245. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/numbers.py +0 -0
  246. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/objects.py +0 -0
  247. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/optionals.py +0 -0
  248. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/primitives.py +0 -0
  249. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/registries.py +0 -0
  250. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/standard.py +0 -0
  251. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/unions.py +0 -0
  252. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/utils.py +0 -0
  253. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/uuids.py +0 -0
  254. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/marshal/values.py +0 -0
  255. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/matchfns.py +0 -0
  256. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/math/__init__.py +0 -0
  257. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/math/bits.py +0 -0
  258. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/math/floats.py +0 -0
  259. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/math/stats.py +0 -0
  260. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/multiprocessing.py +0 -0
  261. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/reflect/__init__.py +0 -0
  262. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/reflect/isinstance.py +0 -0
  263. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/reflect/ops.py +0 -0
  264. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/reflect/subst.py +0 -0
  265. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/reflect/types.py +0 -0
  266. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/runmodule.py +0 -0
  267. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/secrets/__init__.py +0 -0
  268. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/secrets/crypto.py +0 -0
  269. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/secrets/marshal.py +0 -0
  270. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/secrets/openssl.py +0 -0
  271. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/secrets/passwords.py +0 -0
  272. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/secrets/secrets.py +0 -0
  273. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/secrets/subprocesses.py +0 -0
  274. {omlish-0.0.0.dev29/omlish/specs → omlish-0.0.0.dev30/omlish/specs/jsonschema}/__init__.py +0 -0
  275. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/keywords/__init__.py +0 -0
  276. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/keywords/base.py +0 -0
  277. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/keywords/core.py +0 -0
  278. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/keywords/metadata.py +0 -0
  279. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/keywords/parse.py +0 -0
  280. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/keywords/render.py +0 -0
  281. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/keywords/validation.py +0 -0
  282. {omlish-0.0.0.dev29/omlish/specs/jsonschema → omlish-0.0.0.dev30/omlish/specs/jsonschema/schemas}/__init__.py +0 -0
  283. {omlish-0.0.0.dev29/omlish/specs/jsonschema/schemas → omlish-0.0.0.dev30/omlish/specs/jsonschema/schemas/draft202012}/__init__.py +0 -0
  284. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/metaschema.json +0 -0
  285. {omlish-0.0.0.dev29/omlish/specs/jsonschema/schemas/draft202012 → omlish-0.0.0.dev30/omlish/specs/jsonschema/schemas/draft202012/vocabularies}/__init__.py +0 -0
  286. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/applicator.json +0 -0
  287. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/content.json +0 -0
  288. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/core.json +0 -0
  289. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/format-annotation.json +0 -0
  290. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/format-assertion.json +0 -0
  291. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/format.json +0 -0
  292. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/meta-data.json +0 -0
  293. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/unevaluated.json +0 -0
  294. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/schemas/draft202012/vocabularies/validation.json +0 -0
  295. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/specs/jsonschema/types.py +0 -0
  296. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/sql/_abc.py +0 -0
  297. {omlish-0.0.0.dev29/omlish/sql → omlish-0.0.0.dev30/omlish/sql/alchemy}/exprs.py +0 -0
  298. {omlish-0.0.0.dev29/omlish/sql → omlish-0.0.0.dev30/omlish/sql/alchemy}/sqlean.py +0 -0
  299. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/sql/dbs.py +0 -0
  300. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/sql/qualifiedname.py +0 -0
  301. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/sync.py +0 -0
  302. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/term.py +0 -0
  303. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/__init__.py +0 -0
  304. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/__init__.py +0 -0
  305. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/helpers.py +0 -0
  306. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/inject/__init__.py +0 -0
  307. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/inject/harness.py +0 -0
  308. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/marks.py +0 -0
  309. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/__init__.py +0 -0
  310. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/_registry.py +0 -0
  311. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/depskip.py +0 -0
  312. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/logging.py +0 -0
  313. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/managermarks.py +0 -0
  314. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/pydevd.py +0 -0
  315. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/repeat.py +0 -0
  316. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/skips.py +0 -0
  317. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/spacing.py +0 -0
  318. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/switches.py +0 -0
  319. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/pytest/plugins/utils.py +0 -0
  320. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/testing/testing.py +0 -0
  321. {omlish-0.0.0.dev29/omlish/specs/jsonschema/schemas/draft202012/vocabularies → omlish-0.0.0.dev30/omlish/text}/__init__.py +0 -0
  322. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/text/asdl.py +0 -0
  323. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/text/delimit.py +0 -0
  324. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/text/glyphsplit.py +0 -0
  325. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/text/indent.py +0 -0
  326. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish/text/parts.py +0 -0
  327. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish.egg-info/dependency_links.txt +0 -0
  328. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/omlish.egg-info/top_level.txt +0 -0
  329. {omlish-0.0.0.dev29 → omlish-0.0.0.dev30}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev29
3
+ Version: 0.0.0.dev30
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -47,10 +47,10 @@ Requires-Dist: sniffio~=1.3; extra == "async"
47
47
  Requires-Dist: greenlet~=3.1; extra == "async"
48
48
  Requires-Dist: trio~=0.26; extra == "async"
49
49
  Requires-Dist: trio-asyncio~=0.15; extra == "async"
50
- Provides-Extra: compression
51
- Requires-Dist: lz4~=4.0; extra == "compression"
52
- Requires-Dist: python-snappy~=0.7; python_version < "3.13" and extra == "compression"
53
- Requires-Dist: zstd~=1.5; extra == "compression"
50
+ Provides-Extra: compress
51
+ Requires-Dist: lz4~=4.0; extra == "compress"
52
+ Requires-Dist: python-snappy~=0.7; python_version < "3.13" and extra == "compress"
53
+ Requires-Dist: zstd~=1.5; extra == "compress"
54
54
  Provides-Extra: diag
55
55
  Requires-Dist: asttokens~=2.4; extra == "diag"
56
56
  Requires-Dist: executing~=2.1; extra == "diag"
@@ -67,15 +67,15 @@ Provides-Extra: misc
67
67
  Requires-Dist: wrapt~=1.14; extra == "misc"
68
68
  Provides-Extra: secrets
69
69
  Requires-Dist: cryptography~=43.0; extra == "secrets"
70
- Provides-Extra: sql
71
- Requires-Dist: sqlalchemy[asyncio]~=2.0; extra == "sql"
72
- Provides-Extra: sql-drivers
73
- Requires-Dist: pg8000~=1.31; extra == "sql-drivers"
74
- Requires-Dist: pymysql~=1.1; extra == "sql-drivers"
75
- Requires-Dist: aiomysql~=0.2; extra == "sql-drivers"
76
- Requires-Dist: aiosqlite~=0.20; extra == "sql-drivers"
77
- Requires-Dist: asyncpg~=0.29; python_version < "3.13" and extra == "sql-drivers"
78
- Requires-Dist: sqlean.py~=3.45; python_version < "3.13" and extra == "sql-drivers"
79
- Requires-Dist: duckdb~=1.1; extra == "sql-drivers"
70
+ Provides-Extra: sqlalchemy
71
+ Requires-Dist: sqlalchemy[asyncio]~=2.0; extra == "sqlalchemy"
72
+ Provides-Extra: sqlalchemy-drivers
73
+ Requires-Dist: pg8000~=1.31; extra == "sqlalchemy-drivers"
74
+ Requires-Dist: pymysql~=1.1; extra == "sqlalchemy-drivers"
75
+ Requires-Dist: aiomysql~=0.2; extra == "sqlalchemy-drivers"
76
+ Requires-Dist: aiosqlite~=0.20; extra == "sqlalchemy-drivers"
77
+ Requires-Dist: asyncpg~=0.29; python_version < "3.13" and extra == "sqlalchemy-drivers"
78
+ Requires-Dist: sqlean.py~=3.45; python_version < "3.13" and extra == "sqlalchemy-drivers"
79
+ Requires-Dist: duckdb~=1.1; extra == "sqlalchemy-drivers"
80
80
  Provides-Extra: testing
81
81
  Requires-Dist: pytest~=8.0; extra == "testing"
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev29'
2
- __revision__ = 'cde08614ca06e103fcae31adbb677c772002aef1'
1
+ __version__ = '0.0.0.dev30'
2
+ __revision__ = '1378b0a61f7d3ec16204c06bc87e5215b062d378'
3
3
 
4
4
 
5
5
  #
@@ -39,7 +39,7 @@ class Project(ProjectBase):
39
39
  'trio-asyncio ~= 0.15',
40
40
  ],
41
41
 
42
- 'compression': [
42
+ 'compress': [
43
43
  'lz4 ~= 4.0',
44
44
 
45
45
  'python-snappy ~= 0.7; python_version < "3.13"',
@@ -77,11 +77,11 @@ class Project(ProjectBase):
77
77
  'cryptography ~= 43.0',
78
78
  ],
79
79
 
80
- 'sql': [
80
+ 'sqlalchemy': [
81
81
  'sqlalchemy[asyncio] ~= 2.0',
82
82
  ],
83
83
 
84
- 'sql-drivers': [
84
+ 'sqlalchemy-drivers': [
85
85
  'pg8000 ~= 1.31',
86
86
  # 'psycopg2 ~= 2.9',
87
87
  # 'psycopg ~= 3.2',
@@ -9,7 +9,7 @@ TODO:
9
9
  - optional ipython embed
10
10
  - https://github.com/python/cpython/tree/56470004e58911b146c016fc9fec4461b8f69454/Lib/_pyrepl
11
11
 
12
- lookit:
12
+ See:
13
13
  - https://github.com/vxgmichel/aioconsole/blob/e55f4b0601da3b3a40a88c965526d35ab38b5841/aioconsole/server.py
14
14
  - https://github.com/nhoad/aiomanhole
15
15
  - https://github.com/twisted/twisted/blob/00aa56f5257060304d41f09651c6ab58ee6104d6/src/twisted/conch/manhole.py
@@ -0,0 +1,82 @@
1
+ import abc
2
+ import typing as ta
3
+
4
+
5
+ T = ta.TypeVar('T')
6
+ U = ta.TypeVar('U')
7
+
8
+
9
+ class Fn(abc.ABC, ta.Generic[T]):
10
+ @abc.abstractmethod
11
+ def __call__(self, *args: ta.Any, **kwargs: ta.Any) -> T:
12
+ raise NotImplementedError
13
+
14
+ def pipe(self, fn: ta.Callable[..., U], *args: ta.Any, **kwargs: ta.Any) -> 'Fn[U]':
15
+ return Pipe([self], Bind(fn, *args, **kwargs))
16
+
17
+ def __or__(self, fn: ta.Callable[..., U]) -> 'Fn[U]':
18
+ return self.pipe(fn)
19
+
20
+ def apply(self, fn: ta.Callable[[T], ta.Any], *args: ta.Any, **kwargs: ta.Any) -> 'Fn[T]':
21
+ return Pipe([self], Apply(Bind(fn, *args, **kwargs)))
22
+
23
+ def __and__(self, fn: ta.Callable[[T], ta.Any]) -> 'Fn[T]':
24
+ return self.apply(fn)
25
+
26
+
27
+ class Bind(Fn[T]):
28
+ def __init__(self, fn: ta.Callable[..., T], *args: ta.Any, **kwargs: ta.Any) -> None:
29
+ super().__init__()
30
+ if Ellipsis not in args and Ellipsis not in kwargs:
31
+ args += (Ellipsis,)
32
+ self._fn = fn
33
+ self._args = args
34
+ self._kwargs = kwargs
35
+
36
+ def __call__(self, *args: ta.Any, **kwargs: ta.Any) -> T:
37
+ fa: list = []
38
+ for a in self._args:
39
+ if a is Ellipsis:
40
+ fa.extend(args)
41
+ else:
42
+ fa.append(a)
43
+
44
+ fkw = {}
45
+ for k, v in self._kwargs.items():
46
+ if v is Ellipsis:
47
+ if len(args) != 1:
48
+ raise ValueError(args)
49
+ fkw[k] = args[0]
50
+ else:
51
+ fkw[k] = v
52
+ fkw.update(kwargs)
53
+
54
+ return self._fn(*fa, **fkw)
55
+
56
+
57
+ class Pipe(Fn[T]):
58
+ def __init__(self, lfns: ta.Sequence[ta.Callable], rfn: ta.Callable[..., T]) -> None:
59
+ super().__init__()
60
+ self._lfn, *self._rfns = [*lfns, rfn]
61
+
62
+ def __call__(self, *args: ta.Any, **kwargs: ta.Any) -> T:
63
+ o = self._lfn(*args, **kwargs)
64
+ for fn in self._rfns:
65
+ o = fn(o)
66
+ return o
67
+
68
+
69
+ class Apply(Fn[T]):
70
+ def __init__(self, *fns: ta.Callable[[T], ta.Any]) -> None:
71
+ super().__init__()
72
+ self._fns = fns
73
+
74
+ def __call__(self, o: T) -> T: # noqa
75
+ for fn in self._fns:
76
+ fn(o)
77
+ return o
78
+
79
+
80
+ bind = Bind
81
+ pipe = Pipe
82
+ apply = Apply
@@ -8,7 +8,7 @@ import time
8
8
  import typing as ta
9
9
  import zlib
10
10
 
11
- from .. import fnpairs as fps
11
+ from .. import fnpairs as fpa
12
12
  from .. import lang
13
13
  from .. import secrets as sec
14
14
  from .cookies import dump_cookie
@@ -92,7 +92,7 @@ class SessionMarshal:
92
92
  def __init__(
93
93
  self,
94
94
  signer: Signer,
95
- serializer: fps.ObjectStr = fps.of(JSON_TAGGER.dumps, JSON_TAGGER.loads),
95
+ serializer: fpa.ObjectStr = fpa.of(JSON_TAGGER.dumps, JSON_TAGGER.loads),
96
96
  ) -> None:
97
97
  super().__init__()
98
98
 
@@ -60,6 +60,7 @@ from .contextmanagers import ( # noqa
60
60
  NOP_CONTEXT_MANAGER,
61
61
  NopContextManaged,
62
62
  NopContextManager,
63
+ Timer,
63
64
  a_defer,
64
65
  attr_setting,
65
66
  breakpoint_on_exception,
@@ -188,8 +189,11 @@ from .strings import ( # noqa
188
189
  is_ident_cont,
189
190
  is_ident_start,
190
191
  is_sunder,
192
+ prefix_delimited,
191
193
  prefix_lines,
192
194
  snake_case,
195
+ strip_prefix,
196
+ strip_suffix,
193
197
  )
194
198
 
195
199
  from .sys import ( # noqa
@@ -47,7 +47,7 @@ class Abstract(abc.ABC): # noqa
47
47
  seen.update(dir(b))
48
48
  if ams:
49
49
  raise TypeError(
50
- f'Cannot subclass abstract class {cls.__name__} with abstract methods'
50
+ f'Cannot subclass abstract class {cls.__name__} with abstract methods: '
51
51
  f'{", ".join(map(str, sorted(ams)))}',
52
52
  )
53
53
 
@@ -7,6 +7,7 @@ import contextlib
7
7
  import contextvars
8
8
  import functools
9
9
  import threading
10
+ import time
10
11
  import types
11
12
  import typing as ta
12
13
 
@@ -367,3 +368,37 @@ def default_lock(value: DefaultLockable, default: DefaultLockable = None) -> Loc
367
368
 
368
369
  else:
369
370
  raise TypeError(value)
371
+
372
+
373
+ ##
374
+
375
+
376
+ class Timer:
377
+ def __init__(
378
+ self,
379
+ clock: ta.Callable[[], float] | None = None,
380
+ ) -> None:
381
+ super().__init__()
382
+ self._clock = clock if clock is not None else time.monotonic
383
+
384
+ _start: float
385
+ _end: float
386
+
387
+ @property
388
+ def start(self) -> float:
389
+ return self._start
390
+
391
+ @property
392
+ def end(self) -> float:
393
+ return self._end
394
+
395
+ @property
396
+ def elapsed(self) -> float:
397
+ return self._end - self._start
398
+
399
+ def __enter__(self) -> ta.Self:
400
+ self._start = self._clock()
401
+ return self
402
+
403
+ def __exit__(self, exc_type, exc_val, exc_tb):
404
+ self._end = self._clock()
@@ -27,6 +27,7 @@ def get_relative_resources(
27
27
 
28
28
  if os.sep in path:
29
29
  raise ValueError(path) # noqa
30
+
30
31
  if not path.startswith('.'):
31
32
  path = '.' + path
32
33
  if set(path) - {'.'}:
@@ -4,9 +4,22 @@ import unicodedata
4
4
 
5
5
  ##
6
6
 
7
+ @ta.overload
8
+ def prefix_delimited(s: str, p: str, d: str) -> str:
9
+ ...
10
+
11
+
12
+ @ta.overload
13
+ def prefix_delimited(s: bytes, p: bytes, d: bytes) -> bytes:
14
+ ...
15
+
16
+
17
+ def prefix_delimited(s, p, d):
18
+ return d.join([p + l for l in s.split(d)])
19
+
7
20
 
8
21
  def prefix_lines(s: str, p: str) -> str:
9
- return '\n'.join([p + l for l in s.split('\n')])
22
+ return prefix_delimited(s, p, '\n')
10
23
 
11
24
 
12
25
  def indent_lines(s: str, num: int) -> str:
@@ -16,6 +29,41 @@ def indent_lines(s: str, num: int) -> str:
16
29
  ##
17
30
 
18
31
 
32
+ @ta.overload
33
+ def strip_prefix(s: str, pfx: str) -> str:
34
+ ...
35
+
36
+
37
+ @ta.overload
38
+ def strip_prefix(s: bytes, pfx: bytes) -> bytes:
39
+ ...
40
+
41
+
42
+ def strip_prefix(s, pfx):
43
+ if not s.startswith(pfx):
44
+ raise ValueError(f'{s!r} does not start with {pfx!r}')
45
+ return s[len(pfx):]
46
+
47
+
48
+ @ta.overload
49
+ def strip_suffix(s: str, sfx: str) -> str:
50
+ ...
51
+
52
+
53
+ @ta.overload
54
+ def strip_suffix(s: bytes, sfx: bytes) -> bytes:
55
+ ...
56
+
57
+
58
+ def strip_suffix(s, sfx):
59
+ if not s.endswith(sfx):
60
+ raise ValueError(f'{s!r} does not end with {sfx!r}')
61
+ return s[:-len(sfx)]
62
+
63
+
64
+ ##
65
+
66
+
19
67
  def camel_case(name: str) -> str:
20
68
  return ''.join(map(str.capitalize, name.split('_'))) # noqa
21
69
 
@@ -4,6 +4,7 @@ TODO:
4
4
  - debug
5
5
  """
6
6
  # ruff: noqa: UP006 UP007 N802
7
+ import contextlib
7
8
  import datetime
8
9
  import logging
9
10
  import threading
@@ -203,6 +204,24 @@ class StandardLogHandler(ProxyLogHandler):
203
204
  ##
204
205
 
205
206
 
207
+ @contextlib.contextmanager
208
+ def _locking_logging_module_lock() -> ta.Iterator[None]:
209
+ if hasattr(logging, '_acquireLock'):
210
+ logging._acquireLock() # noqa
211
+ try:
212
+ yield
213
+ finally:
214
+ logging._releaseLock() # type: ignore # noqa
215
+
216
+ elif hasattr(logging, '_lock'):
217
+ # https://github.com/python/cpython/commit/74723e11109a320e628898817ab449b3dad9ee96
218
+ with logging._lock: # noqa
219
+ yield
220
+
221
+ else:
222
+ raise Exception("Can't find lock in logging module")
223
+
224
+
206
225
  def configure_standard_logging(
207
226
  level: ta.Union[int, str] = logging.INFO,
208
227
  *,
@@ -210,8 +229,7 @@ def configure_standard_logging(
210
229
  target: ta.Optional[logging.Logger] = None,
211
230
  force: bool = False,
212
231
  ) -> ta.Optional[StandardLogHandler]:
213
- logging._acquireLock() # type: ignore # noqa
214
- try:
232
+ with _locking_logging_module_lock():
215
233
  if target is None:
216
234
  target = logging.root
217
235
 
@@ -250,6 +268,3 @@ def configure_standard_logging(
250
268
  #
251
269
 
252
270
  return StandardLogHandler(handler)
253
-
254
- finally:
255
- logging._releaseLock() # type: ignore # noqa
@@ -1,3 +1,8 @@
1
+ """
2
+ TODO:
3
+ - Namer: ta.TypeAlias = ta.Callable[[str], str] ?
4
+ - this interface is ~intentionally~ limited, but custom overrides would be useful
5
+ """
1
6
  import enum
2
7
 
3
8
  from .. import lang
@@ -98,24 +98,34 @@ def polymorphism_from_subclasses(
98
98
  ty: type,
99
99
  *,
100
100
  naming: Naming | None = None,
101
+ strip_suffix: bool = False,
101
102
  ) -> Polymorphism:
102
103
  dct: dict[str, Impl] = {}
104
+
103
105
  seen: set[type] = set()
104
106
  todo: list[type] = [ty]
105
107
  while todo:
106
108
  cur = todo.pop()
107
109
  seen.add(cur)
108
- if not lang.is_abstract_class(cur):
109
- nam = cur.__name__
110
- if naming is not None:
111
- nam = translate_name(nam, naming)
112
- if nam in dct:
113
- raise KeyError(f'Duplicate name: {nam}')
114
- dct[nam] = Impl(
115
- cur,
116
- nam,
117
- )
110
+
118
111
  todo.extend(nxt for nxt in cur.__subclasses__() if nxt not in seen)
112
+
113
+ if lang.is_abstract_class(cur):
114
+ continue
115
+
116
+ name = cur.__name__
117
+ if strip_suffix:
118
+ name = lang.strip_suffix(name, ty.__name__)
119
+ if naming is not None:
120
+ name = translate_name(name, naming)
121
+ if name in dct:
122
+ raise KeyError(f'Duplicate name: {name}')
123
+
124
+ dct[name] = Impl(
125
+ cur,
126
+ name,
127
+ )
128
+
119
129
  return Polymorphism(ty, dct.values())
120
130
 
121
131
 
@@ -103,3 +103,20 @@ class Pidfile:
103
103
  def kill(self, sig: int = signal.SIGTERM) -> None:
104
104
  pid = self.read()
105
105
  os.kill(pid, sig) # Still racy
106
+
107
+
108
+ def touch(self, mode: int = 0o666, exist_ok: bool = True) -> None:
109
+ if exist_ok:
110
+ # First try to bump modification time
111
+ # Implementation note: GNU touch uses the UTIME_NOW option of the utimensat() / futimens() functions.
112
+ try:
113
+ os.utime(self, None)
114
+ except OSError:
115
+ pass
116
+ else:
117
+ return
118
+ flags = os.O_CREAT | os.O_WRONLY
119
+ if not exist_ok:
120
+ flags |= os.O_EXCL
121
+ fd = os.open(self, flags, mode)
122
+ os.close(fd)
@@ -0,0 +1,9 @@
1
+ """
2
+ TODO:
3
+ - avro
4
+ - jmespath
5
+ - jsonpatch
6
+ - jsonpointer.py
7
+ - openapi
8
+ - protobuf
9
+ """
@@ -0,0 +1,13 @@
1
+ from .dbs import ( # noqa
2
+ DbLoc,
3
+ DbSpec,
4
+ DbType,
5
+ DbTypes,
6
+ HostDbLoc,
7
+ UrlDbLoc,
8
+ )
9
+
10
+ from .qualifiedname import ( # noqa
11
+ QualifiedName,
12
+ qn,
13
+ )
@@ -8,20 +8,6 @@ from .asyncs import ( # noqa
8
8
  async_adapt,
9
9
  )
10
10
 
11
- from .dbs import ( # noqa
12
- DbLoc,
13
- DbSpec,
14
- DbType,
15
- DbTypes,
16
- HostDbLoc,
17
- UrlDbLoc,
18
- )
19
-
20
11
  from .exprs import ( # noqa
21
12
  paren,
22
13
  )
23
-
24
- from .qualifiedname import ( # noqa
25
- QualifiedName,
26
- qn,
27
- )
@@ -9,7 +9,7 @@ import typing as ta
9
9
  import sqlalchemy as sa
10
10
  import sqlalchemy.ext.asyncio as saa
11
11
 
12
- from .. import asyncs as au
12
+ from ... import asyncs as au
13
13
 
14
14
 
15
15
  T = ta.TypeVar('T')
@@ -8,7 +8,7 @@ import typing as ta
8
8
  import sqlalchemy as sa
9
9
  from sqlalchemy.dialects import postgresql as sap
10
10
 
11
- from .. import lang
11
+ from ... import lang
12
12
 
13
13
 
14
14
  if ta.TYPE_CHECKING:
@@ -2,7 +2,7 @@
2
2
  TODO:
3
3
  - sync/async...
4
4
  """
5
- from .. import secrets as sec
5
+ from ... import secrets as sec
6
6
 
7
7
 
8
8
  class SqlFunctionSecrets(sec.Secrets):
@@ -111,6 +111,11 @@ class AsyncsPlugin:
111
111
  else:
112
112
  return
113
113
 
114
+ if 'trio_asyncio' in bes:
115
+ # NOTE: Importing it here is apparently necessary to get its patching working - otherwise fails later with
116
+ # `no running event loop` in anyio._backends._asyncio and such.
117
+ import trio_asyncio # noqa
118
+
114
119
  if pdu.is_present():
115
120
  pdu.patch_for_trio_asyncio()
116
121
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev29
3
+ Version: 0.0.0.dev30
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -47,10 +47,10 @@ Requires-Dist: sniffio~=1.3; extra == "async"
47
47
  Requires-Dist: greenlet~=3.1; extra == "async"
48
48
  Requires-Dist: trio~=0.26; extra == "async"
49
49
  Requires-Dist: trio-asyncio~=0.15; extra == "async"
50
- Provides-Extra: compression
51
- Requires-Dist: lz4~=4.0; extra == "compression"
52
- Requires-Dist: python-snappy~=0.7; python_version < "3.13" and extra == "compression"
53
- Requires-Dist: zstd~=1.5; extra == "compression"
50
+ Provides-Extra: compress
51
+ Requires-Dist: lz4~=4.0; extra == "compress"
52
+ Requires-Dist: python-snappy~=0.7; python_version < "3.13" and extra == "compress"
53
+ Requires-Dist: zstd~=1.5; extra == "compress"
54
54
  Provides-Extra: diag
55
55
  Requires-Dist: asttokens~=2.4; extra == "diag"
56
56
  Requires-Dist: executing~=2.1; extra == "diag"
@@ -67,15 +67,15 @@ Provides-Extra: misc
67
67
  Requires-Dist: wrapt~=1.14; extra == "misc"
68
68
  Provides-Extra: secrets
69
69
  Requires-Dist: cryptography~=43.0; extra == "secrets"
70
- Provides-Extra: sql
71
- Requires-Dist: sqlalchemy[asyncio]~=2.0; extra == "sql"
72
- Provides-Extra: sql-drivers
73
- Requires-Dist: pg8000~=1.31; extra == "sql-drivers"
74
- Requires-Dist: pymysql~=1.1; extra == "sql-drivers"
75
- Requires-Dist: aiomysql~=0.2; extra == "sql-drivers"
76
- Requires-Dist: aiosqlite~=0.20; extra == "sql-drivers"
77
- Requires-Dist: asyncpg~=0.29; python_version < "3.13" and extra == "sql-drivers"
78
- Requires-Dist: sqlean.py~=3.45; python_version < "3.13" and extra == "sql-drivers"
79
- Requires-Dist: duckdb~=1.1; extra == "sql-drivers"
70
+ Provides-Extra: sqlalchemy
71
+ Requires-Dist: sqlalchemy[asyncio]~=2.0; extra == "sqlalchemy"
72
+ Provides-Extra: sqlalchemy-drivers
73
+ Requires-Dist: pg8000~=1.31; extra == "sqlalchemy-drivers"
74
+ Requires-Dist: pymysql~=1.1; extra == "sqlalchemy-drivers"
75
+ Requires-Dist: aiomysql~=0.2; extra == "sqlalchemy-drivers"
76
+ Requires-Dist: aiosqlite~=0.20; extra == "sqlalchemy-drivers"
77
+ Requires-Dist: asyncpg~=0.29; python_version < "3.13" and extra == "sqlalchemy-drivers"
78
+ Requires-Dist: sqlean.py~=3.45; python_version < "3.13" and extra == "sqlalchemy-drivers"
79
+ Requires-Dist: duckdb~=1.1; extra == "sqlalchemy-drivers"
80
80
  Provides-Extra: testing
81
81
  Requires-Dist: pytest~=8.0; extra == "testing"
@@ -14,6 +14,7 @@ omlish/defs.py
14
14
  omlish/docker.py
15
15
  omlish/dynamic.py
16
16
  omlish/fnpairs.py
17
+ omlish/fnpipes.py
17
18
  omlish/genmachine.py
18
19
  omlish/iterators.py
19
20
  omlish/libc.py
@@ -290,13 +291,14 @@ omlish/specs/jsonschema/schemas/draft202012/vocabularies/unevaluated.json
290
291
  omlish/specs/jsonschema/schemas/draft202012/vocabularies/validation.json
291
292
  omlish/sql/__init__.py
292
293
  omlish/sql/_abc.py
293
- omlish/sql/asyncs.py
294
294
  omlish/sql/dbs.py
295
- omlish/sql/duckdb.py
296
- omlish/sql/exprs.py
297
295
  omlish/sql/qualifiedname.py
298
- omlish/sql/secrets.py
299
- omlish/sql/sqlean.py
296
+ omlish/sql/alchemy/__init__.py
297
+ omlish/sql/alchemy/asyncs.py
298
+ omlish/sql/alchemy/duckdb.py
299
+ omlish/sql/alchemy/exprs.py
300
+ omlish/sql/alchemy/secrets.py
301
+ omlish/sql/alchemy/sqlean.py
300
302
  omlish/testing/__init__.py
301
303
  omlish/testing/testing.py
302
304
  omlish/testing/pytest/__init__.py
@@ -38,11 +38,11 @@ greenlet~=3.1
38
38
  trio~=0.26
39
39
  trio-asyncio~=0.15
40
40
 
41
- [compression]
41
+ [compress]
42
42
  lz4~=4.0
43
43
  zstd~=1.5
44
44
 
45
- [compression:python_version < "3.13"]
45
+ [compress:python_version < "3.13"]
46
46
  python-snappy~=0.7
47
47
 
48
48
  [diag]
@@ -66,17 +66,17 @@ wrapt~=1.14
66
66
  [secrets]
67
67
  cryptography~=43.0
68
68
 
69
- [sql]
69
+ [sqlalchemy]
70
70
  sqlalchemy[asyncio]~=2.0
71
71
 
72
- [sql-drivers]
72
+ [sqlalchemy-drivers]
73
73
  pg8000~=1.31
74
74
  pymysql~=1.1
75
75
  aiomysql~=0.2
76
76
  aiosqlite~=0.20
77
77
  duckdb~=1.1
78
78
 
79
- [sql-drivers:python_version < "3.13"]
79
+ [sqlalchemy-drivers:python_version < "3.13"]
80
80
  asyncpg~=0.29
81
81
  sqlean.py~=3.45
82
82