omlish 0.0.0.dev3__tar.gz → 0.0.0.dev4__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.

Potentially problematic release.


This version of omlish might be problematic. Click here for more details.

Files changed (204) hide show
  1. {omlish-0.0.0.dev3/omlish.egg-info → omlish-0.0.0.dev4}/PKG-INFO +4 -1
  2. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/__about__.py +1 -1
  3. omlish-0.0.0.dev4/omlish/__init__.py +8 -0
  4. omlish-0.0.0.dev4/omlish/asyncs/__init__.py +38 -0
  5. omlish-0.0.0.dev4/omlish/asyncs/flavors.py +201 -0
  6. omlish-0.0.0.dev4/omlish/asyncs/trio_asyncio.py +41 -0
  7. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dynamic.py +2 -2
  8. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/fnpairs.py +111 -22
  9. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/elements.py +13 -1
  10. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/injector.py +7 -5
  11. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/scopes.py +3 -2
  12. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/json.py +136 -0
  13. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/__init__.py +4 -0
  14. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/restrict.py +1 -1
  15. omlish-0.0.0.dev4/omlish/lang/sys.py +7 -0
  16. omlish-0.0.0.dev4/omlish/sql/__init__.py +9 -0
  17. omlish-0.0.0.dev4/omlish/sql/asyncs.py +148 -0
  18. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pydevd.py +2 -0
  19. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4/omlish.egg-info}/PKG-INFO +4 -1
  20. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish.egg-info/SOURCES.txt +4 -0
  21. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish.egg-info/requires.txt +4 -0
  22. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/pyproject.toml +8 -5
  23. omlish-0.0.0.dev3/omlish/asyncs/__init__.py +0 -17
  24. omlish-0.0.0.dev3/omlish/sql/__init__.py +0 -0
  25. omlish-0.0.0.dev3/omlish/text/__init__.py +0 -0
  26. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/LICENSE +0 -0
  27. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/MANIFEST.in +0 -0
  28. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/README.md +0 -0
  29. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/argparse.py +0 -0
  30. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/anyio.py +0 -0
  31. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/asyncio.py +0 -0
  32. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/asyncs.py +0 -0
  33. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/futures.py +0 -0
  34. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/asyncs/trio.py +0 -0
  35. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/c3.py +0 -0
  36. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/cached.py +0 -0
  37. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/check.py +0 -0
  38. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/__init__.py +0 -0
  39. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/_abc.py +0 -0
  40. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/_io_abc.py +0 -0
  41. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/cache/__init__.py +0 -0
  42. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/cache/descriptor.py +0 -0
  43. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/cache/impl.py +0 -0
  44. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/cache/types.py +0 -0
  45. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/coerce.py +0 -0
  46. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/frozen.py +0 -0
  47. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/identity.py +0 -0
  48. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/indexed.py +0 -0
  49. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/mappings.py +0 -0
  50. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/ordered.py +0 -0
  51. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/persistent.py +0 -0
  52. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/skiplist.py +0 -0
  53. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/sorted.py +0 -0
  54. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/treap.py +0 -0
  55. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/treapmap.py +0 -0
  56. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/unmodifiable.py +0 -0
  57. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/collections/utils.py +0 -0
  58. {omlish-0.0.0.dev3/omlish → omlish-0.0.0.dev4/omlish/configs}/__init__.py +0 -0
  59. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/configs/flattening.py +0 -0
  60. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/configs/props.py +0 -0
  61. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/__init__.py +0 -0
  62. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/__init__.py +0 -0
  63. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/api.py +0 -0
  64. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/as_.py +0 -0
  65. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/exceptions.py +0 -0
  66. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/fields.py +0 -0
  67. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/frozen.py +0 -0
  68. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/hashing.py +0 -0
  69. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/init.py +0 -0
  70. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/internals.py +0 -0
  71. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/main.py +0 -0
  72. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/metaclass.py +0 -0
  73. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/metadata.py +0 -0
  74. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/order.py +0 -0
  75. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/params.py +0 -0
  76. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/processing.py +0 -0
  77. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/reflect.py +0 -0
  78. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/replace.py +0 -0
  79. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/repr.py +0 -0
  80. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/simple.py +0 -0
  81. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/slots.py +0 -0
  82. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dataclasses/impl/utils.py +0 -0
  83. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/defs.py +0 -0
  84. {omlish-0.0.0.dev3/omlish/configs → omlish-0.0.0.dev4/omlish/diag}/__init__.py +0 -0
  85. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/procfs.py +0 -0
  86. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/ps.py +0 -0
  87. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/replserver/__init__.py +0 -0
  88. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/replserver/__main__.py +0 -0
  89. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/replserver/console.py +0 -0
  90. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/diag/replserver/server.py +0 -0
  91. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dispatch/__init__.py +0 -0
  92. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dispatch/dispatch.py +0 -0
  93. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dispatch/functions.py +0 -0
  94. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/dispatch/methods.py +0 -0
  95. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/docker.py +0 -0
  96. {omlish-0.0.0.dev3/omlish/diag → omlish-0.0.0.dev4/omlish/graphs}/__init__.py +0 -0
  97. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/dot/__init__.py +0 -0
  98. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/dot/items.py +0 -0
  99. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/dot/rendering.py +0 -0
  100. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/dot/utils.py +0 -0
  101. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/graphs/trees.py +0 -0
  102. {omlish-0.0.0.dev3/omlish/graphs → omlish-0.0.0.dev4/omlish/http}/__init__.py +0 -0
  103. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/http/consts.py +0 -0
  104. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/http/wsgi.py +0 -0
  105. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/__init__.py +0 -0
  106. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/binder.py +0 -0
  107. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/bindings.py +0 -0
  108. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/eagers.py +0 -0
  109. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/elements.py +0 -0
  110. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/exceptions.py +0 -0
  111. {omlish-0.0.0.dev3/omlish/http → omlish-0.0.0.dev4/omlish/inject/impl}/__init__.py +0 -0
  112. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/bindings.py +0 -0
  113. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/inspect.py +0 -0
  114. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/private.py +0 -0
  115. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/impl/providers.py +0 -0
  116. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/injector.py +0 -0
  117. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/inspect.py +0 -0
  118. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/keys.py +0 -0
  119. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/managed.py +0 -0
  120. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/overrides.py +0 -0
  121. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/private.py +0 -0
  122. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/providers.py +0 -0
  123. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/proxy.py +0 -0
  124. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/scopes.py +0 -0
  125. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/inject/types.py +0 -0
  126. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/iterators.py +0 -0
  127. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/cached.py +0 -0
  128. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/__init__.py +0 -0
  129. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/abstract.py +0 -0
  130. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/simple.py +0 -0
  131. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/classes/virtual.py +0 -0
  132. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/clsdct.py +0 -0
  133. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/cmp.py +0 -0
  134. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/contextmanagers.py +0 -0
  135. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/datetimes.py +0 -0
  136. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/descriptors.py +0 -0
  137. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/exceptions.py +0 -0
  138. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/functions.py +0 -0
  139. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/imports.py +0 -0
  140. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/iterables.py +0 -0
  141. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/maybes.py +0 -0
  142. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/objects.py +0 -0
  143. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/resolving.py +0 -0
  144. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/strings.py +0 -0
  145. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/timeouts.py +0 -0
  146. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/lang/typing.py +0 -0
  147. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/libc.py +0 -0
  148. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/__init__.py +0 -0
  149. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/_abc.py +0 -0
  150. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/configs.py +0 -0
  151. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/filters.py +0 -0
  152. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/formatters.py +0 -0
  153. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/logs/utils.py +0 -0
  154. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/__init__.py +0 -0
  155. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/any.py +0 -0
  156. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/base.py +0 -0
  157. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/base64.py +0 -0
  158. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/dataclasses.py +0 -0
  159. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/datetimes.py +0 -0
  160. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/enums.py +0 -0
  161. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/exceptions.py +0 -0
  162. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/factories.py +0 -0
  163. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/global_.py +0 -0
  164. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/iterables.py +0 -0
  165. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/mappings.py +0 -0
  166. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/naming.py +0 -0
  167. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/objects.py +0 -0
  168. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/optionals.py +0 -0
  169. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/polymorphism.py +0 -0
  170. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/primitives.py +0 -0
  171. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/registries.py +0 -0
  172. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/standard.py +0 -0
  173. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/utils.py +0 -0
  174. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/uuids.py +0 -0
  175. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/marshal/values.py +0 -0
  176. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/math.py +0 -0
  177. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/os.py +0 -0
  178. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/reflect.py +0 -0
  179. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/runmodule.py +0 -0
  180. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/sql/_abc.py +0 -0
  181. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/sql/dbs.py +0 -0
  182. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/stats.py +0 -0
  183. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/term.py +0 -0
  184. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/__init__.py +0 -0
  185. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/__init__.py +0 -0
  186. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/helpers.py +0 -0
  187. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/inject/__init__.py +0 -0
  188. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/inject/harness.py +0 -0
  189. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/__init__.py +0 -0
  190. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/_registry.py +0 -0
  191. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/logging.py +0 -0
  192. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/pydevd.py +0 -0
  193. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/repeat.py +0 -0
  194. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/skips.py +0 -0
  195. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/spacing.py +0 -0
  196. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/pytest/plugins/switches.py +0 -0
  197. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/testing/testing.py +0 -0
  198. {omlish-0.0.0.dev3/omlish/inject/impl → omlish-0.0.0.dev4/omlish/text}/__init__.py +0 -0
  199. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/text/delimit.py +0 -0
  200. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/text/indent.py +0 -0
  201. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish/text/parts.py +0 -0
  202. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish.egg-info/dependency_links.txt +0 -0
  203. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/omlish.egg-info/top_level.txt +0 -0
  204. {omlish-0.0.0.dev3 → omlish-0.0.0.dev4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev3
3
+ Version: 0.0.0.dev4
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -13,6 +13,9 @@ Requires-Python: >=3.12
13
13
  License-File: LICENSE
14
14
  Provides-Extra: async
15
15
  Requires-Dist: anyio; extra == "async"
16
+ Provides-Extra: trio
17
+ Requires-Dist: trio; extra == "trio"
18
+ Requires-Dist: trio-asyncio; extra == "trio"
16
19
  Provides-Extra: http
17
20
  Requires-Dist: httpx; extra == "http"
18
21
  Provides-Extra: sql
@@ -3,4 +3,4 @@ __url__ = 'https://github.com/wrmsr/omlish'
3
3
  __license__ = 'BSD-3-Clause'
4
4
  __requires_python__ = '>=3.12'
5
5
 
6
- __version__ = '0.0.0.dev3'
6
+ __version__ = '0.0.0.dev4'
@@ -0,0 +1,8 @@
1
+ import sys as _sys
2
+
3
+
4
+ REQUIRED_PYTHON_VERSION = (3, 12)
5
+
6
+
7
+ if _sys.version_info < REQUIRED_PYTHON_VERSION:
8
+ raise EnvironmentError(f'Python version {_sys.version_info=} < {REQUIRED_PYTHON_VERSION}')
@@ -0,0 +1,38 @@
1
+ from .asyncs import ( # noqa
2
+ SyncableIterable,
3
+ async_list,
4
+ sync_await,
5
+ sync_list,
6
+ syncable_iterable,
7
+ )
8
+
9
+ from .flavors import ( # noqa
10
+ ContextManagerAdapter,
11
+ Flavor,
12
+ adapt,
13
+ adapt_context,
14
+ from_anyio,
15
+ from_anyio_context,
16
+ from_asyncio,
17
+ from_asyncio_context,
18
+ from_trio,
19
+ from_trio_context,
20
+ get_flavor,
21
+ mark_anyio,
22
+ mark_asyncio,
23
+ mark_flavor,
24
+ mark_trio,
25
+ )
26
+
27
+ from .futures import ( # noqa
28
+ FutureError,
29
+ FutureTimeoutError,
30
+ ImmediateExecutor,
31
+ new_thread_or_immediate_executor,
32
+ wait_dependent_futures,
33
+ wait_futures,
34
+ )
35
+
36
+ from .trio_asyncio import ( # noqa
37
+ with_trio_asyncio_loop,
38
+ )
@@ -0,0 +1,201 @@
1
+ """
2
+ TODO:
3
+ - 'get current'? -> sniffio..
4
+ - mark whole class / module?
5
+ - sync/greenlet bridge
6
+ """
7
+ import abc
8
+ import dataclasses as dc
9
+ import enum
10
+ import typing as ta
11
+
12
+ from .. import lang
13
+ from .trio_asyncio import check_trio_asyncio
14
+
15
+ if ta.TYPE_CHECKING:
16
+ import sniffio
17
+ import trio_asyncio
18
+ else:
19
+ sniffio = lang.proxy_import('sniffio')
20
+ trio_asyncio = lang.proxy_import('trio_asyncio')
21
+
22
+
23
+ T = ta.TypeVar('T')
24
+
25
+
26
+ ##
27
+
28
+
29
+ _FLAVOR_ATTR = '__async_flavor__'
30
+
31
+
32
+ class _MISSING(lang.Marker):
33
+ pass
34
+
35
+
36
+ class Flavor(enum.Enum):
37
+ ASYNCIO = enum.auto()
38
+ TRIO = enum.auto()
39
+ ANYIO = enum.auto()
40
+
41
+
42
+ def mark_flavor(f: Flavor):
43
+ if not isinstance(f, Flavor):
44
+ raise TypeError(f)
45
+
46
+ def inner(fn):
47
+ setattr(fn, _FLAVOR_ATTR, f)
48
+ return fn
49
+
50
+ return inner
51
+
52
+
53
+ mark_asyncio = mark_flavor(Flavor.ASYNCIO)
54
+ mark_anyio = mark_flavor(Flavor.ANYIO)
55
+ mark_trio = mark_flavor(Flavor.TRIO)
56
+
57
+ PACKAGE_FLAVORS: ta.MutableMapping[str, Flavor] = {
58
+ 'anyio': Flavor.ANYIO,
59
+ 'asyncio': Flavor.ASYNCIO,
60
+ 'trio': Flavor.TRIO,
61
+
62
+ 'sqlalchemy.ext.asyncio': Flavor.ASYNCIO,
63
+ }
64
+
65
+ _MODULE_FLAVOR_CACHE: dict[str, Flavor | None] = {}
66
+
67
+
68
+ def _get_module_flavor(p: str) -> Flavor | None:
69
+ try:
70
+ return _MODULE_FLAVOR_CACHE[p]
71
+ except KeyError:
72
+ pass
73
+ pf: Flavor | None = None
74
+ for cp, cf in PACKAGE_FLAVORS.items():
75
+ if p.startswith(cp) and (len(cp) == len(p) or p[len(cp)] == '.'):
76
+ pf = cf
77
+ break
78
+ _MODULE_FLAVOR_CACHE[p] = pf
79
+ return pf
80
+
81
+
82
+ def get_flavor(obj: ta.Any, default: ta.Union[Flavor, type[_MISSING], None] = _MISSING) -> Flavor:
83
+ u = lang.unwrap_func(obj)
84
+
85
+ try:
86
+ return getattr(u, _FLAVOR_ATTR)
87
+ except AttributeError:
88
+ pass
89
+
90
+ if (mn := getattr(u, '__module__', None)) is not None:
91
+ if (pf := _get_module_flavor(mn)):
92
+ return pf
93
+
94
+ if default is not _MISSING:
95
+ return default # type: ignore
96
+
97
+ raise TypeError(f'not marked with flavor: {obj}')
98
+
99
+
100
+ ##
101
+
102
+
103
+ class Adapter(lang.Abstract):
104
+ _FROM_METHODS_BY_FLAVOR: ta.ClassVar[ta.Mapping[Flavor, str]] = {
105
+ Flavor.ANYIO: 'from_anyio',
106
+ Flavor.ASYNCIO: 'from_asyncio',
107
+ Flavor.TRIO: 'from_trio',
108
+ }
109
+
110
+ def adapt(self, fn, fl=None):
111
+ if fl is None:
112
+ fl = get_flavor(fn)
113
+ return getattr(self, self._FROM_METHODS_BY_FLAVOR[fl])(fn)
114
+
115
+ #
116
+
117
+ def from_anyio(self, fn):
118
+ return fn
119
+
120
+ @abc.abstractmethod
121
+ def from_asyncio(self, fn):
122
+ raise NotImplementedError
123
+
124
+ @abc.abstractmethod
125
+ def from_trio(self, fn):
126
+ raise NotImplementedError
127
+
128
+
129
+ class AsyncioAdapter(Adapter):
130
+ def from_asyncio(self, fn):
131
+ return fn
132
+
133
+ def from_trio(self, fn):
134
+ check_trio_asyncio()
135
+ return trio_asyncio.trio_as_aio(fn)
136
+
137
+
138
+ class TrioAdapter(Adapter):
139
+ def from_asyncio(self, fn):
140
+ check_trio_asyncio()
141
+ return trio_asyncio.aio_as_trio(fn)
142
+
143
+ def from_trio(self, fn):
144
+ return fn
145
+
146
+
147
+ _ADAPTERS_BY_BACKEND: ta.Mapping[str, Adapter] = {
148
+ 'asyncio': AsyncioAdapter(),
149
+ 'trio': TrioAdapter(),
150
+ }
151
+
152
+
153
+ def get_adapter() -> Adapter:
154
+ return _ADAPTERS_BY_BACKEND[sniffio.current_async_library()]
155
+
156
+
157
+ def adapt(fn, fl=None):
158
+ return get_adapter().adapt(fn, fl)
159
+
160
+
161
+ def from_anyio(fn):
162
+ return get_adapter().from_anyio(fn)
163
+
164
+
165
+ def from_asyncio(fn):
166
+ return get_adapter().from_asyncio(fn)
167
+
168
+
169
+ def from_trio(fn):
170
+ return get_adapter().from_trio(fn)
171
+
172
+
173
+ ##
174
+
175
+
176
+ @dc.dataclass(frozen=True)
177
+ class ContextManagerAdapter(ta.Generic[T]):
178
+ obj: ta.AsyncContextManager[T]
179
+ adapt: ta.Callable[[ta.Callable], ta.Callable]
180
+
181
+ async def __aenter__(self, *args: ta.Any, **kwargs: ta.Any) -> T:
182
+ return await self.adapt(self.obj.__aenter__)(*args, **kwargs)
183
+
184
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
185
+ return await self.adapt(self.obj.__aexit__)(exc_type, exc_val, exc_tb)
186
+
187
+
188
+ def adapt_context(obj):
189
+ return ContextManagerAdapter(obj, get_adapter().adapt)
190
+
191
+
192
+ def from_anyio_context(obj):
193
+ return ContextManagerAdapter(obj, get_adapter().from_anyio)
194
+
195
+
196
+ def from_asyncio_context(obj):
197
+ return ContextManagerAdapter(obj, get_adapter().from_asyncio)
198
+
199
+
200
+ def from_trio_context(obj):
201
+ return ContextManagerAdapter(obj, get_adapter().from_trio)
@@ -0,0 +1,41 @@
1
+ import functools
2
+ import typing as ta
3
+
4
+ from .. import lang
5
+
6
+ if ta.TYPE_CHECKING:
7
+ import asyncio
8
+ import sniffio
9
+ import trio_asyncio
10
+ else:
11
+ asyncio = lang.proxy_import('asyncio')
12
+ sniffio = lang.proxy_import('sniffio')
13
+ trio_asyncio = lang.proxy_import('trio_asyncio')
14
+
15
+
16
+ def check_trio_asyncio() -> None:
17
+ if trio_asyncio.current_loop.get() is None:
18
+ raise RuntimeError('trio_asyncio loop not running')
19
+
20
+
21
+ def with_trio_asyncio_loop(fn, *, wait=False):
22
+ @functools.wraps(fn)
23
+ async def inner(*args, **kwargs):
24
+ if trio_asyncio.current_loop.get() is not None:
25
+ await fn(*args, **kwargs)
26
+ return
27
+
28
+ if sniffio.current_async_library() != 'trio':
29
+ raise RuntimeError('trio loop not running')
30
+
31
+ loop: asyncio.BaseEventLoop
32
+ async with trio_asyncio.open_loop() as loop:
33
+ try:
34
+ await fn(*args, **kwargs)
35
+ finally:
36
+ if wait:
37
+ # FIXME: lol
38
+ while asyncio.all_tasks(loop):
39
+ await asyncio.sleep(.2)
40
+
41
+ return inner
@@ -49,7 +49,7 @@ class Var(ta.Generic[T]):
49
49
 
50
50
  def __init__(
51
51
  self,
52
- default: type[MISSING] | T = MISSING, # type: ignore
52
+ default: type[MISSING] | T = MISSING,
53
53
  *,
54
54
  new: ta.Callable[[], T] | type[MISSING] = MISSING,
55
55
  validate: ta.Callable[[T], None] | None = None,
@@ -138,7 +138,7 @@ class Var(ta.Generic[T]):
138
138
  frame = frame.f_back
139
139
 
140
140
  if self._new is not MISSING:
141
- yield self._new()
141
+ yield self._new() # type: ignore
142
142
 
143
143
  def __iter__(self) -> ta.Iterator[T]:
144
144
  return self.values
@@ -1,3 +1,16 @@
1
+ """
2
+ TODO:
3
+ - objects
4
+ - csv
5
+ - csvloader
6
+ - cbor
7
+ - cloudpickle
8
+ - alt json backends
9
+ - compression
10
+ - snappy
11
+ - lz4
12
+ - wrapped (wait for usecase)
13
+ """
1
14
  import abc
2
15
  import codecs
3
16
  import dataclasses as dc
@@ -6,32 +19,41 @@ import typing as ta
6
19
  from . import lang
7
20
 
8
21
  if ta.TYPE_CHECKING:
9
- import bzip2 as _bzip2
22
+ import bz2 as _bz2
23
+ import cloudpickle as _cloudpickle
10
24
  import gzip as _gzip
11
25
  import json as _json
26
+ import lz4.frame as _lz4_frame
12
27
  import lzma as _lzma
13
28
  import pickle as _pickle
29
+ import snappy as _snappy
14
30
  import struct as _struct
15
31
  import tomllib as _tomllib
32
+ import yaml as _yaml
33
+ import zstd as _zstd
16
34
 
17
35
  else:
18
- _bzip2 = lang.proxy_import('bzip2')
36
+ _bz2 = lang.proxy_import('bz2')
37
+ _cloudpickle = lang.proxy_import('cloudpickle')
19
38
  _gzip = lang.proxy_import('gzip')
20
39
  _json = lang.proxy_import('json')
40
+ _lz4_frame = lang.proxy_import('lz4.frame')
21
41
  _lzma = lang.proxy_import('lzma')
22
42
  _pickle = lang.proxy_import('pickle')
43
+ _snappy = lang.proxy_import('snappy')
23
44
  _struct = lang.proxy_import('struct')
24
45
  _tomllib = lang.proxy_import('tomllib')
25
-
26
- _zstd = lang.proxy_import('zstd')
27
- _yaml = lang.proxy_import('yaml')
46
+ _yaml = lang.proxy_import('yaml')
47
+ _zstd = lang.proxy_import('zstd')
28
48
 
29
49
 
30
50
  ##
31
51
 
32
52
 
33
53
  F = ta.TypeVar('F')
54
+ F2 = ta.TypeVar('F2')
34
55
  T = ta.TypeVar('T')
56
+ T2 = ta.TypeVar('T2')
35
57
  U = ta.TypeVar('U')
36
58
 
37
59
 
@@ -44,6 +66,11 @@ class FnPair(ta.Generic[F, T], abc.ABC):
44
66
  def backward(self, t: T) -> F:
45
67
  raise NotImplementedError
46
68
 
69
+ ##
70
+
71
+ def __call__(self, f: F) -> T:
72
+ return self.forward(f)
73
+
47
74
  def invert(self) -> 'FnPair[T, F]':
48
75
  if isinstance(self, Inverted):
49
76
  return self.fp
@@ -76,6 +103,8 @@ Simple.__abstractmethods__ = frozenset() # noqa
76
103
 
77
104
  of = Simple
78
105
 
106
+ NOP: FnPair[ta.Any, ta.Any] = of(lang.identity, lang.identity)
107
+
79
108
 
80
109
  ##
81
110
 
@@ -91,9 +120,6 @@ class Inverted(FnPair[F, T]):
91
120
  return self.fp.forward(t)
92
121
 
93
122
 
94
- ##
95
-
96
-
97
123
  @dc.dataclass(frozen=True)
98
124
  class Composite(FnPair[F, T]):
99
125
  children: ta.Sequence[FnPair]
@@ -109,6 +135,14 @@ class Composite(FnPair[F, T]):
109
135
  return ta.cast(F, t)
110
136
 
111
137
 
138
+ def compose(*ps: FnPair) -> FnPair:
139
+ if not ps:
140
+ return NOP
141
+ if len(ps) == 1:
142
+ return ps[0]
143
+ return Composite(ps)
144
+
145
+
112
146
  ##
113
147
 
114
148
 
@@ -177,6 +211,10 @@ def _register_extension(*ss):
177
211
  return inner
178
212
 
179
213
 
214
+ def get_for_extension(ext: str) -> FnPair:
215
+ return compose(*[_EXTENSION_REGISTRY[p]() for p in ext.split('.')])
216
+
217
+
180
218
  ##
181
219
 
182
220
 
@@ -184,28 +222,28 @@ class Compression(FnPair[bytes, bytes], abc.ABC):
184
222
  pass
185
223
 
186
224
 
187
- @_register_extension('gz')
225
+ @_register_extension('bz2')
188
226
  @dc.dataclass(frozen=True)
189
- class Gzip(Compression):
227
+ class Bz2(Compression):
190
228
  compresslevel: int = 9
191
229
 
192
230
  def forward(self, f: bytes) -> bytes:
193
- return _gzip.compress(f, compresslevel=self.compresslevel)
231
+ return _bz2.compress(f, compresslevel=self.compresslevel)
194
232
 
195
233
  def backward(self, t: bytes) -> bytes:
196
- return _gzip.decompress(t)
234
+ return _bz2.decompress(t)
197
235
 
198
236
 
199
- @_register_extension('bz2')
237
+ @_register_extension('gz')
200
238
  @dc.dataclass(frozen=True)
201
- class Bzip2(Compression):
239
+ class Gzip(Compression):
202
240
  compresslevel: int = 9
203
241
 
204
242
  def forward(self, f: bytes) -> bytes:
205
- return _bzip2.compress(f, compresslevel=self.compresslevel)
243
+ return _gzip.compress(f, compresslevel=self.compresslevel)
206
244
 
207
245
  def backward(self, t: bytes) -> bytes:
208
- return _bzip2.decompress(t)
246
+ return _gzip.decompress(t)
209
247
 
210
248
 
211
249
  @_register_extension('lzma')
@@ -220,6 +258,27 @@ class Lzma(Compression):
220
258
  #
221
259
 
222
260
 
261
+ @_register_extension('lz4')
262
+ @dc.dataclass(frozen=True)
263
+ class Lz4(Compression):
264
+ compression_level: int = 0
265
+
266
+ def forward(self, f: bytes) -> bytes:
267
+ return _lz4_frame.compress(f, compression_level=self.compression_level)
268
+
269
+ def backward(self, t: bytes) -> bytes:
270
+ return _lz4_frame.decompress(t)
271
+
272
+
273
+ @_register_extension('snappy')
274
+ class Snappy(Compression):
275
+ def forward(self, f: bytes) -> bytes:
276
+ return _snappy.compress(f)
277
+
278
+ def backward(self, t: bytes) -> bytes:
279
+ return _snappy.decompress(t)
280
+
281
+
223
282
  @_register_extension('zstd')
224
283
  class Zstd(Compression):
225
284
  def forward(self, f: bytes) -> bytes:
@@ -243,9 +302,27 @@ class Struct(FnPair[tuple, bytes]):
243
302
  return _struct.unpack(self.fmt, t)
244
303
 
245
304
 
305
+ ##
306
+
307
+
308
+ class Object(FnPair[ta.Any, T], lang.Abstract): # noqa
309
+ pass
310
+
311
+
312
+ class ObjectStr(Object[str], lang.Abstract): # noqa
313
+ pass
314
+
315
+
316
+ class ObjectBytes(Object[bytes], lang.Abstract): # noqa
317
+ pass
318
+
319
+
320
+ #
321
+
322
+
246
323
  @_register_extension('pkl')
247
324
  @dc.dataclass(frozen=True)
248
- class Pickle(FnPair[ta.Any, bytes]):
325
+ class Pickle(ObjectBytes):
249
326
  protocol: int | None = None
250
327
 
251
328
  def forward(self, f: ta.Any) -> bytes:
@@ -257,7 +334,7 @@ class Pickle(FnPair[ta.Any, bytes]):
257
334
 
258
335
  @_register_extension('json')
259
336
  @dc.dataclass(frozen=True)
260
- class Json(FnPair[ta.Any, str]):
337
+ class Json(ObjectStr):
261
338
  indent: int | str | None = dc.field(default=None, kw_only=True)
262
339
  separators: tuple[str, str] | None = dc.field(default=None, kw_only=True)
263
340
 
@@ -283,7 +360,7 @@ class JsonLines(FnPair[ta.Sequence[ta.Any], str]):
283
360
 
284
361
 
285
362
  @_register_extension('toml')
286
- class Toml(FnPair[ta.Any, str]):
363
+ class Toml(ObjectStr):
287
364
  def forward(self, f: ta.Any) -> str:
288
365
  raise NotImplementedError
289
366
 
@@ -294,8 +371,20 @@ class Toml(FnPair[ta.Any, str]):
294
371
  #
295
372
 
296
373
 
374
+ @_register_extension('cpkl')
375
+ @dc.dataclass(frozen=True)
376
+ class Cloudpickle(ObjectBytes):
377
+ protocol: int | None = None
378
+
379
+ def forward(self, f: ta.Any) -> bytes:
380
+ return _cloudpickle.dumps(f, protocol=self.protocol)
381
+
382
+ def backward(self, t: bytes) -> ta.Any:
383
+ return _cloudpickle.loads(t)
384
+
385
+
297
386
  @_register_extension('yml', 'yaml')
298
- class Yaml(FnPair[ta.Any, str]):
387
+ class Yaml(ObjectStr):
299
388
  def forward(self, f: ta.Any) -> str:
300
389
  return _yaml.dump(f)
301
390
 
@@ -303,9 +392,9 @@ class Yaml(FnPair[ta.Any, str]):
303
392
  return _yaml.safe_load(t)
304
393
 
305
394
 
306
- class UnsafeYaml(FnPair[ta.Any, str]):
395
+ class YamlUnsafe(ObjectStr):
307
396
  def forward(self, f: ta.Any) -> str:
308
397
  return _yaml.dump(f)
309
398
 
310
399
  def backward(self, t: str) -> ta.Any:
311
- return _yaml.safe_load(t, loader=_yaml.FullLoader)
400
+ return _yaml.load(t, _yaml.FullLoader)
@@ -14,7 +14,7 @@ Element Types:
14
14
  - Overrides
15
15
  - Expose
16
16
  - Private
17
- - ScopeSeed
17
+ - ScopeBinding
18
18
  """
19
19
  import typing as ta
20
20
 
@@ -31,6 +31,7 @@ from ..overrides import Overrides
31
31
  from ..private import Expose
32
32
  from ..private import Private
33
33
  from ..scopes import ScopeBinding
34
+ from ..types import Scope
34
35
  from .bindings import BindingImpl
35
36
  from .providers import MultiProviderImpl
36
37
  from .providers import make_provider_impl
@@ -152,3 +153,14 @@ class ElementCollection(lang.Final):
152
153
  @lang.cached_function
153
154
  def binding_impl_map(self) -> ta.Mapping[Key, BindingImpl]:
154
155
  return self._build_binding_impl_map(self.element_multimap())
156
+
157
+ ##
158
+
159
+ @lang.cached_function
160
+ def eager_keys_by_scope(self) -> ta.Mapping[Scope, ta.Sequence[Key]]:
161
+ bim = self.binding_impl_map()
162
+ ret: dict[Scope, list[Key]] = {}
163
+ for e in self.elements_of_type(Eager):
164
+ bi = bim[e.key]
165
+ ret.setdefault(bi.scope, []).append(e.key)
166
+ return ret
@@ -7,6 +7,8 @@ TODO:
7
7
  - config is probably shared with ElementCollection... but not 'bound', must be shared everywhere
8
8
  - InjectorRoot object?
9
9
  - ** eagers in any scope, on scope init/open
10
+ - injection listeners
11
+ - unions - raise on ambiguous - usecase: sql.AsyncEngineLike
10
12
  """
11
13
  import contextlib
12
14
  import typing as ta
@@ -14,7 +16,6 @@ import weakref
14
16
 
15
17
  from ... import check
16
18
  from ... import lang
17
- from ..eagers import Eager
18
19
  from ..elements import Elements
19
20
  from ..exceptions import CyclicDependencyError
20
21
  from ..exceptions import UnboundKeyError
@@ -52,6 +53,7 @@ class InjectorImpl(Injector, lang.Final):
52
53
  }
53
54
 
54
55
  self._bim = ec.binding_impl_map()
56
+ self._ekbs = ec.eager_keys_by_scope()
55
57
 
56
58
  self._cs: weakref.WeakSet[InjectorImpl] | None = None
57
59
  self._root: InjectorImpl = p._root if p is not None else self # noqa
@@ -66,13 +68,13 @@ class InjectorImpl(Injector, lang.Final):
66
68
  s: make_scope_impl(s) for s in ss
67
69
  }
68
70
 
69
- self._instantiate_eagers()
71
+ self._instantiate_eagers(Unscoped())
70
72
 
71
73
  _root: 'InjectorImpl'
72
74
 
73
- def _instantiate_eagers(self) -> None:
74
- for e in self._ec.elements_of_type(Eager):
75
- self.provide(e.key)
75
+ def _instantiate_eagers(self, sc: Scope) -> None:
76
+ for k in self._ekbs.get(sc, ()):
77
+ self.provide(k)
76
78
 
77
79
  def get_scope_impl(self, sc: Scope) -> ScopeImpl:
78
80
  return self._scopes[sc]
@@ -141,8 +141,8 @@ class SeededScopeImpl(ScopeImpl):
141
141
  def __init__(self, ss: SeededScope, i: Injector) -> None:
142
142
  super().__init__()
143
143
  self._ss = check.isinstance(ss, SeededScope)
144
- ii = check.isinstance(i, injector_.InjectorImpl)
145
- self._ssi = check.isinstance(ii.get_scope_impl(self._ss), SeededScopeImpl)
144
+ self._ii = check.isinstance(i, injector_.InjectorImpl)
145
+ self._ssi = check.isinstance(self._ii.get_scope_impl(self._ss), SeededScopeImpl)
146
146
 
147
147
  @contextlib.contextmanager
148
148
  def __call__(self, seeds: ta.Mapping[Key, ta.Any]) -> ta.Generator[None, None, None]:
@@ -150,6 +150,7 @@ class SeededScopeImpl(ScopeImpl):
150
150
  if self._ssi._st is not None: # noqa
151
151
  raise ScopeAlreadyOpenError(self._ss)
152
152
  self._ssi._st = SeededScopeImpl.State(dict(seeds)) # noqa
153
+ self._ii._instantiate_eagers(self._ss) # noqa
153
154
  yield
154
155
  finally:
155
156
  if self._ssi._st is None: # noqa