vgi-python 0.22.1__tar.gz → 0.24.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 (406) hide show
  1. {vgi_python-0.22.1 → vgi_python-0.24.0}/.github/workflows/integration.yml +8 -1
  2. {vgi_python-0.22.1 → vgi_python-0.24.0}/CLAUDE.md +1 -0
  3. {vgi_python-0.22.1 → vgi_python-0.24.0}/PKG-INFO +6 -3
  4. vgi_python-0.24.0/docs/global-functions.md +88 -0
  5. {vgi_python-0.22.1 → vgi_python-0.24.0}/pyproject.toml +13 -3
  6. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_declarative.py +148 -0
  7. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_serialization.py +3 -1
  8. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_directory_parity.py +13 -0
  9. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_protocol_version.py +3 -3
  10. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/landing/describe.expected.json +39 -1
  11. vgi_python-0.24.0/tests/table/test_wide_columns.py +84 -0
  12. vgi_python-0.24.0/tests/test_call_state_attach.py +346 -0
  13. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_protocol_classes.py +90 -0
  14. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_setting_secret_annotations.py +47 -2
  15. vgi_python-0.24.0/tests/test_signing_key.py +96 -0
  16. {vgi_python-0.22.1 → vgi_python-0.24.0}/uv.lock +164 -32
  17. vgi_python-0.24.0/vgi/_test_fixtures/global_functions.py +316 -0
  18. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/http_server.py +4 -0
  19. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/_common.py +46 -3
  20. vgi_python-0.24.0/vgi/_test_fixtures/table/wide.py +113 -0
  21. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/worker.py +27 -0
  22. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/argument_spec.py +51 -0
  23. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/catalog/catalog_interface.py +39 -0
  24. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/catalog/descriptors.py +79 -0
  25. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/function.py +54 -0
  26. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/function_storage.py +71 -1
  27. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/logging_config.py +68 -0
  28. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/meta_worker.py +31 -0
  29. vgi_python-0.24.0/vgi/profiling.py +93 -0
  30. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/protocol.py +261 -110
  31. vgi_python-0.24.0/vgi/protocol_version.txt +1 -0
  32. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/serve.py +371 -17
  33. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/table_function.py +147 -53
  34. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/worker.py +146 -15
  35. vgi_python-0.22.1/vgi/protocol_version.txt +0 -1
  36. {vgi_python-0.22.1 → vgi_python-0.24.0}/.gitattributes +0 -0
  37. {vgi_python-0.22.1 → vgi_python-0.24.0}/.github/dependabot.yml +0 -0
  38. {vgi_python-0.22.1 → vgi_python-0.24.0}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
  39. {vgi_python-0.22.1 → vgi_python-0.24.0}/.github/workflows/ci.yml +0 -0
  40. {vgi_python-0.22.1 → vgi_python-0.24.0}/.github/workflows/docs.yml +0 -0
  41. {vgi_python-0.22.1 → vgi_python-0.24.0}/.github/workflows/release.yml +0 -0
  42. {vgi_python-0.22.1 → vgi_python-0.24.0}/.gitignore +0 -0
  43. {vgi_python-0.22.1 → vgi_python-0.24.0}/.python-version +0 -0
  44. {vgi_python-0.22.1 → vgi_python-0.24.0}/.vale.ini +0 -0
  45. {vgi_python-0.22.1 → vgi_python-0.24.0}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
  46. {vgi_python-0.22.1 → vgi_python-0.24.0}/DOCS_REVIEW_RUBRIC.md +0 -0
  47. {vgi_python-0.22.1 → vgi_python-0.24.0}/DOCS_USABILITY_TEST.md +0 -0
  48. {vgi_python-0.22.1 → vgi_python-0.24.0}/LICENSE +0 -0
  49. {vgi_python-0.22.1 → vgi_python-0.24.0}/README.md +0 -0
  50. {vgi_python-0.22.1 → vgi_python-0.24.0}/SECURITY.md +0 -0
  51. {vgi_python-0.22.1 → vgi_python-0.24.0}/ci/README.md +0 -0
  52. {vgi_python-0.22.1 → vgi_python-0.24.0}/ci/preprocess-require.awk +0 -0
  53. {vgi_python-0.22.1 → vgi_python-0.24.0}/ci/run-integration.sh +0 -0
  54. {vgi_python-0.22.1 → vgi_python-0.24.0}/dist-vgi/.gitignore +0 -0
  55. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/aggregate-functions.md +0 -0
  56. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/arguments.md +0 -0
  57. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/auth.md +0 -0
  58. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/catalogs.md +0 -0
  59. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/client.md +0 -0
  60. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/exceptions.md +0 -0
  61. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/filters.md +0 -0
  62. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/functions.md +0 -0
  63. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/http.md +0 -0
  64. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/index.md +0 -0
  65. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/metadata.md +0 -0
  66. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/observability.md +0 -0
  67. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/storage.md +0 -0
  68. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/transactor.md +0 -0
  69. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/api/worker.md +0 -0
  70. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/argument-serialization.md +0 -0
  71. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/apple-touch-icon.png +0 -0
  72. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/favicon-16x16.png +0 -0
  73. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/favicon-32x32.png +0 -0
  74. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/favicon.ico +0 -0
  75. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/kinds/aggregate.svg +0 -0
  76. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/kinds/buffering.svg +0 -0
  77. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/kinds/scalar.svg +0 -0
  78. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/kinds/table-in-out.svg +0 -0
  79. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/kinds/table.svg +0 -0
  80. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/logo.png +0 -0
  81. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/assets/social-card.png +0 -0
  82. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/authentication.md +0 -0
  83. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/catalog-interface.md +0 -0
  84. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/cli.md +0 -0
  85. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/column-statistics.md +0 -0
  86. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/concepts/index.md +0 -0
  87. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/contributing-docs.md +0 -0
  88. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/filter-pushdown.md +0 -0
  89. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/generator-api.md +0 -0
  90. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/how-to/catalogs.md +0 -0
  91. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/how-to/function-patterns.md +0 -0
  92. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/how-to/http-auth.md +0 -0
  93. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/how-to/index.md +0 -0
  94. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/how-to/pushdown-and-statistics.md +0 -0
  95. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/how-to/state-storage.md +0 -0
  96. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/index.md +0 -0
  97. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/lifecycle.md +0 -0
  98. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/metadata.md +0 -0
  99. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/overrides/main.html +0 -0
  100. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/robots.txt +0 -0
  101. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/shared-storage.md +0 -0
  102. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/stylesheets/extra.css +0 -0
  103. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/tutorial/index.md +0 -0
  104. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/tutorial/scalar.md +0 -0
  105. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/tutorial/table.md +0 -0
  106. {vgi_python-0.22.1 → vgi_python-0.24.0}/docs/vgi-logo.png +0 -0
  107. {vgi_python-0.22.1 → vgi_python-0.24.0}/examples/calc_scalar_worker.py +0 -0
  108. {vgi_python-0.22.1 → vgi_python-0.24.0}/examples/calc_worker.py +0 -0
  109. {vgi_python-0.22.1 → vgi_python-0.24.0}/examples/filter_worker.py +0 -0
  110. {vgi_python-0.22.1 → vgi_python-0.24.0}/examples/greeting_scalar_worker.py +0 -0
  111. {vgi_python-0.22.1 → vgi_python-0.24.0}/examples/row_count_worker.py +0 -0
  112. {vgi_python-0.22.1 → vgi_python-0.24.0}/examples/series_streaming_worker.py +0 -0
  113. {vgi_python-0.22.1 → vgi_python-0.24.0}/examples/sum_worker.py +0 -0
  114. {vgi_python-0.22.1 → vgi_python-0.24.0}/mkdocs.yml +0 -0
  115. {vgi_python-0.22.1 → vgi_python-0.24.0}/packages/vgi-fixtures/LICENSE +0 -0
  116. {vgi_python-0.22.1 → vgi_python-0.24.0}/packages/vgi-fixtures/README.md +0 -0
  117. {vgi_python-0.22.1 → vgi_python-0.24.0}/packages/vgi-fixtures/docker/Dockerfile +0 -0
  118. {vgi_python-0.22.1 → vgi_python-0.24.0}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
  119. {vgi_python-0.22.1 → vgi_python-0.24.0}/packages/vgi-fixtures/pyproject.toml +0 -0
  120. {vgi_python-0.22.1 → vgi_python-0.24.0}/scripts/measure_startup.py +0 -0
  121. {vgi_python-0.22.1 → vgi_python-0.24.0}/scripts/run_all_tests.sh +0 -0
  122. {vgi_python-0.22.1 → vgi_python-0.24.0}/test-data/generate.sh +0 -0
  123. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/__init__.py +0 -0
  124. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/_http_fixtures.py +0 -0
  125. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/__init__.py +0 -0
  126. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_catalog_interface.py +0 -0
  127. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_client_catalog.py +0 -0
  128. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_column_statistics.py +0 -0
  129. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_example_worker_catalog.py +0 -0
  130. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_integration.py +0 -0
  131. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_required_filters.py +0 -0
  132. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_scan_branches.py +0 -0
  133. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_setting.py +0 -0
  134. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_storage.py +0 -0
  135. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_time_travel.py +0 -0
  136. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/catalog/test_writable_table.py +0 -0
  137. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/client/__init__.py +0 -0
  138. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/client/test_broken_pipe.py +0 -0
  139. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/client/test_cli.py +0 -0
  140. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/client/test_cli_catalog_functions.py +0 -0
  141. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/client/test_worker_debug.py +0 -0
  142. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/__init__.py +0 -0
  143. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/_stub.py +0 -0
  144. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/conftest.py +0 -0
  145. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_accumulate.py +0 -0
  146. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_aggregate.py +0 -0
  147. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_attach.py +0 -0
  148. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_bearer_auth.py +0 -0
  149. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_const_param_enforcement.py +0 -0
  150. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_container.py +0 -0
  151. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_copy_from.py +0 -0
  152. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_copy_to.py +0 -0
  153. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_function_inventory.py +0 -0
  154. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_github.py +0 -0
  155. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_http_client.py +0 -0
  156. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_http_external_location.py +0 -0
  157. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_http_upload_url.py +0 -0
  158. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_macro.py +0 -0
  159. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_overload.py +0 -0
  160. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_protocol_inventory.py +0 -0
  161. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_resumable_scan.py +0 -0
  162. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_scalar.py +0 -0
  163. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
  164. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_secret.py +0 -0
  165. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_settings.py +0 -0
  166. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_table.py +0 -0
  167. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_table_in_out.py +0 -0
  168. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_view.py +0 -0
  169. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conformance/test_writable.py +0 -0
  170. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/conftest.py +0 -0
  171. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/landing/_checker.py +0 -0
  172. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/landing/describe.schema.json +0 -0
  173. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/__init__.py +0 -0
  174. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/test_bernoulli_function.py +0 -0
  175. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/test_binary_packet_function.py +0 -0
  176. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/test_client.py +0 -0
  177. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/test_conditional_message_function.py +0 -0
  178. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/test_hash_seed_function.py +0 -0
  179. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/test_multiply_by_setting_function.py +0 -0
  180. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/test_multiply_function.py +0 -0
  181. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/test_random_bytes_function.py +0 -0
  182. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/scalar/test_return_secret_value_function.py +0 -0
  183. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/__init__.py +0 -0
  184. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/__init__.py +0 -0
  185. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_constant_columns_function.py +0 -0
  186. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_double_sequence_function.py +0 -0
  187. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_exception_function.py +0 -0
  188. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_filter_echo_function.py +0 -0
  189. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_logging_function.py +0 -0
  190. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_nested_sequence_function.py +0 -0
  191. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_partitioned_function.py +0 -0
  192. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_projected_data_function.py +0 -0
  193. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_sequence_function.py +0 -0
  194. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_settings_function.py +0 -0
  195. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_struct_settings_function.py +0 -0
  196. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table/generator/test_ten_thousand_function.py +0 -0
  197. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/__init__.py +0 -0
  198. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/generator/__init__.py +0 -0
  199. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
  200. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/generator/test_echo_function.py +0 -0
  201. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/generator/test_exception_functions.py +0 -0
  202. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
  203. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
  204. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
  205. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
  206. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/test_blended_metadata.py +0 -0
  207. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/table_in_out/test_client.py +0 -0
  208. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_access_log_audit.py +0 -0
  209. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_aggregate_function.py +0 -0
  210. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_argument_spec.py +0 -0
  211. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_auth.py +0 -0
  212. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_bind_exceptions.py +0 -0
  213. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_bind_request_at_clause.py +0 -0
  214. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_bound_storage_conformance.py +0 -0
  215. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_cache_control.py +0 -0
  216. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_catalog_auth_binding.py +0 -0
  217. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_copy_from_function.py +0 -0
  218. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_copy_to_function.py +0 -0
  219. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_docstrings.py +0 -0
  220. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_documentation_examples.py +0 -0
  221. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_example_function_arg_types.py +0 -0
  222. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_examples_workers.py +0 -0
  223. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_exception_handling.py +0 -0
  224. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_exceptions.py +0 -0
  225. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_filter_pushdown.py +0 -0
  226. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_filter_pushdown_extension.py +0 -0
  227. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_function_storage.py +0 -0
  228. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_function_storage_azure_sql.py +0 -0
  229. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_function_storage_cf_do.py +0 -0
  230. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_function_storage_cf_do_integration.py +0 -0
  231. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_function_storage_conformance.py +0 -0
  232. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_cpp_constants.py +0 -0
  233. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_cpp_protocol_version.py +0 -0
  234. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_cpp_request_builders.py +0 -0
  235. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_cpp_schemas.py +0 -0
  236. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_cpp_secret.py +0 -0
  237. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_go_schemas.py +0 -0
  238. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_protocol_version.py +0 -0
  239. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_schemas_cross_lang.py +0 -0
  240. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_ts_client.py +0 -0
  241. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_generated_ts_schemas.py +0 -0
  242. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_http_demo_storage.py +0 -0
  243. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_http_s3_offload_input.py +0 -0
  244. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_http_s3_offload_output.py +0 -0
  245. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_landing_conformance.py +0 -0
  246. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_metadata.py +0 -0
  247. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_mypy_consolidated.py +0 -0
  248. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_nest_tensor.py +0 -0
  249. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_otel.py +0 -0
  250. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_projection_enforcement.py +0 -0
  251. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_projection_repro.py +0 -0
  252. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_resolved_secrets.py +0 -0
  253. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_schema_scoped_functions.py +0 -0
  254. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_schema_utils.py +0 -0
  255. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_serve.py +0 -0
  256. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_table_buffering_function.py +0 -0
  257. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_table_function_dynamic_to_string.py +0 -0
  258. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_tcp_transport.py +0 -0
  259. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_type_bounds.py +0 -0
  260. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_union_argument.py +0 -0
  261. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_worker.py +0 -0
  262. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_worker_cli.py +0 -0
  263. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/test_worker_page.py +0 -0
  264. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/transactor/__init__.py +0 -0
  265. {vgi_python-0.22.1 → vgi_python-0.24.0}/tests/transactor/test_transactor.py +0 -0
  266. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/__init__.py +0 -0
  267. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_duckdb.py +0 -0
  268. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_storage_profile.py +0 -0
  269. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/__init__.py +0 -0
  270. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
  271. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/accumulate/worker.py +0 -0
  272. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
  273. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/_common.py +0 -0
  274. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/basic.py +0 -0
  275. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
  276. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/generic.py +0 -0
  277. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
  278. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
  279. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
  280. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
  281. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
  282. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
  283. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/window.py +0 -0
  284. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/attach_options.py +0 -0
  285. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/bad_enum.py +0 -0
  286. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/bad_protocol.py +0 -0
  287. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/cancellable.py +0 -0
  288. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/catalog.py +0 -0
  289. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/companion.py +0 -0
  290. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/copy_from.py +0 -0
  291. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/copy_to.py +0 -0
  292. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
  293. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
  294. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/nest_tensor.py +0 -0
  295. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/orchard_catalog.py +0 -0
  296. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
  297. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
  298. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/__init__.py +0 -0
  299. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/_common.py +0 -0
  300. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
  301. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
  302. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/binary.py +0 -0
  303. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/formatting.py +0 -0
  304. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/geo.py +0 -0
  305. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
  306. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
  307. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/same_name.py +0 -0
  308. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
  309. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/type_info.py +0 -0
  310. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
  311. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
  312. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/simple_writable.py +0 -0
  313. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/__init__.py +0 -0
  314. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/batch_index.py +0 -0
  315. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
  316. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/cache.py +0 -0
  317. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
  318. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/filters.py +0 -0
  319. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/late_materialization.py +0 -0
  320. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/make_series.py +0 -0
  321. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/misc.py +0 -0
  322. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/order_modes.py +0 -0
  323. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/pairs.py +0 -0
  324. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/partition_columns.py +0 -0
  325. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
  326. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/profiling_example.py +0 -0
  327. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/required_filters.py +0 -0
  328. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
  329. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/sequence.py +0 -0
  330. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/settings.py +0 -0
  331. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
  332. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
  333. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/typed_probe.py +0 -0
  334. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table/versioned.py +0 -0
  335. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table_in_out.py +0 -0
  336. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
  337. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/twin_catalogs.py +0 -0
  338. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/versioned.py +0 -0
  339. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/versioned_tables.py +0 -0
  340. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/writable/__init__.py +0 -0
  341. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/writable/generic.py +0 -0
  342. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/writable/table.py +0 -0
  343. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/_test_fixtures/writable/worker.py +0 -0
  344. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/aggregate_function.py +0 -0
  345. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/arguments.py +0 -0
  346. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/attach_header.py +0 -0
  347. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/auth.py +0 -0
  348. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/cache_control.py +0 -0
  349. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/catalog/__init__.py +0 -0
  350. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/catalog/_descriptor_spec.py +0 -0
  351. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/catalog/attach_option.py +0 -0
  352. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/catalog/duckdb_statistics.py +0 -0
  353. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/catalog/secret_type.py +0 -0
  354. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/catalog/setting.py +0 -0
  355. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/catalog/storage.py +0 -0
  356. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/__init__.py +0 -0
  357. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/catalog_mixin.py +0 -0
  358. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/cli.py +0 -0
  359. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/cli_catalog.py +0 -0
  360. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/cli_schema.py +0 -0
  361. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/cli_table.py +0 -0
  362. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/cli_transaction.py +0 -0
  363. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/cli_utils.py +0 -0
  364. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/cli_view.py +0 -0
  365. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/client/client.py +0 -0
  366. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/__init__.py +0 -0
  367. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/_common.py +0 -0
  368. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/cpp_constants.py +0 -0
  369. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/cpp_protocol_version.py +0 -0
  370. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/cpp_request_builders.py +0 -0
  371. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/cpp_schemas.py +0 -0
  372. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
  373. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/cpp_secret_request_builders.py +0 -0
  374. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/cpp_secret_schemas.py +0 -0
  375. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/go_schemas.py +0 -0
  376. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/protocol_version.py +0 -0
  377. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/ts_client.py +0 -0
  378. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/codegen/ts_schemas.py +0 -0
  379. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/copy_from_function.py +0 -0
  380. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/copy_to_function.py +0 -0
  381. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/exceptions.py +0 -0
  382. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/function_storage_azure_sql.py +0 -0
  383. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/function_storage_cf_do.py +0 -0
  384. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/http/__init__.py +0 -0
  385. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/http/demo_storage.py +0 -0
  386. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/http/describe_json.py +0 -0
  387. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/http/landing.html +0 -0
  388. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/http/landing_page.py +0 -0
  389. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/http/worker_page.py +0 -0
  390. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/invocation.py +0 -0
  391. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/metadata.py +0 -0
  392. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/otel.py +0 -0
  393. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/py.typed +0 -0
  394. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/scalar_function.py +0 -0
  395. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/schema_utils.py +0 -0
  396. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/secret_protocol.py +0 -0
  397. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/secret_service.py +0 -0
  398. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/table_buffering_function.py +0 -0
  399. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/table_filter_pushdown.py +0 -0
  400. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/table_in_out_function.py +0 -0
  401. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/transactor/__init__.py +0 -0
  402. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/transactor/_duckdb_compat.py +0 -0
  403. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/transactor/client.py +0 -0
  404. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/transactor/protocol.py +0 -0
  405. {vgi_python-0.22.1 → vgi_python-0.24.0}/vgi/transactor/server.py +0 -0
  406. {vgi_python-0.22.1 → vgi_python-0.24.0}/wrangler.jsonc +0 -0
@@ -32,7 +32,14 @@ env:
32
32
  VGI_REF: main
33
33
  # The Haybarn release providing the prebuilt haybarn-unittest binary. Must be
34
34
  # ABI-compatible with the community-published vgi extension.
35
- HAYBARN_RELEASE: haybarn-v1.5.4-rc3
35
+ HAYBARN_RELEASE: haybarn-v1.5.5-rc1
36
+ # CI is not a user: its ATTACHes should not land in Query.Farm's adoption data.
37
+ # The vgi extension fires a telemetry event per successful ATTACH, and this
38
+ # suite performs several hundred of them per lane, so opting out keeps the
39
+ # numbers honest. It also removes telemetry as a variable in lane timings —
40
+ # the per-ATTACH event was added in Query-farm/vgi 71e2d51 (2026-07-12), and
41
+ # the stdio lane total stepped from ~690s to ~870s across that window.
42
+ QUERY_FARM_TELEMETRY_OPT_OUT: "1"
36
43
 
37
44
  jobs:
38
45
  integration:
@@ -508,4 +508,5 @@ The table schema is automatically derived from the function's `output_schema`:
508
508
  - **Function lifecycle**: `docs/lifecycle.md`
509
509
  - **Generator API (advanced)**: `docs/generator-api.md`
510
510
  - **Catalog interface**: `docs/catalog-interface.md`
511
+ - **Global functions (system.main)**: `docs/global-functions.md`
511
512
  - **Shared storage backends**: `docs/shared-storage.md`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vgi-python
3
- Version: 0.22.1
3
+ Version: 0.24.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
@@ -162,7 +162,7 @@ Requires-Dist: httpx>=0.24
162
162
  Requires-Dist: platformdirs
163
163
  Requires-Dist: pyarrow
164
164
  Requires-Dist: typer>=0.9
165
- Requires-Dist: vgi-rpc>=0.28.3
165
+ Requires-Dist: vgi-rpc>=0.33.0
166
166
  Provides-Extra: azure
167
167
  Requires-Dist: azure-identity>=1.16.0; extra == 'azure'
168
168
  Requires-Dist: pymssql>=2.3.0; extra == 'azure'
@@ -190,8 +190,11 @@ Provides-Extra: duckdb
190
190
  Requires-Dist: duckdb>=1.5.3; extra == 'duckdb'
191
191
  Provides-Extra: fixtures
192
192
  Requires-Dist: vgi-fixtures; extra == 'fixtures'
193
+ Provides-Extra: granian
194
+ Requires-Dist: granian>=2.7; extra == 'granian'
195
+ Requires-Dist: vgi-rpc[http]; extra == 'granian'
193
196
  Provides-Extra: haybarn
194
- Requires-Dist: haybarn>=1.5.3rc10; extra == 'haybarn'
197
+ Requires-Dist: haybarn>=1.5.5rc1; extra == 'haybarn'
195
198
  Provides-Extra: http
196
199
  Requires-Dist: vgi-rpc[http]; extra == 'http'
197
200
  Provides-Extra: oauth
@@ -0,0 +1,88 @@
1
+ # Global functions
2
+
3
+ A VGI catalog normally exposes its functions under its own name — `mycat.main.my_func()`.
4
+ Some functions aren't *about* the attached catalog at all: diagnostics, converters, format
5
+ helpers. For those, a worker can ask the client to also publish them into the **global**
6
+ function namespace (DuckDB's `system.main`), so they can be called unqualified:
7
+
8
+ ```sql
9
+ ATTACH 'acme' AS acme (TYPE vgi, LOCATION 'acme-worker');
10
+ SELECT * FROM acme_table_info('acme'); -- no catalog qualifier
11
+ ```
12
+
13
+ This mirrors how `ducklake_table_info` is reachable after `LOAD ducklake`, except that a VGI
14
+ worker's globals appear at `ATTACH` time rather than at extension load.
15
+
16
+ ## Declaring globals
17
+
18
+ Add the function classes to `Catalog.global_functions` and pick a prefix:
19
+
20
+ ```python
21
+ from vgi.catalog import Catalog, Schema
22
+
23
+ CATALOG = Catalog(
24
+ name="acme",
25
+ global_function_prefix="acme",
26
+ global_functions=[TableInfoFunction, ChecksumFunction],
27
+ schemas=[
28
+ Schema(name="main", functions=[TableInfoFunction, ChecksumFunction, ...]),
29
+ ],
30
+ )
31
+ ```
32
+
33
+ All four function types are supported: scalar, aggregate, table, and table-buffering.
34
+
35
+ **Every global must also appear in exactly one `Schema.functions`.** This is enforced in
36
+ `Catalog.__post_init__`. Bind dispatch is keyed on `(schema_name, name)`, so a function listed
37
+ only in `global_functions` would be registered by the client but never dispatchable. Keeping it
38
+ schema-resident also means the qualified name (`acme.main.table_info()`) keeps working, which is
39
+ the unambiguous fallback if the global name is unavailable.
40
+
41
+ ### The prefix
42
+
43
+ `global_function_prefix` is applied by the client to form the globally visible name:
44
+
45
+ | prefix | function name | published as |
46
+ |---|---|---|
47
+ | `"acme"` | `table_info` | `acme_table_info` |
48
+ | `None` | `table_info` | `table_info` |
49
+
50
+ The prefix must match `[a-z_][a-z0-9_]*` — it is concatenated into a SQL identifier.
51
+
52
+ **Prefer a prefix.** `system.main` is shared by every extension and every attached VGI worker in
53
+ the process. An unprefixed name like `table_info` is very likely to be claimed by someone else,
54
+ in which case yours is silently skipped (see below). A prefix that identifies your worker makes
55
+ collisions essentially impossible.
56
+
57
+ ## What the client does with them
58
+
59
+ Registration is **best-effort and advisory**. Do not build anything that requires a global name
60
+ to resolve — treat it as an ergonomic alias for the schema-qualified name, which is the one with
61
+ guarantees.
62
+
63
+ Specifically, on the DuckDB side:
64
+
65
+ - **First attach wins.** If the name is already owned by a different worker, yours is skipped and
66
+ logged; your `ATTACH` still succeeds and the function stays reachable at its qualified path.
67
+ - **Re-`ATTACH` is idempotent.** Attaching the same worker again reuses the existing registration
68
+ and refreshes its connection state.
69
+ - **The user can turn it off.** `ATTACH ... (TYPE vgi, global_functions false)` suppresses
70
+ publishing entirely for that attach.
71
+ - **Registration outlives `DETACH`.** DuckDB has no API to unregister a function, so the entry
72
+ persists for the life of the process. Calling it after `DETACH` raises an error telling the user
73
+ to re-`ATTACH` rather than silently reconnecting to a detached catalog.
74
+
75
+ Use `vgi_global_functions()` to see what is currently published, who owns it, and whether it is
76
+ still live.
77
+
78
+ ## Protocol
79
+
80
+ Globals ride on the existing attach response — there is no extra round trip and no separate RPC.
81
+ `CatalogAttachResult` carries:
82
+
83
+ - `global_functions: list[bytes]` — IPC-serialized `FunctionInfo` records. `name` and
84
+ `schema_name` are the real dispatch coordinates; the prefix is *not* baked into `name`.
85
+ - `global_function_prefix: str` — empty string means publish bare names.
86
+
87
+ Both fields are additive and default to empty, so a worker that doesn't set them advertises
88
+ nothing. Introduced in protocol version 1.3.0.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "vgi-python"
3
- version = "0.22.1"
3
+ version = "0.24.0"
4
4
  description = "Vector Gateway Interface - Connect DuckDB to external programs via Apache Arrow"
5
5
  readme = "README.md"
6
6
  keywords = [
@@ -40,7 +40,7 @@ dependencies = [
40
40
  "pyarrow",
41
41
  "typer>=0.9",
42
42
  "platformdirs",
43
- "vgi-rpc>=0.28.3",
43
+ "vgi-rpc>=0.33.0",
44
44
  "httpx>=0.24",
45
45
  ]
46
46
 
@@ -49,9 +49,13 @@ dependencies = [
49
49
  # evaluation, the transactor, and the statistics fixtures. It is resolved
50
50
  # lazily in vgi/_duckdb.py: haybarn is preferred, stock duckdb is the
51
51
  # fallback. Neither is a hard dependency — install one via these extras.
52
- haybarn = ["haybarn>=1.5.3rc10"]
52
+ haybarn = ["haybarn>=1.5.5rc1"]
53
53
  duckdb = ["duckdb>=1.5.3"]
54
54
  http = ["vgi-rpc[http]"]
55
+ # Alternative HTTP server: granian moves socket I/O and HTTP parsing into Rust,
56
+ # off the GIL. Optional because it is a compiled extension where waitress is
57
+ # pure Python; select it with `vgi-serve --http --server granian`.
58
+ granian = ["vgi-rpc[http]", "granian>=2.7"]
55
59
  oauth = ["vgi-rpc[oauth]"]
56
60
  otel = ["vgi-rpc[otel]"]
57
61
  sentry = ["vgi-rpc[sentry]"]
@@ -187,6 +191,12 @@ warn_unused_ignores = true
187
191
  module = "typer.*"
188
192
  ignore_missing_imports = true
189
193
 
194
+ [[tool.mypy.overrides]]
195
+ # granian ships no stubs, and is an optional extra used only behind
196
+ # `--server granian`.
197
+ module = "granian.*"
198
+ ignore_missing_imports = true
199
+
190
200
  [[tool.mypy.overrides]]
191
201
  # These files have type: ignore comments for ty that mypy doesn't need
192
202
  module = ["vgi._test_fixtures.scalar.null_handling", "vgi.table_function"]
@@ -26,6 +26,7 @@ from vgi.catalog import (
26
26
  Catalog,
27
27
  CatalogAttachResult,
28
28
  ForeignKeyDef,
29
+ FunctionInfo,
29
30
  Macro,
30
31
  MacroInfo,
31
32
  MacroType,
@@ -41,6 +42,7 @@ from vgi.catalog import (
41
42
  View,
42
43
  ViewInfo,
43
44
  )
45
+ from vgi.catalog.catalog_interface import FunctionType as CatalogInterfaceFunctionType
44
46
  from vgi.invocation import BindResponse
45
47
  from vgi.schema_utils import schema
46
48
  from vgi.table_function import (
@@ -1394,6 +1396,152 @@ class TestCatalogValidation:
1394
1396
  Catalog(name="myapp", schemas=[s1, s2])
1395
1397
 
1396
1398
 
1399
+ class TestGlobalFunctionsValidation:
1400
+ """Validation for ``Catalog.global_functions`` / ``global_function_prefix``."""
1401
+
1402
+ def test_defaults_are_empty(self) -> None:
1403
+ """A catalog publishes nothing globally unless it asks to."""
1404
+ catalog = Catalog(name="myapp", schemas=[Schema(name="main")])
1405
+ assert catalog.global_functions == ()
1406
+ assert catalog.global_function_prefix is None
1407
+
1408
+ def test_accepts_schema_resident_function(self) -> None:
1409
+ """The happy path: listed once globally, resident in exactly one schema."""
1410
+ catalog = Catalog(
1411
+ name="myapp",
1412
+ schemas=[Schema(name="main", functions=[UsersFunction])],
1413
+ global_functions=[UsersFunction],
1414
+ global_function_prefix="myapp",
1415
+ )
1416
+ assert list(catalog.global_functions) == [UsersFunction]
1417
+ assert catalog.global_function_prefix == "myapp"
1418
+
1419
+ def test_rejects_function_absent_from_every_schema(self) -> None:
1420
+ """A global function that isn't schema-resident would never dispatch."""
1421
+ with pytest.raises(ValueError, match="does not appear in any Schema.functions"):
1422
+ Catalog(
1423
+ name="myapp",
1424
+ schemas=[Schema(name="main")],
1425
+ global_functions=[UsersFunction],
1426
+ )
1427
+
1428
+ def test_rejects_function_resident_in_multiple_schemas(self) -> None:
1429
+ """Two homes make the global registration ambiguous about dispatch."""
1430
+ with pytest.raises(ValueError, match="appears in multiple schemas"):
1431
+ Catalog(
1432
+ name="myapp",
1433
+ schemas=[
1434
+ Schema(name="main", functions=[UsersFunction]),
1435
+ Schema(name="other", functions=[UsersFunction]),
1436
+ ],
1437
+ global_functions=[UsersFunction],
1438
+ )
1439
+
1440
+ def test_rejects_duplicate_global_entries(self) -> None:
1441
+ """Listing a class twice would publish the same name twice."""
1442
+ with pytest.raises(ValueError, match="duplicate entry UsersFunction"):
1443
+ Catalog(
1444
+ name="myapp",
1445
+ schemas=[Schema(name="main", functions=[UsersFunction])],
1446
+ global_functions=[UsersFunction, UsersFunction],
1447
+ )
1448
+
1449
+ @pytest.mark.parametrize("prefix", ["9bad", "Bad", "has-dash", "has space", "", "trailing;"])
1450
+ def test_rejects_non_identifier_prefix(self, prefix: str) -> None:
1451
+ """The prefix is concatenated into a SQL identifier, so it must be safe."""
1452
+ with pytest.raises(ValueError, match="not a valid SQL identifier prefix"):
1453
+ Catalog(
1454
+ name="myapp",
1455
+ schemas=[Schema(name="main", functions=[UsersFunction])],
1456
+ global_functions=[UsersFunction],
1457
+ global_function_prefix=prefix,
1458
+ )
1459
+
1460
+ def test_prefix_validated_even_without_global_functions(self) -> None:
1461
+ """A bad prefix is a bug worth reporting even if nothing uses it yet."""
1462
+ with pytest.raises(ValueError, match="not a valid SQL identifier prefix"):
1463
+ Catalog(name="myapp", schemas=[Schema(name="main")], global_function_prefix="Bad")
1464
+
1465
+
1466
+ class TestGlobalFunctionsAttachResult:
1467
+ """``catalog_attach`` advertises globals so the client can publish them."""
1468
+
1469
+ @staticmethod
1470
+ def _attach(catalog_obj: Catalog) -> CatalogAttachResult:
1471
+ class _TestCatalog(ReadOnlyCatalogInterface):
1472
+ catalog = catalog_obj
1473
+
1474
+ return _TestCatalog().catalog_attach(
1475
+ name=catalog_obj.name,
1476
+ options={},
1477
+ data_version_spec=None,
1478
+ implementation_version=None,
1479
+ )
1480
+
1481
+ def test_absent_when_not_declared(self) -> None:
1482
+ """Catalogs that declare nothing advertise an empty list and no prefix."""
1483
+ result = self._attach(Catalog(name="myapp", schemas=[Schema(name="main", functions=[UsersFunction])]))
1484
+ assert result.global_functions == []
1485
+ assert result.global_function_prefix == ""
1486
+
1487
+ def test_carries_serialized_function_info(self) -> None:
1488
+ """Each global arrives as a FunctionInfo with real dispatch coordinates.
1489
+
1490
+ ``name``/``schema_name`` must stay the values bind dispatches on — the
1491
+ prefix is applied client-side, not baked into the name here.
1492
+ """
1493
+ result = self._attach(
1494
+ Catalog(
1495
+ name="myapp",
1496
+ schemas=[Schema(name="analytics", functions=[UsersFunction])],
1497
+ default_schema="analytics",
1498
+ global_functions=[UsersFunction],
1499
+ global_function_prefix="myapp",
1500
+ )
1501
+ )
1502
+ assert result.global_function_prefix == "myapp"
1503
+ assert len(result.global_functions) == 1
1504
+
1505
+ info = FunctionInfo.deserialize_from_bytes(result.global_functions[0])
1506
+ assert info.name == "users"
1507
+ assert info.schema_name == "analytics"
1508
+ assert info.function_type == CatalogInterfaceFunctionType.TABLE
1509
+
1510
+ def test_prefix_empty_string_when_unset(self) -> None:
1511
+ """``None`` prefix serializes as empty string — the wire type is str."""
1512
+ result = self._attach(
1513
+ Catalog(
1514
+ name="myapp",
1515
+ schemas=[Schema(name="main", functions=[UsersFunction])],
1516
+ global_functions=[UsersFunction],
1517
+ )
1518
+ )
1519
+ assert result.global_function_prefix == ""
1520
+ assert len(result.global_functions) == 1
1521
+
1522
+ def test_example_fixture_publishes_one_of_each_function_type(self) -> None:
1523
+ """The shipped fixture covers all four types for the C++ integration suite."""
1524
+ from vgi._test_fixtures.worker import ExampleCatalog
1525
+
1526
+ result = ExampleCatalog().catalog_attach(
1527
+ name="example",
1528
+ options={},
1529
+ data_version_spec=None,
1530
+ implementation_version=None,
1531
+ )
1532
+ assert result.global_function_prefix == "vgi_example"
1533
+ infos = [FunctionInfo.deserialize_from_bytes(b) for b in result.global_functions]
1534
+ assert {i.function_type for i in infos} == {
1535
+ CatalogInterfaceFunctionType.SCALAR,
1536
+ CatalogInterfaceFunctionType.TABLE,
1537
+ CatalogInterfaceFunctionType.AGGREGATE,
1538
+ CatalogInterfaceFunctionType.TABLE_BUFFERING,
1539
+ }
1540
+ # Every advertised global must be schema-resident, or it could never
1541
+ # be dispatched after the client registers it.
1542
+ assert all(i.schema_name == "main" for i in infos)
1543
+
1544
+
1397
1545
  # =============================================================================
1398
1546
  # ReadOnlyCatalogInterface with Catalog Object Tests
1399
1547
  # =============================================================================
@@ -1110,7 +1110,7 @@ class TestArrowSchemaCorrectness:
1110
1110
  def test_catalog_attach_result_schema(self) -> None:
1111
1111
  """Verify CatalogAttachResult Arrow schema."""
1112
1112
  schema = CatalogAttachResult.ARROW_SCHEMA
1113
- assert len(schema) == 15
1113
+ assert len(schema) == 17
1114
1114
  assert schema.field("attach_opaque_data").type == pa.binary()
1115
1115
  assert schema.field("supports_transactions").type == pa.bool_()
1116
1116
  assert schema.field("supports_time_travel").type == pa.bool_()
@@ -1121,6 +1121,8 @@ class TestArrowSchemaCorrectness:
1121
1121
  assert schema.field("settings").type == pa.list_(pa.binary())
1122
1122
  assert schema.field("secret_types").type == pa.list_(pa.binary())
1123
1123
  assert schema.field("attach_catalogs").type == pa.list_(pa.binary())
1124
+ assert schema.field("global_functions").type == pa.list_(pa.binary())
1125
+ assert schema.field("global_function_prefix").type == pa.string()
1124
1126
  assert schema.field("resolved_data_version").type == pa.string()
1125
1127
  assert schema.field("resolved_implementation_version").type == pa.string()
1126
1128
 
@@ -42,6 +42,19 @@ _EXEMPTIONS: dict[str, str] = {
42
42
  "path, ProcessParams.if_none_match threading, and the revalidatable "
43
43
  "fixture's 304 behavior)."
44
44
  ),
45
+ "global_functions": (
46
+ "Publishing worker-declared functions into DuckDB's system.main is "
47
+ "entirely a C++-extension concern: the registry, prefix application, "
48
+ "first-attach-wins collision policy, post-DETACH liveness, and the "
49
+ "vgi_global_functions() introspection surface all live in the "
50
+ "extension. The Python worker's only role is advertising "
51
+ "global_functions/global_function_prefix on the attach response, which "
52
+ "tests/catalog/test_declarative.py covers directly (descriptor "
53
+ "validation + the serialized FunctionInfo payload). The observable "
54
+ "behaviour is cross-language by construction and is covered by "
55
+ "vgi/test/sql/integration/global_functions/, which any worker "
56
+ "implementation runs via VGI_TEST_WORKER."
57
+ ),
45
58
  "filter_pushdown": (
46
59
  "Per-type filter-pushdown coverage is mirrored by tests/test_filter_pushdown.py "
47
60
  "and tests/test_filter_pushdown_extension.py, which drive the same predicate "
@@ -32,14 +32,14 @@ CLIENT_PROTOCOL_VERSION = VgiProtocol.protocol_version
32
32
 
33
33
  def test_client_protocol_version_is_canonical() -> None:
34
34
  """Sanity-check the constants this test reasons about haven't drifted apart."""
35
- assert CLIENT_PROTOCOL_VERSION == "1.2.0"
35
+ assert CLIENT_PROTOCOL_VERSION == "1.3.0"
36
36
  # The fixture must be a genuine mismatch in the major/minor that the
37
37
  # framework compares; a patch-only difference would (correctly) pass.
38
38
  assert BAD_PROTOCOL_VERSION.split(".")[:2] != CLIENT_PROTOCOL_VERSION.split(".")[:2]
39
39
 
40
40
 
41
41
  def test_mismatched_worker_protocol_version_raises() -> None:
42
- """A worker enforcing 99.0.0 must reject the 1.2.0 client at dispatch."""
42
+ """A worker enforcing 99.0.0 must reject the 1.3.0 client at dispatch."""
43
43
  with Client("vgi-fixture-bad-protocol-worker") as client, pytest.raises(ClientError) as exc_info:
44
44
  list(
45
45
  client.table_function(
@@ -54,5 +54,5 @@ def test_mismatched_worker_protocol_version_raises() -> None:
54
54
  assert "protocol_version mismatch" in message
55
55
  assert CLIENT_PROTOCOL_VERSION in message
56
56
  assert BAD_PROTOCOL_VERSION in message
57
- # Directional hint: the client (1.2.0) is older than the worker (99.0.0).
57
+ # Directional hint: the client (1.3.0) is older than the worker (99.0.0).
58
58
  assert "upgrade the VGI extension/client" in message
@@ -3,7 +3,7 @@
3
3
  {
4
4
  "attach_options": [],
5
5
  "counts": {
6
- "functions": 217,
6
+ "functions": 221,
7
7
  "schemas": 2,
8
8
  "tables": 59,
9
9
  "views": 3
@@ -371,6 +371,19 @@
371
371
  {
372
372
  "doc": "Example functions for testing VGI",
373
373
  "functions": [
374
+ {
375
+ "args": [
376
+ {
377
+ "desc": "Column to sum",
378
+ "name": "value",
379
+ "type": "int64"
380
+ }
381
+ ],
382
+ "doc": "Global-registration probe (aggregate)",
383
+ "name": "global_agg",
384
+ "returns": "int64",
385
+ "type": "aggregate"
386
+ },
374
387
  {
375
388
  "args": [
376
389
  {
@@ -979,6 +992,19 @@
979
992
  "returns": "double",
980
993
  "type": "scalar"
981
994
  },
995
+ {
996
+ "args": [
997
+ {
998
+ "desc": "Value to label",
999
+ "name": "value",
1000
+ "type": "int64"
1001
+ }
1002
+ ],
1003
+ "doc": "Global-registration probe (scalar)",
1004
+ "name": "global_scalar",
1005
+ "returns": "string",
1006
+ "type": "scalar"
1007
+ },
982
1008
  {
983
1009
  "args": [
984
1010
  {
@@ -2146,6 +2172,12 @@
2146
2172
  "name": "geo_encode",
2147
2173
  "type": "table"
2148
2174
  },
2175
+ {
2176
+ "args": [],
2177
+ "doc": "Global-registration probe (table)",
2178
+ "name": "global_table",
2179
+ "type": "table"
2180
+ },
2149
2181
  {
2150
2182
  "args": [
2151
2183
  {
@@ -3281,6 +3313,12 @@
3281
3313
  "name": "exception_process",
3282
3314
  "type": "table_in_out"
3283
3315
  },
3316
+ {
3317
+ "args": [],
3318
+ "doc": "Global-registration probe (table-buffering)",
3319
+ "name": "global_buffered",
3320
+ "type": "table_in_out"
3321
+ },
3284
3322
  {
3285
3323
  "args": [],
3286
3324
  "doc": "Worker sleeps in process (manual cancel test)",
@@ -0,0 +1,84 @@
1
+ # Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+
3
+ """Tests for the wide-schema benchmark fixture.
4
+
5
+ Guards the fixture the width benchmarks depend on: if ``wide`` stops
6
+ producing the schema it claims, a profile taken against it measures
7
+ something other than what it says on the tin.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import pyarrow as pa
13
+ import pytest
14
+ from vgi_rpc.rpc import RpcServer
15
+
16
+ from vgi._test_fixtures.table.wide import DEFAULT_COLUMNS, WideFunction
17
+ from vgi.arguments import Arguments
18
+ from vgi.protocol import BindRequest, FunctionType, InitRequest, VgiProtocol
19
+ from vgi.worker import Worker
20
+
21
+
22
+ class _WideWorker(Worker):
23
+ """Worker exposing only the wide fixture, so it stays off ExampleWorker."""
24
+
25
+ functions = [WideFunction]
26
+
27
+
28
+ def _scan(columns: int, count: int, batch_size: int) -> list[pa.RecordBatch]:
29
+ from vgi_rpc.http import http_connect, make_sync_client
30
+
31
+ key = b"\x11" * 32
32
+ worker = _WideWorker(quiet=True)
33
+ worker._signing_key = key
34
+ client = make_sync_client(RpcServer(VgiProtocol, worker, enable_describe=False), token_key=key)
35
+ with http_connect(VgiProtocol, client=client, compression_level=None) as proxy: # type: ignore[type-abstract]
36
+ bind = BindRequest(
37
+ function_name="wide",
38
+ arguments=Arguments(
39
+ positional=(pa.scalar(count),),
40
+ named={"columns": pa.scalar(columns), "batch_size": pa.scalar(batch_size)},
41
+ ),
42
+ function_type=FunctionType.TABLE,
43
+ input_schema=pa.schema([]),
44
+ )
45
+ resp = proxy.bind(request=bind)
46
+ assert len(resp.output_schema) == columns
47
+ stream = proxy.init(
48
+ request=InitRequest(bind_call=bind, output_schema=resp.output_schema, bind_opaque_data=resp.opaque_data)
49
+ )
50
+ try:
51
+ return [ab.batch for ab in stream]
52
+ finally:
53
+ stream.close()
54
+
55
+
56
+ @pytest.mark.parametrize("columns", [1, 12, 2000])
57
+ def test_wide_emits_the_requested_width(columns: int) -> None:
58
+ """The bound schema and every emitted batch carry exactly ``columns``."""
59
+ batches = _scan(columns=columns, count=8, batch_size=4)
60
+ assert batches, "expected at least one batch"
61
+ assert sum(b.num_rows for b in batches) == 8
62
+ for batch in batches:
63
+ assert batch.num_columns == columns
64
+ assert batch.schema.names[0] == "c0"
65
+ assert batch.schema.names[-1] == f"c{columns - 1}"
66
+
67
+
68
+ def test_wide_survives_multi_turn_state_round_trip() -> None:
69
+ """Rows stay contiguous across turns, so the cursor round-trips at width.
70
+
71
+ Each turn re-serializes state and rebuilds a zero-row sentinel batch of
72
+ the full width; this is the path the width benchmark exercises.
73
+ """
74
+ batches = _scan(columns=DEFAULT_COLUMNS, count=20, batch_size=4)
75
+ values = [v for b in batches for v in b.column(0).to_pylist()]
76
+ assert values == list(range(20))
77
+ assert all(b.num_columns == DEFAULT_COLUMNS for b in batches)
78
+
79
+
80
+ def test_wide_is_not_registered_on_the_example_worker() -> None:
81
+ """Keep it off ExampleWorker: that count is asserted by the C++ suite."""
82
+ from vgi._test_fixtures.worker import ExampleWorker
83
+
84
+ assert WideFunction not in ExampleWorker.functions