vgi-python 0.25.0__tar.gz → 0.27.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.
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.github/workflows/ci.yml +13 -10
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.github/workflows/docs.yml +1 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.github/workflows/integration.yml +1 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.github/workflows/release.yml +4 -4
- {vgi_python-0.25.0 → vgi_python-0.27.0}/CLAUDE.md +1 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/PKG-INFO +3 -3
- vgi_python-0.27.0/RELEASE-RUNBOOK.md +69 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/auth.md +6 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/how-to/state-storage.md +1 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/pyproject.toml +15 -4
- vgi_python-0.27.0/tests/catalog/test_attach_option.py +192 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_declarative.py +6 -3
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_required_filters.py +15 -16
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_scan_branches.py +4 -4
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_accumulate.py +81 -31
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_const_param_enforcement.py +2 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_resumable_scan.py +16 -6
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_scalar_attach_opaque_data.py +3 -4
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/test_wide_columns.py +2 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/test_blended_metadata.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_aggregate_function.py +5 -3
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_argument_spec.py +4 -3
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_auth.py +6 -6
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_bind_request_at_clause.py +5 -4
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_bound_storage_conformance.py +10 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_cache_control.py +6 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_call_state_attach.py +1 -3
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_copy_from_function.py +31 -11
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_copy_to_function.py +30 -13
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_examples_workers.py +11 -5
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_filter_pushdown_extension.py +4 -2
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_function_storage.py +8 -4
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_function_storage_cf_do.py +17 -16
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_function_storage_cf_do_integration.py +8 -7
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_function_storage_conformance.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_cpp_schemas.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_cpp_secret.py +4 -3
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_http_demo_storage.py +3 -3
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_http_s3_offload_input.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_metadata.py +9 -10
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_nest_tensor.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_projection_repro.py +1 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_protocol_classes.py +25 -16
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_resolved_secrets.py +14 -5
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_schema_scoped_functions.py +2 -1
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_serve.py +17 -9
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_table_buffering_function.py +57 -27
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_union_argument.py +8 -4
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_worker.py +15 -5
- {vgi_python-0.25.0 → vgi_python-0.27.0}/uv.lock +696 -712
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/attach_options.py +34 -3
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/http_server.py +5 -14
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/catalog/_descriptor_spec.py +39 -2
- vgi_python-0.27.0/vgi/catalog/attach_option.py +157 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/catalog/catalog_interface.py +3 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/catalog_mixin.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/client.py +8 -8
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/function_storage_cf_do.py +7 -7
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/http/landing.html +260 -18
- vgi_python-0.27.0/vgi/http/landing_page.py +112 -0
- vgi_python-0.27.0/vgi/http/vgi-client.js +23 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/serve.py +3 -10
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/worker.py +1 -1
- vgi_python-0.25.0/tests/landing/_checker.py +0 -151
- vgi_python-0.25.0/tests/landing/describe.expected.json +0 -3442
- vgi_python-0.25.0/tests/landing/describe.schema.json +0 -402
- vgi_python-0.25.0/tests/test_landing_conformance.py +0 -93
- vgi_python-0.25.0/vgi/catalog/attach_option.py +0 -49
- vgi_python-0.25.0/vgi/http/describe_json.py +0 -461
- vgi_python-0.25.0/vgi/http/landing_page.py +0 -95
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.gitattributes +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.github/dependabot.yml +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.gitignore +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.python-version +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/.vale.ini +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/DOCS_REVIEW_RUBRIC.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/DOCS_USABILITY_TEST.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/LICENSE +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/README.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/SECURITY.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/ci/README.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/ci/preprocess-require.awk +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/ci/run-integration.sh +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/dist-vgi/.gitignore +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/aggregate-functions.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/arguments.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/catalogs.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/client.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/exceptions.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/filters.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/functions.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/http.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/metadata.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/observability.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/storage.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/transactor.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/api/worker.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/argument-serialization.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/apple-touch-icon.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/favicon-16x16.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/favicon-32x32.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/favicon.ico +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/kinds/aggregate.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/kinds/buffering.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/kinds/scalar.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/kinds/table-in-out.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/kinds/table.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/logo.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/assets/social-card.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/authentication.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/catalog-interface.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/cli.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/column-statistics.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/concepts/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/contributing-docs.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/filter-pushdown.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/generator-api.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/global-functions.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/how-to/catalogs.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/how-to/function-patterns.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/how-to/http-auth.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/how-to/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/how-to/pushdown-and-statistics.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/lifecycle.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/metadata.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/overrides/main.html +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/robots.txt +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/shared-storage.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/stylesheets/extra.css +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/tutorial/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/tutorial/scalar.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/tutorial/table.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/docs/vgi-logo.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/examples/calc_scalar_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/examples/calc_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/examples/filter_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/examples/greeting_scalar_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/examples/row_count_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/examples/series_streaming_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/examples/sum_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/mkdocs.yml +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/packages/vgi-fixtures/LICENSE +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/packages/vgi-fixtures/README.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/packages/vgi-fixtures/docker/Dockerfile +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/packages/vgi-fixtures/pyproject.toml +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/scripts/measure_startup.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/scripts/run_all_tests.sh +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/test-data/generate.sh +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/_http_fixtures.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_catalog_interface.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_client_catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_column_statistics.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_example_worker_catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_integration.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_serialization.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_setting.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_time_travel.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/catalog/test_writable_table.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/client/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/client/test_broken_pipe.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/client/test_cli.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/client/test_cli_catalog_functions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/client/test_worker_debug.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/_stub.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/conftest.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_aggregate.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_attach.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_bearer_auth.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_container.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_copy_from.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_copy_to.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_directory_parity.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_function_inventory.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_github.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_http_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_http_external_location.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_http_upload_url.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_macro.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_overload.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_protocol_inventory.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_scalar.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_secret.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_settings.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_table.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_table_in_out.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_view.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conformance/test_writable.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/conftest.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/test_bernoulli_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/test_binary_packet_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/test_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/test_conditional_message_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/test_hash_seed_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/test_multiply_by_setting_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/test_multiply_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/test_random_bytes_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/scalar/test_return_secret_value_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_constant_columns_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_double_sequence_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_exception_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_filter_echo_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_logging_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_nested_sequence_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_partitioned_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_projected_data_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_sequence_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_settings_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_struct_settings_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table/generator/test_ten_thousand_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/generator/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/generator/test_echo_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/generator/test_exception_functions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/table_in_out/test_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_access_log_audit.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_bind_exceptions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_catalog_auth_binding.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_docstrings.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_documentation_examples.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_example_function_arg_types.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_exception_handling.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_exceptions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_filter_pushdown.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_function_storage_azure_sql.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_cpp_constants.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_cpp_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_cpp_request_builders.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_go_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_schemas_cross_lang.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_ts_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_generated_ts_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_http_s3_offload_output.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_mypy_consolidated.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_otel.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_projection_enforcement.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_schema_utils.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_setting_secret_annotations.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_signing_key.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_table_function_dynamic_to_string.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_tcp_transport.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_type_bounds.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_worker_cli.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/test_worker_page.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/transactor/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/tests/transactor/test_transactor.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_duckdb.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_storage_profile.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/accumulate/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/_common.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/basic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/generic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/aggregate/window.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/bad_enum.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/bad_protocol.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/cancellable.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/companion.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/copy_from.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/copy_to.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/global_functions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/nest_tensor.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/orchard_catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/_common.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/binary.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/formatting.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/geo.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/same_name.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/scalar/type_info.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/simple_writable.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/_common.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/batch_index.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/cache.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/filters.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/late_materialization.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/make_series.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/misc.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/order_modes.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/pairs.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/partition_columns.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/profiling_example.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/required_filters.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/sequence.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/settings.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/typed_probe.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/versioned.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table/wide.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table_in_out.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/twin_catalogs.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/versioned.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/versioned_tables.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/writable/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/writable/generic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/writable/table.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/_test_fixtures/writable/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/aggregate_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/argument_spec.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/arguments.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/attach_header.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/auth.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/cache_control.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/catalog/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/catalog/descriptors.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/catalog/duckdb_statistics.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/catalog/secret_type.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/catalog/setting.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/catalog/storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/cli.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/cli_catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/cli_schema.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/cli_table.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/cli_transaction.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/cli_utils.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/client/cli_view.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/_common.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/cpp_constants.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/cpp_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/cpp_request_builders.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/cpp_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/cpp_secret_request_builders.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/cpp_secret_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/go_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/ts_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/codegen/ts_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/copy_from_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/copy_to_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/exceptions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/function_storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/function_storage_azure_sql.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/http/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/http/demo_storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/http/worker_page.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/invocation.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/logging_config.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/meta_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/metadata.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/otel.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/profiling.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/protocol.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/protocol_version.txt +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/py.typed +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/scalar_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/schema_utils.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/secret_protocol.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/secret_service.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/table_buffering_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/table_filter_pushdown.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/table_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/table_in_out_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/transactor/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/transactor/_duckdb_compat.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/transactor/client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/transactor/protocol.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/vgi/transactor/server.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.27.0}/wrangler.jsonc +0 -0
|
@@ -30,7 +30,7 @@ jobs:
|
|
|
30
30
|
- uses: actions/checkout@v7
|
|
31
31
|
|
|
32
32
|
- name: Install uv
|
|
33
|
-
uses: astral-sh/setup-uv@
|
|
33
|
+
uses: astral-sh/setup-uv@v9.0.0
|
|
34
34
|
|
|
35
35
|
- name: Set up Python ${{ matrix.python-version }}
|
|
36
36
|
run: uv python install ${{ matrix.python-version }}
|
|
@@ -48,7 +48,7 @@ jobs:
|
|
|
48
48
|
- uses: actions/checkout@v7
|
|
49
49
|
|
|
50
50
|
- name: Install uv
|
|
51
|
-
uses: astral-sh/setup-uv@
|
|
51
|
+
uses: astral-sh/setup-uv@v9.0.0
|
|
52
52
|
|
|
53
53
|
- name: Install dependencies
|
|
54
54
|
run: uv sync --all-extras
|
|
@@ -62,15 +62,18 @@ jobs:
|
|
|
62
62
|
# Docstring consistency (pydoclint) runs inside the pytest suite via
|
|
63
63
|
# tests/test_docstrings.py, so it's not a separate CI lint step.
|
|
64
64
|
|
|
65
|
+
# ty was removed here in 0.25.2. It was already non-blocking, and at
|
|
66
|
+
# 0.0.66 it stopped terminating on this tree at all -- `ty check vgi/`
|
|
67
|
+
# ran past ten minutes and had to be killed. A signal nothing gates on,
|
|
68
|
+
# that also burns a CI job's wall clock, is worse than no signal.
|
|
65
69
|
- name: Type check (mypy)
|
|
66
70
|
run: uv run mypy vgi/
|
|
67
71
|
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
- name: Type check (
|
|
72
|
-
run: uv run
|
|
73
|
-
continue-on-error: true
|
|
72
|
+
# tests/ became clean in 0.26.0 and is gated from here on. It was
|
|
73
|
+
# unchecked for long enough to accumulate 174 errors; the point of the
|
|
74
|
+
# gate is that it never gets to accumulate a second batch.
|
|
75
|
+
- name: Type check tests (mypy)
|
|
76
|
+
run: uv run mypy tests/
|
|
74
77
|
|
|
75
78
|
docs:
|
|
76
79
|
name: Docs (build + examples + prose)
|
|
@@ -81,7 +84,7 @@ jobs:
|
|
|
81
84
|
- uses: actions/checkout@v7
|
|
82
85
|
|
|
83
86
|
- name: Install uv
|
|
84
|
-
uses: astral-sh/setup-uv@
|
|
87
|
+
uses: astral-sh/setup-uv@v9.0.0
|
|
85
88
|
|
|
86
89
|
- name: Set up Python 3.14
|
|
87
90
|
run: uv python install 3.14
|
|
@@ -139,7 +142,7 @@ jobs:
|
|
|
139
142
|
path: vgi-rpc
|
|
140
143
|
|
|
141
144
|
- name: Install uv
|
|
142
|
-
uses: astral-sh/setup-uv@
|
|
145
|
+
uses: astral-sh/setup-uv@v9.0.0
|
|
143
146
|
|
|
144
147
|
- name: Set up Python 3.14
|
|
145
148
|
run: uv python install 3.14
|
|
@@ -33,7 +33,7 @@ jobs:
|
|
|
33
33
|
- uses: actions/checkout@v7
|
|
34
34
|
|
|
35
35
|
- name: Install uv
|
|
36
|
-
uses: astral-sh/setup-uv@
|
|
36
|
+
uses: astral-sh/setup-uv@v9.0.0
|
|
37
37
|
|
|
38
38
|
- name: Build vgi (sdist + wheel)
|
|
39
39
|
run: uv build --sdist --wheel --out-dir dist-vgi .
|
|
@@ -108,17 +108,17 @@ jobs:
|
|
|
108
108
|
fi
|
|
109
109
|
echo "tags=$tags" >> "$GITHUB_OUTPUT"
|
|
110
110
|
|
|
111
|
-
- uses: docker/setup-buildx-action@
|
|
111
|
+
- uses: docker/setup-buildx-action@v4
|
|
112
112
|
|
|
113
113
|
- name: Log in to GHCR
|
|
114
|
-
uses: docker/login-action@
|
|
114
|
+
uses: docker/login-action@v4
|
|
115
115
|
with:
|
|
116
116
|
registry: ghcr.io
|
|
117
117
|
username: ${{ github.actor }}
|
|
118
118
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
119
119
|
|
|
120
120
|
- name: Build & push
|
|
121
|
-
uses: docker/build-push-action@
|
|
121
|
+
uses: docker/build-push-action@v7
|
|
122
122
|
with:
|
|
123
123
|
context: .
|
|
124
124
|
file: packages/vgi-fixtures/docker/Dockerfile
|
|
@@ -437,7 +437,7 @@ class MyWorker(Worker):
|
|
|
437
437
|
try:
|
|
438
438
|
row = api_keys.lookup(token) # your own store
|
|
439
439
|
except ConnectionError as exc:
|
|
440
|
-
# "I could not find out"
|
|
440
|
+
# "I could not find out" -- 503 + Retry-After, not 401.
|
|
441
441
|
raise AuthUnavailableError(str(exc)) from exc
|
|
442
442
|
if row is None:
|
|
443
443
|
return None # "the credential is unknown"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vgi-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.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
|
|
@@ -158,11 +158,11 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
158
158
|
Classifier: Typing :: Typed
|
|
159
159
|
Requires-Python: >=3.13
|
|
160
160
|
Requires-Dist: click
|
|
161
|
-
Requires-Dist:
|
|
161
|
+
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.
|
|
165
|
+
Requires-Dist: vgi-rpc>=0.40.0
|
|
166
166
|
Provides-Extra: azure
|
|
167
167
|
Requires-Dist: azure-identity>=1.16.0; extra == 'azure'
|
|
168
168
|
Requires-Dist: pymssql>=2.3.0; extra == 'azure'
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Release runbook — describe.json retirement + attach-option `required`
|
|
2
|
+
|
|
3
|
+
All code is committed on `main` in each repo and green. Nothing is pushed.
|
|
4
|
+
This is the ordering and the per-repo trigger; fill in `X.Y.Z` per package.
|
|
5
|
+
|
|
6
|
+
**Version decision needed first.** Three transports drop `DescribeProvider`
|
|
7
|
+
from their public API (breaking): `@query-farm/vgi-rpc`, `vgi-rpc` (Rust),
|
|
8
|
+
`farm.query:vgirpc`. Choose major or minor per your compatibility policy — it
|
|
9
|
+
cascades into the implementation pins below.
|
|
10
|
+
|
|
11
|
+
## 1. Transports (must publish first)
|
|
12
|
+
|
|
13
|
+
| Repo | Trigger | Version lives in |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| vgi-rpc-typescript | `gh release create vX.Y.Z` (release: published) | `package.json` (+ `bun install` to sync `bun.lock`) |
|
|
16
|
+
| vgi-rpc-rust | tag push — `gh release create vX.Y.Z` | `[workspace.package] version`; `cargo update -w` |
|
|
17
|
+
| vgi-rpc-java | `gh release create vX.Y.Z` (release: published) | `build.gradle.kts` |
|
|
18
|
+
| vgi-rpc-go | tag push — `gh release create vX.Y.Z` | none (module proxy reads the tag) |
|
|
19
|
+
|
|
20
|
+
Then wait for index propagation: npm, `https://index.crates.io/3/v/vgi-rpc`,
|
|
21
|
+
Maven Central, Go proxy.
|
|
22
|
+
|
|
23
|
+
## 2. Implementation dependency pins
|
|
24
|
+
|
|
25
|
+
These currently cannot build against published transports:
|
|
26
|
+
|
|
27
|
+
- **vgi-typescript** — peer range is `>=0.18.1 <0.19.0`; widen to the new
|
|
28
|
+
transport version. `LandingInfo` resolves only once the transport publishes.
|
|
29
|
+
- **vgi-rust** — workspace dep already bumped to `vgi-rpc 0.20.0`; adjust if you
|
|
30
|
+
pick a different number. The `[patch.crates-io]` block stays uncommitted (it
|
|
31
|
+
is documented in `Cargo.toml` for local co-development only).
|
|
32
|
+
- **vgi-java** — bump `api("farm.query:vgirpc:X")` and the `VGI_RPC_JAVA_REF`
|
|
33
|
+
pin in `.github/workflows/integration.yml`. (`landing.yml` was deleted with
|
|
34
|
+
the contract it checked.)
|
|
35
|
+
- **vgi-go** — self-contained; no pin, but it needs the new vgi-rpc-go tag.
|
|
36
|
+
|
|
37
|
+
## 3. Implementations
|
|
38
|
+
|
|
39
|
+
| Repo | Trigger | Version lives in |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| vgi-python | `gh release create vX.Y.Z --target main` (PyPI on release) | root `pyproject.toml`; `uv lock` |
|
|
42
|
+
| vgi-go | `gh release create vX.Y.Z` (tag → module proxy) | none |
|
|
43
|
+
| vgi-rust | `gh release create vX.Y.Z` (tag → crates.io) | `[workspace.package] version` |
|
|
44
|
+
| vgi-typescript | **`git tag vX.Y.Z && git push origin vX.Y.Z`** — pushing the bump to main does NOT publish and fails silently | `package.json`; `bun install` |
|
|
45
|
+
| vgi-java | `gh release create vX.Y.Z` (Maven Central on release) | `build.gradle.kts` |
|
|
46
|
+
|
|
47
|
+
## 4. Frontend
|
|
48
|
+
|
|
49
|
+
- **vgi-web-frontend** — auto-deploys on push to `main`. Push last, so no worker
|
|
50
|
+
is serving a page newer than its vendored bundle.
|
|
51
|
+
|
|
52
|
+
## Verified before release
|
|
53
|
+
|
|
54
|
+
- vgi-python 2175 pass / 99 skip; ruff + mypy clean
|
|
55
|
+
- vgi-go `go test ./...` clean; vet + gofmt clean
|
|
56
|
+
- vgi-rust tests pass; clippy `-D warnings` clean
|
|
57
|
+
- vgi-java `:vgi:test` passes
|
|
58
|
+
- vgi-rpc-typescript 715 pass / 26 fail — exactly the pre-change baseline
|
|
59
|
+
(confirmed by running the suite at the parent commit in a worktree)
|
|
60
|
+
- Landing page verified in a browser against all four language workers:
|
|
61
|
+
Python 221 functions, Go 221, Rust 654, Java 219 — each 2 schemas, 59 tables,
|
|
62
|
+
3 views, with lazy columns loading.
|
|
63
|
+
|
|
64
|
+
## Not done, tracked
|
|
65
|
+
|
|
66
|
+
- `vgi-rpc-typescript` has 26 pre-existing test failures (integration/streaming;
|
|
67
|
+
unrelated to this work, present before it).
|
|
68
|
+
- `~/vgi-java/CLAUDE.md` still references the landing-conformance workflow in
|
|
69
|
+
its historical notes; the workflow itself is deleted.
|
|
@@ -12,6 +12,12 @@ require `pip install vgi-python[http]`; JWT authentication additionally requires
|
|
|
12
12
|
|
|
13
13
|
::: vgi.auth
|
|
14
14
|
|
|
15
|
+
## Token introspection
|
|
16
|
+
|
|
17
|
+
`TokenIdentity` is what [`Worker.resolve_token`][vgi.worker.Worker.resolve_token] returns: a
|
|
18
|
+
`principal` plus an optional `token_name`. It lives in a private `vgi-rpc` module, so `vgi.auth`
|
|
19
|
+
re-exports it — a worker that implements `resolve_token` never has to name a private import path.
|
|
20
|
+
|
|
15
21
|
## Secret protocol
|
|
16
22
|
|
|
17
23
|
::: vgi.secret_protocol
|
|
@@ -57,7 +57,7 @@ VGI_WORKER_SHARED_STORAGE=cloudflare-do vgi-serve my_worker.py --http
|
|
|
57
57
|
|---|---|---|---|
|
|
58
58
|
| SQLite | `sqlite` (default) | local / subprocess | none (stdlib) |
|
|
59
59
|
| Azure SQL | `azure-sql` | Azure deployments | `vgi-python[azure]` |
|
|
60
|
-
| Cloudflare DO | `cloudflare-do` | edge / multi-cloud | none extra — uses `
|
|
60
|
+
| Cloudflare DO | `cloudflare-do` | edge / multi-cloud | none extra — uses `httpx2`, which ships with `vgi-python`; needs a Worker endpoint + token |
|
|
61
61
|
|
|
62
62
|
The per-backend setup (connection strings, credentials, table provisioning) is documented in the
|
|
63
63
|
[Shared Storage reference](../shared-storage.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "vgi-python"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.27.0"
|
|
4
4
|
description = "Vector Gateway Interface - Connect DuckDB to external programs via Apache Arrow"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
keywords = [
|
|
@@ -40,8 +40,8 @@ dependencies = [
|
|
|
40
40
|
"pyarrow",
|
|
41
41
|
"typer>=0.9",
|
|
42
42
|
"platformdirs",
|
|
43
|
-
"vgi-rpc>=0.
|
|
44
|
-
"
|
|
43
|
+
"vgi-rpc>=0.40.0",
|
|
44
|
+
"httpx2>=2.9.1",
|
|
45
45
|
]
|
|
46
46
|
|
|
47
47
|
[project.optional-dependencies]
|
|
@@ -186,6 +186,10 @@ python_version = "3.13"
|
|
|
186
186
|
strict = true
|
|
187
187
|
warn_return_any = true
|
|
188
188
|
warn_unused_ignores = true
|
|
189
|
+
# tests/test_examples_workers.py puts examples/ on sys.path and imports the
|
|
190
|
+
# doc example workers by bare module name; mirror that for mypy so the imports
|
|
191
|
+
# resolve (and the examples themselves get checked).
|
|
192
|
+
mypy_path = "examples"
|
|
189
193
|
|
|
190
194
|
[[tool.mypy.overrides]]
|
|
191
195
|
module = "typer.*"
|
|
@@ -197,6 +201,13 @@ ignore_missing_imports = true
|
|
|
197
201
|
module = "granian.*"
|
|
198
202
|
ignore_missing_imports = true
|
|
199
203
|
|
|
204
|
+
[[tool.mypy.overrides]]
|
|
205
|
+
# jsonschema ships no py.typed marker and its stubs live in the separate
|
|
206
|
+
# types-jsonschema distribution, which we don't depend on. Used only by the
|
|
207
|
+
# landing-page conformance checker in tests/.
|
|
208
|
+
module = "jsonschema.*"
|
|
209
|
+
ignore_missing_imports = true
|
|
210
|
+
|
|
200
211
|
[[tool.mypy.overrides]]
|
|
201
212
|
# These files have type: ignore comments for ty that mypy doesn't need
|
|
202
213
|
module = ["vgi._test_fixtures.scalar.null_handling", "vgi.table_function"]
|
|
@@ -250,7 +261,7 @@ members = ["packages/vgi-fixtures"]
|
|
|
250
261
|
vgi-fixtures = { workspace = true }
|
|
251
262
|
|
|
252
263
|
[dependency-groups]
|
|
253
|
-
dev = ["lxml>=6.0.2", "pytest-timeout>=2.4.0", "
|
|
264
|
+
dev = ["lxml>=6.0.2", "pytest-timeout>=2.4.0", "vgi-fixtures"]
|
|
254
265
|
docs = [
|
|
255
266
|
"mkdocs>=1.6",
|
|
256
267
|
"mkdocs-material>=9.5",
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Tests for the AttachOption descriptor, its ``required`` flag, and validation."""
|
|
4
|
+
|
|
5
|
+
from typing import Annotated
|
|
6
|
+
|
|
7
|
+
import pyarrow as pa
|
|
8
|
+
import pytest
|
|
9
|
+
from vgi_rpc.utils import deserialize_record_batch, serialize_record_batch_bytes
|
|
10
|
+
|
|
11
|
+
from vgi.catalog._descriptor_spec import _SpecBase
|
|
12
|
+
from vgi.catalog.attach_option import (
|
|
13
|
+
AttachOption,
|
|
14
|
+
AttachOptionSpec,
|
|
15
|
+
MissingAttachOptionsError,
|
|
16
|
+
extract_attach_option_specs,
|
|
17
|
+
validate_required_attach_options,
|
|
18
|
+
)
|
|
19
|
+
from vgi.catalog.catalog_interface import ReadOnlyCatalogInterface
|
|
20
|
+
from vgi.catalog.setting import SettingSpec
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class _Options:
|
|
24
|
+
"""Attach options mixing defaulted and required entries."""
|
|
25
|
+
|
|
26
|
+
region: Annotated[str, AttachOption(desc="AWS region")] = "us-east-1"
|
|
27
|
+
# No class-level assignment: nothing to fall back to, so the caller must supply it.
|
|
28
|
+
api_key: Annotated[str, AttachOption(desc="API key", required=True)]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _roundtrip(spec: AttachOptionSpec) -> AttachOptionSpec:
|
|
32
|
+
batch, _ = deserialize_record_batch(spec.serialize())
|
|
33
|
+
return AttachOptionSpec.deserialize(batch)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class TestRequiredExtraction:
|
|
37
|
+
"""Extraction of the ``required`` flag from Annotated declarations."""
|
|
38
|
+
|
|
39
|
+
def test_defaults_to_false(self) -> None:
|
|
40
|
+
"""An option that isn't declared required isn't required."""
|
|
41
|
+
specs = {s.name: s for s in extract_attach_option_specs(_Options)}
|
|
42
|
+
assert specs["region"].required is False
|
|
43
|
+
assert specs["region"].default == "us-east-1"
|
|
44
|
+
|
|
45
|
+
def test_required_option_extracted(self) -> None:
|
|
46
|
+
"""``required=True`` survives extraction, with no default."""
|
|
47
|
+
specs = {s.name: s for s in extract_attach_option_specs(_Options)}
|
|
48
|
+
assert specs["api_key"].required is True
|
|
49
|
+
assert specs["api_key"].default is None
|
|
50
|
+
|
|
51
|
+
def test_required_with_default_rejected(self) -> None:
|
|
52
|
+
"""A required option that also defaults is contradictory."""
|
|
53
|
+
with pytest.raises(ValueError, match="required but also declares a default"):
|
|
54
|
+
AttachOptionSpec(name="api_key", desc="", type=pa.string(), default="fallback", required=True)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class TestWireFormat:
|
|
58
|
+
"""Serialization of the added ``required`` column."""
|
|
59
|
+
|
|
60
|
+
@pytest.mark.parametrize("required", [True, False], ids=["required", "optional"])
|
|
61
|
+
def test_roundtrip_preserves_required(self, required: bool) -> None:
|
|
62
|
+
"""``required`` survives an Arrow IPC round trip in both states."""
|
|
63
|
+
spec = AttachOptionSpec(name="api_key", desc="API key", type=pa.string(), default=None, required=required)
|
|
64
|
+
assert _roundtrip(spec).required is required
|
|
65
|
+
|
|
66
|
+
def test_roundtrip_preserves_shared_fields(self) -> None:
|
|
67
|
+
"""Widening the schema doesn't disturb the four shared columns."""
|
|
68
|
+
spec = AttachOptionSpec(name="region", desc="AWS region", type=pa.string(), default="us-east-1")
|
|
69
|
+
restored = _roundtrip(spec)
|
|
70
|
+
assert (restored.name, restored.desc, restored.type, restored.default) == (
|
|
71
|
+
"region",
|
|
72
|
+
"AWS region",
|
|
73
|
+
pa.string(),
|
|
74
|
+
"us-east-1",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def test_setting_wire_format_unchanged(self) -> None:
|
|
78
|
+
"""``Setting`` keeps the original four columns; only AttachOption widened."""
|
|
79
|
+
assert SettingSpec.ARROW_SCHEMA.names == ["name", "description", "type", "default_value"]
|
|
80
|
+
assert AttachOptionSpec.ARROW_SCHEMA.names == [
|
|
81
|
+
"name",
|
|
82
|
+
"description",
|
|
83
|
+
"type",
|
|
84
|
+
"default_value",
|
|
85
|
+
"required",
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
def test_reads_batch_without_required_column(self) -> None:
|
|
89
|
+
"""A peer that predates the column yields ``required=False``, not an error."""
|
|
90
|
+
type_bytes = pa.schema([pa.field("value", pa.string())]).serialize().to_pybytes()
|
|
91
|
+
legacy = pa.RecordBatch.from_pylist(
|
|
92
|
+
[{"name": "region", "description": "AWS region", "type": type_bytes, "default_value": None}],
|
|
93
|
+
schema=_SpecBase.ARROW_SCHEMA,
|
|
94
|
+
)
|
|
95
|
+
restored = AttachOptionSpec.deserialize(legacy)
|
|
96
|
+
assert restored.required is False
|
|
97
|
+
assert restored.name == "region"
|
|
98
|
+
|
|
99
|
+
def test_older_reader_ignores_required_column(self) -> None:
|
|
100
|
+
"""A four-column reader still reads a five-column batch (forward compatible)."""
|
|
101
|
+
spec = AttachOptionSpec(name="api_key", desc="API key", type=pa.string(), default=None, required=True)
|
|
102
|
+
batch, _ = deserialize_record_batch(spec.serialize())
|
|
103
|
+
legacy_read = SettingSpec.deserialize(batch)
|
|
104
|
+
assert legacy_read.name == "api_key"
|
|
105
|
+
assert legacy_read.default is None
|
|
106
|
+
|
|
107
|
+
def test_null_required_reads_as_false(self) -> None:
|
|
108
|
+
"""An explicit null in the nullable column means "not required"."""
|
|
109
|
+
type_bytes = pa.schema([pa.field("value", pa.string())]).serialize().to_pybytes()
|
|
110
|
+
batch = pa.RecordBatch.from_pylist(
|
|
111
|
+
[
|
|
112
|
+
{
|
|
113
|
+
"name": "region",
|
|
114
|
+
"description": "",
|
|
115
|
+
"type": type_bytes,
|
|
116
|
+
"default_value": None,
|
|
117
|
+
"required": None,
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
schema=AttachOptionSpec.ARROW_SCHEMA,
|
|
121
|
+
)
|
|
122
|
+
# Round-trip through IPC the way a real peer's bytes would arrive.
|
|
123
|
+
restored, _ = deserialize_record_batch(serialize_record_batch_bytes(batch))
|
|
124
|
+
assert AttachOptionSpec.deserialize(restored).required is False
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class TestValidateRequiredAttachOptions:
|
|
128
|
+
"""The shared validation helper."""
|
|
129
|
+
|
|
130
|
+
SPECS = [
|
|
131
|
+
AttachOptionSpec(name="region", desc="", type=pa.string(), default="us-east-1"),
|
|
132
|
+
AttachOptionSpec(name="api_key", desc="", type=pa.string(), default=None, required=True),
|
|
133
|
+
]
|
|
134
|
+
|
|
135
|
+
def test_missing_required_raises(self) -> None:
|
|
136
|
+
"""Omitting a required option raises with the names attached."""
|
|
137
|
+
with pytest.raises(MissingAttachOptionsError) as exc:
|
|
138
|
+
validate_required_attach_options("demo", self.SPECS, {"region": "eu-west-1"})
|
|
139
|
+
assert exc.value.missing == ["api_key"]
|
|
140
|
+
assert "'api_key'" in str(exc.value)
|
|
141
|
+
|
|
142
|
+
def test_supplied_required_passes(self) -> None:
|
|
143
|
+
"""Supplying the required option is enough; defaults cover the rest."""
|
|
144
|
+
validate_required_attach_options("demo", self.SPECS, {"api_key": "secret"})
|
|
145
|
+
|
|
146
|
+
def test_case_insensitive_match(self) -> None:
|
|
147
|
+
"""DuckDB lowercases ATTACH option keys; matching follows."""
|
|
148
|
+
validate_required_attach_options("demo", self.SPECS, {"API_KEY": "secret"})
|
|
149
|
+
|
|
150
|
+
def test_no_required_specs_always_passes(self) -> None:
|
|
151
|
+
"""A catalog with no required options accepts an empty mapping."""
|
|
152
|
+
validate_required_attach_options("demo", [self.SPECS[0]], {})
|
|
153
|
+
|
|
154
|
+
def test_multiple_missing_reported_together(self) -> None:
|
|
155
|
+
"""Every missing option is reported in one error, not one at a time."""
|
|
156
|
+
specs = [
|
|
157
|
+
AttachOptionSpec(name="api_key", desc="", type=pa.string(), default=None, required=True),
|
|
158
|
+
AttachOptionSpec(name="tenant", desc="", type=pa.string(), default=None, required=True),
|
|
159
|
+
]
|
|
160
|
+
with pytest.raises(MissingAttachOptionsError) as exc:
|
|
161
|
+
validate_required_attach_options("demo", specs, {})
|
|
162
|
+
assert exc.value.missing == ["api_key", "tenant"]
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class _GatedCatalog(ReadOnlyCatalogInterface):
|
|
166
|
+
"""Read-only catalog that cannot be attached without ``api_key``."""
|
|
167
|
+
|
|
168
|
+
catalog_name = "gated"
|
|
169
|
+
attach_option_specs = [
|
|
170
|
+
AttachOptionSpec(name="api_key", desc="API key", type=pa.string(), default=None, required=True),
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class TestCatalogAttachEnforcement:
|
|
175
|
+
"""The default ``catalog_attach`` refuses an attach missing required options."""
|
|
176
|
+
|
|
177
|
+
def test_attach_without_required_option_raises(self) -> None:
|
|
178
|
+
"""The attach fails loudly rather than yielding an empty-looking catalog."""
|
|
179
|
+
with pytest.raises(MissingAttachOptionsError, match="api_key"):
|
|
180
|
+
_GatedCatalog().catalog_attach(
|
|
181
|
+
name="gated", options={}, data_version_spec=None, implementation_version=None
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
def test_attach_with_required_option_succeeds(self) -> None:
|
|
185
|
+
"""Supplying the option attaches normally."""
|
|
186
|
+
result = _GatedCatalog().catalog_attach(
|
|
187
|
+
name="gated",
|
|
188
|
+
options={"api_key": "secret"},
|
|
189
|
+
data_version_spec=None,
|
|
190
|
+
implementation_version=None,
|
|
191
|
+
)
|
|
192
|
+
assert result.attach_opaque_data is not None
|
|
@@ -1279,9 +1279,11 @@ class TestSchemaDescriptor:
|
|
|
1279
1279
|
"""
|
|
1280
1280
|
schema = Schema(name="main", functions=[UsersFunction]) # only table fn
|
|
1281
1281
|
info = schema.to_schema_info(AttachOpaqueData(b"x"))
|
|
1282
|
-
|
|
1283
|
-
assert
|
|
1284
|
-
assert
|
|
1282
|
+
counts = info.estimated_object_count
|
|
1283
|
+
assert counts is not None
|
|
1284
|
+
assert counts["scalar_function"] == 0
|
|
1285
|
+
assert counts["aggregate_function"] == 0
|
|
1286
|
+
assert counts["table_function"] == 1
|
|
1285
1287
|
|
|
1286
1288
|
|
|
1287
1289
|
class TestLegacyFunctionsListSchemaInfo:
|
|
@@ -1320,6 +1322,7 @@ class TestLegacyFunctionsListSchemaInfo:
|
|
|
1320
1322
|
schemas = ci.schemas(attach_opaque_data=AttachOpaqueData(b"x"), transaction_opaque_data=None)
|
|
1321
1323
|
assert len(schemas) == 1
|
|
1322
1324
|
counts = schemas[0].estimated_object_count
|
|
1325
|
+
assert counts is not None
|
|
1323
1326
|
assert counts["scalar_function"] == 1
|
|
1324
1327
|
assert counts["table_function"] == 1
|
|
1325
1328
|
|
|
@@ -23,23 +23,22 @@ class TestRequiredFiltersField:
|
|
|
23
23
|
|
|
24
24
|
def _bbox_columns(self) -> pa.Schema:
|
|
25
25
|
"""Return a small schema with a ``bbox`` STRUCT plus flat id/ticker."""
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
]
|
|
39
|
-
),
|
|
26
|
+
fields: list[tuple[str, pa.DataType]] = [
|
|
27
|
+
("id", pa.int64()),
|
|
28
|
+
("ticker", pa.string()),
|
|
29
|
+
(
|
|
30
|
+
"bbox",
|
|
31
|
+
pa.struct(
|
|
32
|
+
[
|
|
33
|
+
("xmin", pa.float64()),
|
|
34
|
+
("ymin", pa.float64()),
|
|
35
|
+
("xmax", pa.float64()),
|
|
36
|
+
("ymax", pa.float64()),
|
|
37
|
+
]
|
|
40
38
|
),
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
),
|
|
40
|
+
]
|
|
41
|
+
return pa.schema(fields)
|
|
43
42
|
|
|
44
43
|
def test_default_is_empty_tuple(self) -> None:
|
|
45
44
|
"""Default is an empty tuple; TableInfo wire field is an empty list."""
|
|
@@ -63,7 +63,7 @@ class _LegacyOnlyCatalog(_StubCatalogBase):
|
|
|
63
63
|
|
|
64
64
|
# Only the legacy method is overridden; table_scan_branches_get falls back
|
|
65
65
|
# to the CatalogInterface default-impl shim.
|
|
66
|
-
def table_scan_function_get(
|
|
66
|
+
def table_scan_function_get(
|
|
67
67
|
self,
|
|
68
68
|
*,
|
|
69
69
|
attach_opaque_data: AttachOpaqueData,
|
|
@@ -89,7 +89,7 @@ class _MultiBranchCatalog(_StubCatalogBase):
|
|
|
89
89
|
keep them non-overlapping at scan time.
|
|
90
90
|
"""
|
|
91
91
|
|
|
92
|
-
def table_scan_function_get(
|
|
92
|
+
def table_scan_function_get(
|
|
93
93
|
self,
|
|
94
94
|
*,
|
|
95
95
|
attach_opaque_data: AttachOpaqueData,
|
|
@@ -108,7 +108,7 @@ class _MultiBranchCatalog(_StubCatalogBase):
|
|
|
108
108
|
required_extensions=[],
|
|
109
109
|
)
|
|
110
110
|
|
|
111
|
-
def table_scan_branches_get(
|
|
111
|
+
def table_scan_branches_get(
|
|
112
112
|
self,
|
|
113
113
|
*,
|
|
114
114
|
attach_opaque_data: AttachOpaqueData,
|
|
@@ -184,7 +184,7 @@ class TestDefaultImplShim:
|
|
|
184
184
|
super().__init__()
|
|
185
185
|
self.last_at: tuple[str | None, str | None] | None = None
|
|
186
186
|
|
|
187
|
-
def table_scan_function_get(
|
|
187
|
+
def table_scan_function_get(
|
|
188
188
|
self,
|
|
189
189
|
*,
|
|
190
190
|
attach_opaque_data: AttachOpaqueData,
|