vgi-python 0.29.0__tar.gz → 0.29.4__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 (441) hide show
  1. {vgi_python-0.29.0 → vgi_python-0.29.4}/PKG-INFO +15 -8
  2. {vgi_python-0.29.0 → vgi_python-0.29.4}/README.md +9 -5
  3. vgi_python-0.29.4/docs/vgi-logo.png +0 -0
  4. {vgi_python-0.29.0 → vgi_python-0.29.4}/pyproject.toml +9 -4
  5. vgi_python-0.29.4/tests/client/test_batch_metadata_callback.py +77 -0
  6. vgi_python-0.29.4/tests/client/test_scan_branches_client.py +67 -0
  7. vgi_python-0.29.4/tests/client/test_split_client.py +93 -0
  8. vgi_python-0.29.4/tests/client/test_time_travel_client.py +85 -0
  9. vgi_python-0.29.4/tests/test_launch_transport.py +114 -0
  10. {vgi_python-0.29.0 → vgi_python-0.29.4}/uv.lock +33 -10
  11. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table_in_out.py +96 -1
  12. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/worker.py +2 -0
  13. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/catalog_mixin.py +117 -4
  14. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/client.py +380 -17
  15. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/cpp_request_builders.py +98 -12
  16. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/worker.py +11 -0
  17. vgi_python-0.29.0/docs/vgi-logo.png +0 -0
  18. {vgi_python-0.29.0 → vgi_python-0.29.4}/.gitattributes +0 -0
  19. {vgi_python-0.29.0 → vgi_python-0.29.4}/.github/dependabot.yml +0 -0
  20. {vgi_python-0.29.0 → vgi_python-0.29.4}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
  21. {vgi_python-0.29.0 → vgi_python-0.29.4}/.github/workflows/ci.yml +0 -0
  22. {vgi_python-0.29.0 → vgi_python-0.29.4}/.github/workflows/docs.yml +0 -0
  23. {vgi_python-0.29.0 → vgi_python-0.29.4}/.github/workflows/integration.yml +0 -0
  24. {vgi_python-0.29.0 → vgi_python-0.29.4}/.github/workflows/release.yml +0 -0
  25. {vgi_python-0.29.0 → vgi_python-0.29.4}/.gitignore +0 -0
  26. {vgi_python-0.29.0 → vgi_python-0.29.4}/.python-version +0 -0
  27. {vgi_python-0.29.0 → vgi_python-0.29.4}/.vale.ini +0 -0
  28. {vgi_python-0.29.0 → vgi_python-0.29.4}/CLAUDE.md +0 -0
  29. {vgi_python-0.29.0 → vgi_python-0.29.4}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
  30. {vgi_python-0.29.0 → vgi_python-0.29.4}/DOCS_REVIEW_RUBRIC.md +0 -0
  31. {vgi_python-0.29.0 → vgi_python-0.29.4}/DOCS_USABILITY_TEST.md +0 -0
  32. {vgi_python-0.29.0 → vgi_python-0.29.4}/LICENSE +0 -0
  33. {vgi_python-0.29.0 → vgi_python-0.29.4}/RELEASE-RUNBOOK.md +0 -0
  34. {vgi_python-0.29.0 → vgi_python-0.29.4}/SECURITY.md +0 -0
  35. {vgi_python-0.29.0 → vgi_python-0.29.4}/ci/README.md +0 -0
  36. {vgi_python-0.29.0 → vgi_python-0.29.4}/ci/preprocess-require.awk +0 -0
  37. {vgi_python-0.29.0 → vgi_python-0.29.4}/ci/run-integration.sh +0 -0
  38. {vgi_python-0.29.0 → vgi_python-0.29.4}/dist-vgi/.gitignore +0 -0
  39. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/aggregate-functions.md +0 -0
  40. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/arguments.md +0 -0
  41. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/auth.md +0 -0
  42. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/catalogs.md +0 -0
  43. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/client.md +0 -0
  44. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/exceptions.md +0 -0
  45. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/filters.md +0 -0
  46. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/functions.md +0 -0
  47. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/http.md +0 -0
  48. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/index.md +0 -0
  49. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/metadata.md +0 -0
  50. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/observability.md +0 -0
  51. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/storage.md +0 -0
  52. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/transactor.md +0 -0
  53. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/api/worker.md +0 -0
  54. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/argument-serialization.md +0 -0
  55. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/apple-touch-icon.png +0 -0
  56. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/favicon-16x16.png +0 -0
  57. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/favicon-32x32.png +0 -0
  58. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/favicon.ico +0 -0
  59. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/kinds/aggregate.svg +0 -0
  60. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/kinds/buffering.svg +0 -0
  61. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/kinds/scalar.svg +0 -0
  62. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/kinds/table-in-out.svg +0 -0
  63. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/kinds/table.svg +0 -0
  64. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/logo.png +0 -0
  65. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/assets/social-card.png +0 -0
  66. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/authentication.md +0 -0
  67. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/catalog-interface.md +0 -0
  68. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/cli.md +0 -0
  69. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/column-statistics.md +0 -0
  70. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/concepts/index.md +0 -0
  71. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/contributing-docs.md +0 -0
  72. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/filter-pushdown.md +0 -0
  73. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/generator-api.md +0 -0
  74. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/global-functions.md +0 -0
  75. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/how-to/catalogs.md +0 -0
  76. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/how-to/function-patterns.md +0 -0
  77. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/how-to/http-auth.md +0 -0
  78. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/how-to/index.md +0 -0
  79. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/how-to/pushdown-and-statistics.md +0 -0
  80. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/how-to/state-storage.md +0 -0
  81. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/index.md +0 -0
  82. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/lifecycle.md +0 -0
  83. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/metadata.md +0 -0
  84. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/overrides/main.html +0 -0
  85. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/robots.txt +0 -0
  86. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/shared-storage.md +0 -0
  87. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/stylesheets/extra.css +0 -0
  88. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/tutorial/index.md +0 -0
  89. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/tutorial/scalar.md +0 -0
  90. {vgi_python-0.29.0 → vgi_python-0.29.4}/docs/tutorial/table.md +0 -0
  91. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/batch_index_worker.py +0 -0
  92. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/cache_worker.py +0 -0
  93. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/calc_scalar_worker.py +0 -0
  94. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/calc_worker.py +0 -0
  95. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/copy_format_worker.py +0 -0
  96. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/filter_worker.py +0 -0
  97. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/greeting_scalar_worker.py +0 -0
  98. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/row_count_worker.py +0 -0
  99. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/series_streaming_worker.py +0 -0
  100. {vgi_python-0.29.0 → vgi_python-0.29.4}/examples/sum_worker.py +0 -0
  101. {vgi_python-0.29.0 → vgi_python-0.29.4}/mkdocs.yml +0 -0
  102. {vgi_python-0.29.0 → vgi_python-0.29.4}/packages/vgi-fixtures/LICENSE +0 -0
  103. {vgi_python-0.29.0 → vgi_python-0.29.4}/packages/vgi-fixtures/README.md +0 -0
  104. {vgi_python-0.29.0 → vgi_python-0.29.4}/packages/vgi-fixtures/docker/Dockerfile +0 -0
  105. {vgi_python-0.29.0 → vgi_python-0.29.4}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
  106. {vgi_python-0.29.0 → vgi_python-0.29.4}/packages/vgi-fixtures/pyproject.toml +0 -0
  107. {vgi_python-0.29.0 → vgi_python-0.29.4}/scripts/measure_startup.py +0 -0
  108. {vgi_python-0.29.0 → vgi_python-0.29.4}/scripts/run_all_tests.sh +0 -0
  109. {vgi_python-0.29.0 → vgi_python-0.29.4}/test-data/generate.sh +0 -0
  110. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/__init__.py +0 -0
  111. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/_http_fixtures.py +0 -0
  112. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/__init__.py +0 -0
  113. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_attach_option.py +0 -0
  114. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_catalog_interface.py +0 -0
  115. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_client_catalog.py +0 -0
  116. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_column_statistics.py +0 -0
  117. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_declarative.py +0 -0
  118. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_example_worker_catalog.py +0 -0
  119. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_integration.py +0 -0
  120. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_required_filters.py +0 -0
  121. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_scan_branches.py +0 -0
  122. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_serialization.py +0 -0
  123. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_setting.py +0 -0
  124. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_storage.py +0 -0
  125. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_time_travel.py +0 -0
  126. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/catalog/test_writable_table.py +0 -0
  127. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/client/__init__.py +0 -0
  128. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/client/test_aggregate_client.py +0 -0
  129. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/client/test_broken_pipe.py +0 -0
  130. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/client/test_cli.py +0 -0
  131. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/client/test_cli_catalog_functions.py +0 -0
  132. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/client/test_copy_client.py +0 -0
  133. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/client/test_stop_force.py +0 -0
  134. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/client/test_table_column_statistics.py +0 -0
  135. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/client/test_worker_debug.py +0 -0
  136. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/__init__.py +0 -0
  137. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/_stub.py +0 -0
  138. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/conftest.py +0 -0
  139. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_accumulate.py +0 -0
  140. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_aggregate.py +0 -0
  141. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_attach.py +0 -0
  142. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_bearer_auth.py +0 -0
  143. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_const_param_enforcement.py +0 -0
  144. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_container.py +0 -0
  145. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_copy_from.py +0 -0
  146. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_copy_to.py +0 -0
  147. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_directory_parity.py +0 -0
  148. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_function_inventory.py +0 -0
  149. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_github.py +0 -0
  150. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_http_client.py +0 -0
  151. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_http_external_location.py +0 -0
  152. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_http_upload_url.py +0 -0
  153. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_macro.py +0 -0
  154. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_overload.py +0 -0
  155. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_protocol_inventory.py +0 -0
  156. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_protocol_version.py +0 -0
  157. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_resumable_scan.py +0 -0
  158. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_scalar.py +0 -0
  159. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
  160. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_secret.py +0 -0
  161. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_settings.py +0 -0
  162. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_splits.py +0 -0
  163. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_table.py +0 -0
  164. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_table_in_out.py +0 -0
  165. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_view.py +0 -0
  166. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conformance/test_writable.py +0 -0
  167. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/conftest.py +0 -0
  168. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/anchor_len_overrun.bin +0 -0
  169. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/bad_fingerprint.bin +0 -0
  170. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/bad_flags_unsealed_but_key_present.bin +0 -0
  171. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/bad_version.bin +0 -0
  172. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/generate.py +0 -0
  173. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/manifest.json +0 -0
  174. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/reserved_flag_bit.bin +0 -0
  175. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/stale_anchor.bin +0 -0
  176. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/truncated.bin +0 -0
  177. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/valid_sealed.bin +0 -0
  178. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/data/split_tokens/valid_unsealed.bin +0 -0
  179. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/__init__.py +0 -0
  180. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/test_bernoulli_function.py +0 -0
  181. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/test_binary_packet_function.py +0 -0
  182. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/test_client.py +0 -0
  183. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/test_conditional_message_function.py +0 -0
  184. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/test_hash_seed_function.py +0 -0
  185. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/test_multiply_by_setting_function.py +0 -0
  186. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/test_multiply_function.py +0 -0
  187. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/test_random_bytes_function.py +0 -0
  188. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/scalar/test_return_secret_value_function.py +0 -0
  189. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/__init__.py +0 -0
  190. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/__init__.py +0 -0
  191. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_constant_columns_function.py +0 -0
  192. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_double_sequence_function.py +0 -0
  193. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_exception_function.py +0 -0
  194. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_filter_echo_function.py +0 -0
  195. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_logging_function.py +0 -0
  196. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_nested_sequence_function.py +0 -0
  197. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_partitioned_function.py +0 -0
  198. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_projected_data_function.py +0 -0
  199. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_sequence_function.py +0 -0
  200. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_settings_function.py +0 -0
  201. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_struct_settings_function.py +0 -0
  202. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/generator/test_ten_thousand_function.py +0 -0
  203. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table/test_wide_columns.py +0 -0
  204. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/__init__.py +0 -0
  205. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/generator/__init__.py +0 -0
  206. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
  207. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/generator/test_echo_function.py +0 -0
  208. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/generator/test_exception_functions.py +0 -0
  209. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
  210. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
  211. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
  212. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
  213. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/test_blended_metadata.py +0 -0
  214. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/table_in_out/test_client.py +0 -0
  215. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_access_log_audit.py +0 -0
  216. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_aggregate_function.py +0 -0
  217. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_argument_spec.py +0 -0
  218. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_auth.py +0 -0
  219. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_bind_exceptions.py +0 -0
  220. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_bind_request_at_clause.py +0 -0
  221. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_bound_storage_conformance.py +0 -0
  222. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_cache_control.py +0 -0
  223. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_call_state_attach.py +0 -0
  224. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_catalog_auth_binding.py +0 -0
  225. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_copy_from_function.py +0 -0
  226. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_copy_to_function.py +0 -0
  227. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_docstrings.py +0 -0
  228. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_documentation_examples.py +0 -0
  229. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_example_function_arg_types.py +0 -0
  230. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_examples_workers.py +0 -0
  231. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_exception_handling.py +0 -0
  232. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_exceptions.py +0 -0
  233. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_filter_pushdown.py +0 -0
  234. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_filter_pushdown_extension.py +0 -0
  235. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_fixture_catalog_parity.py +0 -0
  236. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_function_storage.py +0 -0
  237. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_function_storage_azure_sql.py +0 -0
  238. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_function_storage_cf_do.py +0 -0
  239. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_function_storage_cf_do_integration.py +0 -0
  240. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_function_storage_conformance.py +0 -0
  241. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_cpp_constants.py +0 -0
  242. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_cpp_protocol_version.py +0 -0
  243. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_cpp_request_builders.py +0 -0
  244. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_cpp_schemas.py +0 -0
  245. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_cpp_secret.py +0 -0
  246. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_go_schemas.py +0 -0
  247. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_java_schemas.py +0 -0
  248. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_protocol_version.py +0 -0
  249. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_rust_request_builders.py +0 -0
  250. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_rust_schemas.py +0 -0
  251. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_schemas_cross_lang.py +0 -0
  252. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_ts_client.py +0 -0
  253. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_generated_ts_schemas.py +0 -0
  254. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_http_demo_storage.py +0 -0
  255. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_http_s3_offload_input.py +0 -0
  256. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_http_s3_offload_output.py +0 -0
  257. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_metadata.py +0 -0
  258. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_mypy_consolidated.py +0 -0
  259. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_nest_tensor.py +0 -0
  260. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_otel.py +0 -0
  261. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_projection_enforcement.py +0 -0
  262. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_projection_repro.py +0 -0
  263. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_protocol_classes.py +0 -0
  264. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_resolved_secrets.py +0 -0
  265. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_schema_scoped_functions.py +0 -0
  266. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_schema_utils.py +0 -0
  267. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_serve.py +0 -0
  268. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_setting_secret_annotations.py +0 -0
  269. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_signing_key.py +0 -0
  270. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_split_token.py +0 -0
  271. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_table_buffering_function.py +0 -0
  272. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_table_function_dynamic_to_string.py +0 -0
  273. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_tcp_transport.py +0 -0
  274. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_type_bounds.py +0 -0
  275. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_union_argument.py +0 -0
  276. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_wire_record_schema_parity.py +0 -0
  277. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_worker.py +0 -0
  278. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_worker_cli.py +0 -0
  279. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/test_worker_page.py +0 -0
  280. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/transactor/__init__.py +0 -0
  281. {vgi_python-0.29.0 → vgi_python-0.29.4}/tests/transactor/test_transactor.py +0 -0
  282. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/__init__.py +0 -0
  283. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_duckdb.py +0 -0
  284. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_storage_profile.py +0 -0
  285. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/__init__.py +0 -0
  286. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
  287. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/accumulate/worker.py +0 -0
  288. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
  289. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/_common.py +0 -0
  290. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/basic.py +0 -0
  291. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
  292. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/generic.py +0 -0
  293. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
  294. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
  295. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
  296. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
  297. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
  298. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
  299. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/aggregate/window.py +0 -0
  300. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/attach_options.py +0 -0
  301. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/bad_enum.py +0 -0
  302. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/bad_protocol.py +0 -0
  303. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/cancellable.py +0 -0
  304. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/catalog.py +0 -0
  305. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/companion.py +0 -0
  306. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/copy_from.py +0 -0
  307. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/copy_to.py +0 -0
  308. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/global_functions.py +0 -0
  309. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/http_server.py +0 -0
  310. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
  311. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
  312. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/nest_tensor.py +0 -0
  313. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/orchard_catalog.py +0 -0
  314. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
  315. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
  316. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/__init__.py +0 -0
  317. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/_common.py +0 -0
  318. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
  319. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
  320. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/binary.py +0 -0
  321. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/formatting.py +0 -0
  322. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/geo.py +0 -0
  323. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
  324. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
  325. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/same_name.py +0 -0
  326. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
  327. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/scalar/type_info.py +0 -0
  328. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
  329. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
  330. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/simple_writable.py +0 -0
  331. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/__init__.py +0 -0
  332. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/_common.py +0 -0
  333. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/batch_index.py +0 -0
  334. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
  335. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/cache.py +0 -0
  336. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
  337. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/filters.py +0 -0
  338. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/late_materialization.py +0 -0
  339. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/make_series.py +0 -0
  340. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/misc.py +0 -0
  341. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/order_modes.py +0 -0
  342. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/pairs.py +0 -0
  343. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/partition_columns.py +0 -0
  344. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
  345. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/profiling_example.py +0 -0
  346. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/required_filters.py +0 -0
  347. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
  348. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/sequence.py +0 -0
  349. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/settings.py +0 -0
  350. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/splits.py +0 -0
  351. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
  352. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
  353. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/typed_probe.py +0 -0
  354. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/versioned.py +0 -0
  355. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table/wide.py +0 -0
  356. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
  357. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/twin_catalogs.py +0 -0
  358. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/versioned.py +0 -0
  359. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/versioned_tables.py +0 -0
  360. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/writable/__init__.py +0 -0
  361. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/writable/generic.py +0 -0
  362. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/writable/table.py +0 -0
  363. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/_test_fixtures/writable/worker.py +0 -0
  364. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/aggregate_function.py +0 -0
  365. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/argument_spec.py +0 -0
  366. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/arguments.py +0 -0
  367. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/attach_header.py +0 -0
  368. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/auth.py +0 -0
  369. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/cache_control.py +0 -0
  370. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/catalog/__init__.py +0 -0
  371. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/catalog/_descriptor_spec.py +0 -0
  372. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/catalog/attach_option.py +0 -0
  373. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/catalog/catalog_interface.py +0 -0
  374. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/catalog/descriptors.py +0 -0
  375. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/catalog/duckdb_statistics.py +0 -0
  376. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/catalog/secret_type.py +0 -0
  377. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/catalog/setting.py +0 -0
  378. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/catalog/storage.py +0 -0
  379. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/__init__.py +0 -0
  380. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/aggregate.py +0 -0
  381. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/cli.py +0 -0
  382. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/cli_catalog.py +0 -0
  383. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/cli_schema.py +0 -0
  384. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/cli_table.py +0 -0
  385. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/cli_transaction.py +0 -0
  386. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/cli_utils.py +0 -0
  387. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/cli_view.py +0 -0
  388. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/client/errors.py +0 -0
  389. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/__init__.py +0 -0
  390. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/_common.py +0 -0
  391. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/cpp_constants.py +0 -0
  392. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/cpp_protocol_version.py +0 -0
  393. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/cpp_schemas.py +0 -0
  394. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
  395. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/cpp_secret_request_builders.py +0 -0
  396. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/cpp_secret_schemas.py +0 -0
  397. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/go_schemas.py +0 -0
  398. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/java_schemas.py +0 -0
  399. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/protocol_version.py +0 -0
  400. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/rust_request_builders.py +0 -0
  401. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/rust_schemas.py +0 -0
  402. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/ts_client.py +0 -0
  403. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/codegen/ts_schemas.py +0 -0
  404. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/copy_from_function.py +0 -0
  405. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/copy_to_function.py +0 -0
  406. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/exceptions.py +0 -0
  407. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/function.py +0 -0
  408. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/function_storage.py +0 -0
  409. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/function_storage_azure_sql.py +0 -0
  410. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/function_storage_cf_do.py +0 -0
  411. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/http/__init__.py +0 -0
  412. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/http/demo_storage.py +0 -0
  413. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/http/landing.html +0 -0
  414. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/http/landing_page.py +0 -0
  415. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/http/vgi-client.js +0 -0
  416. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/http/worker_page.py +0 -0
  417. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/invocation.py +0 -0
  418. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/logging_config.py +0 -0
  419. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/meta_worker.py +0 -0
  420. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/metadata.py +0 -0
  421. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/otel.py +0 -0
  422. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/profiling.py +0 -0
  423. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/protocol.py +0 -0
  424. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/protocol_version.txt +0 -0
  425. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/py.typed +0 -0
  426. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/scalar_function.py +0 -0
  427. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/schema_utils.py +0 -0
  428. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/secret_protocol.py +0 -0
  429. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/secret_service.py +0 -0
  430. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/serve.py +0 -0
  431. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/split_token.py +0 -0
  432. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/table_buffering_function.py +0 -0
  433. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/table_filter_pushdown.py +0 -0
  434. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/table_function.py +0 -0
  435. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/table_in_out_function.py +0 -0
  436. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/transactor/__init__.py +0 -0
  437. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/transactor/_duckdb_compat.py +0 -0
  438. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/transactor/client.py +0 -0
  439. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/transactor/protocol.py +0 -0
  440. {vgi_python-0.29.0 → vgi_python-0.29.4}/vgi/transactor/server.py +0 -0
  441. {vgi_python-0.29.0 → vgi_python-0.29.4}/wrangler.jsonc +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: vgi-python
3
- Version: 0.29.0
3
+ Version: 0.29.4
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: httpx2>=2.9.1
162
162
  Requires-Dist: platformdirs
163
163
  Requires-Dist: pyarrow
164
164
  Requires-Dist: typer>=0.9
165
- Requires-Dist: vgi-rpc>=0.43.0
165
+ Requires-Dist: vgi-rpc>=0.43.2
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'
@@ -181,7 +181,8 @@ Requires-Dist: pytest-ruff; extra == 'dev'
181
181
  Requires-Dist: pytest-xdist; extra == 'dev'
182
182
  Requires-Dist: ruff; extra == 'dev'
183
183
  Requires-Dist: sqlglot; extra == 'dev'
184
- Requires-Dist: vgi-rpc[conformance,external,http,oauth,otel,sentry]; extra == 'dev'
184
+ Requires-Dist: vgi-rpc[cli,conformance,external,http,oauth,otel,sentry]; extra == 'dev'
185
+ Requires-Dist: vgi-rpc[cli]; extra == 'dev'
185
186
  Requires-Dist: vgi-rpc[http]; extra == 'dev'
186
187
  Requires-Dist: vgi-rpc[oauth]; extra == 'dev'
187
188
  Requires-Dist: vgi-rpc[otel]; extra == 'dev'
@@ -197,6 +198,8 @@ Provides-Extra: haybarn
197
198
  Requires-Dist: haybarn>=1.5.5rc1; extra == 'haybarn'
198
199
  Provides-Extra: http
199
200
  Requires-Dist: vgi-rpc[http]; extra == 'http'
201
+ Provides-Extra: launch
202
+ Requires-Dist: vgi-rpc[cli]; extra == 'launch'
200
203
  Provides-Extra: oauth
201
204
  Requires-Dist: vgi-rpc[oauth]; extra == 'oauth'
202
205
  Provides-Extra: otel
@@ -212,18 +215,22 @@ Provides-Extra: transactor
212
215
  Requires-Dist: sqlglot; extra == 'transactor'
213
216
  Description-Content-Type: text/markdown
214
217
 
215
- # VGI (Vector Gateway Interface)
216
-
217
218
  <p align="center">
218
- <img src="https://raw.githubusercontent.com/Query-farm/vgi-python/main/docs/vgi-logo.png" alt="VGI Logo" width="480">
219
+ <img src="https://raw.githubusercontent.com/Query-farm/vgi-python/main/docs/vgi-logo.png?v=2" alt="Vector Gateway Interface logo" width="320">
219
220
  </p>
220
221
 
222
+ <h1 align="center">VGI</h1>
223
+
221
224
  <p align="center">
222
- <strong>Apache Arrow-based protocol for extending DuckDB using any language.</strong>
225
+ Apache Arrow-based protocol for extending DuckDB using any language — the Python reference implementation.<br>
226
+ Built by <a href="https://query.farm">🚜 Query.Farm</a>
223
227
  </p>
224
228
 
225
229
  <p align="center">
226
- Created by <a href="https://query.farm">Query.Farm</a>
230
+ <a href="https://github.com/Query-farm/vgi-python/actions/workflows/ci.yml"><img src="https://github.com/Query-farm/vgi-python/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
231
+ <a href="https://pypi.org/project/vgi-python/"><img src="https://img.shields.io/pypi/v/vgi-python" alt="PyPI"></a>
232
+ <a href="https://pypi.org/project/vgi-python/"><img src="https://img.shields.io/pypi/pyversions/vgi-python" alt="Python versions"></a>
233
+ <a href="LICENSE"><img src="https://img.shields.io/pypi/l/vgi-python" alt="License"></a>
227
234
  </p>
228
235
 
229
236
  ---
@@ -1,15 +1,19 @@
1
- # VGI (Vector Gateway Interface)
2
-
3
1
  <p align="center">
4
- <img src="https://raw.githubusercontent.com/Query-farm/vgi-python/main/docs/vgi-logo.png" alt="VGI Logo" width="480">
2
+ <img src="https://raw.githubusercontent.com/Query-farm/vgi-python/main/docs/vgi-logo.png?v=2" alt="Vector Gateway Interface logo" width="320">
5
3
  </p>
6
4
 
5
+ <h1 align="center">VGI</h1>
6
+
7
7
  <p align="center">
8
- <strong>Apache Arrow-based protocol for extending DuckDB using any language.</strong>
8
+ Apache Arrow-based protocol for extending DuckDB using any language — the Python reference implementation.<br>
9
+ Built by <a href="https://query.farm">🚜 Query.Farm</a>
9
10
  </p>
10
11
 
11
12
  <p align="center">
12
- Created by <a href="https://query.farm">Query.Farm</a>
13
+ <a href="https://github.com/Query-farm/vgi-python/actions/workflows/ci.yml"><img src="https://github.com/Query-farm/vgi-python/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
14
+ <a href="https://pypi.org/project/vgi-python/"><img src="https://img.shields.io/pypi/v/vgi-python" alt="PyPI"></a>
15
+ <a href="https://pypi.org/project/vgi-python/"><img src="https://img.shields.io/pypi/pyversions/vgi-python" alt="Python versions"></a>
16
+ <a href="LICENSE"><img src="https://img.shields.io/pypi/l/vgi-python" alt="License"></a>
13
17
  </p>
14
18
 
15
19
  ---
Binary file
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "vgi-python"
3
- version = "0.29.0"
3
+ version = "0.29.4"
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.43.0",
43
+ "vgi-rpc>=0.43.2",
44
44
  "httpx2>=2.9.1",
45
45
  ]
46
46
 
@@ -52,6 +52,11 @@ dependencies = [
52
52
  haybarn = ["haybarn>=1.5.5rc1"]
53
53
  duckdb = ["duckdb>=1.5.3"]
54
54
  http = ["vgi-rpc[http]"]
55
+ # transport="launch": vgi_rpc.launcher imports filelock unconditionally at
56
+ # module level, which lives behind vgi-rpc's own `cli` extra (alongside
57
+ # typer, already a core dependency here, and httpx2, ditto) rather than in
58
+ # vgi-rpc's core dependency set.
59
+ launch = ["vgi-rpc[cli]"]
55
60
  # Alternative HTTP server: granian moves socket I/O and HTTP parsing into Rust,
56
61
  # off the GIL. Optional because it is a compiled extension where waitress is
57
62
  # pure Python; select it with `vgi-serve --http --server granian`.
@@ -93,8 +98,8 @@ dev = [
93
98
  "pytest-ruff",
94
99
  "pytest-xdist",
95
100
  "ruff",
96
- "vgi-python[test-fixtures,test-fixtures-writable,http,oauth,otel,sentry,azure]",
97
- "vgi-rpc[conformance,external,http,oauth,otel,sentry]",
101
+ "vgi-python[test-fixtures,test-fixtures-writable,http,launch,oauth,otel,sentry,azure]",
102
+ "vgi-rpc[cli,conformance,external,http,oauth,otel,sentry]",
98
103
  ]
99
104
  [project.scripts]
100
105
  vgi-serve = "vgi.serve:main"
@@ -0,0 +1,77 @@
1
+ # Copyright 2026 Query Farm LLC - https://query.farm
2
+
3
+ # ruff: noqa: S101, D101, D102, D103
4
+ """`Client.table_function(batch_metadata_callback=...)`.
5
+
6
+ `_table_function_parallel` previously discarded `AnnotatedBatch.custom_metadata`
7
+ unconditionally (`if output.batch.num_rows > 0: output_queue.put(output.batch)`)
8
+ and only forwarded the bare `pa.RecordBatch` — so a worker's `vgi.cache.*`
9
+ cacheability advertisement (`vgi/cache_control.py`), which rides
10
+ `custom_metadata`, was structurally unreachable through the public
11
+ `table_function()` generator. `batch_metadata_callback` mirrors the existing
12
+ `bind_result_callback` pattern to fix that additively, with no change to the
13
+ generator's yield type. Exercised against `cacheable_numbers`
14
+ (`vgi/_test_fixtures/table/cache.py`), which advertises `vgi.cache.ttl` on its
15
+ first batch.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from typing import Any
21
+
22
+ import pyarrow as pa
23
+ import pytest
24
+
25
+ from vgi.arguments import Arguments
26
+
27
+ DATA = "data"
28
+
29
+
30
+ @pytest.fixture
31
+ def client(client_transport: Any) -> Any:
32
+ with client_transport() as c:
33
+ c.catalog_attach(name="example", data_version_spec=None, implementation_version=None)
34
+ yield c
35
+
36
+
37
+ def test_callback_receives_cache_control_metadata(client: Any) -> None:
38
+ metas: list[pa.KeyValueMetadata | None] = []
39
+ batches = list(
40
+ client.table_function(
41
+ function_name="cacheable_numbers",
42
+ schema_name=DATA,
43
+ arguments=Arguments(named={"n": pa.scalar(5)}),
44
+ batch_metadata_callback=metas.append,
45
+ )
46
+ )
47
+ assert sum(b.num_rows for b in batches) == 5
48
+ assert len(metas) == len(batches)
49
+ assert metas[0] is not None
50
+ assert dict(metas[0])[b"vgi.cache.ttl"] == b"300"
51
+
52
+
53
+ def test_callback_is_optional_and_defaults_to_none(client: Any) -> None:
54
+ """No `batch_metadata_callback` -> unchanged behavior, no crash."""
55
+ batches = list(
56
+ client.table_function(
57
+ function_name="cacheable_numbers",
58
+ schema_name=DATA,
59
+ arguments=Arguments(named={"n": pa.scalar(3)}),
60
+ )
61
+ )
62
+ assert sum(b.num_rows for b in batches) == 3
63
+
64
+
65
+ def test_callback_sees_none_for_a_batch_without_custom_metadata(client: Any) -> None:
66
+ """A function that never advertises cache control still drives the callback once per batch, with `None`."""
67
+ metas: list[pa.KeyValueMetadata | None] = []
68
+ list(
69
+ client.table_function(
70
+ function_name="sequence",
71
+ schema_name="main",
72
+ arguments=Arguments(positional=[pa.scalar(4)]),
73
+ batch_metadata_callback=metas.append,
74
+ )
75
+ )
76
+ assert metas
77
+ assert all(m is None for m in metas)
@@ -0,0 +1,67 @@
1
+ # Copyright 2026 Query Farm LLC - https://query.farm
2
+
3
+ # ruff: noqa: S101, D101, D102, D103
4
+ """`Client.table_scan_branches_get`.
5
+
6
+ `Client` had no wrapper for `catalog_table_scan_branches_get` at all —
7
+ grepped the whole `vgi/client/` package for "branch" and the only hit was an
8
+ unrelated code comment ("skip the subprocess branch"). A multi-branch table
9
+ was therefore invisible to any non-DuckDB caller, not just unsupported by a
10
+ higher-level connector. Exercised against `data.multi_branch_numbers` (two
11
+ `sequence(50)` arms — `vgi/_test_fixtures/worker.py`) and, for the legacy
12
+ fallback, `data.numbers` (an ordinary single-branch table whose worker only
13
+ implements the older `table_scan_function_get`).
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from typing import Any
19
+
20
+ import pytest
21
+
22
+ from vgi.catalog import ScanBranch, ScanBranchesResult
23
+
24
+ DATA = "data"
25
+
26
+
27
+ @pytest.fixture
28
+ def client(client_transport: Any) -> Any:
29
+ with client_transport() as c:
30
+ c.catalog_attach(name="example", data_version_spec=None, implementation_version=None)
31
+ yield c
32
+
33
+
34
+ def _attach_opaque(client: Any) -> Any:
35
+ # catalog_attach() was already called by the fixture above (its return
36
+ # value discarded) — re-attach here to get the opaque data this method
37
+ # needs, mirroring how CatalogClientMixin methods are used standalone.
38
+ return client.catalog_attach(name="example", data_version_spec=None, implementation_version=None).attach_opaque_data
39
+
40
+
41
+ def test_multi_branch_table_returns_all_branches(client: Any) -> None:
42
+ result = client.table_scan_branches_get(
43
+ attach_opaque_data=_attach_opaque(client),
44
+ schema_name=DATA,
45
+ name="multi_branch_numbers",
46
+ )
47
+ assert isinstance(result, ScanBranchesResult)
48
+ assert len(result.branches) == 2
49
+ for branch in result.branches:
50
+ assert isinstance(branch, ScanBranch)
51
+ assert branch.function_name == "sequence"
52
+ assert branch.source_table is None # function branch, not catalog-table
53
+
54
+
55
+ def test_single_branch_table_falls_back_to_legacy_rpc(client: Any) -> None:
56
+ """`data.numbers` only implements `table_scan_function_get` — the fallback wraps it as one branch."""
57
+ result = client.table_scan_branches_get(
58
+ attach_opaque_data=_attach_opaque(client),
59
+ schema_name=DATA,
60
+ name="numbers",
61
+ )
62
+ assert len(result.branches) == 1
63
+ assert result.branches[0].function_name == client.table_scan_function_get(
64
+ attach_opaque_data=_attach_opaque(client),
65
+ schema_name=DATA,
66
+ name="numbers",
67
+ ).function_name
@@ -0,0 +1,93 @@
1
+ # Copyright 2026 Query Farm LLC - https://query.farm
2
+
3
+ # ruff: noqa: S101, D101, D102, D103
4
+ """`Client.table_function_plan` + `Client.table_function(split_tokens=...)`.
5
+
6
+ Splits were previously entirely unreachable from `Client` — no wrapper for
7
+ `on_plan()` existed at all, and `table_function()`/`_do_init` had no
8
+ `split_tokens` parameter to redeem one, even though the wire protocol
9
+ (`TableFunctionPlanRequest`/`PlanResponse`/`InitRequest.split_tokens`) and the
10
+ `VgiProtocol.table_function_plan` RPC already supported it — the DuckDB C++
11
+ extension drives this today, but the reference Python client never grew the
12
+ equivalent. Exercised against `split_sequence` (the split-capable twin of
13
+ `sequence`, `vgi/_test_fixtures/table/splits.py`) over every client transport.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from typing import Any
19
+
20
+ import pyarrow as pa
21
+ import pytest
22
+
23
+ from vgi.arguments import Arguments
24
+ from vgi.protocol import ScanSplit
25
+
26
+ MAIN = "main"
27
+
28
+
29
+ @pytest.fixture
30
+ def client(client_transport: Any) -> Any:
31
+ with client_transport() as c:
32
+ c.catalog_attach(name="example", data_version_spec=None, implementation_version=None)
33
+ yield c
34
+
35
+
36
+ def test_plan_returns_typed_scan_splits(client: Any) -> None:
37
+ args = Arguments(named={"n": pa.scalar(20), "splits": pa.scalar(4)})
38
+ plan = client.table_function_plan(function_name="split_sequence", schema_name=MAIN, arguments=args)
39
+ assert len(plan.splits) == 4
40
+ for split in plan.splits:
41
+ assert isinstance(split, ScanSplit)
42
+ assert split.token # framework-stamped, non-empty
43
+ assert split.estimated_rows == 5
44
+
45
+
46
+ def test_redeeming_each_split_in_order_reproduces_the_whole_scan(client: Any) -> None:
47
+ """split_sequence redeemed split-by-split must equal sequence(n)'s output.
48
+
49
+ Also threads ``split_execution_id``/``split_init_opaque_data`` from the
50
+ plan on every redemption — this fixture doesn't need cross-split shared
51
+ state to be correct, but this proves the wire path accepts and round-trips
52
+ them without erroring, for workers that do.
53
+ """
54
+ args = Arguments(named={"n": pa.scalar(37), "splits": pa.scalar(5)})
55
+ plan = client.table_function_plan(function_name="split_sequence", schema_name=MAIN, arguments=args)
56
+
57
+ all_rows: list[int] = []
58
+ for split in plan.splits:
59
+ batches = list(
60
+ client.table_function(
61
+ function_name="split_sequence",
62
+ schema_name=MAIN,
63
+ arguments=args,
64
+ split_tokens=[split.token],
65
+ split_execution_id=plan.execution_id,
66
+ split_init_opaque_data=plan.init_opaque_data,
67
+ )
68
+ )
69
+ for batch in batches:
70
+ all_rows.extend(batch.column("n").to_pylist())
71
+
72
+ assert sorted(all_rows) == list(range(37))
73
+
74
+
75
+ def test_split_zero_yields_no_splits_and_no_rows(client: Any) -> None:
76
+ args = Arguments(named={"n": pa.scalar(10), "splits": pa.scalar(4)})
77
+ plan = client.table_function_plan(function_name="split_zero", schema_name=MAIN, arguments=args)
78
+ assert plan.splits == []
79
+
80
+
81
+ def test_redeeming_a_split_forces_single_worker(client: Any) -> None:
82
+ """`split_tokens` bypasses `_spawn_additional_workers` — no additional worker connections open."""
83
+ args = Arguments(named={"n": pa.scalar(8), "splits": pa.scalar(2)})
84
+ plan = client.table_function_plan(function_name="split_sequence", schema_name=MAIN, arguments=args)
85
+ list(
86
+ client.table_function(
87
+ function_name="split_sequence",
88
+ schema_name=MAIN,
89
+ arguments=args,
90
+ split_tokens=[plan.splits[0].token],
91
+ )
92
+ )
93
+ assert client._additional_workers == []
@@ -0,0 +1,85 @@
1
+ # Copyright 2026 Query Farm LLC - https://query.farm
2
+
3
+ # ruff: noqa: S101, D101, D102, D103
4
+ """`Client.table_get`/`table_function(at_unit=..., at_value=...)`.
5
+
6
+ Both methods previously dropped `at_unit`/`at_value` on the floor even though
7
+ the underlying wire RPCs (`catalog_table_get`, `BindRequest.at_unit`/
8
+ `.at_value`) already carried them — `table_scan_function_get` was the only
9
+ `Client` method that exposed time travel at all. Two distinct worker
10
+ patterns are exercised, both real fixtures, proving this isn't just plumbing
11
+ that happens to compile:
12
+
13
+ * `data.versioned_data` reads its version through a pre-resolved bind
14
+ argument (`table_scan_function_get(at_unit=...)` bakes it into the
15
+ returned `ScanFunctionResult.arguments`) — `table_get(at_unit=...)` is
16
+ what needed fixing here, to see the schema at that version at all.
17
+ * `data.tt_pushdown_fn` (`tt_pushdown_scan`) reads `at_unit`/`at_value`
18
+ **directly off the init request** (`ProcessParams.at_unit`/`.at_value`,
19
+ see `vgi/_test_fixtures/table/tt_pushdown.py`) — this is the pattern that
20
+ needed `table_function(at_unit=...)` specifically; no amount of
21
+ pre-resolved arguments would reach it.
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ from typing import Any
27
+
28
+ import pyarrow as pa
29
+ import pytest
30
+
31
+ from vgi.arguments import Arguments
32
+
33
+ DATA = "data"
34
+
35
+
36
+ @pytest.fixture
37
+ def client(client_transport: Any) -> Any:
38
+ with client_transport() as c:
39
+ c.catalog_attach(name="example", data_version_spec=None, implementation_version=None)
40
+ yield c
41
+
42
+
43
+ def _attach_opaque(client: Any) -> Any:
44
+ result = client.catalog_attach(name="example", data_version_spec=None, implementation_version=None)
45
+ return result.attach_opaque_data
46
+
47
+
48
+ def test_table_get_at_unit_returns_the_versioned_schema(client: Any) -> None:
49
+ opaque = _attach_opaque(client)
50
+ v1 = client.table_get(
51
+ attach_opaque_data=opaque, schema_name=DATA, name="versioned_data", at_unit="VERSION", at_value="1"
52
+ )
53
+ live = client.table_get(attach_opaque_data=opaque, schema_name=DATA, name="versioned_data")
54
+
55
+ v1_schema = pa.ipc.read_schema(pa.py_buffer(v1.columns))
56
+ live_schema = pa.ipc.read_schema(pa.py_buffer(live.columns))
57
+ assert v1_schema.names == ["id"] # version 1: (id int64) only
58
+ assert live_schema.names == ["id", "score"] # current: version 3
59
+
60
+
61
+ def test_table_get_with_no_at_clause_is_unaffected(client: Any) -> None:
62
+ """The new `at_unit`/`at_value` params default to `None` — unchanged behavior without them."""
63
+ info = client.table_get(attach_opaque_data=_attach_opaque(client), schema_name=DATA, name="numbers")
64
+ assert info is not None
65
+
66
+
67
+ def test_table_function_at_unit_reaches_a_worker_that_reads_it_from_init(client: Any) -> None:
68
+ """`tt_pushdown_scan` reads `at_unit`/`at_value` off the init request, not a resolved bind arg."""
69
+ v1_batches = list(
70
+ client.table_function(function_name="tt_pushdown_scan", schema_name=DATA, at_unit="VERSION", at_value="1")
71
+ )
72
+ live_batches = list(client.table_function(function_name="tt_pushdown_scan", schema_name=DATA))
73
+
74
+ assert sum(b.num_rows for b in v1_batches) == 5
75
+ assert sum(b.num_rows for b in live_batches) == 10
76
+
77
+
78
+ def test_table_function_with_no_at_clause_is_unaffected(client: Any) -> None:
79
+ """The new `at_unit`/`at_value` params default to `None` — unchanged behavior without them."""
80
+ batches = list(
81
+ client.table_function(
82
+ function_name="sequence", schema_name="main", arguments=Arguments(positional=[pa.scalar(5)])
83
+ )
84
+ )
85
+ assert sum(b.num_rows for b in batches) == 5
@@ -0,0 +1,114 @@
1
+ # Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+
3
+ """Round-trip tests for the launcher-managed (``transport="launch"``) transport.
4
+
5
+ Drives ``vgi._test_fixtures.worker`` (the same fixture module ``test_tcp_transport.py``
6
+ uses) through ``Client.from_launch(...)`` — no separate fixture worker needed, since
7
+ ``MetaWorker.serve`` already passes argv through to ``vgi_rpc.rpc.run_server()``, which
8
+ participates in the AF_UNIX launcher path (``--unix PATH --idle-timeout SEC``) the same
9
+ way it participates in the TCP path (``--tcp HOST:PORT``).
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import shutil
15
+ import sys
16
+ import tempfile
17
+ import uuid
18
+ from collections.abc import Iterator
19
+ from pathlib import Path
20
+
21
+ import pyarrow as pa
22
+ import pytest
23
+ from vgi_rpc.launcher import status_rows
24
+
25
+ from vgi.arguments import Arguments
26
+ from vgi.client import Client
27
+
28
+ _WORKER_ARGV = (sys.executable, "-m", "vgi._test_fixtures.worker")
29
+
30
+
31
+ @pytest.fixture
32
+ def state_dir() -> Iterator[str]:
33
+ """Per-test state dir under ``/tmp`` to stay under macOS's 104-byte AF_UNIX limit.
34
+
35
+ Mirrors ``vgi-rpc``'s own ``test_launcher.py`` fixture — ``tmp_path`` resolves to a
36
+ deeply nested path that, concatenated with ``<hash>.sock``, blows past the cap.
37
+ """
38
+ d = Path(tempfile.gettempdir()) / f"vgi-launch-test-{uuid.uuid4().hex[:8]}"
39
+ d.mkdir(mode=0o700)
40
+ try:
41
+ yield str(d)
42
+ finally:
43
+ shutil.rmtree(d, ignore_errors=True)
44
+
45
+
46
+ def test_launch_round_trip_table_function(state_dir: str) -> None:
47
+ """A table function streams rows correctly over the launch transport."""
48
+ with Client.from_launch(_WORKER_ARGV, idle_timeout=10.0, state_dir=state_dir) as client:
49
+ batches = list(
50
+ client.table_function(
51
+ function_name="sequence",
52
+ schema_name="main",
53
+ arguments=Arguments(positional=(pa.scalar(5),)),
54
+ )
55
+ )
56
+
57
+ table = pa.Table.from_batches(batches)
58
+ assert table.column("n").to_pylist() == [0, 1, 2, 3, 4]
59
+
60
+
61
+ def test_launch_round_trip_catalog_listing(state_dir: str) -> None:
62
+ """Catalog discovery works over the launch transport (catalog_mixin path)."""
63
+ with Client.from_launch(_WORKER_ARGV, idle_timeout=10.0, state_dir=state_dir) as client:
64
+ catalogs = client.catalogs()
65
+
66
+ assert any(c.name == "example" for c in catalogs)
67
+
68
+
69
+ def test_launch_shares_one_worker_across_clients(state_dir: str) -> None:
70
+ """Two `Client`s with the same worker_argv + state_dir share one warm worker.
71
+
72
+ The whole point of the launcher over plain subprocess/TCP: a second client
73
+ pointing at the same command must reuse the first client's worker rather than
74
+ spawning its own. Proven by checking exactly one tracked worker exists in the
75
+ shared state dir after both clients have connected, not by any client-visible
76
+ process identity (the client has no API for that, by design — it shouldn't need
77
+ to know or care).
78
+ """
79
+ with Client.from_launch(_WORKER_ARGV, idle_timeout=10.0, state_dir=state_dir) as client_a:
80
+ assert client_a.catalogs()
81
+ with Client.from_launch(_WORKER_ARGV, idle_timeout=10.0, state_dir=state_dir) as client_b:
82
+ assert client_b.catalogs()
83
+ rows = status_rows(Path(state_dir))
84
+ assert len(rows) == 1, f"expected exactly one shared worker, found {len(rows)}: {rows}"
85
+ assert rows[0].alive
86
+
87
+
88
+ class TestLaunchConstructorValidation:
89
+ """``transport='launch'`` argument validation."""
90
+
91
+ def test_requires_launch_argv(self) -> None:
92
+ """Launch transport without launch_argv is rejected."""
93
+ with pytest.raises(ValueError, match="requires a non-empty launch_argv"):
94
+ Client(transport="launch", pool=None)
95
+
96
+ def test_rejects_empty_launch_argv(self) -> None:
97
+ """An explicitly empty launch_argv is rejected the same as omitting it."""
98
+ with pytest.raises(ValueError, match="requires a non-empty launch_argv"):
99
+ Client(transport="launch", launch_argv=(), pool=None)
100
+
101
+ def test_rejects_server_path(self) -> None:
102
+ """server_path is subprocess-only."""
103
+ with pytest.raises(ValueError, match="server_path is only meaningful"):
104
+ Client("some-worker", transport="launch", launch_argv=("x",), pool=None)
105
+
106
+ def test_rejects_base_url(self) -> None:
107
+ """base_url is http-only."""
108
+ with pytest.raises(ValueError, match="base_url is only meaningful"):
109
+ Client(transport="launch", launch_argv=("x",), base_url="http://x", pool=None)
110
+
111
+ def test_rejects_tcp_host_and_port(self) -> None:
112
+ """tcp_host/tcp_port are tcp-only."""
113
+ with pytest.raises(ValueError, match="tcp_host/tcp_port are only meaningful"):
114
+ Client(transport="launch", launch_argv=("x",), tcp_host="127.0.0.1", tcp_port=1, pool=None)