vgi-python 0.46.0__tar.gz → 0.47.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 (758) hide show
  1. {vgi_python-0.46.0 → vgi_python-0.47.0}/.github/workflows/integration.yml +1 -1
  2. {vgi_python-0.46.0 → vgi_python-0.47.0}/PKG-INFO +1 -1
  3. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/generator-api.md +24 -6
  4. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/metadata.md +1 -0
  5. vgi_python-0.47.0/examples/paged_api_worker.py +117 -0
  6. {vgi_python-0.46.0 → vgi_python-0.47.0}/packages/vgi-fixtures/pyproject.toml +1 -1
  7. {vgi_python-0.46.0 → vgi_python-0.47.0}/pyproject.toml +1 -1
  8. {vgi_python-0.46.0 → vgi_python-0.47.0}/scripts/regen_generated.py +34 -4
  9. vgi_python-0.47.0/tests/table_in_out/test_continuation.py +391 -0
  10. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_examples_workers.py +40 -0
  11. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_http_demo_storage.py +6 -0
  12. vgi_python-0.47.0/tests/test_reporting_contracts.py +312 -0
  13. vgi_python-0.47.0/tests/test_reporting_enterprise.py +247 -0
  14. vgi_python-0.47.0/tests/test_reporting_scale.py +475 -0
  15. vgi_python-0.47.0/tests/test_reporting_sources.py +69 -0
  16. {vgi_python-0.46.0 → vgi_python-0.47.0}/uv.lock +2 -2
  17. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/cache.py +17 -3
  18. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table_in_out.py +339 -0
  19. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/worker.py +6 -0
  20. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/catalog_interface.py +8 -0
  21. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/client.py +22 -9
  22. vgi_python-0.47.0/vgi/codegen/reporting_docs.py +162 -0
  23. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/http/demo_storage.py +2 -2
  24. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/metadata.py +60 -0
  25. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/protocol.py +85 -9
  26. vgi_python-0.47.0/vgi/reporting/__init__.py +72 -0
  27. vgi_python-0.47.0/vgi/reporting/_arrow.py +26 -0
  28. vgi_python-0.47.0/vgi/reporting/_enums.py +69 -0
  29. vgi_python-0.47.0/vgi/reporting/_metadata.py +60 -0
  30. vgi_python-0.47.0/vgi/reporting/alerts.py +454 -0
  31. vgi_python-0.47.0/vgi/reporting/common.py +575 -0
  32. vgi_python-0.47.0/vgi/reporting/delegations.py +78 -0
  33. vgi_python-0.47.0/vgi/reporting/discovery.py +249 -0
  34. vgi_python-0.47.0/vgi/reporting/notify.py +178 -0
  35. vgi_python-0.47.0/vgi/reporting/objects.py +349 -0
  36. vgi_python-0.47.0/vgi/reporting/ownership.py +65 -0
  37. vgi_python-0.47.0/vgi/reporting/render.py +130 -0
  38. vgi_python-0.47.0/vgi/reporting/reports.py +330 -0
  39. vgi_python-0.47.0/vgi/reporting/resource_identity.py +186 -0
  40. vgi_python-0.47.0/vgi/reporting/resource_ownership.py +56 -0
  41. vgi_python-0.47.0/vgi/reporting/schedules.py +401 -0
  42. vgi_python-0.47.0/vgi/reporting/schedules_v2.py +406 -0
  43. vgi_python-0.47.0/vgi/reporting/sources.py +138 -0
  44. vgi_python-0.47.0/vgi/reporting/sql_tasks.py +476 -0
  45. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/table_in_out_function.py +40 -1
  46. {vgi_python-0.46.0 → vgi_python-0.47.0}/.dockerignore +0 -0
  47. {vgi_python-0.46.0 → vgi_python-0.47.0}/.gitattributes +0 -0
  48. {vgi_python-0.46.0 → vgi_python-0.47.0}/.github/dependabot.yml +0 -0
  49. {vgi_python-0.46.0 → vgi_python-0.47.0}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
  50. {vgi_python-0.46.0 → vgi_python-0.47.0}/.github/workflows/ci.yml +0 -0
  51. {vgi_python-0.46.0 → vgi_python-0.47.0}/.github/workflows/docs.yml +0 -0
  52. {vgi_python-0.46.0 → vgi_python-0.47.0}/.github/workflows/release.yml +0 -0
  53. {vgi_python-0.46.0 → vgi_python-0.47.0}/.github/workflows/tailnet-integration.yml +0 -0
  54. {vgi_python-0.46.0 → vgi_python-0.47.0}/.gitignore +0 -0
  55. {vgi_python-0.46.0 → vgi_python-0.47.0}/.python-version +0 -0
  56. {vgi_python-0.46.0 → vgi_python-0.47.0}/.vale.ini +0 -0
  57. {vgi_python-0.46.0 → vgi_python-0.47.0}/CLAUDE.md +0 -0
  58. {vgi_python-0.46.0 → vgi_python-0.47.0}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
  59. {vgi_python-0.46.0 → vgi_python-0.47.0}/DOCS_REVIEW_RUBRIC.md +0 -0
  60. {vgi_python-0.46.0 → vgi_python-0.47.0}/DOCS_USABILITY_TEST.md +0 -0
  61. {vgi_python-0.46.0 → vgi_python-0.47.0}/LICENSE +0 -0
  62. {vgi_python-0.46.0 → vgi_python-0.47.0}/PROTOCOL.md +0 -0
  63. {vgi_python-0.46.0 → vgi_python-0.47.0}/README.md +0 -0
  64. {vgi_python-0.46.0 → vgi_python-0.47.0}/RELEASE-RUNBOOK.md +0 -0
  65. {vgi_python-0.46.0 → vgi_python-0.47.0}/SECURITY.md +0 -0
  66. {vgi_python-0.46.0 → vgi_python-0.47.0}/ci/README.md +0 -0
  67. {vgi_python-0.46.0 → vgi_python-0.47.0}/ci/preprocess-require.awk +0 -0
  68. {vgi_python-0.46.0 → vgi_python-0.47.0}/ci/run-integration.sh +0 -0
  69. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/README.md +0 -0
  70. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/negative/and-too-few-children.json +0 -0
  71. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/negative/delta-required-upsert.json +0 -0
  72. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/negative/nested-runtime-filter.json +0 -0
  73. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/negative/remove-with-expression.json +0 -0
  74. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/negative/required-runtime-filter.json +0 -0
  75. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/negative/snapshot-nonzero-revision.json +0 -0
  76. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/negative/unknown-document-property.json +0 -0
  77. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/negative/unknown-node.json +0 -0
  78. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/positive/advisory-upsert-delta.json +0 -0
  79. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/positive/boolean-column-predicate.json +0 -0
  80. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/positive/empty-snapshot.json +0 -0
  81. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/positive/nested-required-snapshot.json +0 -0
  82. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/positive/remove-delta.json +0 -0
  83. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/cases/positive/runtime-filter-snapshot.json +0 -0
  84. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/filter-v2.schema.json +0 -0
  85. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/generate_runtime.py +0 -0
  86. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/manifest.json +0 -0
  87. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/run_worker.py +0 -0
  88. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-add/expected.arrow +0 -0
  89. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-add/filter.arrow +0 -0
  90. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-add/input.arrow +0 -0
  91. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-multiply/expected.arrow +0 -0
  92. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-multiply/filter.arrow +0 -0
  93. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-multiply/input.arrow +0 -0
  94. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-negate/expected.arrow +0 -0
  95. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-negate/filter.arrow +0 -0
  96. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-negate/input.arrow +0 -0
  97. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-subtract/expected.arrow +0 -0
  98. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-subtract/filter.arrow +0 -0
  99. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/arithmetic-subtract/input.arrow +0 -0
  100. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/cast-integer-to-double/expected.arrow +0 -0
  101. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/cast-integer-to-double/filter.arrow +0 -0
  102. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/cast-integer-to-double/input.arrow +0 -0
  103. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-distinct_from/expected.arrow +0 -0
  104. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-distinct_from/filter.arrow +0 -0
  105. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-distinct_from/input.arrow +0 -0
  106. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-distinct_from/worker-expected.arrow +0 -0
  107. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-eq/expected.arrow +0 -0
  108. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-eq/filter.arrow +0 -0
  109. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-eq/input.arrow +0 -0
  110. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-eq/worker-expected.arrow +0 -0
  111. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-ge/expected.arrow +0 -0
  112. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-ge/filter.arrow +0 -0
  113. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-ge/input.arrow +0 -0
  114. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-ge/worker-expected.arrow +0 -0
  115. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-gt/expected.arrow +0 -0
  116. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-gt/filter.arrow +0 -0
  117. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-gt/input.arrow +0 -0
  118. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-gt/worker-expected.arrow +0 -0
  119. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-le/expected.arrow +0 -0
  120. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-le/filter.arrow +0 -0
  121. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-le/input.arrow +0 -0
  122. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-le/worker-expected.arrow +0 -0
  123. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-lt/expected.arrow +0 -0
  124. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-lt/filter.arrow +0 -0
  125. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-lt/input.arrow +0 -0
  126. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-lt/worker-expected.arrow +0 -0
  127. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-ne/expected.arrow +0 -0
  128. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-ne/filter.arrow +0 -0
  129. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-ne/input.arrow +0 -0
  130. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-ne/worker-expected.arrow +0 -0
  131. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-not_distinct_from/expected.arrow +0 -0
  132. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-not_distinct_from/filter.arrow +0 -0
  133. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-not_distinct_from/input.arrow +0 -0
  134. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/comparison-not_distinct_from/worker-expected.arrow +0 -0
  135. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-atomic-multi-update/delta-0.arrow +0 -0
  136. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-atomic-multi-update/expected.arrow +0 -0
  137. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-atomic-multi-update/filter.arrow +0 -0
  138. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-atomic-multi-update/input.arrow +0 -0
  139. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-empty-noop/delta-0.arrow +0 -0
  140. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-empty-noop/expected.arrow +0 -0
  141. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-empty-noop/filter.arrow +0 -0
  142. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-empty-noop/input.arrow +0 -0
  143. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-0.arrow +0 -0
  144. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-1.arrow +0 -0
  145. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-2.arrow +0 -0
  146. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/expected.arrow +0 -0
  147. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/filter.arrow +0 -0
  148. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/delta-upsert-remove-stale/input.arrow +0 -0
  149. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/empty-snapshot/expected.arrow +0 -0
  150. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/empty-snapshot/filter.arrow +0 -0
  151. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/empty-snapshot/input.arrow +0 -0
  152. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/empty-snapshot/worker-expected.arrow +0 -0
  153. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-cast-type-not-null/filter.arrow +0 -0
  154. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-cast-type-not-null/input.arrow +0 -0
  155. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-column-index/filter.arrow +0 -0
  156. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-column-index/input.arrow +0 -0
  157. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-column-name/filter.arrow +0 -0
  158. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-column-name/input.arrow +0 -0
  159. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-contextual-cast-without-session/filter.arrow +0 -0
  160. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-contextual-cast-without-session/input.arrow +0 -0
  161. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-duplicate-predicate-id/filter.arrow +0 -0
  162. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-duplicate-predicate-id/input.arrow +0 -0
  163. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-external-column-index/filter.arrow +0 -0
  164. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-external-column-index/input.arrow +0 -0
  165. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-external-column-index/join-keys-0.arrow +0 -0
  166. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-external-column-name/filter.arrow +0 -0
  167. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-external-column-name/input.arrow +0 -0
  168. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-external-column-name/join-keys-0.arrow +0 -0
  169. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-field-non-struct/filter.arrow +0 -0
  170. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-field-non-struct/input.arrow +0 -0
  171. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-in-payload-not-list/filter.arrow +0 -0
  172. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-in-payload-not-list/input.arrow +0 -0
  173. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-in-payload-null-list/filter.arrow +0 -0
  174. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-in-payload-null-list/input.arrow +0 -0
  175. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-invalid-overload/filter.arrow +0 -0
  176. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-invalid-overload/input.arrow +0 -0
  177. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-missing-literal/filter.arrow +0 -0
  178. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-missing-literal/input.arrow +0 -0
  179. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-non-boolean-root/filter.arrow +0 -0
  180. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-non-boolean-root/input.arrow +0 -0
  181. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-unknown-standard-function/filter.arrow +0 -0
  182. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/error-unknown-standard-function/input.arrow +0 -0
  183. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/external-in-nonzero-column/expected.arrow +0 -0
  184. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/external-in-nonzero-column/filter.arrow +0 -0
  185. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/external-in-nonzero-column/input.arrow +0 -0
  186. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/external-in-nonzero-column/join-keys-0.arrow +0 -0
  187. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/external-in-nonzero-column/worker-expected.arrow +0 -0
  188. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-contains/expected.arrow +0 -0
  189. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-contains/filter.arrow +0 -0
  190. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-contains/input.arrow +0 -0
  191. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-ends-with/expected.arrow +0 -0
  192. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-ends-with/filter.arrow +0 -0
  193. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-ends-with/input.arrow +0 -0
  194. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-list-contains/expected.arrow +0 -0
  195. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-list-contains/filter.arrow +0 -0
  196. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-list-contains/input.arrow +0 -0
  197. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-starts-with/expected.arrow +0 -0
  198. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-starts-with/filter.arrow +0 -0
  199. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/function-starts-with/input.arrow +0 -0
  200. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/in-empty/expected.arrow +0 -0
  201. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/in-empty/filter.arrow +0 -0
  202. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/in-empty/input.arrow +0 -0
  203. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/in-empty/worker-expected.arrow +0 -0
  204. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/in-with-null/expected.arrow +0 -0
  205. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/in-with-null/filter.arrow +0 -0
  206. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/in-with-null/input.arrow +0 -0
  207. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/in-with-null/worker-expected.arrow +0 -0
  208. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/is-not-null/expected.arrow +0 -0
  209. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/is-not-null/filter.arrow +0 -0
  210. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/is-not-null/input.arrow +0 -0
  211. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/is-not-null/worker-expected.arrow +0 -0
  212. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/is-null/expected.arrow +0 -0
  213. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/is-null/filter.arrow +0 -0
  214. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/is-null/input.arrow +0 -0
  215. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/is-null/worker-expected.arrow +0 -0
  216. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/kleene-and/expected.arrow +0 -0
  217. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/kleene-and/filter.arrow +0 -0
  218. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/kleene-and/input.arrow +0 -0
  219. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/kleene-not/expected.arrow +0 -0
  220. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/kleene-not/filter.arrow +0 -0
  221. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/kleene-not/input.arrow +0 -0
  222. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/kleene-or/expected.arrow +0 -0
  223. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/kleene-or/filter.arrow +0 -0
  224. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/kleene-or/input.arrow +0 -0
  225. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/nan-comparison/expected.arrow +0 -0
  226. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/nan-comparison/filter.arrow +0 -0
  227. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/nan-comparison/input.arrow +0 -0
  228. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/negative-zero-membership/expected.arrow +0 -0
  229. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/negative-zero-membership/filter.arrow +0 -0
  230. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/negative-zero-membership/input.arrow +0 -0
  231. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/nested-null-propagation/expected.arrow +0 -0
  232. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/nested-null-propagation/filter.arrow +0 -0
  233. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/nested-null-propagation/input.arrow +0 -0
  234. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/not-in-empty/expected.arrow +0 -0
  235. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/not-in-empty/filter.arrow +0 -0
  236. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/not-in-empty/input.arrow +0 -0
  237. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/not-in-empty/worker-expected.arrow +0 -0
  238. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/not-in-with-null/expected.arrow +0 -0
  239. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/not-in-with-null/filter.arrow +0 -0
  240. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/not-in-with-null/input.arrow +0 -0
  241. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/not-in-with-null/worker-expected.arrow +0 -0
  242. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/session-integer-division/expected.arrow +0 -0
  243. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/session-integer-division/filter.arrow +0 -0
  244. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime/session-integer-division/input.arrow +0 -0
  245. {vgi_python-0.46.0 → vgi_python-0.47.0}/conformance/filter-v2/runtime-manifest.json +0 -0
  246. {vgi_python-0.46.0 → vgi_python-0.47.0}/dist-vgi/.gitignore +0 -0
  247. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/aggregate-functions.md +0 -0
  248. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/arguments.md +0 -0
  249. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/auth.md +0 -0
  250. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/catalogs.md +0 -0
  251. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/client.md +0 -0
  252. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/exceptions.md +0 -0
  253. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/filters.md +0 -0
  254. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/functions.md +0 -0
  255. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/http.md +0 -0
  256. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/index.md +0 -0
  257. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/metadata.md +0 -0
  258. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/observability.md +0 -0
  259. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/storage.md +0 -0
  260. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/transactor.md +0 -0
  261. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/api/worker.md +0 -0
  262. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/argument-serialization.md +0 -0
  263. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/apple-touch-icon.png +0 -0
  264. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/favicon-16x16.png +0 -0
  265. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/favicon-32x32.png +0 -0
  266. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/favicon.ico +0 -0
  267. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/kinds/aggregate.svg +0 -0
  268. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/kinds/buffering.svg +0 -0
  269. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/kinds/scalar.svg +0 -0
  270. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/kinds/table-in-out.svg +0 -0
  271. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/kinds/table.svg +0 -0
  272. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/logo.png +0 -0
  273. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/social-card.png +0 -0
  274. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/assets/video-thumbnail.jpg +0 -0
  275. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/authentication.md +0 -0
  276. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/catalog-interface.md +0 -0
  277. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/catalog_publication.md +0 -0
  278. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/cli.md +0 -0
  279. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/column-statistics.md +0 -0
  280. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/concepts/index.md +0 -0
  281. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/contributing-docs.md +0 -0
  282. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/IMPLEMENTATION.md +0 -0
  283. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/README.md +0 -0
  284. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/alerts.md +0 -0
  285. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/attach-tickets-plan.md +0 -0
  286. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/credentials.md +0 -0
  287. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/notify.md +0 -0
  288. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/prerequisites.md +0 -0
  289. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/render.md +0 -0
  290. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/reporting-protocols.html +0 -0
  291. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/reports.md +0 -0
  292. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/schedules.md +0 -0
  293. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/design/reporting-protocols/sql_tasks.md +0 -0
  294. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/filter-pushdown.md +0 -0
  295. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/global-functions.md +0 -0
  296. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/how-to/catalogs.md +0 -0
  297. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/how-to/function-patterns.md +0 -0
  298. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/how-to/http-auth.md +0 -0
  299. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/how-to/index.md +0 -0
  300. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/how-to/iroh.md +0 -0
  301. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/how-to/pushdown-and-statistics.md +0 -0
  302. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/how-to/state-storage.md +0 -0
  303. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/how-to/tailnet.md +0 -0
  304. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/index.md +0 -0
  305. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/lifecycle.md +0 -0
  306. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/overrides/main.html +0 -0
  307. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/protocol/index.md +0 -0
  308. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/protocol/vgi-attach-tickets.md +0 -0
  309. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/protocol/vgi-catalog-query-pushdown-design.md +0 -0
  310. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/protocol/vgi-duckdb-filter-adapter.md +0 -0
  311. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/protocol/vgi-filter-encoding-v2-spec.md +0 -0
  312. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/protocol/vgi-opaque-data-sealing.md +0 -0
  313. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/protocol/vgi-protocol-proposed-changes.md +0 -0
  314. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/protocol/vgi-runtime-filter-artifacts.md +0 -0
  315. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/protocol/vgi-secrets.md +0 -0
  316. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/robots.txt +0 -0
  317. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/shared-storage.md +0 -0
  318. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/stylesheets/extra.css +0 -0
  319. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/tutorial/index.md +0 -0
  320. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/tutorial/scalar.md +0 -0
  321. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/tutorial/table.md +0 -0
  322. {vgi_python-0.46.0 → vgi_python-0.47.0}/docs/vgi-logo.png +0 -0
  323. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/batch_index_worker.py +0 -0
  324. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/cache_worker.py +0 -0
  325. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/calc_scalar_worker.py +0 -0
  326. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/calc_worker.py +0 -0
  327. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/copy_format_worker.py +0 -0
  328. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/filter_worker.py +0 -0
  329. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/greeting_scalar_worker.py +0 -0
  330. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/row_count_worker.py +0 -0
  331. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/series_streaming_worker.py +0 -0
  332. {vgi_python-0.46.0 → vgi_python-0.47.0}/examples/sum_worker.py +0 -0
  333. {vgi_python-0.46.0 → vgi_python-0.47.0}/identity.png +0 -0
  334. {vgi_python-0.46.0 → vgi_python-0.47.0}/mkdocs.yml +0 -0
  335. {vgi_python-0.46.0 → vgi_python-0.47.0}/packages/vgi-fixtures/LICENSE +0 -0
  336. {vgi_python-0.46.0 → vgi_python-0.47.0}/packages/vgi-fixtures/README.md +0 -0
  337. {vgi_python-0.46.0 → vgi_python-0.47.0}/packages/vgi-fixtures/docker/Dockerfile +0 -0
  338. {vgi_python-0.46.0 → vgi_python-0.47.0}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
  339. {vgi_python-0.46.0 → vgi_python-0.47.0}/scripts/build_reporting_protocols_html.py +0 -0
  340. {vgi_python-0.46.0 → vgi_python-0.47.0}/scripts/catalog_publication_fixture.py +0 -0
  341. {vgi_python-0.46.0 → vgi_python-0.47.0}/scripts/gen_attach_ticket_vectors.py +0 -0
  342. {vgi_python-0.46.0 → vgi_python-0.47.0}/scripts/hosted_protocols_conformance.sh +0 -0
  343. {vgi_python-0.46.0 → vgi_python-0.47.0}/scripts/measure_startup.py +0 -0
  344. {vgi_python-0.46.0 → vgi_python-0.47.0}/scripts/run_all_tests.sh +0 -0
  345. {vgi_python-0.46.0 → vgi_python-0.47.0}/test-data/generate.sh +0 -0
  346. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/__init__.py +0 -0
  347. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/_hosted_protocols_worker.py +0 -0
  348. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/_http_fixtures.py +0 -0
  349. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/__init__.py +0 -0
  350. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_attach_option.py +0 -0
  351. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_catalog_contents.py +0 -0
  352. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_catalog_interface.py +0 -0
  353. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_catalog_publication.py +0 -0
  354. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_client_catalog.py +0 -0
  355. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_client_load_catalog.py +0 -0
  356. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_column_statistics.py +0 -0
  357. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_declarative.py +0 -0
  358. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_example_worker_catalog.py +0 -0
  359. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_function_info_binary_dictionary.py +0 -0
  360. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_integration.py +0 -0
  361. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_required_filters.py +0 -0
  362. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_scan_branches.py +0 -0
  363. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_serialization.py +0 -0
  364. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_setting.py +0 -0
  365. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_storage.py +0 -0
  366. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_time_travel.py +0 -0
  367. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/catalog/test_writable_table.py +0 -0
  368. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/__init__.py +0 -0
  369. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_aggregate_client.py +0 -0
  370. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_batch_metadata_callback.py +0 -0
  371. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_bind_and_join_keys.py +0 -0
  372. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_broken_pipe.py +0 -0
  373. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_cli.py +0 -0
  374. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_cli_catalog_functions.py +0 -0
  375. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_copy_client.py +0 -0
  376. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_http_response_budget.py +0 -0
  377. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_iroh_client.py +0 -0
  378. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_scan_branches_client.py +0 -0
  379. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_split_client.py +0 -0
  380. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_stop_force.py +0 -0
  381. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_table_column_statistics.py +0 -0
  382. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_time_travel_client.py +0 -0
  383. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/client/test_worker_debug.py +0 -0
  384. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/__init__.py +0 -0
  385. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/_stub.py +0 -0
  386. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/conftest.py +0 -0
  387. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_accumulate.py +0 -0
  388. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_aggregate.py +0 -0
  389. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_attach.py +0 -0
  390. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_bearer_auth.py +0 -0
  391. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_const_param_enforcement.py +0 -0
  392. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_container.py +0 -0
  393. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_copy_from.py +0 -0
  394. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_copy_to.py +0 -0
  395. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_directory_parity.py +0 -0
  396. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_function_inventory.py +0 -0
  397. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_github.py +0 -0
  398. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_http_client.py +0 -0
  399. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_http_external_location.py +0 -0
  400. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_http_upload_url.py +0 -0
  401. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_macro.py +0 -0
  402. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_overload.py +0 -0
  403. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_protocol_inventory.py +0 -0
  404. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_protocol_version.py +0 -0
  405. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_resumable_scan.py +0 -0
  406. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_scalar.py +0 -0
  407. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
  408. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_secret.py +0 -0
  409. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_settings.py +0 -0
  410. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_splits.py +0 -0
  411. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_table.py +0 -0
  412. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_table_in_out.py +0 -0
  413. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_view.py +0 -0
  414. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conformance/test_writable.py +0 -0
  415. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/conftest.py +0 -0
  416. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/anchor_len_overrun.bin +0 -0
  417. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/bad_fingerprint.bin +0 -0
  418. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/bad_flags_unsealed_but_key_present.bin +0 -0
  419. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/bad_version.bin +0 -0
  420. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/generate.py +0 -0
  421. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/manifest.json +0 -0
  422. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/reserved_flag_bit.bin +0 -0
  423. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/stale_anchor.bin +0 -0
  424. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/truncated.bin +0 -0
  425. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/valid_sealed.bin +0 -0
  426. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/data/split_tokens/valid_unsealed.bin +0 -0
  427. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/__init__.py +0 -0
  428. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/test_bernoulli_function.py +0 -0
  429. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/test_binary_packet_function.py +0 -0
  430. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/test_client.py +0 -0
  431. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/test_conditional_message_function.py +0 -0
  432. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/test_hash_seed_function.py +0 -0
  433. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/test_multiply_by_setting_function.py +0 -0
  434. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/test_multiply_function.py +0 -0
  435. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/test_random_bytes_function.py +0 -0
  436. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/scalar/test_return_secret_value_function.py +0 -0
  437. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/sdk_conformance/__init__.py +0 -0
  438. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/sdk_conformance/test_opaque_sealing.py +0 -0
  439. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/sdk_conformance/test_opaque_sealing_stdio.py +0 -0
  440. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/__init__.py +0 -0
  441. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/__init__.py +0 -0
  442. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_constant_columns_function.py +0 -0
  443. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_double_sequence_function.py +0 -0
  444. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_exception_function.py +0 -0
  445. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_filter_echo_function.py +0 -0
  446. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_logging_function.py +0 -0
  447. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_nested_sequence_function.py +0 -0
  448. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_partitioned_function.py +0 -0
  449. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_projected_data_function.py +0 -0
  450. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_sequence_function.py +0 -0
  451. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_settings_function.py +0 -0
  452. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_struct_settings_function.py +0 -0
  453. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/generator/test_ten_thousand_function.py +0 -0
  454. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table/test_wide_columns.py +0 -0
  455. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/__init__.py +0 -0
  456. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/generator/__init__.py +0 -0
  457. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
  458. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/generator/test_echo_function.py +0 -0
  459. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/generator/test_exception_functions.py +0 -0
  460. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
  461. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
  462. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
  463. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
  464. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/test_blended_exchange.py +0 -0
  465. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/test_blended_metadata.py +0 -0
  466. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/test_client.py +0 -0
  467. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/table_in_out/test_table_buffering_empty_input.py +0 -0
  468. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/tailnet/Dockerfile +0 -0
  469. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/tailnet/__init__.py +0 -0
  470. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/tailnet/compose.yaml +0 -0
  471. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/tailnet/probe.py +0 -0
  472. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/tailnet/run.sh +0 -0
  473. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/tailnet/test_worker.py +0 -0
  474. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/tailnet/worker.py +0 -0
  475. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_access_log_audit.py +0 -0
  476. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_aggregate_function.py +0 -0
  477. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_argument_spec.py +0 -0
  478. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_attach_ticket.py +0 -0
  479. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_auth.py +0 -0
  480. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_bind_exceptions.py +0 -0
  481. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_bind_request_at_clause.py +0 -0
  482. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_bound_storage_conformance.py +0 -0
  483. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_cache_control.py +0 -0
  484. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_call_state_attach.py +0 -0
  485. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_catalog_auth_binding.py +0 -0
  486. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_client_oauth.py +0 -0
  487. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_client_reflection.py +0 -0
  488. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_codegen_request_inventory.py +0 -0
  489. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_copy_from_function.py +0 -0
  490. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_copy_to_function.py +0 -0
  491. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_docstrings.py +0 -0
  492. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_documentation_examples.py +0 -0
  493. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_dynamic_filter_http_turns.py +0 -0
  494. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_error_codes.py +0 -0
  495. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_example_function_arg_types.py +0 -0
  496. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_exception_handling.py +0 -0
  497. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_exceptions.py +0 -0
  498. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_filter_pushdown.py +0 -0
  499. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_filter_pushdown_extension.py +0 -0
  500. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_filter_v2.py +0 -0
  501. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_filter_v2_builder.py +0 -0
  502. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_filter_v2_runtime_corpus.py +0 -0
  503. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_filter_v2_spec_schema.py +0 -0
  504. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_fixture_catalog_parity.py +0 -0
  505. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_function_shape_mismatch.py +0 -0
  506. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_function_storage.py +0 -0
  507. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_function_storage_azure_sql.py +0 -0
  508. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_function_storage_cf_do.py +0 -0
  509. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_function_storage_cf_do_integration.py +0 -0
  510. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_function_storage_conformance.py +0 -0
  511. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_function_subclass_check.py +0 -0
  512. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_cpp_constants.py +0 -0
  513. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_cpp_protocol_name.py +0 -0
  514. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_cpp_protocol_version.py +0 -0
  515. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_cpp_records.py +0 -0
  516. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_cpp_request_builders.py +0 -0
  517. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_cpp_schemas.py +0 -0
  518. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_cpp_secret.py +0 -0
  519. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_csharp.py +0 -0
  520. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_go_schemas.py +0 -0
  521. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_go_types.py +0 -0
  522. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_java_schemas.py +0 -0
  523. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_java_types.py +0 -0
  524. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_protocol_version.py +0 -0
  525. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_registry.py +0 -0
  526. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_rust_request_builders.py +0 -0
  527. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_rust_schemas.py +0 -0
  528. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_rust_types.py +0 -0
  529. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_schemas_cross_lang.py +0 -0
  530. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_ts_client.py +0 -0
  531. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_ts_schemas.py +0 -0
  532. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_generated_ts_types.py +0 -0
  533. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_grant_auth.py +0 -0
  534. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_hosted_protocols.py +0 -0
  535. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_http_s3_offload_input.py +0 -0
  536. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_http_s3_offload_output.py +0 -0
  537. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_import_side_effects.py +0 -0
  538. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_landing_discovery.py +0 -0
  539. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_launch_transport.py +0 -0
  540. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_metadata.py +0 -0
  541. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_mypy_consolidated.py +0 -0
  542. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_nest_tensor.py +0 -0
  543. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_otel.py +0 -0
  544. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_projection_enforcement.py +0 -0
  545. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_projection_repro.py +0 -0
  546. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_protocol_classes.py +0 -0
  547. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_resolved_secrets.py +0 -0
  548. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_schema_paths_v2.py +0 -0
  549. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_schema_scoped_functions.py +0 -0
  550. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_schema_utils.py +0 -0
  551. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_serve.py +0 -0
  552. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_setting_secret_annotations.py +0 -0
  553. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_signing_key.py +0 -0
  554. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_split_token.py +0 -0
  555. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_subprocess_transport.py +0 -0
  556. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_table_buffering_function.py +0 -0
  557. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_table_function_dynamic_to_string.py +0 -0
  558. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_table_function_early_close.py +0 -0
  559. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_tcp_transport.py +0 -0
  560. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_type_bounds.py +0 -0
  561. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_union_argument.py +0 -0
  562. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_wire_record_schema_parity.py +0 -0
  563. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_worker.py +0 -0
  564. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_worker_cli.py +0 -0
  565. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_worker_page.py +0 -0
  566. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/test_write_results.py +0 -0
  567. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/transactor/__init__.py +0 -0
  568. {vgi_python-0.46.0 → vgi_python-0.47.0}/tests/transactor/test_transactor.py +0 -0
  569. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/__init__.py +0 -0
  570. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_duckdb.py +0 -0
  571. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_redact.py +0 -0
  572. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_storage_profile.py +0 -0
  573. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/__init__.py +0 -0
  574. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
  575. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/accumulate/worker.py +0 -0
  576. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
  577. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/_common.py +0 -0
  578. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/basic.py +0 -0
  579. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
  580. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/generic.py +0 -0
  581. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
  582. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
  583. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
  584. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
  585. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
  586. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
  587. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/aggregate/window.py +0 -0
  588. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/attach_options.py +0 -0
  589. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/attach_ticket_vectors.json +0 -0
  590. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/bad_enum.py +0 -0
  591. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/bad_protocol.py +0 -0
  592. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/cancellable.py +0 -0
  593. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/catalog.py +0 -0
  594. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/catalog_contents.py +0 -0
  595. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/catalog_publication.py +0 -0
  596. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/companion.py +0 -0
  597. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/copy_from.py +0 -0
  598. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/copy_to.py +0 -0
  599. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/global_functions.py +0 -0
  600. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/http_server.py +0 -0
  601. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/identity_fixture.py +0 -0
  602. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
  603. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
  604. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/nest_tensor.py +0 -0
  605. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/orchard_catalog.py +0 -0
  606. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
  607. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
  608. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/__init__.py +0 -0
  609. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/_common.py +0 -0
  610. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
  611. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
  612. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/binary.py +0 -0
  613. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/formatting.py +0 -0
  614. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/geo.py +0 -0
  615. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
  616. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
  617. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/same_name.py +0 -0
  618. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
  619. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/scalar/type_info.py +0 -0
  620. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
  621. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
  622. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/secret_cache.py +0 -0
  623. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/simple_writable.py +0 -0
  624. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/__init__.py +0 -0
  625. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/_common.py +0 -0
  626. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/batch_index.py +0 -0
  627. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
  628. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
  629. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/filters.py +0 -0
  630. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/late_materialization.py +0 -0
  631. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/make_series.py +0 -0
  632. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/misc.py +0 -0
  633. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/order_modes.py +0 -0
  634. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/pairs.py +0 -0
  635. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/partition_columns.py +0 -0
  636. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
  637. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/profiling_example.py +0 -0
  638. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/required_filters.py +0 -0
  639. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
  640. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/same_name_schemas.py +0 -0
  641. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/sequence.py +0 -0
  642. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/settings.py +0 -0
  643. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/splits.py +0 -0
  644. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
  645. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
  646. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/typed_probe.py +0 -0
  647. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/versioned.py +0 -0
  648. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table/wide.py +0 -0
  649. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
  650. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/ticket_probe.py +0 -0
  651. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/twin_catalogs.py +0 -0
  652. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/versioned.py +0 -0
  653. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/versioned_tables.py +0 -0
  654. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/writable/__init__.py +0 -0
  655. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/writable/generic.py +0 -0
  656. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/writable/table.py +0 -0
  657. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/_test_fixtures/writable/worker.py +0 -0
  658. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/aggregate_function.py +0 -0
  659. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/argument_spec.py +0 -0
  660. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/arguments.py +0 -0
  661. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/attach_header.py +0 -0
  662. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/attach_ticket.py +0 -0
  663. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/auth.py +0 -0
  664. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/cache_control.py +0 -0
  665. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/__init__.py +0 -0
  666. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/_descriptor_spec.py +0 -0
  667. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/attach_option.py +0 -0
  668. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/contents_codec.py +0 -0
  669. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/contract.py +0 -0
  670. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/descriptors.py +0 -0
  671. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/duckdb_statistics.py +0 -0
  672. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/secret_type.py +0 -0
  673. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/setting.py +0 -0
  674. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/snapshot.py +0 -0
  675. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/catalog/storage.py +0 -0
  676. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/__init__.py +0 -0
  677. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/aggregate.py +0 -0
  678. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/catalog_mixin.py +0 -0
  679. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/cli.py +0 -0
  680. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/cli_catalog.py +0 -0
  681. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/cli_schema.py +0 -0
  682. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/cli_table.py +0 -0
  683. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/cli_transaction.py +0 -0
  684. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/cli_utils.py +0 -0
  685. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/cli_view.py +0 -0
  686. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/client/errors.py +0 -0
  687. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/__init__.py +0 -0
  688. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/_common.py +0 -0
  689. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/_registry.py +0 -0
  690. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/_registry_backend.py +0 -0
  691. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_constants.py +0 -0
  692. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_protocol_name.py +0 -0
  693. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_protocol_version.py +0 -0
  694. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_records.py +0 -0
  695. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_registry.py +0 -0
  696. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_request_builders.py +0 -0
  697. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_schemas.py +0 -0
  698. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
  699. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_secret_request_builders.py +0 -0
  700. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/cpp_secret_schemas.py +0 -0
  701. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/csharp_registry.py +0 -0
  702. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/csharp_schemas.py +0 -0
  703. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/csharp_types.py +0 -0
  704. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/go_registry.py +0 -0
  705. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/go_schemas.py +0 -0
  706. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/go_types.py +0 -0
  707. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/java_registry.py +0 -0
  708. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/java_schemas.py +0 -0
  709. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/java_types.py +0 -0
  710. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/protocol_version.py +0 -0
  711. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/rust_registry.py +0 -0
  712. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/rust_request_builders.py +0 -0
  713. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/rust_schemas.py +0 -0
  714. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/rust_types.py +0 -0
  715. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/ts_client.py +0 -0
  716. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/ts_registry.py +0 -0
  717. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/ts_schemas.py +0 -0
  718. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/codegen/ts_types.py +0 -0
  719. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/copy_from_function.py +0 -0
  720. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/copy_to_function.py +0 -0
  721. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/exceptions.py +0 -0
  722. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/filter_v2.py +0 -0
  723. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/filter_v2_builder.py +0 -0
  724. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/function.py +0 -0
  725. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/function_storage.py +0 -0
  726. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/function_storage_azure_sql.py +0 -0
  727. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/function_storage_cf_do.py +0 -0
  728. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/http/__init__.py +0 -0
  729. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/http/landing.html +0 -0
  730. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/http/landing_page.py +0 -0
  731. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/http/vgi-client.js +0 -0
  732. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/http/worker_page.py +0 -0
  733. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/invocation.py +0 -0
  734. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/logging_config.py +0 -0
  735. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/meta_worker.py +0 -0
  736. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/otel.py +0 -0
  737. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/profiling.py +0 -0
  738. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/protocol_version.txt +0 -0
  739. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/py.typed +0 -0
  740. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/rpc_server.py +0 -0
  741. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/scalar_function.py +0 -0
  742. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/schema_path.py +0 -0
  743. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/schema_utils.py +0 -0
  744. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/secret_protocol.py +0 -0
  745. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/secret_service.py +0 -0
  746. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/serve.py +0 -0
  747. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/split_token.py +0 -0
  748. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/table_buffering_function.py +0 -0
  749. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/table_filter_pushdown.py +0 -0
  750. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/table_function.py +0 -0
  751. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/transactor/__init__.py +0 -0
  752. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/transactor/_duckdb_compat.py +0 -0
  753. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/transactor/client.py +0 -0
  754. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/transactor/protocol.py +0 -0
  755. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/transactor/server.py +0 -0
  756. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/worker.py +0 -0
  757. {vgi_python-0.46.0 → vgi_python-0.47.0}/vgi/write_results.py +0 -0
  758. {vgi_python-0.46.0 → vgi_python-0.47.0}/wrangler.jsonc +0 -0
@@ -27,7 +27,7 @@ concurrency:
27
27
  env:
28
28
  # The test suite and native Actions artifact must come from this exact ref.
29
29
  # The downloader verifies its provenance against the checked-out commit.
30
- VGI_REF: 3a2249f815ff6e2a8b5289a3e6284326084e3630
30
+ VGI_REF: fc3e08f7e7fd800165a0edc00313de46fed15329
31
31
  # CI is not a user: its ATTACHes should not land in Query.Farm's adoption data.
32
32
  # The vgi extension fires a telemetry event per successful ATTACH, and this
33
33
  # suite performs several hundred of them per lane, so opting out keeps the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: vgi-python
3
- Version: 0.46.0
3
+ Version: 0.47.0
4
4
  Summary: Vector Gateway Interface - Connect DuckDB to external programs via Apache Arrow
5
5
  Project-URL: Homepage, https://query.farm
6
6
  Project-URL: Repository, https://github.com/Query-farm/vgi-python
@@ -275,15 +275,33 @@ class SumFunction(TableInOutFunction):
275
275
  )]
276
276
  ```
277
277
 
278
- **Multiple outputs per input (HAVE_MORE_OUTPUT status):**
279
- ```python
280
- from vgi_rpc.rpc import OutputCollector
278
+ **Multiple outputs per input (`more=True` and `resume()`):**
281
279
 
282
- def process(cls, params, state, batch, out: OutputCollector) -> None:
283
- # Emit multiple batches for one input by setting vgi.status metadata
284
- out.emit(batch, custom_metadata={b"vgi.status": b"HAVE_MORE_OUTPUT"})
280
+ Each call still emits exactly one batch. To return several for one input
281
+ batch, emit the first with `more=True`; the framework then calls `resume()`,
282
+ with no input, for each next batch until one is emitted without `more=True`.
283
+ `resume()` continues from `state` alone, so the function must declare a
284
+ serializable `TState`; over HTTP it travels in the stream's state token, so
285
+ store positions to resume from, not output rows. A function with `resume()`
286
+ cannot set `max_workers = 1`: the client runs such a function on one connection
287
+ shared by every pipeline, which cannot leave output pending.
288
+
289
+ ```python test="skip"
290
+ @classmethod
291
+ def process(cls, params, state, batch, out) -> None:
292
+ state.pages = plan_pages(batch) # where each page starts: small
293
+ cls.resume(params, state, out)
294
+
295
+ @classmethod
296
+ def resume(cls, params, state, out) -> None:
297
+ page = fetch(state.pages.pop(0))
298
+ out.emit(page.batch, parent_rows=page.parent_rows, more=bool(state.pages))
285
299
  ```
286
300
 
301
+ On the wire the reply carries `vgi.status: HAVE_MORE_OUTPUT` and the client
302
+ asks for the next batch with a zero-row input carrying `vgi.status: CONTINUE`.
303
+ While output is pending that tick is the only valid input.
304
+
287
305
  **In-band logging via OutputCollector:**
288
306
  ```python
289
307
  from vgi_rpc.rpc import OutputCollector
@@ -80,6 +80,7 @@ info = SumValuesFunction.describe()
80
80
  | `tags` | `dict[str, str]` | `{}` | Custom key-value tags |
81
81
  | `examples` | `list` | `[]` | SQL examples (str or FunctionExample) |
82
82
  | `max_workers` | `int\|None` | `None` (unlimited) | Max parallel workers |
83
+ | `input_rows_per_call` | `int\|None` | `None` (a whole chunk) | `RowTransformFunction` only: most input rows per worker call; the client splits each chunk into calls of at most this many rows |
83
84
  | `stability` | `FunctionStability` | `CONSISTENT` | Output determinism |
84
85
  | `null_handling` | `NullHandling` | `DEFAULT` | NULL input behavior |
85
86
  | `argument_monotonicity` | `list[ArgumentMonotonicity]\|None` | `None` | Scalar-only monotonicity claims in argument declaration order |
@@ -0,0 +1,117 @@
1
+ # /// script
2
+ # requires-python = ">=3.13"
3
+ # dependencies = ["vgi-python"]
4
+ # ///
5
+ """A lateral function backed by a paged API, returning one API page per reply.
6
+
7
+ ``orders(customer_id)`` lists a customer's orders from an API that returns them a
8
+ page at a time behind a cursor. Rather than fetching every page before replying,
9
+ ``process()`` fetches the first page and emits it with ``more=True``; the framework
10
+ then calls ``resume()`` for each next page. The state holds only where to resume
11
+ (which input row, which page cursor), never fetched rows, so it is small enough to
12
+ travel in an HTTP state token.
13
+
14
+ ATTACH 'shop' (TYPE vgi, LOCATION 'uv run paged_api_worker.py');
15
+ SELECT c.id, o.order_id, o.total
16
+ FROM (VALUES (1), (2), (3)) c(id), shop.orders(c.id) o;
17
+ """
18
+
19
+ from dataclasses import dataclass
20
+ from typing import Annotated, Any, cast
21
+
22
+ import pyarrow as pa
23
+ from vgi_rpc import ArrowSerializableDataclass
24
+
25
+ from vgi import Arg, Worker
26
+ from vgi.catalog import Catalog, Schema
27
+ from vgi.invocation import BindResponse
28
+ from vgi.table_function import BindParams, ProcessParams
29
+ from vgi.table_in_out_function import OutputCollector, RowTransformFunction
30
+
31
+ PAGE_SIZE = 5
32
+
33
+
34
+ def fetch_orders_page(customer_id: int, cursor: str) -> tuple[list[dict[str, Any]], str]:
35
+ """Stand-in for an HTTP API: one page of a customer's orders and the next cursor.
36
+
37
+ Customer ``n`` has ``7 * n`` orders. An empty next cursor means the last page.
38
+ """
39
+ start = int(cursor or "0")
40
+ total = 7 * customer_id
41
+ orders = [
42
+ {"order_id": customer_id * 1000 + k, "total": round(10.0 + k * 2.5, 2)}
43
+ for k in range(start, min(start + PAGE_SIZE, total))
44
+ ]
45
+ end = start + len(orders)
46
+ return orders, str(end) if end < total else ""
47
+
48
+
49
+ @dataclass(slots=True, frozen=True, kw_only=True)
50
+ class OrdersArgs:
51
+ """One positional input column: the customer to list orders for."""
52
+
53
+ customer_id: Annotated[int, Arg(0, doc="Customer whose orders to list")]
54
+
55
+
56
+ @dataclass(kw_only=True)
57
+ class OrdersCursor(ArrowSerializableDataclass):
58
+ """Where the next reply resumes: the input's customer ids, a row, and that row's page cursor."""
59
+
60
+ customer_ids: list[int] | None = None
61
+ row: int = 0
62
+ cursor: str = ""
63
+
64
+
65
+ class Orders(RowTransformFunction[OrdersArgs, OrdersCursor]):
66
+ """List each input customer's orders, one API page per reply."""
67
+
68
+ @classmethod
69
+ def on_bind(cls, params: BindParams[OrdersArgs]) -> BindResponse:
70
+ """A fixed output schema."""
71
+ return BindResponse(output_schema=pa.schema([("order_id", pa.int64()), ("total", pa.float64())]))
72
+
73
+ @classmethod
74
+ def initial_state(cls, params: ProcessParams[OrdersArgs]) -> OrdersCursor:
75
+ """An empty cursor; ``process()`` fills it for each input batch."""
76
+ return OrdersCursor()
77
+
78
+ @classmethod
79
+ def process(
80
+ cls, params: ProcessParams[OrdersArgs], state: OrdersCursor, batch: pa.RecordBatch, out: OutputCollector
81
+ ) -> None:
82
+ """Start a new input batch at its first row, then emit the first page."""
83
+ state.customer_ids = [-1 if c is None else c for c in batch.column("customer_id").to_pylist()]
84
+ state.row = 0
85
+ state.cursor = ""
86
+ cls.resume(params, state, out)
87
+
88
+ @classmethod
89
+ def resume(cls, params: ProcessParams[OrdersArgs], state: OrdersCursor, out: OutputCollector) -> None:
90
+ """Emit the next non-empty page, with ``more=True`` unless it is the last."""
91
+ ids = state.customer_ids or []
92
+ orders: list[dict[str, Any]] = []
93
+ row = state.row
94
+ while state.row < len(ids) and not orders:
95
+ row = state.row
96
+ orders, state.cursor = fetch_orders_page(ids[row], state.cursor) if ids[row] > 0 else ([], "")
97
+ if not state.cursor: # that customer is done: the next page starts the next row
98
+ state.row += 1
99
+ # Every row of a page came from one input row; parent_rows says which.
100
+ cast(Any, out).emit(
101
+ pa.RecordBatch.from_pylist(orders, schema=params.output_schema),
102
+ parent_rows=[row] * len(orders),
103
+ more=state.row < len(ids),
104
+ )
105
+
106
+
107
+ class ShopWorker(Worker):
108
+ """A worker exposing the ``shop`` catalog with the paged ``orders`` function."""
109
+
110
+ catalog = Catalog(
111
+ name="shop",
112
+ schemas=[Schema(path=["main"], functions=[Orders])],
113
+ )
114
+
115
+
116
+ if __name__ == "__main__":
117
+ ShopWorker().run()
@@ -8,7 +8,7 @@
8
8
  # and the conformance suite import it by its normal `vgi._test_fixtures` path.
9
9
  [project]
10
10
  name = "vgi-fixtures"
11
- version = "0.46.0"
11
+ version = "0.47.0"
12
12
  description = "Example/test VGI worker modules and entry points (not for production use)"
13
13
  readme = "README.md"
14
14
  # Local copy of the repo-root LICENSE (kept in sync): the build can't reach
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "vgi-python"
3
- version = "0.46.0"
3
+ version = "0.47.0"
4
4
  description = "Vector Gateway Interface - Connect DuckDB to external programs via Apache Arrow"
5
5
  readme = "README.md"
6
6
  keywords = [
@@ -16,7 +16,11 @@ and only then written.
16
16
 
17
17
  Targets in sibling repos that are not checked out are skipped, not failed:
18
18
  nobody has all of them. A registry backend's ``root_env`` (``VGI_JAVA_ROOT``,
19
- ``VGI_TYPESCRIPT_ROOT``, ...) points its SDK target at another checkout.
19
+ ``VGI_TYPESCRIPT_ROOT``, ...) points its SDK target at another checkout, as does
20
+ ``--root REPO=PATH``. ``--only REPO`` (repeatable) limits the run to those repos,
21
+ so regenerating one SDK's worktree writes nothing into any other checkout:
22
+
23
+ uv run python scripts/regen_generated.py --only vgi-go --root vgi-go=~/Development/vgi-go-feature
20
24
  """
21
25
 
22
26
  from __future__ import annotations
@@ -96,9 +100,9 @@ _ROOT_ENV: dict[str, str] = {b.repo: b.root_env for b in _REGISTRY_BACKENDS}
96
100
  _ROOT_ENV.setdefault("vgi", "VGI_EXTENSION_ROOT")
97
101
 
98
102
 
99
- def _repo_root(name: str) -> Path | None:
103
+ def _repo_root(name: str, roots: dict[str, str]) -> Path | None:
100
104
  """Locate a sibling checkout, or ``None`` when it is not present."""
101
- override = os.environ.get(_ROOT_ENV.get(name, ""))
105
+ override = roots.get(name) or os.environ.get(_ROOT_ENV.get(name, ""))
102
106
  if override:
103
107
  return Path(override) if Path(override).is_dir() else None
104
108
  siblings = Path(__file__).resolve().parents[2]
@@ -135,12 +139,38 @@ def main() -> int:
135
139
  action="store_true",
136
140
  help="report drift without writing anything (exit 1 if any file is stale)",
137
141
  )
142
+ parser.add_argument(
143
+ "--only",
144
+ action="append",
145
+ default=[],
146
+ metavar="REPO",
147
+ help="only these repos' targets (repeatable), e.g. --only vgi-go",
148
+ )
149
+ parser.add_argument(
150
+ "--root",
151
+ action="append",
152
+ default=[],
153
+ metavar="REPO=PATH",
154
+ help="the checkout to use for REPO (repeatable), e.g. --root vgi-go=../vgi-go-feature",
155
+ )
138
156
  args = parser.parse_args()
157
+ known = {repo for _, _, repo in _TARGETS}
158
+ unknown = set(args.only) - known
159
+ if unknown:
160
+ parser.error(f"--only: unknown repo(s) {sorted(unknown)}; known: {sorted(known)}")
161
+ roots: dict[str, str] = {}
162
+ for spec in args.root:
163
+ repo, sep, path = spec.partition("=")
164
+ if not sep or repo not in known:
165
+ parser.error(f"--root expects REPO=PATH with REPO one of {sorted(known)}, got {spec!r}")
166
+ roots[repo] = str(Path(path).expanduser())
139
167
 
140
168
  stale, wrote, skipped, failed = [], [], [], []
141
169
 
142
170
  for module_name, relative, repo in _TARGETS:
143
- root = _repo_root(repo)
171
+ if args.only and repo not in args.only:
172
+ continue
173
+ root = _repo_root(repo, roots)
144
174
  if root is None:
145
175
  skipped.append(f"{repo} (not checked out)")
146
176
  continue
@@ -0,0 +1,391 @@
1
+ # Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+
3
+ """Continued output: several replies for one table-in-out input batch.
4
+
5
+ A function emits ``out.emit(..., more=True)`` and the framework calls its
6
+ ``resume()`` for each next batch. Each batch is its own reply; the client
7
+ fetches the next one with a zero-row ``vgi.status: CONTINUE`` tick.
8
+ ``blended_paged`` is the fixture: ``blended_explode``'s output, ``page_size``
9
+ rows per reply.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from collections.abc import Callable, Sequence
15
+ from dataclasses import dataclass
16
+ from typing import Annotated, Any
17
+
18
+ import pyarrow as pa
19
+ import pytest
20
+ from vgi_rpc import ArrowSerializableDataclass
21
+ from vgi_rpc.rpc import AnnotatedBatch, OutputCollector
22
+
23
+ from tests.conftest import make_schema
24
+ from vgi.arguments import Arg, Arguments, TableInput
25
+ from vgi.cache_control import CacheControl
26
+ from vgi.client import Client
27
+ from vgi.client.client import ClientError
28
+ from vgi.invocation import BindResponse
29
+ from vgi.metadata import resolve_metadata
30
+ from vgi.protocol import (
31
+ CONTINUE,
32
+ STATUS_KEY,
33
+ _FilteringOutputCollector,
34
+ _TrackingOutputCollector,
35
+ )
36
+ from vgi.schema_utils import schema
37
+ from vgi.table_function import BindParams, ProcessParams
38
+ from vgi.table_in_out_function import RowTransformFunction, TableInOutGenerator
39
+
40
+ _INPUT_SCHEMA = make_schema([pa.field("n", pa.int64())])
41
+
42
+
43
+ def _expected_pairs(counts: Sequence[int | None]) -> list[tuple[int, int]]:
44
+ return [(row, k) for row, n in enumerate(counts) for k in range(n or 0)]
45
+
46
+
47
+ def _run_paged(
48
+ client: Client,
49
+ monkeypatch: pytest.MonkeyPatch,
50
+ batches: Sequence[Sequence[int | None]],
51
+ page_size: int,
52
+ ) -> tuple[list[tuple[int, int]], list[int]]:
53
+ """Run ``blended_paged``; return (parent_row, value) pairs and replies per input batch."""
54
+ replies: list[int] = []
55
+ original = Client._process_batch_on_worker
56
+
57
+ def counting(self: Client, *args: Any, **kwargs: Any) -> Any:
58
+ outputs, parent_rows = original(self, *args, **kwargs)
59
+ replies.append(len(outputs))
60
+ return outputs, parent_rows
61
+
62
+ monkeypatch.setattr(Client, "_process_batch_on_worker", counting)
63
+ parent_rows_seen: list[int] = []
64
+ with client:
65
+ results = list(
66
+ client.table_in_out_function(
67
+ function_name="blended_paged",
68
+ schema_path=["main"],
69
+ input=iter(
70
+ [pa.RecordBatch.from_pydict({"n": list(counts)}, schema=_INPUT_SCHEMA) for counts in batches]
71
+ ),
72
+ arguments=Arguments(named={"page_size": pa.scalar(page_size)}),
73
+ parent_row_callback=parent_rows_seen.extend,
74
+ )
75
+ )
76
+ values: list[Any] = [v for batch in results for v in batch.column("i").to_pylist()]
77
+ return list(zip(parent_rows_seen, values, strict=True)), replies
78
+
79
+
80
+ class TestContinuedOutput:
81
+ """A client that accepts more output gets one reply per page."""
82
+
83
+ def test_pages_cover_the_output_in_order(
84
+ self, client_transport: Callable[[], Client], monkeypatch: pytest.MonkeyPatch
85
+ ) -> None:
86
+ """Every transport, including HTTP, where the cursor rides the state token."""
87
+ counts = [0, 1, 3, 2, 0, 4]
88
+ pairs, replies = _run_paged(client_transport(), monkeypatch, [counts], page_size=2)
89
+ assert pairs == _expected_pairs(counts)
90
+ assert replies == [5] # 10 rows, 2 per reply
91
+
92
+ def test_each_input_batch_pages_independently(
93
+ self, client_transport: Callable[[], Client], monkeypatch: pytest.MonkeyPatch
94
+ ) -> None:
95
+ """A second input batch starts over: provenance indexes its own rows."""
96
+ pairs, replies = _run_paged(client_transport(), monkeypatch, [[3], [1, 2]], page_size=2)
97
+ assert pairs == _expected_pairs([3]) + _expected_pairs([1, 2])
98
+ assert replies == [2, 2]
99
+
100
+ @pytest.mark.parametrize(("page_size", "expected_replies"), [(1, 10), (3, 4), (4, 3), (10, 1), (100, 1)])
101
+ def test_page_size_sets_the_reply_count(
102
+ self,
103
+ client_transport: Callable[[], Client],
104
+ monkeypatch: pytest.MonkeyPatch,
105
+ page_size: int,
106
+ expected_replies: int,
107
+ ) -> None:
108
+ """10 output rows: one reply per page_size rows, pages crossing input rows."""
109
+ counts = [0, 1, 3, 2, 0, 4]
110
+ pairs, replies = _run_paged(client_transport(), monkeypatch, [counts], page_size=page_size)
111
+ assert pairs == _expected_pairs(counts)
112
+ assert replies == [expected_replies]
113
+
114
+ def test_null_and_trailing_empty_rows_add_no_reply(
115
+ self, fixture_worker: str, monkeypatch: pytest.MonkeyPatch
116
+ ) -> None:
117
+ """NULL counts as 0, and rows with no output after the last page add no empty reply."""
118
+ counts: list[int | None] = [None, 2, 0, 0]
119
+ pairs, replies = _run_paged(Client(fixture_worker), monkeypatch, [counts], page_size=2)
120
+ assert pairs == _expected_pairs(counts)
121
+ assert replies == [1]
122
+
123
+ def test_invalid_page_size_is_refused_at_bind(self, fixture_worker: str, monkeypatch: pytest.MonkeyPatch) -> None:
124
+ """page_size := 0 fails at bind, before any exchange."""
125
+ with pytest.raises(ClientError, match="page_size must be at least 1"):
126
+ _run_paged(Client(fixture_worker), monkeypatch, [[3]], page_size=0)
127
+
128
+ def test_output_that_fits_one_page_is_one_reply(self, fixture_worker: str, monkeypatch: pytest.MonkeyPatch) -> None:
129
+ """A function that never says more=True answers with a single reply."""
130
+ pairs, replies = _run_paged(Client(fixture_worker), monkeypatch, [[2, 1]], page_size=10)
131
+ assert pairs == _expected_pairs([2, 1])
132
+ assert replies == [1]
133
+
134
+ def test_no_output_is_one_empty_reply(self, fixture_worker: str, monkeypatch: pytest.MonkeyPatch) -> None:
135
+ """No output rows at all is one empty reply, not a page followed by an empty one."""
136
+ pairs, replies = _run_paged(Client(fixture_worker), monkeypatch, [[0, 0]], page_size=2)
137
+ assert pairs == []
138
+ assert replies == [1]
139
+
140
+
141
+ def _tick() -> AnnotatedBatch:
142
+ return AnnotatedBatch(
143
+ batch=pa.RecordBatch.from_pydict({"n": []}, schema=_INPUT_SCHEMA),
144
+ custom_metadata=pa.KeyValueMetadata({STATUS_KEY: CONTINUE}),
145
+ )
146
+
147
+
148
+ def _real(*counts: int) -> AnnotatedBatch:
149
+ return AnnotatedBatch(batch=pa.RecordBatch.from_pydict({"n": list(counts)}, schema=_INPUT_SCHEMA))
150
+
151
+
152
+ class TestOutOfTurnInput:
153
+ """While output is pending only a tick is valid, and a tick only then."""
154
+
155
+ @staticmethod
156
+ def _send(fixture_worker: str, monkeypatch: pytest.MonkeyPatch, sequence: list[AnnotatedBatch]) -> None:
157
+ """Send ``sequence`` raw on one blended_paged stream (page_size 2); the last must be refused."""
158
+
159
+ def send(self: Client, worker: Any, input_batch: pa.RecordBatch, *args: Any, **kwargs: Any) -> Any:
160
+ from vgi_rpc.rpc import RpcError
161
+
162
+ try:
163
+ for batch in sequence:
164
+ worker.stream.exchange(batch)
165
+ except RpcError as e:
166
+ raise ClientError.from_rpc_error(e) from e
167
+ raise AssertionError("the worker accepted out-of-turn input")
168
+
169
+ monkeypatch.setattr(Client, "_process_batch_on_worker", send)
170
+ with Client(fixture_worker) as client:
171
+ list(
172
+ client.table_in_out_function(
173
+ function_name="blended_paged",
174
+ schema_path=["main"],
175
+ input=iter([_real(3).batch]),
176
+ )
177
+ )
178
+
179
+ def test_tick_without_pending_output_is_refused(self, fixture_worker: str, monkeypatch: pytest.MonkeyPatch) -> None:
180
+ """A tick before any reply said HAVE_MORE_OUTPUT is a protocol error."""
181
+ with pytest.raises(ClientError, match="no output is pending"):
182
+ self._send(fixture_worker, monkeypatch, [_tick()])
183
+
184
+ def test_tick_after_the_last_page_is_refused(self, fixture_worker: str, monkeypatch: pytest.MonkeyPatch) -> None:
185
+ """3 rows in pages of 2: the second reply is the last, so a third tick is refused."""
186
+ with pytest.raises(ClientError, match="no output is pending"):
187
+ self._send(fixture_worker, monkeypatch, [_real(3), _tick(), _tick()])
188
+
189
+ def test_input_while_output_is_pending_is_refused(
190
+ self, fixture_worker: str, monkeypatch: pytest.MonkeyPatch
191
+ ) -> None:
192
+ """Skipping the pending pages with new input would lose them: refused."""
193
+ with pytest.raises(ClientError, match="while output is pending"):
194
+ self._send(fixture_worker, monkeypatch, [_real(3), _real(1)])
195
+
196
+
197
+ @dataclass(slots=True, frozen=True, kw_only=True)
198
+ class _NArgs:
199
+ n: Annotated[int, Arg(0)]
200
+
201
+
202
+ @dataclass(slots=True, frozen=True, kw_only=True)
203
+ class _TableArgs:
204
+ data: Annotated[TableInput, Arg(0)]
205
+
206
+
207
+ @dataclass(kw_only=True)
208
+ class _CursorState(ArrowSerializableDataclass):
209
+ row: int = 0
210
+
211
+
212
+ class TestResumeRegistration:
213
+ """resume() continues from state alone, so it needs a serializable TState."""
214
+
215
+ def test_resume_without_state_is_refused(self) -> None:
216
+ """Without a TState the cursor would be lost between HTTP turns."""
217
+
218
+ class _Stateless(RowTransformFunction[_NArgs]):
219
+ class Meta:
220
+ name = "stateless_resume"
221
+
222
+ @classmethod
223
+ def on_bind(cls, params: BindParams[_NArgs]) -> BindResponse:
224
+ return BindResponse(output_schema=schema({"i": pa.int64()}))
225
+
226
+ @classmethod
227
+ def resume(cls, params: ProcessParams[_NArgs], state: None, out: OutputCollector) -> None:
228
+ pass
229
+
230
+ with pytest.raises(TypeError, match="serializable TState"):
231
+ resolve_metadata(_Stateless)
232
+
233
+ def test_resume_with_max_workers_1_is_refused(self) -> None:
234
+ """max_workers = 1 runs on one shared connection, which cannot continue."""
235
+
236
+ class _Serial(RowTransformFunction[_NArgs, _CursorState]):
237
+ class Meta:
238
+ name = "serial_resume"
239
+ max_workers = 1
240
+
241
+ @classmethod
242
+ def on_bind(cls, params: BindParams[_NArgs]) -> BindResponse:
243
+ return BindResponse(output_schema=schema({"i": pa.int64()}))
244
+
245
+ @classmethod
246
+ def resume(cls, params: ProcessParams[_NArgs], state: _CursorState, out: OutputCollector) -> None:
247
+ pass
248
+
249
+ with pytest.raises(TypeError, match="max_workers = 1"):
250
+ resolve_metadata(_Serial)
251
+
252
+ def test_resume_with_state_resolves(self) -> None:
253
+ """RowTransformFunction[Args, State] is the supported shape."""
254
+
255
+ class _Stateful(RowTransformFunction[_NArgs, _CursorState]):
256
+ class Meta:
257
+ name = "stateful_resume"
258
+
259
+ @classmethod
260
+ def on_bind(cls, params: BindParams[_NArgs]) -> BindResponse:
261
+ return BindResponse(output_schema=schema({"i": pa.int64()}))
262
+
263
+ @classmethod
264
+ def resume(cls, params: ProcessParams[_NArgs], state: _CursorState, out: OutputCollector) -> None:
265
+ pass
266
+
267
+ assert resolve_metadata(_Stateful).input_from_args is True
268
+
269
+
270
+ class _RecordingCollector:
271
+ def __init__(self) -> None:
272
+ self.emits: list[dict[str, Any]] = []
273
+
274
+ def emit(self, batch: pa.RecordBatch, **kwargs: Any) -> None:
275
+ self.emits.append({"batch": batch, **kwargs})
276
+
277
+
278
+ class _MaskFilters:
279
+ """Stands in for PushdownFilters: keeps the rows a fixed mask selects."""
280
+
281
+ def __init__(self, mask: list[bool]) -> None:
282
+ self._mask = pa.array(mask)
283
+
284
+ def __bool__(self) -> bool:
285
+ return True
286
+
287
+ def evaluate(self, batch: pa.RecordBatch) -> pa.BooleanArray:
288
+ return self._mask
289
+
290
+
291
+ class TestFilteredProvenance:
292
+ """Auto-applied filters must drop the parent_rows of the rows they drop."""
293
+
294
+ def test_parent_rows_follow_the_filter(self) -> None:
295
+ """Filtering rows 1 and 3 drops their provenance; more= passes through."""
296
+ inner = _RecordingCollector()
297
+ out = _FilteringOutputCollector(inner, RowTransformFunction, _MaskFilters([True, False, True, False])) # type: ignore[arg-type]
298
+ out.emit(pa.record_batch({"i": [10, 11, 12, 13]}), parent_rows=[0, 0, 1, 2], more=True)
299
+ [emit] = inner.emits
300
+ assert emit["batch"].column("i").to_pylist() == [10, 12]
301
+ assert emit["parent_rows"] == [0, 1]
302
+ assert emit["more"] is True
303
+
304
+
305
+ class _FakeOut:
306
+ """The innermost collector: records what reaches the wire."""
307
+
308
+ def __init__(self) -> None:
309
+ self.emits: list[tuple[pa.RecordBatch, dict[str, str] | None]] = []
310
+ self.output_schema = pa.schema([pa.field("i", pa.int64())])
311
+ self.finished = False
312
+
313
+ def emit(self, batch: pa.RecordBatch, metadata: dict[str, str] | None = None) -> None:
314
+ self.emits.append((batch, metadata))
315
+
316
+
317
+ def _rows(*values: int) -> pa.RecordBatch:
318
+ return pa.record_batch({"i": pa.array(values, type=pa.int64())})
319
+
320
+
321
+ class TestCollectors:
322
+ """The tracking collector's continuation rules."""
323
+
324
+ def test_more_sets_have_more_output(self) -> None:
325
+ """more=True is the reply's vgi.status, and the collector remembers it."""
326
+ fake = _FakeOut()
327
+ out = _TrackingOutputCollector(fake, allows_more=True) # type: ignore[arg-type]
328
+ out.emit(_rows(1), more=True)
329
+ assert out.more is True
330
+ assert fake.emits[0][1] == {"vgi.status": "HAVE_MORE_OUTPUT"}
331
+
332
+ def test_more_is_refused_outside_a_table_in_out_exchange(self) -> None:
333
+ """Only a table-in-out exchange is ever ticked, so more=True elsewhere is an error."""
334
+ fake = _FakeOut()
335
+ out = _TrackingOutputCollector(fake) # type: ignore[arg-type]
336
+ with pytest.raises(ValueError, match="only valid in a table-in-out"):
337
+ out.emit(_rows(1), more=True)
338
+ assert fake.emits == []
339
+
340
+ def test_cache_control_is_refused_on_a_continuation(self) -> None:
341
+ """A reply to a tick is never an input's first batch, so it can't carry cache_control."""
342
+ out = _TrackingOutputCollector(_FakeOut(), continuation=True) # type: ignore[arg-type]
343
+ with pytest.raises(RuntimeError, match="only valid on the first emitted batch"):
344
+ out.emit(_rows(1), cache_control=CacheControl(ttl=60))
345
+
346
+
347
+ class TestInputRowsPerCall:
348
+ """Meta.input_rows_per_call: a positive int, on a RowTransformFunction only."""
349
+
350
+ def test_declared_value_resolves_and_round_trips(self) -> None:
351
+ """blended_sliced declares 3; it survives the Arrow and dict round-trips."""
352
+ from vgi._test_fixtures.table_in_out import BlendedSlicedFunction
353
+ from vgi.metadata import ResolvedMetadata, arrow_to_metadata, metadata_to_arrow
354
+
355
+ m = resolve_metadata(BlendedSlicedFunction)
356
+ assert m.input_rows_per_call == 3
357
+ assert arrow_to_metadata(metadata_to_arrow(m)).input_rows_per_call == 3
358
+ assert ResolvedMetadata.from_dict(m.to_dict()).input_rows_per_call == 3
359
+
360
+ def test_default_is_a_whole_chunk(self) -> None:
361
+ """Undeclared means no limit: the client sends a whole chunk per call."""
362
+ from vgi._test_fixtures.table_in_out import BlendedPagedFunction
363
+
364
+ assert resolve_metadata(BlendedPagedFunction).input_rows_per_call is None
365
+
366
+ @pytest.mark.parametrize("value", [0, -1, True, 2.5, "3"])
367
+ def test_non_positive_or_non_int_is_refused(self, value: object) -> None:
368
+ """Only a positive int is a row count."""
369
+
370
+ class _Bad(RowTransformFunction[_NArgs]):
371
+ class Meta:
372
+ name = "bad_rows_per_call"
373
+ input_rows_per_call = value
374
+
375
+ @classmethod
376
+ def on_bind(cls, params: BindParams[_NArgs]) -> BindResponse:
377
+ return BindResponse(output_schema=schema({"i": pa.int64()}))
378
+
379
+ with pytest.raises(ValueError, match="must be a positive int"):
380
+ resolve_metadata(_Bad)
381
+
382
+ def test_refused_outside_a_row_transform_function(self) -> None:
383
+ """A classic table-in-out function receives DuckDB's chunks as they are."""
384
+
385
+ class _Classic(TableInOutGenerator[_TableArgs]):
386
+ class Meta:
387
+ name = "classic_rows_per_call"
388
+ input_rows_per_call = 3
389
+
390
+ with pytest.raises(TypeError, match="applies only to a RowTransformFunction"):
391
+ resolve_metadata(_Classic)