loom-kernel 1.2.2__tar.gz → 1.4.0__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 (968) hide show
  1. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/CHANGELOG.md +124 -0
  2. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/PKG-INFO +1 -1
  3. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/etl/pipelines.md +15 -0
  4. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/getting-started/etl.md +1 -0
  5. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/guides/etl.md +16 -0
  6. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/pyproject.toml +2 -2
  7. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_merge.py +4 -4
  8. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_write_policy.py +53 -0
  9. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/_writer.py +59 -15
  10. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/spark/_writer.py +38 -5
  11. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/compiler/_errors.py +29 -10
  12. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/compiler/_validators_step.py +72 -15
  13. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/__init__.py +4 -0
  14. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_into.py +63 -1
  15. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_table.py +46 -0
  16. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/pipeline/_step.py +2 -2
  17. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/pipeline/_step_client.py +4 -2
  18. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/__init__.py +1 -1
  19. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/__init__.py +2 -2
  20. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_backfill.py +3 -1
  21. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_backfill_body.py +20 -2
  22. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/__init__.py +11 -0
  23. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/compiler/__init__.py +5 -0
  24. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/compiler/_bindings.py +30 -18
  25. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/compiler/_compiler.py +5 -2
  26. loom_kernel-1.4.0/src/loom/streaming/compiler/_errors.py +408 -0
  27. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/compiler/_plan.py +22 -5
  28. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/compiler/phases/build_plan.py +11 -8
  29. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/compiler/phases/validate.py +99 -115
  30. loom_kernel-1.4.0/tests/unit/etl/backends/test_polars/test_update_writer.py +166 -0
  31. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_write_policy_historify.py +10 -0
  32. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_file_template_validator.py +28 -0
  33. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_param_exprs_validator.py +42 -0
  34. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_upsert_validator.py +80 -0
  35. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/test_target.py +25 -1
  36. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/test_variants.py +16 -0
  37. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/pipeline/test_step.py +10 -1
  38. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_backfill_flow.py +56 -0
  39. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/cases.py +1 -1
  40. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_adapter.py +1 -1
  41. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_runtime_io.py +1 -1
  42. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_storage.py +1 -1
  43. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/test_basics.py +1 -2
  44. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/test_config_bindings.py +1 -2
  45. loom_kernel-1.4.0/tests/unit/streaming/compiler/test_error_codes.py +176 -0
  46. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/test_mongo_source.py +1 -1
  47. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/test_router.py +1 -2
  48. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/test_window.py +1 -2
  49. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/test_with.py +1 -2
  50. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/test_compiler_examples.py +1 -1
  51. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/mongo/test_bytewax_source.py +1 -1
  52. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/nodes/test_broadcast.py +1 -2
  53. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/uv.lock +1 -1
  54. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/.github/workflows/ci-main.yml +0 -0
  55. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/.github/workflows/ci-pr.yml +0 -0
  56. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/.github/workflows/docs.yml +0 -0
  57. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/.github/workflows/release.yml +0 -0
  58. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/.gitignore +0 -0
  59. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/.pre-commit-config.yaml +0 -0
  60. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/.readthedocs.yaml +0 -0
  61. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/LICENSE +0 -0
  62. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/Makefile +0 -0
  63. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/README.md +0 -0
  64. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/codecov.yml +0 -0
  65. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docker-compose.local.yaml +0 -0
  66. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/_static/.gitkeep +0 -0
  67. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/_static/custom.css +0 -0
  68. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/_static/logo-transparent.png +0 -0
  69. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/_static/logo.svg +0 -0
  70. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/architecture/adr/README.md +0 -0
  71. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/architecture/clean-architecture.md +0 -0
  72. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/architecture/overview.md +0 -0
  73. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/conf.py +0 -0
  74. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/etl/examples.md +0 -0
  75. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/etl/testing.md +0 -0
  76. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/examples-repo/index.md +0 -0
  77. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/getting-started/rest.md +0 -0
  78. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/getting-started/streaming.md +0 -0
  79. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/guides/autocrud.md +0 -0
  80. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/guides/celery.md +0 -0
  81. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/guides/fake-repo-examples.md +0 -0
  82. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/guides/quickstart.md +0 -0
  83. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/guides/use-case-dsl.md +0 -0
  84. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/index.rst +0 -0
  85. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/overview.md +0 -0
  86. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/reference/api/core.rst +0 -0
  87. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/reference/api/etl.rst +0 -0
  88. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/reference/api/repository.rst +0 -0
  89. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/reference/api/rest.rst +0 -0
  90. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/reference/api/streaming.rst +0 -0
  91. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/reference/api/testing.rst +0 -0
  92. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/reference/index.rst +0 -0
  93. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/requirements.txt +0 -0
  94. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/rest/autocrud.md +0 -0
  95. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/rest/celery.md +0 -0
  96. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/rest/examples.md +0 -0
  97. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/rest/identity.md +0 -0
  98. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/rest/sql.md +0 -0
  99. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/rest/testing.md +0 -0
  100. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/rest/use-case-dsl.md +0 -0
  101. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/docs/streaming/bytewax.md +0 -0
  102. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/scripts/release/checkout_merged_release.py +0 -0
  103. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/sonar-project.properties +0 -0
  104. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/__init__.py +0 -0
  105. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/celery/__init__.py +0 -0
  106. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/celery/auto.py +0 -0
  107. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/celery/bootstrap.py +0 -0
  108. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/celery/config.py +0 -0
  109. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/celery/constants.py +0 -0
  110. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/celery/runner.py +0 -0
  111. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/celery/service.py +0 -0
  112. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/async_bridge.py +0 -0
  113. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/backend/__init__.py +0 -0
  114. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/backend/core_model.py +0 -0
  115. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/backend/protocol.py +0 -0
  116. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/backend/sqlalchemy.py +0 -0
  117. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/bootstrap/__init__.py +0 -0
  118. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/bootstrap/bootstrap.py +0 -0
  119. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/bootstrap/kernel.py +0 -0
  120. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/__init__.py +0 -0
  121. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/abc/__init__.py +0 -0
  122. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/abc/backend.py +0 -0
  123. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/abc/config.py +0 -0
  124. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/abc/dependency.py +0 -0
  125. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/codec.py +0 -0
  126. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/decorators.py +0 -0
  127. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/dependency.py +0 -0
  128. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/gateway.py +0 -0
  129. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/keys.py +0 -0
  130. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/repository.py +0 -0
  131. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/cache/serializer.py +0 -0
  132. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/command/__init__.py +0 -0
  133. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/command/adapter.py +0 -0
  134. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/command/base.py +0 -0
  135. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/command/field.py +0 -0
  136. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/command/introspection.py +0 -0
  137. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/compiler.py +0 -0
  138. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/__init__.py +0 -0
  139. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/_resolver_utils.py +0 -0
  140. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/binder.py +0 -0
  141. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/configurable.py +0 -0
  142. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/context.py +0 -0
  143. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/errors.py +0 -0
  144. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/keys.py +0 -0
  145. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/loader.py +0 -0
  146. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/model.py +0 -0
  147. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/observability.py +0 -0
  148. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/resolver.py +0 -0
  149. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/secrets.py +0 -0
  150. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/config/ssm.py +0 -0
  151. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/contracts/__init__.py +0 -0
  152. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/contracts/manifest.py +0 -0
  153. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/di/__init__.py +0 -0
  154. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/di/container.py +0 -0
  155. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/di/scope.py +0 -0
  156. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/discovery/__init__.py +0 -0
  157. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/discovery/_utils.py +0 -0
  158. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/discovery/base.py +0 -0
  159. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/discovery/interfaces.py +0 -0
  160. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/discovery/manifest.py +0 -0
  161. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/discovery/modules.py +0 -0
  162. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/engine/__init__.py +0 -0
  163. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/engine/compilable.py +0 -0
  164. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/engine/compiler.py +0 -0
  165. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/engine/events.py +0 -0
  166. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/engine/executor.py +0 -0
  167. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/engine/metrics.py +0 -0
  168. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/engine/plan.py +0 -0
  169. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/errors/__init__.py +0 -0
  170. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/errors/codes.py +0 -0
  171. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/errors/errors.py +0 -0
  172. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/expr/__init__.py +0 -0
  173. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/expr/eval.py +0 -0
  174. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/expr/nodes.py +0 -0
  175. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/expr/refs.py +0 -0
  176. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/identity/__init__.py +0 -0
  177. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/identity/context.py +0 -0
  178. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/identity/identity.py +0 -0
  179. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/identity/issuer.py +0 -0
  180. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/identity/wire.py +0 -0
  181. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/job/__init__.py +0 -0
  182. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/job/callback.py +0 -0
  183. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/job/context.py +0 -0
  184. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/job/handle.py +0 -0
  185. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/job/job.py +0 -0
  186. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/job/service.py +0 -0
  187. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/logger/__init__.py +0 -0
  188. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/logger/abc.py +0 -0
  189. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/logger/config.py +0 -0
  190. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/logger/registry.py +0 -0
  191. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/logger/structlogger.py +0 -0
  192. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/__init__.py +0 -0
  193. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/base.py +0 -0
  194. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/enums.py +0 -0
  195. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/field.py +0 -0
  196. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/introspection.py +0 -0
  197. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/projection.py +0 -0
  198. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/relation.py +0 -0
  199. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/struct.py +0 -0
  200. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/timestamped.py +0 -0
  201. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/types.py +0 -0
  202. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/model/types_postgres.py +0 -0
  203. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/__init__.py +0 -0
  204. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/config.py +0 -0
  205. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/event.py +0 -0
  206. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/observer/__init__.py +0 -0
  207. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/observer/noop.py +0 -0
  208. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/observer/otel.py +0 -0
  209. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/observer/structlog.py +0 -0
  210. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/protocol.py +0 -0
  211. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/runtime.py +0 -0
  212. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/observability/topology.py +0 -0
  213. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/projection/__init__.py +0 -0
  214. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/projection/loaders.py +0 -0
  215. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/projection/runtime.py +0 -0
  216. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/__init__.py +0 -0
  217. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/abc/__init__.py +0 -0
  218. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/abc/query.py +0 -0
  219. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/abc/repo_for.py +0 -0
  220. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/abc/repository.py +0 -0
  221. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/dynamodb/__init__.py +0 -0
  222. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/dynamodb/registry.py +0 -0
  223. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/dynamodb/repository.py +0 -0
  224. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/dynamodb/uow.py +0 -0
  225. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/mutation.py +0 -0
  226. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/registration.py +0 -0
  227. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/registry.py +0 -0
  228. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/__init__.py +0 -0
  229. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/integrity.py +0 -0
  230. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/loaders.py +0 -0
  231. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/mixins.py +0 -0
  232. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/model.py +0 -0
  233. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/profile_loader.py +0 -0
  234. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/projection.py +0 -0
  235. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/__init__.py +0 -0
  236. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/compiler.py +0 -0
  237. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/cursor.py +0 -0
  238. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/errors.py +0 -0
  239. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/filters.py +0 -0
  240. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/ordering.py +0 -0
  241. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/paths.py +0 -0
  242. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/query_compiler/subquery.py +0 -0
  243. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/registry.py +0 -0
  244. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/repository.py +0 -0
  245. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/session_manager.py +0 -0
  246. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/transactional.py +0 -0
  247. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/repository/sqlalchemy/uow.py +0 -0
  248. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/response/__init__.py +0 -0
  249. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/response/base.py +0 -0
  250. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/routing/__init__.py +0 -0
  251. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/routing/ref.py +0 -0
  252. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/routing/resolver.py +0 -0
  253. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/runner.py +0 -0
  254. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/schema/__init__.py +0 -0
  255. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/schema/schema_mode.py +0 -0
  256. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/__init__.py +0 -0
  257. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/abc/__init__.py +0 -0
  258. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/abc/contracts.py +0 -0
  259. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/abc/errors.py +0 -0
  260. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/clickhouse/__init__.py +0 -0
  261. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/clickhouse/_client.py +0 -0
  262. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/clickhouse/executor.py +0 -0
  263. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/clickhouse/registry.py +0 -0
  264. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/config.py +0 -0
  265. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/sql/service.py +0 -0
  266. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/tracing/__init__.py +0 -0
  267. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/tracing/context.py +0 -0
  268. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/transport/__init__.py +0 -0
  269. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/transport/adapter.py +0 -0
  270. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/uow/__init__.py +0 -0
  271. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/uow/abc.py +0 -0
  272. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/uow/context.py +0 -0
  273. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/__init__.py +0 -0
  274. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/_predicates.py +0 -0
  275. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/compute.py +0 -0
  276. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/constants.py +0 -0
  277. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/factory.py +0 -0
  278. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/field_ref.py +0 -0
  279. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/invoker.py +0 -0
  280. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/keys.py +0 -0
  281. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/markers.py +0 -0
  282. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/registry.py +0 -0
  283. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/rule.py +0 -0
  284. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/core/use_case/use_case.py +0 -0
  285. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/__init__.py +0 -0
  286. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/__init__.py +0 -0
  287. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_format_registry.py +0 -0
  288. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_historify/__init__.py +0 -0
  289. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_historify/_common.py +0 -0
  290. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_historify/_log.py +0 -0
  291. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_historify/_ops.py +0 -0
  292. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_historify/_snapshot.py +0 -0
  293. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_historify/_transform.py +0 -0
  294. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_path_template.py +0 -0
  295. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_predicate.py +0 -0
  296. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_schema_aligner/__init__.py +0 -0
  297. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_schema_aligner/_aligner.py +0 -0
  298. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/_schema_aligner/_policy.py +0 -0
  299. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/__init__.py +0 -0
  300. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/_dtype.py +0 -0
  301. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/_file_writer.py +0 -0
  302. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/_historify.py +0 -0
  303. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/_predicate.py +0 -0
  304. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/_reader.py +0 -0
  305. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/_schema.py +0 -0
  306. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/_schema_aligner.py +0 -0
  307. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/_streaming.py +0 -0
  308. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/polars/provider.py +0 -0
  309. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/spark/__init__.py +0 -0
  310. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/spark/_dtype.py +0 -0
  311. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/spark/_historify.py +0 -0
  312. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/spark/_reader.py +0 -0
  313. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/spark/_schema.py +0 -0
  314. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/spark/_schema_aligner.py +0 -0
  315. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/backends/spark/provider.py +0 -0
  316. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/checkpoint/__init__.py +0 -0
  317. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/checkpoint/_backends/_polars.py +0 -0
  318. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/checkpoint/_backends/_spark.py +0 -0
  319. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/checkpoint/_cleaners.py +0 -0
  320. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/checkpoint/_paths.py +0 -0
  321. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/checkpoint/_scope.py +0 -0
  322. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/checkpoint/_store.py +0 -0
  323. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/compiler/__init__.py +0 -0
  324. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/compiler/_binding.py +0 -0
  325. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/compiler/_compiler.py +0 -0
  326. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/compiler/_plan.py +0 -0
  327. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/compiler/_validators.py +0 -0
  328. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/compiler/_validators_plan.py +0 -0
  329. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/__init__.py +0 -0
  330. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/_format.py +0 -0
  331. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/_read_options.py +0 -0
  332. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/_utils.py +0 -0
  333. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/_write_options.py +0 -0
  334. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/expr/__init__.py +0 -0
  335. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/expr/_params.py +0 -0
  336. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/expr/_predicate.py +0 -0
  337. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/expr/_predicate_dialect.py +0 -0
  338. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/expr/_refs.py +0 -0
  339. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/source/__init__.py +0 -0
  340. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/source/_from.py +0 -0
  341. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/source/_from_clickhouse.py +0 -0
  342. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/source/_from_dynamodb.py +0 -0
  343. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/source/_from_mongo.py +0 -0
  344. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/source/_specs.py +0 -0
  345. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_client.py +0 -0
  346. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_file.py +0 -0
  347. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_history/__init__.py +0 -0
  348. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_history/_builder.py +0 -0
  349. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_history/_enums.py +0 -0
  350. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_history/_errors.py +0 -0
  351. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_history/_report.py +0 -0
  352. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_history/_spec.py +0 -0
  353. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_schema_mode.py +0 -0
  354. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/declarative/target/_temp.py +0 -0
  355. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/executor/__init__.py +0 -0
  356. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/executor/_dispatcher.py +0 -0
  357. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/executor/_executor.py +0 -0
  358. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/__init__.py +0 -0
  359. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/_registry.py +0 -0
  360. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/__init__.py +0 -0
  361. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/_clickhouse.py +0 -0
  362. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/_dynamodb.py +0 -0
  363. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/_dynamodb_items.py +0 -0
  364. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/_dynamodb_predicate.py +0 -0
  365. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/_mongo.py +0 -0
  366. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/_mongo_batch.py +0 -0
  367. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/_mongo_bson.py +0 -0
  368. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/_mongo_predicate.py +0 -0
  369. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/sources/_serialization.py +0 -0
  370. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/targets/__init__.py +0 -0
  371. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/io/targets/_clickhouse.py +0 -0
  372. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/lineage/__init__.py +0 -0
  373. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/lineage/_config.py +0 -0
  374. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/lineage/_observer.py +0 -0
  375. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/lineage/_records.py +0 -0
  376. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/lineage/sinks/__init__.py +0 -0
  377. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/lineage/sinks/_protocol.py +0 -0
  378. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/lineage/sinks/_table.py +0 -0
  379. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/lineage/sinks/_writer.py +0 -0
  380. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/maintenance/__init__.py +0 -0
  381. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/maintenance/_builder.py +0 -0
  382. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/maintenance/_ops.py +0 -0
  383. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/maintenance/_protocol.py +0 -0
  384. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/maintenance/_runner.py +0 -0
  385. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/maintenance/_step.py +0 -0
  386. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/maintenance/backends/__init__.py +0 -0
  387. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/maintenance/backends/_delta_rs.py +0 -0
  388. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/pipeline/__init__.py +0 -0
  389. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/pipeline/_generics.py +0 -0
  390. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/pipeline/_params.py +0 -0
  391. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/pipeline/_pipeline.py +0 -0
  392. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/pipeline/_process.py +0 -0
  393. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/pipeline/_sql.py +0 -0
  394. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/pipeline/_step_sql.py +0 -0
  395. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/runner/__init__.py +0 -0
  396. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/runner/_providers.py +0 -0
  397. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/runner/_wiring.py +0 -0
  398. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/runner/config_loader.py +0 -0
  399. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/runner/core.py +0 -0
  400. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/runner/errors.py +0 -0
  401. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/runner/filtering.py +0 -0
  402. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/runtime/__init__.py +0 -0
  403. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/runtime/contracts.py +0 -0
  404. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/schema/__init__.py +0 -0
  405. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/schema/_contract.py +0 -0
  406. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/schema/_schema.py +0 -0
  407. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/storage/__init__.py +0 -0
  408. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/storage/_config.py +0 -0
  409. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/storage/_file_locator.py +0 -0
  410. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/storage/_locator.py +0 -0
  411. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/storage/routing.py +0 -0
  412. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/testing/__init__.py +0 -0
  413. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/testing/_result.py +0 -0
  414. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/testing/_runners.py +0 -0
  415. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/testing/_scenario.py +0 -0
  416. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/testing/_stubs.py +0 -0
  417. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/etl/testing/spark.py +0 -0
  418. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/_async.py +0 -0
  419. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/_config.py +0 -0
  420. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/_ctx.py +0 -0
  421. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/_meta.py +0 -0
  422. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/_placeholders.py +0 -0
  423. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/_summary.py +0 -0
  424. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/deploy/__init__.py +0 -0
  425. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/deploy/_discovery.py +0 -0
  426. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/deploy/_schedule.py +0 -0
  427. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/deploy/_yaml.py +0 -0
  428. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_assemble.py +0 -0
  429. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_body.py +0 -0
  430. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_common.py +0 -0
  431. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_factory.py +0 -0
  432. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_hooks.py +0 -0
  433. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_maintenance.py +0 -0
  434. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_run_name.py +0 -0
  435. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_runtime.py +0 -0
  436. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_signature.py +0 -0
  437. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/flow/_stages.py +0 -0
  438. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/manifest/__init__.py +0 -0
  439. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/manifest/_model.py +0 -0
  440. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/manifest/_s3.py +0 -0
  441. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/manifest/_store.py +0 -0
  442. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/notify/__init__.py +0 -0
  443. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/notify/_event.py +0 -0
  444. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/notify/_factory.py +0 -0
  445. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/notify/_port.py +0 -0
  446. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/notify/_slack.py +0 -0
  447. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/observer/__init__.py +0 -0
  448. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/observer/_flow.py +0 -0
  449. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/observer/_logging_bridge.py +0 -0
  450. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/observer/_manifest.py +0 -0
  451. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prefect/observer/_task_run.py +0 -0
  452. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prometheus/__init__.py +0 -0
  453. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prometheus/adapter.py +0 -0
  454. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prometheus/kafka.py +0 -0
  455. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prometheus/lifecycle.py +0 -0
  456. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/prometheus/middleware.py +0 -0
  457. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/py.typed +0 -0
  458. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/__init__.py +0 -0
  459. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/_body.py +0 -0
  460. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/adapter.py +0 -0
  461. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/auth/__init__.py +0 -0
  462. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/auth/abc.py +0 -0
  463. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/auth/config.py +0 -0
  464. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/auth/jwt.py +0 -0
  465. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/auth/middleware.py +0 -0
  466. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/autocrud.py +0 -0
  467. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/compiler.py +0 -0
  468. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/constants.py +0 -0
  469. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/cors.py +0 -0
  470. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/errors.py +0 -0
  471. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/__init__.py +0 -0
  472. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/_errors.py +0 -0
  473. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/_exclusions.py +0 -0
  474. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/_sql_roles.py +0 -0
  475. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/app.py +0 -0
  476. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/auto.py +0 -0
  477. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/openapi.py +0 -0
  478. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/response.py +0 -0
  479. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/router_runtime.py +0 -0
  480. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/fastapi/sql.py +0 -0
  481. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/middleware.py +0 -0
  482. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/model.py +0 -0
  483. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/rest/rest_adapter.py +0 -0
  484. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/__init__.py +0 -0
  485. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/_adapter.py +0 -0
  486. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/_commit_tracker.py +0 -0
  487. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/_dlq.py +0 -0
  488. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/_error_boundary.py +0 -0
  489. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/_operators.py +0 -0
  490. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/_resource_manager.py +0 -0
  491. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/_runtime_io.py +0 -0
  492. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/_sink_registry.py +0 -0
  493. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/handlers/__init__.py +0 -0
  494. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/handlers/_shared.py +0 -0
  495. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/handlers/boundary.py +0 -0
  496. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/handlers/dispatcher.py +0 -0
  497. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/handlers/routing.py +0 -0
  498. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/handlers/scopes.py +0 -0
  499. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/handlers/shapes.py +0 -0
  500. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/handlers/steps.py +0 -0
  501. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/handlers/storage.py +0 -0
  502. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/bytewax/runner.py +0 -0
  503. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/core/__init__.py +0 -0
  504. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/core/_errors.py +0 -0
  505. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/core/_exceptions.py +0 -0
  506. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/core/_message.py +0 -0
  507. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/core/_typing.py +0 -0
  508. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/graph/__init__.py +0 -0
  509. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/graph/_flow.py +0 -0
  510. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/__init__.py +0 -0
  511. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/_codec.py +0 -0
  512. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/_config.py +0 -0
  513. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/_errors.py +0 -0
  514. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/_key_resolver.py +0 -0
  515. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/_message.py +0 -0
  516. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/_record.py +0 -0
  517. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/_wire.py +0 -0
  518. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/client/__init__.py +0 -0
  519. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/client/_consumer.py +0 -0
  520. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/client/_producer.py +0 -0
  521. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/client/_protocol.py +0 -0
  522. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/message/__init__.py +0 -0
  523. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/message/_consumer.py +0 -0
  524. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/message/_producer.py +0 -0
  525. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/kafka/message/_protocol.py +0 -0
  526. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/mongo/__init__.py +0 -0
  527. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/mongo/_bytewax_source.py +0 -0
  528. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/mongo/_config.py +0 -0
  529. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/mongo/_event.py +0 -0
  530. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/mongo/_normalize.py +0 -0
  531. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/__init__.py +0 -0
  532. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_boundary.py +0 -0
  533. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_broadcast.py +0 -0
  534. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_capabilities.py +0 -0
  535. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_decompose.py +0 -0
  536. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_expand_routes.py +0 -0
  537. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_expr_eval.py +0 -0
  538. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_fork.py +0 -0
  539. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_helpers.py +0 -0
  540. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_mongo.py +0 -0
  541. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_protocols.py +0 -0
  542. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_router.py +0 -0
  543. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_shape.py +0 -0
  544. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_sink.py +0 -0
  545. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_step.py +0 -0
  546. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_table/__init__.py +0 -0
  547. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_table/common.py +0 -0
  548. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_table/config.py +0 -0
  549. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/_with.py +0 -0
  550. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/nodes/refs.py +0 -0
  551. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/streaming/testing.py +0 -0
  552. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/testing/__init__.py +0 -0
  553. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/testing/golden.py +0 -0
  554. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/testing/http_harness.py +0 -0
  555. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/testing/in_memory.py +0 -0
  556. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/testing/repository_harness.py +0 -0
  557. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/src/loom/testing/runner.py +0 -0
  558. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/__init__.py +0 -0
  559. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/conftest.py +0 -0
  560. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/golden/__init__.py +0 -0
  561. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/golden/baselines/.gitkeep +0 -0
  562. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/golden/outputs/.gitkeep +0 -0
  563. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/golden/plans/.gitkeep +0 -0
  564. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/helpers/__init__.py +0 -0
  565. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/__init__.py +0 -0
  566. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/celery_bootstrap/__init__.py +0 -0
  567. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/celery_bootstrap/config/conf.celery.integration.yaml +0 -0
  568. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/celery_bootstrap/test_auto_create_app_integration.py +0 -0
  569. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/celery_bootstrap/test_bootstrap_worker.py +0 -0
  570. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/conftest.py +0 -0
  571. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/__init__.py +0 -0
  572. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/bootstrap/__init__.py +0 -0
  573. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/bootstrap/test_bootstrap_integration.py +0 -0
  574. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/repository/__init__.py +0 -0
  575. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/repository/sqlalchemy/__init__.py +0 -0
  576. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/repository/sqlalchemy/conftest.py +0 -0
  577. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/repository/sqlalchemy/test_cache_integration.py +0 -0
  578. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/repository/sqlalchemy/test_repository_integration.py +0 -0
  579. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/rest/__init__.py +0 -0
  580. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/rest/test_auto_interface_integration.py +0 -0
  581. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/rest/test_fastapi_app_integration.py +0 -0
  582. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/rest/test_rest_error_mapping.py +0 -0
  583. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/rest/test_rest_observability.py +0 -0
  584. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/use_case/__init__.py +0 -0
  585. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/use_case/test_custom_repository_integration.py +0 -0
  586. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/core/use_case/test_use_case_crud_integration.py +0 -0
  587. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/etl/__init__.py +0 -0
  588. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/etl/test_runner_integration.py +0 -0
  589. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/__init__.py +0 -0
  590. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/config/__init__.py +0 -0
  591. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/config/conf.interfaces.yaml +0 -0
  592. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/config/conf.manifest.yaml +0 -0
  593. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/config/conf.modules.yaml +0 -0
  594. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/config/conf.yaml +0 -0
  595. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/main.py +0 -0
  596. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/manifest.py +0 -0
  597. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/__init__.py +0 -0
  598. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/category/__init__.py +0 -0
  599. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/category/model.py +0 -0
  600. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/category/schemas.py +0 -0
  601. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/interface.py +0 -0
  602. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/jobs.py +0 -0
  603. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/model.py +0 -0
  604. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/relations.py +0 -0
  605. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/repository.py +0 -0
  606. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/repository_contract.py +0 -0
  607. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/review/__init__.py +0 -0
  608. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/review/model.py +0 -0
  609. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/review/schemas.py +0 -0
  610. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/schemas.py +0 -0
  611. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/fake_repo/product/use_cases.py +0 -0
  612. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/sql/__init__.py +0 -0
  613. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/sql/init/01_users_roles.sql +0 -0
  614. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/sql/test_clickhouse_integration.py +0 -0
  615. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/streaming/__init__.py +0 -0
  616. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/streaming/test_into_table_integration.py +0 -0
  617. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/support/__init__.py +0 -0
  618. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/integration/support/logical_repo_fixtures.py +0 -0
  619. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/__init__.py +0 -0
  620. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/celery_bootstrap/__init__.py +0 -0
  621. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/celery_bootstrap/test_async_runtime.py +0 -0
  622. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/celery_bootstrap/test_bootstrap.py +0 -0
  623. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/celery_jobs/__init__.py +0 -0
  624. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/celery_jobs/test_auto.py +0 -0
  625. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/celery_jobs/test_celery_service.py +0 -0
  626. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/celery_jobs/test_config.py +0 -0
  627. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/celery_jobs/test_identity_propagation.py +0 -0
  628. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/celery_jobs/test_runner.py +0 -0
  629. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/ci/test_workflow_supply_chain_contract.py +0 -0
  630. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/__init__.py +0 -0
  631. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/backend/__init__.py +0 -0
  632. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/backend/test_backend_compiler.py +0 -0
  633. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/bootstrap/__init__.py +0 -0
  634. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/bootstrap/test_bootstrap.py +0 -0
  635. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/bootstrap/test_bootstrap_metrics.py +0 -0
  636. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/bootstrap/test_kernel.py +0 -0
  637. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/cache/__init__.py +0 -0
  638. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/cache/test_cached_repository.py +0 -0
  639. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/cache/test_config_wiring.py +0 -0
  640. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/cache/test_gateway_config.py +0 -0
  641. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/command/__init__.py +0 -0
  642. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/command/test_command_base.py +0 -0
  643. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/command/test_command_field.py +0 -0
  644. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/command/test_command_patch.py +0 -0
  645. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/command/test_introspection.py +0 -0
  646. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/config/__init__.py +0 -0
  647. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/config/test_binder.py +0 -0
  648. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/config/test_config.py +0 -0
  649. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/config/test_configurable.py +0 -0
  650. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/config/test_context.py +0 -0
  651. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/config/test_resolver_utils.py +0 -0
  652. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/config/test_secrets.py +0 -0
  653. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/config/test_ssm.py +0 -0
  654. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/di/__init__.py +0 -0
  655. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/di/test_container.py +0 -0
  656. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/discovery/__init__.py +0 -0
  657. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/discovery/test_manifest.py +0 -0
  658. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/engine/__init__.py +0 -0
  659. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/engine/test_caller_binding.py +0 -0
  660. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/engine/test_compiler.py +0 -0
  661. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/engine/test_executor.py +0 -0
  662. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/engine/test_executor_trace.py +0 -0
  663. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/engine/test_executor_uow.py +0 -0
  664. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/engine/test_metrics.py +0 -0
  665. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/engine/test_plan.py +0 -0
  666. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/errors/__init__.py +0 -0
  667. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/errors/test_errors.py +0 -0
  668. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/expr/__init__.py +0 -0
  669. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/expr/test_expr.py +0 -0
  670. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/identity/__init__.py +0 -0
  671. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/identity/test_context.py +0 -0
  672. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/identity/test_identity.py +0 -0
  673. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/identity/test_wire.py +0 -0
  674. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/job/__init__.py +0 -0
  675. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/job/conftest.py +0 -0
  676. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/job/test_callback.py +0 -0
  677. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/job/test_context.py +0 -0
  678. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/job/test_handle.py +0 -0
  679. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/job/test_inline_service.py +0 -0
  680. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/job/test_job.py +0 -0
  681. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/logger/__init__.py +0 -0
  682. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/logger/test_config.py +0 -0
  683. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/logger/test_registry.py +0 -0
  684. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/model/__init__.py +0 -0
  685. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/model/test_model.py +0 -0
  686. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/model/test_struct.py +0 -0
  687. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/model/test_timestamped.py +0 -0
  688. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/observability/__init__.py +0 -0
  689. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/observability/test_observers.py +0 -0
  690. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/observability/test_runtime.py +0 -0
  691. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/projection/__init__.py +0 -0
  692. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/projection/test_runtime.py +0 -0
  693. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/__init__.py +0 -0
  694. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/abc/__init__.py +0 -0
  695. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/abc/conftest.py +0 -0
  696. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/abc/test_query.py +0 -0
  697. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/abc/test_repository_contract.py +0 -0
  698. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/dynamodb/__init__.py +0 -0
  699. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/dynamodb/conftest.py +0 -0
  700. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/dynamodb/test_registry.py +0 -0
  701. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/dynamodb/test_repository.py +0 -0
  702. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/sqlalchemy/__init__.py +0 -0
  703. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/sqlalchemy/conftest.py +0 -0
  704. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/sqlalchemy/test_loaders.py +0 -0
  705. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/sqlalchemy/test_repository.py +0 -0
  706. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/repository/sqlalchemy/test_transactional.py +0 -0
  707. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/routing/__init__.py +0 -0
  708. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/routing/test_routing.py +0 -0
  709. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/__init__.py +0 -0
  710. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/_fakes.py +0 -0
  711. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/conftest.py +0 -0
  712. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/test_clickhouse_executor.py +0 -0
  713. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/test_clickhouse_transport.py +0 -0
  714. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/test_config.py +0 -0
  715. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/test_isolation.py +0 -0
  716. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/test_null_service.py +0 -0
  717. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/test_pagination_limits.py +0 -0
  718. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/test_registry_lifecycle.py +0 -0
  719. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/sql/test_role_policy.py +0 -0
  720. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/test_async_bridge.py +0 -0
  721. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/test_compiler_contracts.py +0 -0
  722. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/test_runner_contracts.py +0 -0
  723. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/tracing/__init__.py +0 -0
  724. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/tracing/test_context.py +0 -0
  725. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/uow/__init__.py +0 -0
  726. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/uow/test_executor_uow.py +0 -0
  727. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/uow/test_sqlalchemy_uow.py +0 -0
  728. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/uow/test_uow_protocols.py +0 -0
  729. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/use_case/__init__.py +0 -0
  730. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/use_case/test_compute.py +0 -0
  731. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/use_case/test_factory.py +0 -0
  732. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/use_case/test_field_ref.py +0 -0
  733. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/use_case/test_invoker.py +0 -0
  734. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/use_case/test_markers.py +0 -0
  735. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/use_case/test_rule.py +0 -0
  736. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/core/use_case/test_use_case.py +0 -0
  737. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/__init__.py +0 -0
  738. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/__init__.py +0 -0
  739. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/_historify_contract.py +0 -0
  740. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_empty_write_warning.py +0 -0
  741. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_historify_common.py +0 -0
  742. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_path_template.py +0 -0
  743. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/__init__.py +0 -0
  744. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/conftest.py +0 -0
  745. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_apply_schema.py +0 -0
  746. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_backend.py +0 -0
  747. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_dtype.py +0 -0
  748. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_file_writer.py +0 -0
  749. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_historify_polars.py +0 -0
  750. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_predicate_pushdown.py +0 -0
  751. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_reader_columns.py +0 -0
  752. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_reader_json_columns.py +0 -0
  753. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_step_execution.py +0 -0
  754. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_streaming_write.py +0 -0
  755. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_upsert_writer.py +0 -0
  756. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_writer_null_schema.py +0 -0
  757. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_polars/test_writer_to_frame.py +0 -0
  758. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_spark/__init__.py +0 -0
  759. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_spark/conftest.py +0 -0
  760. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_spark/test_dtype.py +0 -0
  761. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_spark/test_historify_spark.py +0 -0
  762. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_spark/test_spark_apply_schema.py +0 -0
  763. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_spark/test_step_execution.py +0 -0
  764. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/backends/test_spark/test_writer_to_frame.py +0 -0
  765. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/checkpoint/__init__.py +0 -0
  766. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/checkpoint/backends/__init__.py +0 -0
  767. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/checkpoint/backends/test_checkpoint_polars.py +0 -0
  768. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/checkpoint/test_checkpoint_paths.py +0 -0
  769. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/checkpoint/test_cleaners.py +0 -0
  770. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/checkpoint/test_store.py +0 -0
  771. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/client_step/__init__.py +0 -0
  772. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/client_step/test_client_step.py +0 -0
  773. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/__init__.py +0 -0
  774. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_catalog_validator.py +0 -0
  775. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_compiler.py +0 -0
  776. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_compiler_catalog.py +0 -0
  777. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_compiler_upsert.py +0 -0
  778. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_errors.py +0 -0
  779. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_errors_additional_factories.py +0 -0
  780. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_errors_runtime_factories.py +0 -0
  781. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_historify_validator.py +0 -0
  782. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_plan_traversal.py +0 -0
  783. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_step_validator.py +0 -0
  784. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_structural.py +0 -0
  785. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/compiler/test_temp_validator.py +0 -0
  786. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/conftest.py +0 -0
  787. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/__init__.py +0 -0
  788. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/__init__.py +0 -0
  789. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/test_clickhouse_reader.py +0 -0
  790. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/test_dynamodb_predicate.py +0 -0
  791. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/test_dynamodb_reader.py +0 -0
  792. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/test_from_clickhouse.py +0 -0
  793. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/test_from_dynamodb.py +0 -0
  794. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/test_from_mongo.py +0 -0
  795. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/test_mongo_predicate.py +0 -0
  796. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/test_mongo_reader.py +0 -0
  797. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/sources/test_mongo_reader_memory.py +0 -0
  798. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/targets/__init__.py +0 -0
  799. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/targets/test_clickhouse_writer.py +0 -0
  800. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/targets/test_into_clickhouse.py +0 -0
  801. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/test_history_target.py +0 -0
  802. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/test_registry.py +0 -0
  803. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/test_source.py +0 -0
  804. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/test_source_json.py +0 -0
  805. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/test_source_options.py +0 -0
  806. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/io/test_utils.py +0 -0
  807. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/lineage/test_observer.py +0 -0
  808. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/lineage/test_records.py +0 -0
  809. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/lineage/test_store.py +0 -0
  810. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/maintenance/__init__.py +0 -0
  811. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/maintenance/backends/__init__.py +0 -0
  812. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/maintenance/backends/test_delta_rs.py +0 -0
  813. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/maintenance/conftest.py +0 -0
  814. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/maintenance/test_builder.py +0 -0
  815. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/maintenance/test_runner.py +0 -0
  816. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/maintenance/test_step.py +0 -0
  817. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/pipeline/__init__.py +0 -0
  818. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/pipeline/test_pipeline_process.py +0 -0
  819. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/pipeline/test_proxy.py +0 -0
  820. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/schema/__init__.py +0 -0
  821. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/schema/test_contract.py +0 -0
  822. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/schema/test_schema.py +0 -0
  823. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/schema/test_table.py +0 -0
  824. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/sql/__init__.py +0 -0
  825. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/sql/test_merge.py +0 -0
  826. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/sql/test_predicate.py +0 -0
  827. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/sql/test_predicate_dialect.py +0 -0
  828. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/sql/test_sql_runtime.py +0 -0
  829. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/storage/__init__.py +0 -0
  830. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/storage/test_backend_factory.py +0 -0
  831. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/storage/test_io_protocols.py +0 -0
  832. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/storage/test_locator.py +0 -0
  833. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/storage/test_observability_and_protocols.py +0 -0
  834. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/storage/test_route_build.py +0 -0
  835. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/storage/test_schema_readers.py +0 -0
  836. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/storage/test_storage_config.py +0 -0
  837. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/test_config_loader.py +0 -0
  838. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/test_executor.py +0 -0
  839. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/test_format_registry.py +0 -0
  840. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/test_module_contracts.py +0 -0
  841. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/test_public_api_discovery.py +0 -0
  842. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/test_record_schema_coverage.py +0 -0
  843. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/test_runner.py +0 -0
  844. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/test_runner_errors.py +0 -0
  845. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/test_spark_testing.py +0 -0
  846. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/testing/__init__.py +0 -0
  847. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/testing/test_runners.py +0 -0
  848. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/testing/test_scenario_and_stubs.py +0 -0
  849. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/etl/testing/test_spark_helpers.py +0 -0
  850. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/__init__.py +0 -0
  851. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_config.py +0 -0
  852. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_ctx.py +0 -0
  853. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_etl_flow.py +0 -0
  854. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_logging_bridge.py +0 -0
  855. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_maintenance_flow.py +0 -0
  856. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_manifest.py +0 -0
  857. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_manifest_s3.py +0 -0
  858. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_notify.py +0 -0
  859. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_observer.py +0 -0
  860. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_placeholders.py +0 -0
  861. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_task_run_observer.py +0 -0
  862. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prefect/test_yaml_loader.py +0 -0
  863. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prometheus/__init__.py +0 -0
  864. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prometheus/test_adapter.py +0 -0
  865. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/prometheus/test_middleware.py +0 -0
  866. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/release/test_checkout_merged_release.py +0 -0
  867. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/release/test_release_workflow_contract.py +0 -0
  868. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/__init__.py +0 -0
  869. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/_fixture_app.py +0 -0
  870. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_app_hardening.py +0 -0
  871. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_auth_middleware.py +0 -0
  872. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_auth_rejection_logging.py +0 -0
  873. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_autocrud.py +0 -0
  874. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_cors.py +0 -0
  875. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_fastapi_auto_logger.py +0 -0
  876. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_fastapi_auto_persistence.py +0 -0
  877. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_jwt_issuer.py +0 -0
  878. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_jwt_middleware.py +0 -0
  879. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_middleware.py +0 -0
  880. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_pydantic_adapter.py +0 -0
  881. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_request_hardening.py +0 -0
  882. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_response.py +0 -0
  883. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_rest_adapter.py +0 -0
  884. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_rest_compiler.py +0 -0
  885. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_rest_model.py +0 -0
  886. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_route_rbac.py +0 -0
  887. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_router_identity.py +0 -0
  888. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_router_runtime.py +0 -0
  889. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_sql_endpoint.py +0 -0
  890. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_sql_endpoint_auth_gate.py +0 -0
  891. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_sql_endpoint_roles.py +0 -0
  892. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/rest/test_sql_serialization.py +0 -0
  893. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/__init__.py +0 -0
  894. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/__init__.py +0 -0
  895. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/conftest.py +0 -0
  896. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_batch_key.py +0 -0
  897. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_bytewax_dispatcher.py +0 -0
  898. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_collect_batch.py +0 -0
  899. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_dlq.py +0 -0
  900. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_error_boundary.py +0 -0
  901. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_operators.py +0 -0
  902. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_resource_manager.py +0 -0
  903. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_runner.py +0 -0
  904. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_runtime_sink.py +0 -0
  905. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_runtime_source.py +0 -0
  906. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_sink_registry.py +0 -0
  907. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/bytewax/test_steps.py +0 -0
  908. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/__init__.py +0 -0
  909. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/cases.py +0 -0
  910. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/test_async_walk.py +0 -0
  911. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/compiler/test_multi_source.py +0 -0
  912. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/conftest.py +0 -0
  913. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/contracts/__init__.py +0 -0
  914. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/contracts/cases.py +0 -0
  915. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/contracts/test_boundary.py +0 -0
  916. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/contracts/test_message.py +0 -0
  917. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/contracts/test_mongo_contracts.py +0 -0
  918. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/contracts/test_multi_boundary.py +0 -0
  919. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/contracts/test_steps.py +0 -0
  920. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/__init__.py +0 -0
  921. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/cases/__init__.py +0 -0
  922. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/cases/batch.py +0 -0
  923. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/cases/explode.py +0 -0
  924. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/cases/fork.py +0 -0
  925. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/cases/router.py +0 -0
  926. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/cases/shared.py +0 -0
  927. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/cases/simple.py +0 -0
  928. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/conftest.py +0 -0
  929. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/flows/test_flow_examples.py +0 -0
  930. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/__init__.py +0 -0
  931. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/cases.py +0 -0
  932. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/conftest.py +0 -0
  933. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/fakes.py +0 -0
  934. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/test_client.py +0 -0
  935. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/test_config.py +0 -0
  936. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/test_key_resolver.py +0 -0
  937. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/test_message.py +0 -0
  938. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/test_message_client.py +0 -0
  939. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/test_multi_wire.py +0 -0
  940. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/test_observability.py +0 -0
  941. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/test_settings.py +0 -0
  942. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/kafka/test_wire.py +0 -0
  943. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/nodes/__init__.py +0 -0
  944. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/nodes/conftest.py +0 -0
  945. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/nodes/test_delta_config.py +0 -0
  946. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/nodes/test_logging.py +0 -0
  947. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/nodes/test_table_package.py +0 -0
  948. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/observability/__init__.py +0 -0
  949. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/observability/cases.py +0 -0
  950. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/observability/conftest.py +0 -0
  951. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/observability/test_observability_runner.py +0 -0
  952. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/observability/test_protocols.py +0 -0
  953. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/observability/test_registry.py +0 -0
  954. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/observability/test_structlog.py +0 -0
  955. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/support/__init__.py +0 -0
  956. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/support/flow_cases.py +0 -0
  957. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/test_expand_routes.py +0 -0
  958. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/test_fork.py +0 -0
  959. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/test_otel_observability.py +0 -0
  960. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/test_routing.py +0 -0
  961. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/test_testing_mongo.py +0 -0
  962. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/streaming/test_with.py +0 -0
  963. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/testing/__init__.py +0 -0
  964. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/testing/test_golden.py +0 -0
  965. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/testing/test_http_harness.py +0 -0
  966. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/testing/test_identity_harness.py +0 -0
  967. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/testing/test_in_memory.py +0 -0
  968. {loom_kernel-1.2.2 → loom_kernel-1.4.0}/tests/unit/testing/test_runner.py +0 -0
@@ -1,3 +1,127 @@
1
+ # 🚀 Release 1.4.0 ([#129](https://github.com/the-reacher-data/loom-py/pull/129)) ([`71520ce`](https://github.com/the-reacher-data/loom-py/commit/71520ce4840f8a3b9b914081704520f90d46b31e))
2
+
3
+
4
+ ## ✨ Features
5
+ ### streaming
6
+ - **streaming:** structured compiler error codes and public compiler exports<br>
7
+ > Replace the compiler's bare list[str] failures with structured issues so a
8
+ > guided platform can map compilation errors to form fields, mirroring
9
+ > loom.etl's ETLErrorCode:
10
+ > New loom.streaming.compiler._errors with StreamingErrorCode (StrEnum
11
+ > covering the binding, validation, and plan-building phases, plus codes
12
+ > reserved for the delivery-semantics phase) and CompilationIssue
13
+ > (LoomFrozenStruct with code, message, component, field). All message
14
+ > formatting lives in per-code factory functions; validator call-sites stay
15
+ > intention-revealing.
16
+ > CompilationError now aggregates issues (.issues) while keeping the legacy
17
+ > .errors accessor and the exact aggregated message format. The constructor
18
+ > still accepts bare strings, normalized to code UNSPECIFIED.
19
+ > Branch validation scopes nested issues via CompilationIssue.prefixed(),
20
+ > preserving the historical "fork/router/broadcast branch X: ..." messages.
21
+ > Two previously uncoded build-phase failures now raise CompilationError
22
+ > with codes: STORAGE_SINK_UNSUPPORTED (was a bare ValueError) and
23
+ > PAYLOAD_TYPE_INVALID (was an unguarded AttributeError).
24
+ > validate.py no longer constructs UnsupportedNodeError/MissingSinkError just
25
+ > to str() them; the exception classes remain runtime errors of the adapter.
26
+ > Export symmetry: loom.streaming now exports CompilationError, CompiledPlan,
27
+ > CompilationIssue, and StreamingErrorCode; loom.streaming.compiler adds
28
+ > CompiledMongoCDCSource. Tests migrated from private to public import paths.
29
+
30
+
31
+
32
+ ## 🐛 Fixes
33
+ ### docs
34
+ - **docs:** keep compilation types canonical in loom.streaming.compiler<br>
35
+ > The strict docs build (warnings-as-errors) rejected re-exporting
36
+ > CompilationError/CompilationIssue/CompiledPlan/StreamingErrorCode at the
37
+ > loom.streaming package level: both the package and loom.streaming.compiler
38
+ > pages are in the autosummary, so each symbol was documented twice and
39
+ > cross-references became ambiguous.
40
+ > Follow the real loom.etl convention instead: compilation types have a single
41
+ > canonical import path (loom.streaming.compiler) and the package front-page
42
+ > docstring points there, exactly like loom.etl does with ETLCompilationError.
43
+ > compile_flow stays exported at the package level as before.
44
+ > --------
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+ # 🚀 Release 1.3.0 ([#127](https://github.com/the-reacher-data/loom-py/pull/127)) ([`1fcaa1c`](https://github.com/the-reacher-data/loom-py/commit/1fcaa1ca1520db435d1ba4974284a96a35d2734f))
55
+
56
+
57
+ ## ✨ Features
58
+ ### etl
59
+ - **etl:** update() — matched-only MERGE, the insert-less sibling of upsert<br>
60
+ > IntoTable(...).update(keys=..., include=/exclude=) issues the upsert
61
+ > MERGE WITHOUT when_not_matched_insert: source rows whose keys match are
62
+ > updated, rows without a match are IGNORED — nothing is ever inserted,
63
+ > by construction. This is the mode for repairing columns of an existing
64
+ > table (re-attribution), where an insert would be a bug that until now
65
+ > had to be guarded with row-count assertions outside the write.
66
+ > UpdateSpec keeps neutral public field names (keys/exclude/include) and
67
+ > exposes upsert_* read-only aliases that satisfy the shared _UpsertLike
68
+ > merge protocol, so the MERGE plan, the partition pre-filter and the
69
+ > compile-time key/exclude/include validators are reused untouched;
70
+ > compilation errors name update() instead of upsert(). A new compile
71
+ > guard rejects an include= fully absorbed by keys/partition_cols — in
72
+ > update() that write is a guaranteed no-op. At write time there is no
73
+ > creation path: a missing table is an error, never a create. Implemented
74
+ > in the Polars and Spark writers by factoring the shared merge up to
75
+ > when_matched_update.
76
+ > Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
77
+ > Claude-Session: https://claude.ai/code/session_01U65Md2FMcEaEgpZCKkYqGL
78
+
79
+ - **etl:** IntoHistory joins the declared target union of ETLStep<br>
80
+ > It worked at runtime but mypy rejected the assignment on every step
81
+ > with a historified target. One line in the ClassVar (mirrored in
82
+ > ClientStep, which redeclares the same union — pyright requires the
83
+ > override to be identical) and a test pinning union membership via
84
+ > get_type_hints.
85
+ > Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
86
+ > Claude-Session: https://claude.ai/code/session_01U65Md2FMcEaEgpZCKkYqGL
87
+
88
+ - **etl:** param exprs and path templates accept read-only params properties<br>
89
+ > A computed @property (e.g. partition_day) resolves at runtime through
90
+ > the same getattr chain as a struct field, but compile-time validation
91
+ > only looked at msgspec.structs.fields — forcing the filter down to
92
+ > runtime and losing the declarative pushdown. Now names resolving to a
93
+ > property on the CLASS (public properties only — no methods, no private
94
+ > names) count as known fields, symmetrically in validate_param_exprs and
95
+ > validate_file_path_templates; an unknown name still fails with the same
96
+ > error.
97
+ > Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
98
+ > Claude-Session: https://claude.ai/code/session_01U65Md2FMcEaEgpZCKkYqGL
99
+
100
+
101
+ ### prefect
102
+ - **prefect:** "year" chunk in backfill_flow for overhead-dominated backfills<br>
103
+ > When backfill cost is dominated by per-chunk overhead rather than data
104
+ > volume (real case: 135 monthly chunks x ~2.5 min ≈ 6 h for a fact that
105
+ > resolves each chunk in seconds), a multi-year window drops to a handful
106
+ > of calendar-year chunks. Same algebra as month: floor to January 1,
107
+ > calendar-year advance, %Y label for correlation/run ids, and start_from
108
+ > resume intact. The docstrings call out that both documented window
109
+ > edges — the start floor and the finalize window_end pin — operate at
110
+ > year scale at this granularity.
111
+ > Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
112
+ > Claude-Session: https://claude.ai/code/session_01U65Md2FMcEaEgpZCKkYqGL
113
+ > --------
114
+ > Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
1
125
  # 🚀 Release 1.2.2 ([#124](https://github.com/the-reacher-data/loom-py/pull/124)) ([`ced8b6a`](https://github.com/the-reacher-data/loom-py/commit/ced8b6ab8bba62b7d34e57ad334d26f29af1e0c2))
2
126
 
3
127
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: loom-kernel
3
- Version: 1.2.2
3
+ Version: 1.4.0
4
4
  Summary: Loom Python project
5
5
  License-File: LICENSE
6
6
  Classifier: Typing :: Typed
@@ -269,6 +269,21 @@ target = IntoTable("events.orders").upsert(
269
269
  `partition_cols` is optional but strongly recommended — without it every MERGE
270
270
  forces a full table scan.
271
271
 
272
+ ### update
273
+
274
+ Matched-only MERGE. Rows whose keys match are updated; source rows without a
275
+ match are ignored — nothing is ever inserted. Use it when an insert would be
276
+ a bug, e.g. repairing columns of an existing table. The target table must
277
+ already exist: a missing table is a write error, not a create.
278
+
279
+ ```python
280
+ target = IntoTable("events.orders").update(
281
+ keys=("order_id",),
282
+ partition_cols=("year", "month"), # strongly recommended for large tables
283
+ include=("status",), # only these columns are updated
284
+ )
285
+ ```
286
+
272
287
  ---
273
288
 
274
289
  ## Running only selected stages
@@ -71,6 +71,7 @@ Every `IntoTable` target declares exactly one write mode by chaining a method.
71
71
  | `replace_partition` | Overwrite a single known partition | `IntoTable("staging.orders").replace_partition(year=params.run_date.year)` |
72
72
  | `replace_where` | Overwrite rows matching a predicate | `IntoTable("staging.orders").replace_where(col("date") == params.run_date)` |
73
73
  | `upsert` | Merge on key columns | `IntoTable("staging.orders").upsert(keys=("order_id",))` |
74
+ | `update` | Update matching rows only — never inserts | `IntoTable("staging.orders").update(keys=("order_id",))` |
74
75
 
75
76
  See the [ETL pipelines guide](../etl/pipelines.md) for the full write-mode reference.
76
77
 
@@ -269,6 +269,21 @@ target = IntoTable("events.orders").upsert(
269
269
  `partition_cols` is optional but strongly recommended — without it every MERGE
270
270
  forces a full table scan.
271
271
 
272
+ ### update
273
+
274
+ Matched-only MERGE. Rows whose keys match are updated; source rows without a
275
+ match are ignored — nothing is ever inserted. Use it when an insert would be
276
+ a bug, e.g. repairing columns of an existing table. The target table must
277
+ already exist: a missing table is a write error, not a create.
278
+
279
+ ```python
280
+ target = IntoTable("events.orders").update(
281
+ keys=("order_id",),
282
+ partition_cols=("year", "month"), # strongly recommended for large tables
283
+ include=("status",), # only these columns are updated
284
+ )
285
+ ```
286
+
272
287
  ### historify
273
288
 
274
289
  For SCD Type 2 history tracking use `IntoHistory` instead of `IntoTable`.
@@ -283,6 +298,7 @@ SNAPSHOT vs LOG mode, and configuration of boundary columns.
283
298
  | `IntoTable(...).replace_partition(...)` | Replace known partition | Above |
284
299
  | `IntoTable(...).replace_where(...)` | Predicate-based overwrite | Above |
285
300
  | `IntoTable(...).upsert(...)` | Merge by key | Above |
301
+ | `IntoTable(...).update(...)` | Update matches only, never insert | Above |
286
302
  | `IntoHistory(...)` | SCD Type 2 historification | [Below](#historify) |
287
303
 
288
304
  ---
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "loom-kernel"
3
- version = "1.2.2"
3
+ version = "1.4.0"
4
4
  description = "Loom Python project"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -278,7 +278,7 @@ markers = [
278
278
 
279
279
  [tool.commitizen]
280
280
  name = "cz_conventional_commits"
281
- version = "1.2.2"
281
+ version = "1.4.0"
282
282
  tag_format = "v$version"
283
283
  version_files = [
284
284
  "pyproject.toml:project.version",
@@ -35,7 +35,7 @@ TARGET_ALIAS = "t"
35
35
 
36
36
 
37
37
  class _UpsertLike(Protocol):
38
- """Structural protocol satisfied by both ``UpsertSpec`` and ``UpsertOp``.
38
+ """Structural protocol satisfied by the merge specs (``UpsertSpec``, ``UpdateSpec``).
39
39
 
40
40
  Declared as read-only properties so frozen dataclasses satisfy it.
41
41
  """
@@ -214,7 +214,7 @@ def _build_merge_plan(
214
214
 
215
215
 
216
216
  def _warn_no_partition_cols(table_ref: str) -> None:
217
- """Emit a WARNING when no partition columns are declared on an UPSERT.
217
+ """Emit a WARNING when no partition columns are declared on a MERGE write.
218
218
 
219
219
  Without partition columns the MERGE predicate cannot prune Delta log files,
220
220
  forcing a full table scan. For large tables this can be very expensive.
@@ -223,7 +223,7 @@ def _warn_no_partition_cols(table_ref: str) -> None:
223
223
  table_ref: Logical table reference string (for the log message).
224
224
  """
225
225
  _log.warning(
226
- "upsert table=%s has no partition_cols — full table scan on MERGE. "
226
+ "merge table=%s has no partition_cols — full table scan on MERGE. "
227
227
  "Declare partition_cols= to enable Delta log file pruning.",
228
228
  table_ref,
229
229
  )
@@ -239,7 +239,7 @@ def _log_partition_combos(
239
239
  combos: List of partition combination dicts collected from the frame.
240
240
  table_ref: Logical table reference string.
241
241
  """
242
- _log.debug("upsert table=%s partition_combos=%d", table_ref, len(combos))
242
+ _log.debug("merge table=%s partition_combos=%d", table_ref, len(combos))
243
243
 
244
244
 
245
245
  def _build_partition_predicate(
@@ -23,6 +23,7 @@ from loom.etl.declarative.target import (
23
23
  TargetSpec,
24
24
  TempFanInSpec,
25
25
  TempSpec,
26
+ UpdateSpec,
26
27
  UpsertSpec,
27
28
  )
28
29
  from loom.etl.declarative.target._history import HistorifyRepairReport, HistorifySpec
@@ -158,6 +159,7 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
158
159
  ReplacePartitionsSpec: self._dispatch_replace_partitions,
159
160
  ReplaceWhereSpec: self._dispatch_replace_where,
160
161
  UpsertSpec: self._dispatch_upsert,
162
+ UpdateSpec: self._dispatch_update,
161
163
  HistorifySpec: self._dispatch_historify,
162
164
  }
163
165
 
@@ -213,6 +215,16 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
213
215
  ) -> None:
214
216
  self._do_upsert(frame, target, cast(UpsertSpec, spec), streaming)
215
217
 
218
+ def _dispatch_update(
219
+ self,
220
+ frame: InputFrameT,
221
+ target: ResolvedTarget,
222
+ spec: TargetSpec,
223
+ _params_instance: Any,
224
+ streaming: bool,
225
+ ) -> None:
226
+ self._do_update(frame, target, cast(UpdateSpec, spec), streaming)
227
+
216
228
  def _dispatch_historify(
217
229
  self,
218
230
  frame: InputFrameT,
@@ -390,6 +402,36 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
390
402
  existing_schema=existing,
391
403
  )
392
404
 
405
+ def _do_update(
406
+ self,
407
+ frame: InputFrameT,
408
+ target: ResolvedTarget,
409
+ spec: UpdateSpec,
410
+ streaming: bool,
411
+ ) -> None:
412
+ """Update policy: require exists → align+write.
413
+
414
+ Unlike :meth:`_do_upsert` there is no creation path: an update-only
415
+ MERGE against a missing table has nothing to update, and creating the
416
+ table from the frame would insert every row — exactly what this mode
417
+ exists to prevent.
418
+ """
419
+ existing = self._physical_schema(target)
420
+ if existing is None:
421
+ raise SchemaNotFoundError(
422
+ f"Destination table does not exist: {target}. "
423
+ "update() never inserts, so it cannot create the table — "
424
+ "create it first with append/replace/upsert."
425
+ )
426
+ aligned = self._align(frame, existing, spec.schema_mode)
427
+ materialized = self._materialize_checked(aligned, target, streaming=False)
428
+ self._update(
429
+ materialized,
430
+ target,
431
+ spec=spec,
432
+ existing_schema=existing,
433
+ )
434
+
393
435
  def _do_historify(
394
436
  self,
395
437
  frame: InputFrameT,
@@ -590,6 +632,17 @@ class _WritePolicy(TargetWriter, Generic[InputFrameT, WriteFrameT, PhysicalSchem
590
632
  ) -> None:
591
633
  """Upsert/merge into existing table."""
592
634
 
635
+ @abstractmethod
636
+ def _update(
637
+ self,
638
+ frame: WriteFrameT,
639
+ target: ResolvedTarget,
640
+ *,
641
+ spec: UpdateSpec,
642
+ existing_schema: PhysicalSchemaT,
643
+ ) -> None:
644
+ """Matched-only merge into existing table — never inserts."""
645
+
593
646
  @abstractmethod
594
647
  def _historify(
595
648
  self,
@@ -7,6 +7,7 @@ from typing import Any, Literal
7
7
 
8
8
  import polars as pl
9
9
  from deltalake import CommitProperties, DeltaTable, WriterProperties, write_deltalake
10
+ from deltalake.table import TableMerger
10
11
 
11
12
  from loom.core.logger import get_logger
12
13
  from loom.etl.backends._historify._transform import scd2_transform
@@ -16,6 +17,7 @@ from loom.etl.backends._merge import (
16
17
  _build_merge_plan,
17
18
  _build_partition_predicate,
18
19
  _log_partition_combos,
20
+ _MergePlan,
19
21
  _warn_no_partition_cols,
20
22
  )
21
23
  from loom.etl.backends._path_template import resolve_file_uri
@@ -33,6 +35,7 @@ from loom.etl.declarative.target._history import HistorifyRepairReport, Historif
33
35
  from loom.etl.declarative.target._table import (
34
36
  AppendSpec,
35
37
  ReplacePartitionsSpec,
38
+ UpdateSpec,
36
39
  UpsertSpec,
37
40
  )
38
41
  from loom.etl.lineage._records import LineageRecord, WriteContext, get_lineage_schema
@@ -490,9 +493,55 @@ class PolarsTargetWriter(_WritePolicy[pl.LazyFrame, pl.DataFrame, PolarsPhysical
490
493
  spec: UpsertSpec,
491
494
  existing_schema: PolarsPhysicalSchema,
492
495
  ) -> None:
493
- """Merge frame into target using Delta MERGE."""
494
- path_target = self._as_path_target(target)
496
+ """Merge frame into target using Delta MERGE (update + insert)."""
497
+ _ = existing_schema
498
+ merger, plan, location = self._matched_update_merger(frame, target, spec, mode="upsert")
499
+ merger.when_not_matched_insert(updates=plan.insert_values).execute()
500
+ _log_write_commit("upsert", location)
501
+
502
+ def _update(
503
+ self,
504
+ frame: pl.DataFrame,
505
+ target: ResolvedTarget,
506
+ *,
507
+ spec: UpdateSpec,
508
+ existing_schema: PolarsPhysicalSchema,
509
+ ) -> None:
510
+ """Merge frame into target using a matched-only Delta MERGE.
511
+
512
+ No ``when_not_matched_insert`` clause is emitted, so unmatched source
513
+ rows are ignored and the MERGE inserts zero rows by construction.
514
+ """
495
515
  _ = existing_schema
516
+ merger, _plan, location = self._matched_update_merger(frame, target, spec, mode="update")
517
+ merger.execute()
518
+ _log_write_commit("update", location)
519
+
520
+ def _matched_update_merger(
521
+ self,
522
+ frame: pl.DataFrame,
523
+ target: ResolvedTarget,
524
+ spec: UpsertSpec | UpdateSpec,
525
+ *,
526
+ mode: str,
527
+ ) -> tuple[TableMerger, _MergePlan, TableLocation]:
528
+ """Build the Delta MERGE up to the shared ``when_matched_update`` clause.
529
+
530
+ Both :meth:`_upsert` and :meth:`_update` start from the same merge:
531
+ partition-combo pre-filter, ON predicate, and the matched-update
532
+ column map. The caller chains its remaining clauses and executes.
533
+
534
+ Args:
535
+ frame: Materialised source frame.
536
+ target: Resolved path target.
537
+ spec: Upsert or update spec (identical merge fields).
538
+ mode: Write-mode label for logging.
539
+
540
+ Returns:
541
+ Tuple of the prepared merger, the merge plan, and the target
542
+ location (for commit logging).
543
+ """
544
+ path_target = self._as_path_target(target)
496
545
  location = path_target.location
497
546
 
498
547
  # Collect partition combinations for pre-filter
@@ -512,24 +561,19 @@ class PolarsTargetWriter(_WritePolicy[pl.LazyFrame, pl.DataFrame, PolarsPhysical
512
561
 
513
562
  dt = DeltaTable(location.uri, storage_options=location.storage_options or {})
514
563
  _log_write_start(
515
- "upsert",
564
+ mode,
516
565
  location,
517
566
  frame,
518
567
  partition_cols=spec.partition_cols,
519
568
  predicate=merge_plan.predicate,
520
569
  )
521
- (
522
- dt.merge(
523
- source=frame,
524
- predicate=merge_plan.predicate,
525
- source_alias=SOURCE_ALIAS,
526
- target_alias=TARGET_ALIAS,
527
- )
528
- .when_matched_update(updates=merge_plan.update_set)
529
- .when_not_matched_insert(updates=merge_plan.insert_values)
530
- .execute()
531
- )
532
- _log_write_commit("upsert", location)
570
+ merger = dt.merge(
571
+ source=frame,
572
+ predicate=merge_plan.predicate,
573
+ source_alias=SOURCE_ALIAS,
574
+ target_alias=TARGET_ALIAS,
575
+ ).when_matched_update(updates=merge_plan.update_set)
576
+ return merger, merge_plan, location
533
577
 
534
578
  def _read_existing_data(
535
579
  self,
@@ -7,7 +7,7 @@ import logging
7
7
  from collections.abc import Callable, Sequence
8
8
  from typing import Any, cast
9
9
 
10
- from delta.tables import DeltaTable
10
+ from delta.tables import DeltaMergeBuilder, DeltaTable
11
11
  from pyspark.errors.exceptions.base import AnalysisException
12
12
  from pyspark.sql import DataFrame, SparkSession
13
13
  from pyspark.sql import types as T
@@ -20,6 +20,7 @@ from loom.etl.backends._merge import (
20
20
  TARGET_ALIAS,
21
21
  _build_merge_plan,
22
22
  _log_partition_combos,
23
+ _MergePlan,
23
24
  _warn_no_partition_cols,
24
25
  )
25
26
  from loom.etl.backends._path_template import resolve_file_uri
@@ -37,7 +38,7 @@ from loom.etl.declarative._write_options import (
37
38
  from loom.etl.declarative.target import SchemaMode
38
39
  from loom.etl.declarative.target._file import FileSpec
39
40
  from loom.etl.declarative.target._history import HistorifyRepairReport, HistorifySpec
40
- from loom.etl.declarative.target._table import AppendSpec, UpsertSpec
41
+ from loom.etl.declarative.target._table import AppendSpec, UpdateSpec, UpsertSpec
41
42
  from loom.etl.lineage._records import LineageRecord, get_lineage_schema
42
43
  from loom.etl.storage._config import MissingTablePolicy
43
44
  from loom.etl.storage._file_locator import FileLocator
@@ -250,7 +251,40 @@ class SparkTargetWriter(_WritePolicy[DataFrame, DataFrame, SparkPhysicalSchema])
250
251
  ) -> None:
251
252
  """Merge frame into target using Delta MERGE (delta-spark)."""
252
253
  _ = existing_schema
254
+ merger, plan = self._matched_update_merger(frame, target, spec)
255
+ merger.whenNotMatchedInsert(
256
+ values=cast(dict[str, str | Column], plan.insert_values)
257
+ ).execute()
253
258
 
259
+ def _update(
260
+ self,
261
+ frame: DataFrame,
262
+ target: ResolvedTarget,
263
+ *,
264
+ spec: UpdateSpec,
265
+ existing_schema: SparkPhysicalSchema,
266
+ ) -> None:
267
+ """Merge frame into target using a matched-only Delta MERGE.
268
+
269
+ No ``whenNotMatchedInsert`` clause is emitted, so unmatched source
270
+ rows are ignored and the MERGE inserts zero rows by construction.
271
+ """
272
+ _ = existing_schema
273
+ merger, _plan = self._matched_update_merger(frame, target, spec)
274
+ merger.execute()
275
+
276
+ def _matched_update_merger(
277
+ self,
278
+ frame: DataFrame,
279
+ target: ResolvedTarget,
280
+ spec: UpsertSpec | UpdateSpec,
281
+ ) -> tuple[DeltaMergeBuilder, _MergePlan]:
282
+ """Build the Delta MERGE up to the shared ``whenMatchedUpdate`` clause.
283
+
284
+ Both :meth:`_upsert` and :meth:`_update` start from the same merge:
285
+ partition-combo pre-filter, ON predicate, and the matched-update
286
+ column map. The caller chains its remaining clauses and executes.
287
+ """
254
288
  if isinstance(target, CatalogTarget):
255
289
  dt = DeltaTable.forName(self._spark, target.catalog_ref.ref)
256
290
  else:
@@ -265,13 +299,12 @@ class SparkTargetWriter(_WritePolicy[DataFrame, DataFrame, SparkPhysicalSchema])
265
299
  source_alias=SOURCE_ALIAS,
266
300
  )
267
301
 
268
- (
302
+ merger = (
269
303
  dt.alias(TARGET_ALIAS)
270
304
  .merge(frame.alias(SOURCE_ALIAS), merge_plan.predicate)
271
305
  .whenMatchedUpdate(set=cast(dict[str, str | Column], merge_plan.update_set))
272
- .whenNotMatchedInsert(values=cast(dict[str, str | Column], merge_plan.insert_values))
273
- .execute()
274
306
  )
307
+ return merger, merge_plan
275
308
 
276
309
  def _read_existing_data(
277
310
  self,
@@ -28,6 +28,7 @@ class ETLErrorCode(StrEnum):
28
28
  UPSERT_NO_KEYS = "UPSERT_NO_KEYS"
29
29
  UPSERT_EXCLUDE_INCLUDE_CONFLICT = "UPSERT_EXCLUDE_INCLUDE_CONFLICT"
30
30
  UPSERT_KEY_IN_EXCLUDE = "UPSERT_KEY_IN_EXCLUDE"
31
+ UPDATE_EMPTY_UPDATE_SET = "UPDATE_EMPTY_UPDATE_SET"
31
32
  MISSING_GENERIC_PARAM = "MISSING_GENERIC_PARAM"
32
33
  MISSING_TARGET = "MISSING_TARGET"
33
34
  INVALID_TARGET_TYPE = "INVALID_TARGET_TYPE"
@@ -171,38 +172,56 @@ class ETLCompilationError(Exception):
171
172
  )
172
173
 
173
174
  @classmethod
174
- def upsert_no_keys(cls, step: type) -> ETLCompilationError:
175
- """upsert() declared with no key columns."""
175
+ def upsert_no_keys(cls, step: type, method: str = "upsert") -> ETLCompilationError:
176
+ """upsert()/update() declared with no key columns."""
176
177
  return cls(
177
178
  code=ETLErrorCode.UPSERT_NO_KEYS,
178
179
  component=step.__qualname__,
179
180
  message=(
180
- f"{step.__qualname__}: upsert() requires at least one key column. "
181
+ f"{step.__qualname__}: {method}() requires at least one key column. "
181
182
  'Pass keys=("col",) to identify rows uniquely.'
182
183
  ),
183
184
  )
184
185
 
185
186
  @classmethod
186
- def upsert_exclude_include_conflict(cls, step: type) -> ETLCompilationError:
187
- """upsert() has both exclude= and include= set."""
187
+ def upsert_exclude_include_conflict(
188
+ cls, step: type, method: str = "upsert"
189
+ ) -> ETLCompilationError:
190
+ """upsert()/update() has both exclude= and include= set."""
188
191
  return cls(
189
192
  code=ETLErrorCode.UPSERT_EXCLUDE_INCLUDE_CONFLICT,
190
193
  component=step.__qualname__,
191
194
  message=(
192
- f"{step.__qualname__}: upsert() exclude= and include= are mutually exclusive. "
195
+ f"{step.__qualname__}: {method}() exclude= and include= are mutually exclusive. "
193
196
  "Use one or the other, not both."
194
197
  ),
195
198
  )
196
199
 
197
200
  @classmethod
198
- def upsert_key_in_exclude(cls, step: type, overlap: frozenset[str]) -> ETLCompilationError:
199
- """upsert() exclude= contains columns that are also upsert keys."""
201
+ def upsert_key_in_exclude(
202
+ cls, step: type, overlap: frozenset[str], method: str = "upsert"
203
+ ) -> ETLCompilationError:
204
+ """upsert()/update() exclude= contains columns that are also merge keys."""
200
205
  return cls(
201
206
  code=ETLErrorCode.UPSERT_KEY_IN_EXCLUDE,
202
207
  component=step.__qualname__,
203
208
  message=(
204
- f"{step.__qualname__}: upsert() exclude={sorted(overlap)} overlaps with "
205
- "upsert keys — key columns are always excluded from UPDATE SET."
209
+ f"{step.__qualname__}: {method}() exclude={sorted(overlap)} overlaps with "
210
+ f"{method} keys — key columns are always excluded from UPDATE SET."
211
+ ),
212
+ )
213
+
214
+ @classmethod
215
+ def update_empty_update_set(cls, step: type, include: tuple[str, ...]) -> ETLCompilationError:
216
+ """update() include= is fully absorbed by keys and partition columns."""
217
+ return cls(
218
+ code=ETLErrorCode.UPDATE_EMPTY_UPDATE_SET,
219
+ component=step.__qualname__,
220
+ message=(
221
+ f"{step.__qualname__}: update() include={sorted(include)} is fully covered "
222
+ "by keys/partition_cols, which are always excluded from UPDATE SET — "
223
+ "the MERGE would update no columns and the write would be a guaranteed "
224
+ "no-op. List at least one non-key, non-partition column."
206
225
  ),
207
226
  )
208
227