vgi-python 0.29.6__tar.gz → 0.31.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 (444) hide show
  1. {vgi_python-0.29.6 → vgi_python-0.31.0}/PKG-INFO +2 -2
  2. {vgi_python-0.29.6 → vgi_python-0.31.0}/pyproject.toml +2 -2
  3. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_serialization.py +65 -0
  4. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_batch_metadata_callback.py +1 -1
  5. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_scan_branches_client.py +8 -5
  6. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_time_travel_client.py +1 -1
  7. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_protocol_version.py +3 -3
  8. vgi_python-0.31.0/tests/test_client_oauth.py +204 -0
  9. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_wire_record_schema_parity.py +2 -0
  10. {vgi_python-0.29.6 → vgi_python-0.31.0}/uv.lock +5 -5
  11. vgi_python-0.31.0/vgi/_test_fixtures/table/same_name_schemas.py +136 -0
  12. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/worker.py +63 -0
  13. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/catalog/catalog_interface.py +51 -0
  14. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/catalog/descriptors.py +15 -4
  15. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/client.py +112 -11
  16. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/cpp_request_builders.py +1 -1
  17. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/protocol.py +1 -1
  18. vgi_python-0.31.0/vgi/protocol_version.txt +1 -0
  19. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/worker.py +44 -15
  20. vgi_python-0.29.6/vgi/protocol_version.txt +0 -1
  21. {vgi_python-0.29.6 → vgi_python-0.31.0}/.gitattributes +0 -0
  22. {vgi_python-0.29.6 → vgi_python-0.31.0}/.github/dependabot.yml +0 -0
  23. {vgi_python-0.29.6 → vgi_python-0.31.0}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
  24. {vgi_python-0.29.6 → vgi_python-0.31.0}/.github/workflows/ci.yml +0 -0
  25. {vgi_python-0.29.6 → vgi_python-0.31.0}/.github/workflows/docs.yml +0 -0
  26. {vgi_python-0.29.6 → vgi_python-0.31.0}/.github/workflows/integration.yml +0 -0
  27. {vgi_python-0.29.6 → vgi_python-0.31.0}/.github/workflows/release.yml +0 -0
  28. {vgi_python-0.29.6 → vgi_python-0.31.0}/.gitignore +0 -0
  29. {vgi_python-0.29.6 → vgi_python-0.31.0}/.python-version +0 -0
  30. {vgi_python-0.29.6 → vgi_python-0.31.0}/.vale.ini +0 -0
  31. {vgi_python-0.29.6 → vgi_python-0.31.0}/CLAUDE.md +0 -0
  32. {vgi_python-0.29.6 → vgi_python-0.31.0}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
  33. {vgi_python-0.29.6 → vgi_python-0.31.0}/DOCS_REVIEW_RUBRIC.md +0 -0
  34. {vgi_python-0.29.6 → vgi_python-0.31.0}/DOCS_USABILITY_TEST.md +0 -0
  35. {vgi_python-0.29.6 → vgi_python-0.31.0}/LICENSE +0 -0
  36. {vgi_python-0.29.6 → vgi_python-0.31.0}/README.md +0 -0
  37. {vgi_python-0.29.6 → vgi_python-0.31.0}/RELEASE-RUNBOOK.md +0 -0
  38. {vgi_python-0.29.6 → vgi_python-0.31.0}/SECURITY.md +0 -0
  39. {vgi_python-0.29.6 → vgi_python-0.31.0}/ci/README.md +0 -0
  40. {vgi_python-0.29.6 → vgi_python-0.31.0}/ci/preprocess-require.awk +0 -0
  41. {vgi_python-0.29.6 → vgi_python-0.31.0}/ci/run-integration.sh +0 -0
  42. {vgi_python-0.29.6 → vgi_python-0.31.0}/dist-vgi/.gitignore +0 -0
  43. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/aggregate-functions.md +0 -0
  44. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/arguments.md +0 -0
  45. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/auth.md +0 -0
  46. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/catalogs.md +0 -0
  47. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/client.md +0 -0
  48. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/exceptions.md +0 -0
  49. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/filters.md +0 -0
  50. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/functions.md +0 -0
  51. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/http.md +0 -0
  52. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/index.md +0 -0
  53. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/metadata.md +0 -0
  54. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/observability.md +0 -0
  55. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/storage.md +0 -0
  56. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/transactor.md +0 -0
  57. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/api/worker.md +0 -0
  58. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/argument-serialization.md +0 -0
  59. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/apple-touch-icon.png +0 -0
  60. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/favicon-16x16.png +0 -0
  61. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/favicon-32x32.png +0 -0
  62. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/favicon.ico +0 -0
  63. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/kinds/aggregate.svg +0 -0
  64. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/kinds/buffering.svg +0 -0
  65. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/kinds/scalar.svg +0 -0
  66. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/kinds/table-in-out.svg +0 -0
  67. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/kinds/table.svg +0 -0
  68. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/logo.png +0 -0
  69. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/assets/social-card.png +0 -0
  70. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/authentication.md +0 -0
  71. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/catalog-interface.md +0 -0
  72. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/cli.md +0 -0
  73. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/column-statistics.md +0 -0
  74. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/concepts/index.md +0 -0
  75. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/contributing-docs.md +0 -0
  76. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/filter-pushdown.md +0 -0
  77. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/generator-api.md +0 -0
  78. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/global-functions.md +0 -0
  79. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/how-to/catalogs.md +0 -0
  80. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/how-to/function-patterns.md +0 -0
  81. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/how-to/http-auth.md +0 -0
  82. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/how-to/index.md +0 -0
  83. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/how-to/pushdown-and-statistics.md +0 -0
  84. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/how-to/state-storage.md +0 -0
  85. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/index.md +0 -0
  86. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/lifecycle.md +0 -0
  87. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/metadata.md +0 -0
  88. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/overrides/main.html +0 -0
  89. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/robots.txt +0 -0
  90. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/shared-storage.md +0 -0
  91. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/stylesheets/extra.css +0 -0
  92. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/tutorial/index.md +0 -0
  93. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/tutorial/scalar.md +0 -0
  94. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/tutorial/table.md +0 -0
  95. {vgi_python-0.29.6 → vgi_python-0.31.0}/docs/vgi-logo.png +0 -0
  96. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/batch_index_worker.py +0 -0
  97. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/cache_worker.py +0 -0
  98. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/calc_scalar_worker.py +0 -0
  99. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/calc_worker.py +0 -0
  100. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/copy_format_worker.py +0 -0
  101. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/filter_worker.py +0 -0
  102. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/greeting_scalar_worker.py +0 -0
  103. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/row_count_worker.py +0 -0
  104. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/series_streaming_worker.py +0 -0
  105. {vgi_python-0.29.6 → vgi_python-0.31.0}/examples/sum_worker.py +0 -0
  106. {vgi_python-0.29.6 → vgi_python-0.31.0}/mkdocs.yml +0 -0
  107. {vgi_python-0.29.6 → vgi_python-0.31.0}/packages/vgi-fixtures/LICENSE +0 -0
  108. {vgi_python-0.29.6 → vgi_python-0.31.0}/packages/vgi-fixtures/README.md +0 -0
  109. {vgi_python-0.29.6 → vgi_python-0.31.0}/packages/vgi-fixtures/docker/Dockerfile +0 -0
  110. {vgi_python-0.29.6 → vgi_python-0.31.0}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
  111. {vgi_python-0.29.6 → vgi_python-0.31.0}/packages/vgi-fixtures/pyproject.toml +0 -0
  112. {vgi_python-0.29.6 → vgi_python-0.31.0}/scripts/measure_startup.py +0 -0
  113. {vgi_python-0.29.6 → vgi_python-0.31.0}/scripts/run_all_tests.sh +0 -0
  114. {vgi_python-0.29.6 → vgi_python-0.31.0}/test-data/generate.sh +0 -0
  115. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/__init__.py +0 -0
  116. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/_http_fixtures.py +0 -0
  117. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/__init__.py +0 -0
  118. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_attach_option.py +0 -0
  119. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_catalog_interface.py +0 -0
  120. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_client_catalog.py +0 -0
  121. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_column_statistics.py +0 -0
  122. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_declarative.py +0 -0
  123. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_example_worker_catalog.py +0 -0
  124. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_integration.py +0 -0
  125. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_required_filters.py +0 -0
  126. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_scan_branches.py +0 -0
  127. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_setting.py +0 -0
  128. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_storage.py +0 -0
  129. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_time_travel.py +0 -0
  130. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/catalog/test_writable_table.py +0 -0
  131. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/__init__.py +0 -0
  132. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_aggregate_client.py +0 -0
  133. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_broken_pipe.py +0 -0
  134. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_cli.py +0 -0
  135. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_cli_catalog_functions.py +0 -0
  136. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_copy_client.py +0 -0
  137. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_split_client.py +0 -0
  138. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_stop_force.py +0 -0
  139. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_table_column_statistics.py +0 -0
  140. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/client/test_worker_debug.py +0 -0
  141. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/__init__.py +0 -0
  142. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/_stub.py +0 -0
  143. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/conftest.py +0 -0
  144. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_accumulate.py +0 -0
  145. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_aggregate.py +0 -0
  146. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_attach.py +0 -0
  147. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_bearer_auth.py +0 -0
  148. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_const_param_enforcement.py +0 -0
  149. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_container.py +0 -0
  150. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_copy_from.py +0 -0
  151. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_copy_to.py +0 -0
  152. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_directory_parity.py +0 -0
  153. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_function_inventory.py +0 -0
  154. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_github.py +0 -0
  155. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_http_client.py +0 -0
  156. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_http_external_location.py +0 -0
  157. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_http_upload_url.py +0 -0
  158. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_macro.py +0 -0
  159. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_overload.py +0 -0
  160. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_protocol_inventory.py +0 -0
  161. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_resumable_scan.py +0 -0
  162. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_scalar.py +0 -0
  163. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
  164. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_secret.py +0 -0
  165. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_settings.py +0 -0
  166. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_splits.py +0 -0
  167. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_table.py +0 -0
  168. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_table_in_out.py +0 -0
  169. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_view.py +0 -0
  170. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conformance/test_writable.py +0 -0
  171. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/conftest.py +0 -0
  172. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/anchor_len_overrun.bin +0 -0
  173. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/bad_fingerprint.bin +0 -0
  174. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/bad_flags_unsealed_but_key_present.bin +0 -0
  175. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/bad_version.bin +0 -0
  176. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/generate.py +0 -0
  177. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/manifest.json +0 -0
  178. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/reserved_flag_bit.bin +0 -0
  179. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/stale_anchor.bin +0 -0
  180. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/truncated.bin +0 -0
  181. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/valid_sealed.bin +0 -0
  182. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/data/split_tokens/valid_unsealed.bin +0 -0
  183. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/__init__.py +0 -0
  184. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/test_bernoulli_function.py +0 -0
  185. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/test_binary_packet_function.py +0 -0
  186. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/test_client.py +0 -0
  187. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/test_conditional_message_function.py +0 -0
  188. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/test_hash_seed_function.py +0 -0
  189. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/test_multiply_by_setting_function.py +0 -0
  190. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/test_multiply_function.py +0 -0
  191. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/test_random_bytes_function.py +0 -0
  192. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/scalar/test_return_secret_value_function.py +0 -0
  193. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/__init__.py +0 -0
  194. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/__init__.py +0 -0
  195. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_constant_columns_function.py +0 -0
  196. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_double_sequence_function.py +0 -0
  197. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_exception_function.py +0 -0
  198. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_filter_echo_function.py +0 -0
  199. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_logging_function.py +0 -0
  200. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_nested_sequence_function.py +0 -0
  201. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_partitioned_function.py +0 -0
  202. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_projected_data_function.py +0 -0
  203. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_sequence_function.py +0 -0
  204. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_settings_function.py +0 -0
  205. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_struct_settings_function.py +0 -0
  206. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/generator/test_ten_thousand_function.py +0 -0
  207. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table/test_wide_columns.py +0 -0
  208. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/__init__.py +0 -0
  209. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/generator/__init__.py +0 -0
  210. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
  211. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/generator/test_echo_function.py +0 -0
  212. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/generator/test_exception_functions.py +0 -0
  213. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
  214. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
  215. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
  216. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
  217. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/test_blended_exchange.py +0 -0
  218. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/test_blended_metadata.py +0 -0
  219. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/table_in_out/test_client.py +0 -0
  220. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_access_log_audit.py +0 -0
  221. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_aggregate_function.py +0 -0
  222. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_argument_spec.py +0 -0
  223. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_auth.py +0 -0
  224. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_bind_exceptions.py +0 -0
  225. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_bind_request_at_clause.py +0 -0
  226. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_bound_storage_conformance.py +0 -0
  227. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_cache_control.py +0 -0
  228. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_call_state_attach.py +0 -0
  229. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_catalog_auth_binding.py +0 -0
  230. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_copy_from_function.py +0 -0
  231. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_copy_to_function.py +0 -0
  232. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_docstrings.py +0 -0
  233. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_documentation_examples.py +0 -0
  234. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_example_function_arg_types.py +0 -0
  235. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_examples_workers.py +0 -0
  236. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_exception_handling.py +0 -0
  237. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_exceptions.py +0 -0
  238. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_filter_pushdown.py +0 -0
  239. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_filter_pushdown_extension.py +0 -0
  240. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_fixture_catalog_parity.py +0 -0
  241. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_function_storage.py +0 -0
  242. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_function_storage_azure_sql.py +0 -0
  243. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_function_storage_cf_do.py +0 -0
  244. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_function_storage_cf_do_integration.py +0 -0
  245. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_function_storage_conformance.py +0 -0
  246. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_cpp_constants.py +0 -0
  247. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_cpp_protocol_version.py +0 -0
  248. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_cpp_request_builders.py +0 -0
  249. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_cpp_schemas.py +0 -0
  250. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_cpp_secret.py +0 -0
  251. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_go_schemas.py +0 -0
  252. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_java_schemas.py +0 -0
  253. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_protocol_version.py +0 -0
  254. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_rust_request_builders.py +0 -0
  255. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_rust_schemas.py +0 -0
  256. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_schemas_cross_lang.py +0 -0
  257. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_ts_client.py +0 -0
  258. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_generated_ts_schemas.py +0 -0
  259. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_http_demo_storage.py +0 -0
  260. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_http_s3_offload_input.py +0 -0
  261. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_http_s3_offload_output.py +0 -0
  262. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_launch_transport.py +0 -0
  263. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_metadata.py +0 -0
  264. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_mypy_consolidated.py +0 -0
  265. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_nest_tensor.py +0 -0
  266. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_otel.py +0 -0
  267. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_projection_enforcement.py +0 -0
  268. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_projection_repro.py +0 -0
  269. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_protocol_classes.py +0 -0
  270. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_resolved_secrets.py +0 -0
  271. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_schema_scoped_functions.py +0 -0
  272. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_schema_utils.py +0 -0
  273. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_serve.py +0 -0
  274. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_setting_secret_annotations.py +0 -0
  275. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_signing_key.py +0 -0
  276. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_split_token.py +0 -0
  277. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_table_buffering_function.py +0 -0
  278. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_table_function_dynamic_to_string.py +0 -0
  279. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_tcp_transport.py +0 -0
  280. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_type_bounds.py +0 -0
  281. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_union_argument.py +0 -0
  282. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_worker.py +0 -0
  283. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_worker_cli.py +0 -0
  284. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/test_worker_page.py +0 -0
  285. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/transactor/__init__.py +0 -0
  286. {vgi_python-0.29.6 → vgi_python-0.31.0}/tests/transactor/test_transactor.py +0 -0
  287. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/__init__.py +0 -0
  288. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_duckdb.py +0 -0
  289. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_storage_profile.py +0 -0
  290. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/__init__.py +0 -0
  291. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
  292. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/accumulate/worker.py +0 -0
  293. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
  294. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/_common.py +0 -0
  295. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/basic.py +0 -0
  296. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
  297. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/generic.py +0 -0
  298. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
  299. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
  300. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
  301. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
  302. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
  303. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
  304. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/aggregate/window.py +0 -0
  305. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/attach_options.py +0 -0
  306. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/bad_enum.py +0 -0
  307. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/bad_protocol.py +0 -0
  308. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/cancellable.py +0 -0
  309. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/catalog.py +0 -0
  310. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/companion.py +0 -0
  311. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/copy_from.py +0 -0
  312. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/copy_to.py +0 -0
  313. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/global_functions.py +0 -0
  314. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/http_server.py +0 -0
  315. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
  316. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
  317. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/nest_tensor.py +0 -0
  318. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/orchard_catalog.py +0 -0
  319. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
  320. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
  321. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/__init__.py +0 -0
  322. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/_common.py +0 -0
  323. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
  324. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
  325. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/binary.py +0 -0
  326. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/formatting.py +0 -0
  327. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/geo.py +0 -0
  328. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
  329. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
  330. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/same_name.py +0 -0
  331. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
  332. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/scalar/type_info.py +0 -0
  333. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
  334. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
  335. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/simple_writable.py +0 -0
  336. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/__init__.py +0 -0
  337. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/_common.py +0 -0
  338. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/batch_index.py +0 -0
  339. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
  340. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/cache.py +0 -0
  341. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
  342. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/filters.py +0 -0
  343. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/late_materialization.py +0 -0
  344. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/make_series.py +0 -0
  345. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/misc.py +0 -0
  346. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/order_modes.py +0 -0
  347. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/pairs.py +0 -0
  348. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/partition_columns.py +0 -0
  349. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
  350. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/profiling_example.py +0 -0
  351. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/required_filters.py +0 -0
  352. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
  353. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/sequence.py +0 -0
  354. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/settings.py +0 -0
  355. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/splits.py +0 -0
  356. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
  357. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
  358. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/typed_probe.py +0 -0
  359. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/versioned.py +0 -0
  360. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table/wide.py +0 -0
  361. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table_in_out.py +0 -0
  362. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
  363. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/twin_catalogs.py +0 -0
  364. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/versioned.py +0 -0
  365. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/versioned_tables.py +0 -0
  366. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/writable/__init__.py +0 -0
  367. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/writable/generic.py +0 -0
  368. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/writable/table.py +0 -0
  369. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/_test_fixtures/writable/worker.py +0 -0
  370. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/aggregate_function.py +0 -0
  371. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/argument_spec.py +0 -0
  372. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/arguments.py +0 -0
  373. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/attach_header.py +0 -0
  374. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/auth.py +0 -0
  375. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/cache_control.py +0 -0
  376. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/catalog/__init__.py +0 -0
  377. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/catalog/_descriptor_spec.py +0 -0
  378. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/catalog/attach_option.py +0 -0
  379. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/catalog/duckdb_statistics.py +0 -0
  380. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/catalog/secret_type.py +0 -0
  381. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/catalog/setting.py +0 -0
  382. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/catalog/storage.py +0 -0
  383. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/__init__.py +0 -0
  384. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/aggregate.py +0 -0
  385. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/catalog_mixin.py +0 -0
  386. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/cli.py +0 -0
  387. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/cli_catalog.py +0 -0
  388. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/cli_schema.py +0 -0
  389. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/cli_table.py +0 -0
  390. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/cli_transaction.py +0 -0
  391. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/cli_utils.py +0 -0
  392. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/cli_view.py +0 -0
  393. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/client/errors.py +0 -0
  394. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/__init__.py +0 -0
  395. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/_common.py +0 -0
  396. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/cpp_constants.py +0 -0
  397. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/cpp_protocol_version.py +0 -0
  398. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/cpp_schemas.py +0 -0
  399. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
  400. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/cpp_secret_request_builders.py +0 -0
  401. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/cpp_secret_schemas.py +0 -0
  402. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/go_schemas.py +0 -0
  403. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/java_schemas.py +0 -0
  404. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/protocol_version.py +0 -0
  405. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/rust_request_builders.py +0 -0
  406. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/rust_schemas.py +0 -0
  407. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/ts_client.py +0 -0
  408. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/codegen/ts_schemas.py +0 -0
  409. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/copy_from_function.py +0 -0
  410. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/copy_to_function.py +0 -0
  411. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/exceptions.py +0 -0
  412. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/function.py +0 -0
  413. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/function_storage.py +0 -0
  414. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/function_storage_azure_sql.py +0 -0
  415. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/function_storage_cf_do.py +0 -0
  416. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/http/__init__.py +0 -0
  417. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/http/demo_storage.py +0 -0
  418. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/http/landing.html +0 -0
  419. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/http/landing_page.py +0 -0
  420. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/http/vgi-client.js +0 -0
  421. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/http/worker_page.py +0 -0
  422. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/invocation.py +0 -0
  423. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/logging_config.py +0 -0
  424. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/meta_worker.py +0 -0
  425. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/metadata.py +0 -0
  426. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/otel.py +0 -0
  427. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/profiling.py +0 -0
  428. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/py.typed +0 -0
  429. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/scalar_function.py +0 -0
  430. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/schema_utils.py +0 -0
  431. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/secret_protocol.py +0 -0
  432. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/secret_service.py +0 -0
  433. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/serve.py +0 -0
  434. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/split_token.py +0 -0
  435. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/table_buffering_function.py +0 -0
  436. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/table_filter_pushdown.py +0 -0
  437. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/table_function.py +0 -0
  438. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/table_in_out_function.py +0 -0
  439. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/transactor/__init__.py +0 -0
  440. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/transactor/_duckdb_compat.py +0 -0
  441. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/transactor/client.py +0 -0
  442. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/transactor/protocol.py +0 -0
  443. {vgi_python-0.29.6 → vgi_python-0.31.0}/vgi/transactor/server.py +0 -0
  444. {vgi_python-0.29.6 → vgi_python-0.31.0}/wrangler.jsonc +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: vgi-python
3
- Version: 0.29.6
3
+ Version: 0.31.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: 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.2
165
+ Requires-Dist: vgi-rpc>=0.44.1
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'
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "vgi-python"
3
- version = "0.29.6"
3
+ version = "0.31.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.43.2",
43
+ "vgi-rpc>=0.44.1",
44
44
  "httpx2>=2.9.1",
45
45
  ]
46
46
 
@@ -1008,6 +1008,33 @@ class TestScanFunctionResultSerialization:
1008
1008
 
1009
1009
  assert restored.required_extensions == ["iceberg", "parquet", "httpfs"]
1010
1010
 
1011
+ def test_schema_name_round_trip(self) -> None:
1012
+ """schema_name (protocol 1.5.0) round-trips when set."""
1013
+ original = ScanFunctionResult(
1014
+ function_name="rowid_sequence",
1015
+ positional_arguments=[],
1016
+ named_arguments={},
1017
+ schema_name="main",
1018
+ )
1019
+ serialized = original.serialize()
1020
+ batch, _ = deserialize_record_batch(serialized)
1021
+ restored = ScanFunctionResult.deserialize(batch)
1022
+
1023
+ assert restored.schema_name == "main"
1024
+
1025
+ def test_schema_name_defaults_to_none(self) -> None:
1026
+ """schema_name is None when the caller doesn't set it (e.g. a pre-1.5.0 peer)."""
1027
+ original = ScanFunctionResult(
1028
+ function_name="read_parquet",
1029
+ positional_arguments=[],
1030
+ named_arguments={},
1031
+ )
1032
+ serialized = original.serialize()
1033
+ batch, _ = deserialize_record_batch(serialized)
1034
+ restored = ScanFunctionResult.deserialize(batch)
1035
+
1036
+ assert restored.schema_name is None
1037
+
1011
1038
 
1012
1039
  class TestSettingSpecSerialization:
1013
1040
  """Test SettingSpec serialization round-trip."""
@@ -1176,6 +1203,10 @@ class TestArrowSchemaCorrectness:
1176
1203
  assert schema.field("function_name").type == pa.string()
1177
1204
  assert schema.field("arguments").type == pa.binary()
1178
1205
  assert schema.field("required_extensions").type == pa.list_(pa.string())
1206
+ # Added in protocol 1.5.0 — nullable so a pre-1.5.0 peer's payload
1207
+ # still deserializes (the column is simply absent there).
1208
+ assert schema.field("schema_name").type == pa.string()
1209
+ assert schema.field("schema_name").nullable is True
1179
1210
 
1180
1211
 
1181
1212
  class TestScanBranchSerialization:
@@ -1192,6 +1223,10 @@ class TestScanBranchSerialization:
1192
1223
  assert schema.field("branch_filter").nullable is True
1193
1224
  assert schema.field("writable").type == pa.bool_()
1194
1225
  assert schema.field("writable").nullable is False
1226
+ # Added in protocol 1.5.0 — function-branch only; None for a
1227
+ # catalog-table/format branch or a pre-1.5.0 peer.
1228
+ assert schema.field("schema_name").type == pa.string()
1229
+ assert schema.field("schema_name").nullable is True
1195
1230
 
1196
1231
  def test_scan_branches_result_schema(self) -> None:
1197
1232
  """ScanBranchesResult Arrow schema: branches as list<binary>, required_extensions hoisted to top-level."""
@@ -1249,6 +1284,36 @@ class TestScanBranchSerialization:
1249
1284
  assert restored.branch_filter == "ts >= TIMESTAMP '2026-05-15 00:00:00'"
1250
1285
  assert len(restored.positional_arguments) == 2
1251
1286
 
1287
+ def test_scan_branch_schema_name_round_trip(self) -> None:
1288
+ """A function branch's schema_name (protocol 1.5.0) round-trips when set."""
1289
+ from vgi.catalog import ScanBranch
1290
+
1291
+ original = ScanBranch(
1292
+ function_name="rowid_sequence",
1293
+ positional_arguments=[],
1294
+ named_arguments={},
1295
+ schema_name="main",
1296
+ )
1297
+ batch, _ = deserialize_record_batch(original.serialize())
1298
+ restored = ScanBranch.deserialize(batch)
1299
+ assert restored.schema_name == "main"
1300
+
1301
+ def test_scan_branch_schema_name_defaults_to_none(self) -> None:
1302
+ """schema_name is None for a branch that doesn't set it (e.g. a catalog-table branch)."""
1303
+ from vgi.catalog import ScanBranch
1304
+
1305
+ original = ScanBranch(
1306
+ function_name="",
1307
+ positional_arguments=[],
1308
+ named_arguments={},
1309
+ source_catalog="lakehouse",
1310
+ source_schema="bronze",
1311
+ source_table="orders",
1312
+ )
1313
+ batch, _ = deserialize_record_batch(original.serialize())
1314
+ restored = ScanBranch.deserialize(batch)
1315
+ assert restored.schema_name is None
1316
+
1252
1317
  def test_scan_branches_result_round_trip(self) -> None:
1253
1318
  """ScanBranchesResult round-trips two heterogeneous branches + required_extensions."""
1254
1319
  from vgi.catalog import ScanBranch, ScanBranchesResult
@@ -69,7 +69,7 @@ def test_callback_sees_none_for_a_batch_without_custom_metadata(client: Any) ->
69
69
  client.table_function(
70
70
  function_name="sequence",
71
71
  schema_name="main",
72
- arguments=Arguments(positional=[pa.scalar(4)]),
72
+ arguments=Arguments(positional=(pa.scalar(4),)),
73
73
  batch_metadata_callback=metas.append,
74
74
  )
75
75
  )
@@ -60,8 +60,11 @@ def test_single_branch_table_falls_back_to_legacy_rpc(client: Any) -> None:
60
60
  name="numbers",
61
61
  )
62
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
63
+ assert (
64
+ result.branches[0].function_name
65
+ == client.table_scan_function_get(
66
+ attach_opaque_data=_attach_opaque(client),
67
+ schema_name=DATA,
68
+ name="numbers",
69
+ ).function_name
70
+ )
@@ -79,7 +79,7 @@ def test_table_function_with_no_at_clause_is_unaffected(client: Any) -> None:
79
79
  """The new `at_unit`/`at_value` params default to `None` — unchanged behavior without them."""
80
80
  batches = list(
81
81
  client.table_function(
82
- function_name="sequence", schema_name="main", arguments=Arguments(positional=[pa.scalar(5)])
82
+ function_name="sequence", schema_name="main", arguments=Arguments(positional=(pa.scalar(5),))
83
83
  )
84
84
  )
85
85
  assert sum(b.num_rows for b in batches) == 5
@@ -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.4.0"
35
+ assert CLIENT_PROTOCOL_VERSION == "1.5.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.4.0 client at dispatch."""
42
+ """A worker enforcing 99.0.0 must reject the 1.5.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.3.0) is older than the worker (99.0.0).
57
+ # Directional hint: the client (1.5.0) is older than the worker (99.0.0).
58
58
  assert "upgrade the VGI extension/client" in message
@@ -0,0 +1,204 @@
1
+ # Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+
3
+ """Tests for vgi.client.Client's OAuth wiring (oauth=/oauth_refresh_token=/oauth_flow=).
4
+
5
+ The device-code/PKCE flow logic itself is tested exhaustively in
6
+ vgi-rpc-python's tests/test_oauth_client.py (mock IdP, no network). These
7
+ tests cover the integration seam: does `Client` build a `VgiOAuthAuth` with
8
+ the right configuration, does construction-time validation reject bad
9
+ combinations, and does a full round trip actually work when driven through
10
+ `Client`'s real request path (via the `httpx_client=` escape hatch, wired to
11
+ a mock IdP the same way vgi-rpc-python's own tests are).
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import httpx2
17
+ import pytest
18
+ from vgi_rpc.http import VgiOAuthAuth
19
+
20
+ from vgi.client.client import Client
21
+
22
+ RESOURCE_METADATA_URL = "https://api.example.com/.well-known/oauth-protected-resource"
23
+ DEVICE_AUTH_URL = "https://auth.example.com/device/code"
24
+ TOKEN_URL = "https://auth.example.com/token"
25
+
26
+
27
+ class _MockIdp:
28
+ """Minimal mock IdP + protected resource for one full device-code round trip."""
29
+
30
+ def __init__(self) -> None:
31
+ self.device_auth_calls = 0
32
+ self.granted_token = "mock-access-token"
33
+
34
+ def handler(self, request: httpx2.Request) -> httpx2.Response:
35
+ """Route a request to the matching mock endpoint by exact URL."""
36
+ url = str(request.url)
37
+ if url == RESOURCE_METADATA_URL:
38
+ return httpx2.Response(
39
+ 200,
40
+ json={
41
+ "resource": "https://api.example.com",
42
+ "authorization_servers": ["https://auth.example.com"],
43
+ "device_code_client_id": "device-client",
44
+ "device_code_client_secret": "device-secret",
45
+ },
46
+ )
47
+ if url == "https://auth.example.com/.well-known/openid-configuration":
48
+ return httpx2.Response(
49
+ 200,
50
+ json={
51
+ "token_endpoint": TOKEN_URL,
52
+ "device_authorization_endpoint": DEVICE_AUTH_URL,
53
+ "grant_types_supported": ["urn:ietf:params:oauth:grant-type:device_code"],
54
+ },
55
+ )
56
+ if url == DEVICE_AUTH_URL:
57
+ self.device_auth_calls += 1
58
+ return httpx2.Response(
59
+ 200,
60
+ json={
61
+ "device_code": "devcode-123",
62
+ "user_code": "ABCD-EFGH",
63
+ "verification_uri": "https://auth.example.com/activate",
64
+ "expires_in": 600,
65
+ "interval": 0,
66
+ },
67
+ )
68
+ if url == TOKEN_URL:
69
+ return httpx2.Response(200, json={"access_token": self.granted_token, "token_type": "Bearer"})
70
+ if url.endswith("/vgi/catalogs"):
71
+ token = request.headers.get("authorization", "")
72
+ if token:
73
+ return httpx2.Response(200, json={"authorization": token})
74
+ return httpx2.Response(
75
+ 401,
76
+ headers={"www-authenticate": f'Bearer resource_metadata="{RESOURCE_METADATA_URL}"'},
77
+ )
78
+ return httpx2.Response(404, json={"error": "not_found", "url": url}) # pragma: no cover
79
+
80
+
81
+ class TestConstructorValidation:
82
+ """Tests for the mutually-exclusive oauth/bearer_token/httpx_client combinations."""
83
+
84
+ def test_oauth_and_bearer_token_raises(self) -> None:
85
+ """Passing both oauth=True and bearer_token= raises ValueError."""
86
+ with pytest.raises(ValueError, match="mutually exclusive"):
87
+ Client(transport="http", base_url="https://example.com", oauth=True, bearer_token="tok")
88
+
89
+ def test_oauth_refresh_token_and_bearer_token_raises(self) -> None:
90
+ """oauth_refresh_token= (which implies oauth=True) also conflicts with bearer_token=."""
91
+ with pytest.raises(ValueError, match="mutually exclusive"):
92
+ Client(
93
+ transport="http",
94
+ base_url="https://example.com",
95
+ oauth_refresh_token="seed",
96
+ bearer_token="tok",
97
+ )
98
+
99
+ def test_oauth_and_httpx_client_raises(self) -> None:
100
+ """Passing both oauth=True and httpx_client= raises ValueError."""
101
+ with pytest.raises(ValueError, match="httpx_client"):
102
+ Client(
103
+ transport="http",
104
+ base_url="https://example.com",
105
+ oauth=True,
106
+ httpx_client=httpx2.Client(),
107
+ )
108
+
109
+ def test_invalid_oauth_flow_raises(self) -> None:
110
+ """An unrecognized oauth_flow value raises ValueError, not a silent no-op."""
111
+ with pytest.raises(ValueError, match="oauth_flow"):
112
+ Client(transport="http", base_url="https://example.com", oauth=True, oauth_flow="carrier-pigeon") # type: ignore[arg-type]
113
+
114
+ def test_invalid_oauth_prompt_raises(self) -> None:
115
+ """An unrecognized oauth_prompt value raises ValueError, not a silent no-op."""
116
+ with pytest.raises(ValueError, match="oauth_prompt"):
117
+ Client(transport="http", base_url="https://example.com", oauth=True, oauth_prompt="shout") # type: ignore[arg-type]
118
+
119
+ def test_bearer_token_alone_still_works(self) -> None:
120
+ """The existing bearer_token= path is unaffected by the new oauth params."""
121
+ client = Client(transport="http", base_url="https://example.com", bearer_token="tok")
122
+ assert client._bearer_token == "tok"
123
+ assert not client._use_oauth
124
+
125
+
126
+ class TestOAuthWiring:
127
+ """Tests that Client(oauth=...) builds a correctly-configured VgiOAuthAuth."""
128
+
129
+ def test_oauth_true_builds_vgi_oauth_auth(self) -> None:
130
+ """oauth=True lazily builds a VgiOAuthAuth with the client's own oauth_* settings."""
131
+ client = Client(
132
+ transport="http",
133
+ base_url="https://example.com",
134
+ oauth=True,
135
+ oauth_flow="device_code",
136
+ oauth_timeout_seconds=42.0,
137
+ oauth_prompt="consent",
138
+ )
139
+ assert client.oauth_identity() is None # nothing has authenticated yet
140
+ client._get_or_create_httpx_client()
141
+ assert isinstance(client._oauth_auth, VgiOAuthAuth)
142
+ assert client._oauth_auth._flow == "device_code" # noqa: SLF001 -- white-box wiring check
143
+ assert client._oauth_auth._timeout_seconds == 42.0 # noqa: SLF001
144
+ assert client._oauth_auth._prompt == "consent" # noqa: SLF001
145
+ client._oauth_auth.close()
146
+
147
+ def test_oauth_refresh_token_seeds_the_auth_object(self) -> None:
148
+ """oauth_refresh_token= implies oauth=True and seeds the refresh token."""
149
+ client = Client(
150
+ transport="http",
151
+ base_url="https://example.com",
152
+ oauth_refresh_token="pre-seeded-token",
153
+ )
154
+ assert client._use_oauth
155
+ client._get_or_create_httpx_client()
156
+ assert client._oauth_auth is not None
157
+ assert client._oauth_auth._token.refresh_token == "pre-seeded-token" # noqa: SLF001
158
+ client._oauth_auth.close()
159
+
160
+
161
+ class TestOAuthEndToEnd:
162
+ """A full device-code login round trip through the exact client Client would use.
163
+
164
+ Uses the httpx_client= escape hatch to wire a VgiOAuthAuth against a mock
165
+ IdP (httpx2.MockTransport) -- the same technique vgi-rpc-python's own
166
+ tests use. The device-code/PKCE flow mechanics are covered exhaustively
167
+ there (mock IdP, no network); this test's job is narrower: prove
168
+ ``Client`` actually issues its RPCs through the httpx2.Client it was
169
+ handed (so a real attach would carry the OAuth-obtained token), and that
170
+ a 401-triggered login on that client completes end to end.
171
+ """
172
+
173
+ def test_client_issues_requests_through_the_oauth_authed_httpx_client(self) -> None:
174
+ """A 401 on the client Client._get_or_create_httpx_client() returns triggers a real login."""
175
+ idp = _MockIdp()
176
+ auth = VgiOAuthAuth(
177
+ base_url="https://example.com",
178
+ flow="device_code",
179
+ timeout_seconds=5.0,
180
+ transport=httpx2.MockTransport(idp.handler),
181
+ )
182
+ httpx_client = httpx2.Client(
183
+ transport=httpx2.MockTransport(idp.handler), auth=auth, base_url="https://example.com"
184
+ )
185
+ # Not started (no worker spawned) -- this test only exercises the HTTP/OAuth
186
+ # plumbing, not a full RPC call, so client.stop() (which requires start())
187
+ # doesn't apply; the httpx_client/auth are closed directly instead.
188
+ client = Client(transport="http", base_url="https://example.com", httpx_client=httpx_client)
189
+ try:
190
+ # This is the exact client object Client's own RPC machinery sends
191
+ # every request through -- not a parallel one built just for the test.
192
+ assert client._get_or_create_httpx_client() is httpx_client
193
+
194
+ resp = httpx_client.get("/vgi/catalogs")
195
+ assert resp.status_code == 200
196
+ assert resp.json()["authorization"] == f"Bearer {idp.granted_token}"
197
+ assert idp.device_auth_calls == 1
198
+
199
+ # A second request reuses the cached token -- no second login.
200
+ httpx_client.get("/vgi/catalogs")
201
+ assert idp.device_auth_calls == 1
202
+ finally:
203
+ httpx_client.close()
204
+ auth.close()
@@ -81,6 +81,7 @@ def _scan_function_result() -> ScanFunctionResult:
81
81
  positional_arguments=positional,
82
82
  named_arguments=named,
83
83
  required_extensions=["parquet"],
84
+ schema_name="main",
84
85
  )
85
86
 
86
87
 
@@ -98,6 +99,7 @@ def _scan_branch() -> ScanBranch:
98
99
  format_name="parquet",
99
100
  format_locations=["s3://bucket/a.parquet"],
100
101
  format_options={"delim": pa.scalar("|", pa.string())},
102
+ schema_name="main",
101
103
  )
102
104
 
103
105
 
@@ -2569,7 +2569,7 @@ requires-dist = [
2569
2569
 
2570
2570
  [[package]]
2571
2571
  name = "vgi-python"
2572
- version = "0.29.6"
2572
+ version = "0.31.0"
2573
2573
  source = { editable = "." }
2574
2574
  dependencies = [
2575
2575
  { name = "click" },
@@ -2686,7 +2686,7 @@ requires-dist = [
2686
2686
  { name = "vgi-python", extras = ["test-fixtures"], marker = "extra == 'test-fixtures-writable'" },
2687
2687
  { name = "vgi-python", extras = ["test-fixtures", "test-fixtures-writable", "http", "launch", "oauth", "otel", "sentry", "azure"], marker = "extra == 'dev'" },
2688
2688
  { name = "vgi-python", extras = ["transactor"], marker = "extra == 'test-fixtures-writable'" },
2689
- { name = "vgi-rpc", specifier = ">=0.43.2" },
2689
+ { name = "vgi-rpc", specifier = ">=0.44.1" },
2690
2690
  { name = "vgi-rpc", extras = ["cli"], marker = "extra == 'launch'" },
2691
2691
  { name = "vgi-rpc", extras = ["cli", "conformance", "external", "http", "oauth", "otel", "sentry"], marker = "extra == 'dev'" },
2692
2692
  { name = "vgi-rpc", extras = ["http"], marker = "extra == 'granian'" },
@@ -2716,7 +2716,7 @@ docs = [
2716
2716
 
2717
2717
  [[package]]
2718
2718
  name = "vgi-rpc"
2719
- version = "0.43.2"
2719
+ version = "0.44.1"
2720
2720
  source = { registry = "https://pypi.org/simple" }
2721
2721
  dependencies = [
2722
2722
  { name = "docstring-parser" },
@@ -2724,9 +2724,9 @@ dependencies = [
2724
2724
  { name = "pywin32", marker = "sys_platform == 'win32'" },
2725
2725
  { name = "tzdata", marker = "sys_platform == 'win32'" },
2726
2726
  ]
2727
- sdist = { url = "https://files.pythonhosted.org/packages/ce/04/efb99f0fb56535bcba110e6c12448c31b429e0861aae4bc2f7136299cfc2/vgi_rpc-0.43.2.tar.gz", hash = "sha256:6a06437af17442451bfe07186bc472a2efb57e030b0e5b38a28922034a814123", size = 1147340, upload-time = "2026-08-27T18:33:54.608Z" }
2727
+ sdist = { url = "https://files.pythonhosted.org/packages/1a/16/5a78053080117cac00a8945b70298d636a63d57801a33528bb63b14cdd95/vgi_rpc-0.44.1.tar.gz", hash = "sha256:37a54ae2cb7e5a7a2603aad69ece92c3c99a96906c96d2196806202ee4b70825", size = 1170809, upload-time = "2026-08-28T15:03:07.221Z" }
2728
2728
  wheels = [
2729
- { url = "https://files.pythonhosted.org/packages/ac/b9/33cdb4fe27ef3893e1cded63f396af8bc517e390615f34db6f4bd227ef4c/vgi_rpc-0.43.2-py3-none-any.whl", hash = "sha256:b112ab76828367176a41f1b9a4ceeaba8979629e4e5972f64bf769c94b3e36a4", size = 528134, upload-time = "2026-08-27T18:33:52.829Z" },
2729
+ { url = "https://files.pythonhosted.org/packages/8f/d6/3bfff42bd723ffcd0c2550d932e766aa65d39a886017cb9c002174e68196/vgi_rpc-0.44.1-py3-none-any.whl", hash = "sha256:e9785753bdb30e3f07f2bdbeafcddd09533cc014baa310e093a94fdeda6ad517", size = 545257, upload-time = "2026-08-28T15:03:05.268Z" },
2730
2730
  ]
2731
2731
 
2732
2732
  [package.optional-dependencies]
@@ -0,0 +1,136 @@
1
+ # Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+
3
+ """Same-name-in-two-schemas producer, backing a DECLARATIVE TABLE in each schema.
4
+
5
+ The table-dispatch member of the schema-disambiguation family (see
6
+ ``scalar/same_name.py``, ``table_in_out_same_name.py``, ``aggregate/same_name.py``,
7
+ and ``table/same_name_cached.py`` for the result-cache member). Those probe a
8
+ function called directly (or the result cache); this one probes
9
+ ``catalog_table_scan_function_get``/``catalog_table_scan_branches_get`` — the RPC
10
+ pair that tells a client which function backs a *declarative catalog table*.
11
+
12
+ ``test_same_name_table_scan`` is a one-row producer registered under the SAME
13
+ NAME in BOTH the ``main`` and ``data`` schemas of the ``example`` catalog, each
14
+ emitting a single row tagged with its own schema. A declarative ``Table``
15
+ descriptor named ``test_same_name_table`` is registered in each schema too, each
16
+ backed by that schema's own implementation.
17
+
18
+ This is also the end-to-end regression guard for protocol 1.5.0's
19
+ ``ScanFunctionResult.schema_name``/``ScanBranch.schema_name``: the C++ extension
20
+ now prefers the worker-declared schema over its old table-schema/default-schema
21
+ heuristic when resolving which catalog entry ``function_name`` refers to. A
22
+ worker that regressed to leaving ``schema_name`` unset, or a client that stopped
23
+ consuming it, would silently fall back to the old heuristic — which still
24
+ happens to get *this* two-schema case right (the table's own schema is tried
25
+ first and always matches here), so a regression here would show up not as a
26
+ wrong row, but as the exact filter/projection-pushdown breakage this session's
27
+ own investigation traced to passing the wire-parsed schema string somewhere the
28
+ resolver couldn't safely reuse it — see ``cache/filter_pushdown_keys.test`` and
29
+ this table family's own pushdown assertions below. Driven by
30
+ ``table/same_name_schemas.test``.
31
+ """
32
+
33
+ from __future__ import annotations
34
+
35
+ from dataclasses import dataclass
36
+ from typing import ClassVar
37
+
38
+ import pyarrow as pa
39
+ from vgi_rpc import ArrowSerializableDataclass
40
+ from vgi_rpc.rpc import OutputCollector
41
+
42
+ from vgi.metadata import FunctionExample
43
+ from vgi.schema_utils import schema
44
+ from vgi.table_function import (
45
+ ProcessParams,
46
+ TableFunctionGenerator,
47
+ bind_fixed_schema,
48
+ init_single_worker,
49
+ )
50
+
51
+ FUNCTION_NAME = "test_same_name_table_scan"
52
+ TABLE_NAME = "test_same_name_table"
53
+
54
+
55
+ @dataclass(slots=True, frozen=True)
56
+ class _SameNameTableArgs:
57
+ """Arguments for the same-name table producer (none)."""
58
+
59
+
60
+ @dataclass(kw_only=True)
61
+ class _SameNameTableState(ArrowSerializableDataclass):
62
+ """One-shot emit latch for the single output row."""
63
+
64
+ done: bool = False
65
+
66
+
67
+ class _SameNameTableScan(TableFunctionGenerator[_SameNameTableArgs, _SameNameTableState]):
68
+ """Shared body; each subclass supplies the schema it is declared in."""
69
+
70
+ #: Schema this implementation is declared in — the tag it stamps.
71
+ OWNING_SCHEMA: ClassVar[str] = ""
72
+
73
+ FunctionArguments = _SameNameTableArgs
74
+ FIXED_SCHEMA: ClassVar[pa.Schema] = schema(tag=pa.string())
75
+
76
+ @classmethod
77
+ def initial_state(cls, params: ProcessParams[_SameNameTableArgs]) -> _SameNameTableState:
78
+ """Fresh latch per invocation."""
79
+ return _SameNameTableState()
80
+
81
+ @classmethod
82
+ def process(
83
+ cls,
84
+ params: ProcessParams[_SameNameTableArgs],
85
+ state: _SameNameTableState,
86
+ out: OutputCollector,
87
+ ) -> None:
88
+ """Emit the single schema-tagged row once."""
89
+ if state.done:
90
+ out.finish()
91
+ return
92
+ batch = pa.RecordBatch.from_pydict({"tag": [cls.OWNING_SCHEMA]}, schema=params.output_schema)
93
+ out.emit(batch)
94
+ state.done = True
95
+
96
+
97
+ @init_single_worker
98
+ @bind_fixed_schema
99
+ class SameNameTableMainScan(_SameNameTableScan):
100
+ """``test_same_name_table_scan`` as declared in the ``main`` schema."""
101
+
102
+ OWNING_SCHEMA = "main"
103
+
104
+ class Meta:
105
+ """Function metadata."""
106
+
107
+ name = FUNCTION_NAME
108
+ description = "Schema-disambiguation probe; the main-schema table producer"
109
+ categories = ["generator", "testing"]
110
+ examples = [
111
+ FunctionExample(
112
+ sql="SELECT * FROM example.main.test_same_name_table",
113
+ description="One row tagged 'main'",
114
+ ),
115
+ ]
116
+
117
+
118
+ @init_single_worker
119
+ @bind_fixed_schema
120
+ class SameNameTableDataScan(_SameNameTableScan):
121
+ """``test_same_name_table_scan`` as declared in the ``data`` schema."""
122
+
123
+ OWNING_SCHEMA = "data"
124
+
125
+ class Meta:
126
+ """Function metadata."""
127
+
128
+ name = FUNCTION_NAME
129
+ description = "Schema-disambiguation probe; the data-schema table producer"
130
+ categories = ["generator", "testing"]
131
+ examples = [
132
+ FunctionExample(
133
+ sql="SELECT * FROM example.data.test_same_name_table",
134
+ description="One row tagged 'data'",
135
+ ),
136
+ ]