vgi-python 0.25.0__tar.gz → 0.26.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.26.0}/.github/workflows/ci.yml +13 -10
- {vgi_python-0.25.0 → vgi_python-0.26.0}/.github/workflows/docs.yml +1 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/.github/workflows/integration.yml +1 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/.github/workflows/release.yml +4 -4
- {vgi_python-0.25.0 → vgi_python-0.26.0}/CLAUDE.md +1 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/PKG-INFO +3 -3
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/auth.md +6 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/how-to/state-storage.md +1 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/pyproject.toml +15 -4
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_declarative.py +6 -3
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_required_filters.py +15 -16
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_scan_branches.py +4 -4
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_accumulate.py +81 -31
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_const_param_enforcement.py +2 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_resumable_scan.py +16 -6
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_scalar_attach_opaque_data.py +3 -4
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/landing/_checker.py +5 -3
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/test_wide_columns.py +2 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/test_blended_metadata.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_aggregate_function.py +5 -3
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_argument_spec.py +4 -3
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_auth.py +6 -6
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_bind_request_at_clause.py +5 -4
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_bound_storage_conformance.py +10 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_cache_control.py +6 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_call_state_attach.py +1 -3
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_copy_from_function.py +31 -11
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_copy_to_function.py +30 -13
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_examples_workers.py +11 -5
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_filter_pushdown_extension.py +4 -2
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_function_storage.py +8 -4
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_function_storage_cf_do.py +17 -16
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_function_storage_cf_do_integration.py +8 -7
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_function_storage_conformance.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_cpp_schemas.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_cpp_secret.py +4 -3
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_http_demo_storage.py +3 -3
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_http_s3_offload_input.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_metadata.py +9 -10
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_nest_tensor.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_projection_repro.py +1 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_protocol_classes.py +25 -16
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_resolved_secrets.py +14 -5
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_schema_scoped_functions.py +2 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_serve.py +7 -4
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_table_buffering_function.py +57 -27
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_union_argument.py +8 -4
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_worker.py +15 -5
- {vgi_python-0.25.0 → vgi_python-0.26.0}/uv.lock +696 -712
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/catalog_mixin.py +2 -2
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/client.py +8 -8
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/function_storage_cf_do.py +7 -7
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/worker.py +1 -1
- {vgi_python-0.25.0 → vgi_python-0.26.0}/.gitattributes +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/.github/dependabot.yml +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/.gitignore +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/.python-version +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/.vale.ini +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/DOCS_REVIEW_RUBRIC.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/DOCS_USABILITY_TEST.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/LICENSE +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/README.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/SECURITY.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/ci/README.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/ci/preprocess-require.awk +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/ci/run-integration.sh +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/dist-vgi/.gitignore +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/aggregate-functions.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/arguments.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/catalogs.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/client.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/exceptions.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/filters.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/functions.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/http.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/metadata.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/observability.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/storage.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/transactor.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/api/worker.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/argument-serialization.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/apple-touch-icon.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/favicon-16x16.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/favicon-32x32.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/favicon.ico +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/kinds/aggregate.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/kinds/buffering.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/kinds/scalar.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/kinds/table-in-out.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/kinds/table.svg +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/logo.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/assets/social-card.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/authentication.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/catalog-interface.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/cli.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/column-statistics.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/concepts/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/contributing-docs.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/filter-pushdown.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/generator-api.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/global-functions.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/how-to/catalogs.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/how-to/function-patterns.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/how-to/http-auth.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/how-to/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/how-to/pushdown-and-statistics.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/lifecycle.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/metadata.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/overrides/main.html +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/robots.txt +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/shared-storage.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/stylesheets/extra.css +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/tutorial/index.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/tutorial/scalar.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/tutorial/table.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/docs/vgi-logo.png +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/examples/calc_scalar_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/examples/calc_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/examples/filter_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/examples/greeting_scalar_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/examples/row_count_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/examples/series_streaming_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/examples/sum_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/mkdocs.yml +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/packages/vgi-fixtures/LICENSE +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/packages/vgi-fixtures/README.md +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/packages/vgi-fixtures/docker/Dockerfile +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/packages/vgi-fixtures/pyproject.toml +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/scripts/measure_startup.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/scripts/run_all_tests.sh +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/test-data/generate.sh +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/_http_fixtures.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_catalog_interface.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_client_catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_column_statistics.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_example_worker_catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_integration.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_serialization.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_setting.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_time_travel.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/catalog/test_writable_table.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/client/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/client/test_broken_pipe.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/client/test_cli.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/client/test_cli_catalog_functions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/client/test_worker_debug.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/_stub.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/conftest.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_aggregate.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_attach.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_bearer_auth.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_container.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_copy_from.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_copy_to.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_directory_parity.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_function_inventory.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_github.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_http_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_http_external_location.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_http_upload_url.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_macro.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_overload.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_protocol_inventory.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_scalar.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_secret.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_settings.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_table.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_table_in_out.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_view.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conformance/test_writable.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/conftest.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/landing/describe.expected.json +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/landing/describe.schema.json +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/test_bernoulli_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/test_binary_packet_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/test_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/test_conditional_message_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/test_hash_seed_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/test_multiply_by_setting_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/test_multiply_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/test_random_bytes_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/scalar/test_return_secret_value_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_constant_columns_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_double_sequence_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_exception_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_filter_echo_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_logging_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_nested_sequence_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_partitioned_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_projected_data_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_sequence_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_settings_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_struct_settings_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table/generator/test_ten_thousand_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/generator/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/generator/test_echo_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/generator/test_exception_functions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/table_in_out/test_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_access_log_audit.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_bind_exceptions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_catalog_auth_binding.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_docstrings.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_documentation_examples.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_example_function_arg_types.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_exception_handling.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_exceptions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_filter_pushdown.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_function_storage_azure_sql.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_cpp_constants.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_cpp_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_cpp_request_builders.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_go_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_schemas_cross_lang.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_ts_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_generated_ts_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_http_s3_offload_output.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_landing_conformance.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_mypy_consolidated.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_otel.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_projection_enforcement.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_schema_utils.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_setting_secret_annotations.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_signing_key.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_table_function_dynamic_to_string.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_tcp_transport.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_type_bounds.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_worker_cli.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/test_worker_page.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/transactor/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/tests/transactor/test_transactor.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_duckdb.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_storage_profile.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/accumulate/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/_common.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/basic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/generic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/aggregate/window.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/attach_options.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/bad_enum.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/bad_protocol.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/cancellable.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/companion.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/copy_from.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/copy_to.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/global_functions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/http_server.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/nest_tensor.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/orchard_catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/_common.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/binary.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/formatting.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/geo.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/same_name.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/scalar/type_info.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/simple_writable.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/_common.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/batch_index.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/cache.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/filters.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/late_materialization.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/make_series.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/misc.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/order_modes.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/pairs.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/partition_columns.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/profiling_example.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/required_filters.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/sequence.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/settings.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/typed_probe.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/versioned.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table/wide.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table_in_out.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/twin_catalogs.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/versioned.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/versioned_tables.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/writable/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/writable/generic.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/writable/table.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/_test_fixtures/writable/worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/aggregate_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/argument_spec.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/arguments.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/attach_header.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/auth.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/cache_control.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/catalog/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/catalog/_descriptor_spec.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/catalog/attach_option.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/catalog/catalog_interface.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/catalog/descriptors.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/catalog/duckdb_statistics.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/catalog/secret_type.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/catalog/setting.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/catalog/storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/cli.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/cli_catalog.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/cli_schema.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/cli_table.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/cli_transaction.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/cli_utils.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/client/cli_view.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/_common.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/cpp_constants.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/cpp_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/cpp_request_builders.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/cpp_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/cpp_secret_request_builders.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/cpp_secret_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/go_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/protocol_version.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/ts_client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/codegen/ts_schemas.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/copy_from_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/copy_to_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/exceptions.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/function_storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/function_storage_azure_sql.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/http/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/http/demo_storage.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/http/describe_json.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/http/landing.html +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/http/landing_page.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/http/worker_page.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/invocation.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/logging_config.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/meta_worker.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/metadata.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/otel.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/profiling.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/protocol.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/protocol_version.txt +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/py.typed +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/scalar_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/schema_utils.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/secret_protocol.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/secret_service.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/serve.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/table_buffering_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/table_filter_pushdown.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/table_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/table_in_out_function.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/transactor/__init__.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/transactor/_duckdb_compat.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/transactor/client.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/transactor/protocol.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.0}/vgi/transactor/server.py +0 -0
- {vgi_python-0.25.0 → vgi_python-0.26.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.26.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'
|
|
@@ -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.26.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",
|
|
@@ -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,
|
|
@@ -18,16 +18,23 @@ transport is covered by the sqllogictest suite in the C++ repo.
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
20
|
import contextlib
|
|
21
|
+
from collections.abc import Callable, Iterator
|
|
21
22
|
from datetime import timedelta
|
|
23
|
+
from pathlib import Path
|
|
22
24
|
from types import SimpleNamespace
|
|
25
|
+
from typing import Any, cast
|
|
23
26
|
|
|
24
27
|
import pyarrow as pa
|
|
25
28
|
import pytest
|
|
29
|
+
from vgi_rpc.rpc import OutputCollector
|
|
26
30
|
|
|
27
31
|
from vgi._test_fixtures.accumulate import worker as m
|
|
28
32
|
from vgi.function_storage import BoundStorage, FunctionStorage, FunctionStorageSqlite
|
|
33
|
+
from vgi.table_buffering_function import TableBufferingParams
|
|
34
|
+
from vgi.table_function import BindParams
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
_INPUT_FIELDS: list[pa.Field[Any]] = [pa.field("x", pa.int64()), pa.field("label", pa.string())]
|
|
37
|
+
INPUT_SCHEMA = pa.schema(_INPUT_FIELDS)
|
|
31
38
|
OUTPUT_SCHEMA = m._output_schema(INPUT_SCHEMA)
|
|
32
39
|
|
|
33
40
|
SCOPE_A = b"session-a"
|
|
@@ -43,7 +50,7 @@ def _set_storage(fs: FunctionStorage) -> None:
|
|
|
43
50
|
|
|
44
51
|
|
|
45
52
|
@pytest.fixture(autouse=True)
|
|
46
|
-
def _storage(tmp_path):
|
|
53
|
+
def _storage(tmp_path: Path) -> Iterator[SimpleNamespace]:
|
|
47
54
|
"""Inject a throwaway file-backed FunctionStorage for the persistent collection."""
|
|
48
55
|
path = str(tmp_path / "fs.db")
|
|
49
56
|
_set_storage(FunctionStorageSqlite(db_path=path))
|
|
@@ -69,51 +76,85 @@ class FakeOut:
|
|
|
69
76
|
"""Mark the stream finished."""
|
|
70
77
|
self.finished = True
|
|
71
78
|
|
|
79
|
+
@property
|
|
80
|
+
def collector(self) -> OutputCollector:
|
|
81
|
+
"""This fake viewed as the ``OutputCollector`` the fixture's API declares.
|
|
72
82
|
|
|
73
|
-
|
|
83
|
+
``OutputCollector`` is a concrete class, not a protocol, so the
|
|
84
|
+
duck-typed stand-in needs one cast to reach the real signatures.
|
|
85
|
+
"""
|
|
86
|
+
return cast("OutputCollector", self)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _exec_storage() -> tuple[bytes, BoundStorage]:
|
|
74
90
|
"""Build a fresh execution-scoped BoundStorage (mimics a distinct query)."""
|
|
75
91
|
_exec_counter[0] += 1
|
|
76
92
|
eid = f"exec-{_exec_counter[0]}".encode()
|
|
77
93
|
return eid, BoundStorage(m.AccumulateFunction.storage, eid)
|
|
78
94
|
|
|
79
95
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
# The two param builders return duck-typed SimpleNamespaces — the fixture only
|
|
97
|
+
# reads a handful of fields off them — cast to the declared param types so the
|
|
98
|
+
# call sites below type-check against the real fixture signatures.
|
|
99
|
+
def _bind_params(name: str, input_schema: pa.Schema = INPUT_SCHEMA, opaque: bytes = SCOPE_A) -> BindParams[Any]:
|
|
100
|
+
return cast(
|
|
101
|
+
"BindParams[Any]",
|
|
102
|
+
SimpleNamespace(
|
|
103
|
+
args=SimpleNamespace(name=name, data=None, ttl=None, max_row_size=0, result="all"),
|
|
104
|
+
bind_call=SimpleNamespace(input_schema=input_schema),
|
|
105
|
+
attach_opaque_data=opaque,
|
|
106
|
+
),
|
|
85
107
|
)
|
|
86
108
|
|
|
87
109
|
|
|
88
|
-
def _buf_params(
|
|
110
|
+
def _buf_params(
|
|
111
|
+
name: str,
|
|
112
|
+
*,
|
|
113
|
+
ttl: Any = None,
|
|
114
|
+
max_row_size: int = 0,
|
|
115
|
+
result: str = "all",
|
|
116
|
+
output_schema: pa.Schema = OUTPUT_SCHEMA,
|
|
117
|
+
opaque: bytes = SCOPE_A,
|
|
118
|
+
) -> TableBufferingParams[Any]:
|
|
89
119
|
eid, storage = _exec_storage()
|
|
90
|
-
return
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
120
|
+
return cast(
|
|
121
|
+
"TableBufferingParams[Any]",
|
|
122
|
+
SimpleNamespace(
|
|
123
|
+
args=SimpleNamespace(name=name, data=None, ttl=ttl, max_row_size=max_row_size, result=result),
|
|
124
|
+
output_schema=output_schema,
|
|
125
|
+
attach_opaque_data=opaque,
|
|
126
|
+
storage=storage,
|
|
127
|
+
execution_id=eid,
|
|
128
|
+
),
|
|
96
129
|
)
|
|
97
130
|
|
|
98
131
|
|
|
99
|
-
def _input_batch(xs):
|
|
132
|
+
def _input_batch(xs: list[int]) -> pa.RecordBatch:
|
|
100
133
|
return pa.RecordBatch.from_arrays(
|
|
101
134
|
[pa.array(xs, pa.int64()), pa.array([f"r{x}" for x in xs], pa.string())],
|
|
102
135
|
schema=INPUT_SCHEMA,
|
|
103
136
|
)
|
|
104
137
|
|
|
105
138
|
|
|
106
|
-
def _drain(fn) -> FakeOut:
|
|
139
|
+
def _drain(fn: Callable[[OutputCollector], None]) -> FakeOut:
|
|
107
140
|
out = FakeOut()
|
|
108
141
|
guard = 0
|
|
109
142
|
while not out.finished:
|
|
110
|
-
fn(out)
|
|
143
|
+
fn(out.collector)
|
|
111
144
|
guard += 1
|
|
112
145
|
assert guard < 1_000_000, "stream did not terminate"
|
|
113
146
|
return out
|
|
114
147
|
|
|
115
148
|
|
|
116
|
-
def _run(
|
|
149
|
+
def _run(
|
|
150
|
+
name: str,
|
|
151
|
+
*,
|
|
152
|
+
batches: list[pa.RecordBatch],
|
|
153
|
+
ttl: Any = None,
|
|
154
|
+
max_row_size: int = 0,
|
|
155
|
+
result: str = "all",
|
|
156
|
+
opaque: bytes = SCOPE_A,
|
|
157
|
+
) -> pa.Table:
|
|
117
158
|
resp = m.AccumulateFunction.on_bind(_bind_params(name, opaque=opaque))
|
|
118
159
|
pp = _buf_params(
|
|
119
160
|
name, ttl=ttl, max_row_size=max_row_size, result=result, output_schema=resp.output_schema, opaque=opaque
|
|
@@ -131,38 +172,47 @@ def _run(name, *, batches, ttl=None, max_row_size=0, result="all", opaque=SCOPE_
|
|
|
131
172
|
)
|
|
132
173
|
|
|
133
174
|
|
|
134
|
-
def _call(
|
|
175
|
+
def _call(
|
|
176
|
+
name: str,
|
|
177
|
+
xs: list[int],
|
|
178
|
+
*,
|
|
179
|
+
ttl: Any = None,
|
|
180
|
+
max_row_size: int = 0,
|
|
181
|
+
result: str = "all",
|
|
182
|
+
opaque: bytes = SCOPE_A,
|
|
183
|
+
) -> pa.Table:
|
|
135
184
|
return _run(name, batches=[_input_batch(xs)], ttl=ttl, max_row_size=max_row_size, result=result, opaque=opaque)
|
|
136
185
|
|
|
137
186
|
|
|
138
|
-
def _read_batches(name, *, opaque=SCOPE_A) -> list[pa.RecordBatch]:
|
|
187
|
+
def _read_batches(name: str, *, opaque: bytes = SCOPE_A) -> list[pa.RecordBatch]:
|
|
139
188
|
resp = m.AccumulateReadFunction.on_bind(_bind_params(name, opaque=opaque))
|
|
140
189
|
pp = _buf_params(name, output_schema=resp.output_schema, opaque=opaque)
|
|
141
190
|
state = m.AccumulateReadFunction.initial_state(pp)
|
|
142
191
|
return _drain(lambda o: m.AccumulateReadFunction.process(pp, state, o)).batches
|
|
143
192
|
|
|
144
193
|
|
|
145
|
-
def _read(name, *, opaque=SCOPE_A) -> pa.Table:
|
|
194
|
+
def _read(name: str, *, opaque: bytes = SCOPE_A) -> pa.Table:
|
|
146
195
|
resp = m.AccumulateReadFunction.on_bind(_bind_params(name, opaque=opaque))
|
|
147
196
|
batches = _read_batches(name, opaque=opaque)
|
|
148
197
|
return pa.Table.from_batches(batches, schema=resp.output_schema) if batches else resp.output_schema.empty_table()
|
|
149
198
|
|
|
150
199
|
|
|
151
|
-
def _clear(name, *, opaque=SCOPE_A) -> pa.RecordBatch:
|
|
200
|
+
def _clear(name: str, *, opaque: bytes = SCOPE_A) -> pa.RecordBatch:
|
|
152
201
|
pp = _buf_params(name, output_schema=m.CLEAR_SCHEMA, opaque=opaque)
|
|
153
202
|
state = m.AccumulateClearFunction.initial_state(pp)
|
|
154
203
|
out = FakeOut()
|
|
155
|
-
m.AccumulateClearFunction.process(pp, state, out)
|
|
156
|
-
m.AccumulateClearFunction.process(pp, state, out) # second tick -> finish
|
|
204
|
+
m.AccumulateClearFunction.process(pp, state, out.collector)
|
|
205
|
+
m.AccumulateClearFunction.process(pp, state, out.collector) # second tick -> finish
|
|
157
206
|
assert out.finished and len(out.batches) == 1
|
|
158
207
|
return out.batches[0]
|
|
159
208
|
|
|
160
209
|
|
|
161
|
-
def _xs(table) -> list[int]:
|
|
162
|
-
|
|
210
|
+
def _xs(table: pa.Table) -> list[int]:
|
|
211
|
+
# `x` is declared non-null int64; to_pylist() types every element optional.
|
|
212
|
+
return sorted(cast("list[int]", table.column("x").to_pylist()))
|
|
163
213
|
|
|
164
214
|
|
|
165
|
-
def _total(name, opaque=SCOPE_A) -> int:
|
|
215
|
+
def _total(name: str, opaque: bytes = SCOPE_A) -> int:
|
|
166
216
|
ps = m._store(m.AccumulateFunction.storage, opaque)
|
|
167
217
|
sch = m._get_schema(ps, name.encode())
|
|
168
218
|
return 0 if sch is None else m._read_collection(ps, name.encode(), sch).num_rows
|
|
@@ -209,7 +259,7 @@ def test_on_bind_rejects_schema_mismatch_for_same_name() -> None:
|
|
|
209
259
|
|
|
210
260
|
|
|
211
261
|
@pytest.mark.parametrize("name", ["", " "])
|
|
212
|
-
def test_on_bind_rejects_blank_name(name) -> None:
|
|
262
|
+
def test_on_bind_rejects_blank_name(name: str) -> None:
|
|
213
263
|
"""Empty or blank collection names are rejected by all three functions."""
|
|
214
264
|
with pytest.raises(ValueError, match="non-empty"):
|
|
215
265
|
m.AccumulateFunction.on_bind(_bind_params(name))
|
|
@@ -310,7 +360,7 @@ def test_read_is_scoped_to_attach_session() -> None:
|
|
|
310
360
|
# --- persistence & scoping -------------------------------------------------
|
|
311
361
|
|
|
312
362
|
|
|
313
|
-
def test_persists_across_reconnect(tmp_path) -> None:
|
|
363
|
+
def test_persists_across_reconnect(tmp_path: Path) -> None:
|
|
314
364
|
"""Collections survive a worker restart (fresh handle on the same DB file)."""
|
|
315
365
|
_call("a", [1, 2])
|
|
316
366
|
# Simulate a worker restart: a fresh storage handle on the same DB file.
|
|
@@ -372,7 +422,7 @@ def test_large_input_round_trips_all_rows() -> None:
|
|
|
372
422
|
assert len(set(t.column("_timestamp").to_pylist())) == 1
|
|
373
423
|
|
|
374
424
|
|
|
375
|
-
def test_output_returned_in_bounded_batches(monkeypatch) -> None:
|
|
425
|
+
def test_output_returned_in_bounded_batches(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
376
426
|
"""Output is staged and drained in batches bounded by OUT_BATCH_ROWS."""
|
|
377
427
|
monkeypatch.setattr(m, "OUT_BATCH_ROWS", 100)
|
|
378
428
|
_call("big", list(range(1000)), result="none")
|
|
@@ -17,7 +17,8 @@ import pyarrow as pa
|
|
|
17
17
|
import pytest
|
|
18
18
|
|
|
19
19
|
from vgi.arguments import Arguments, ArgumentValidationError, ConstParam, Param, Returns
|
|
20
|
-
from vgi.
|
|
20
|
+
from vgi.invocation import FunctionType
|
|
21
|
+
from vgi.protocol import BindRequest
|
|
21
22
|
from vgi.scalar_function import BindResult, ScalarFunction
|
|
22
23
|
|
|
23
24
|
|
|
@@ -11,6 +11,7 @@ dropped rows. Also checks the capability gate on the non-resumable transport.
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
13
|
from collections.abc import Iterator
|
|
14
|
+
from typing import cast
|
|
14
15
|
|
|
15
16
|
import pyarrow as pa
|
|
16
17
|
import pytest
|
|
@@ -45,13 +46,22 @@ def http_base_url() -> Iterator[str]:
|
|
|
45
46
|
stack.close()
|
|
46
47
|
|
|
47
48
|
|
|
49
|
+
def _ns(batch: pa.RecordBatch) -> list[int]:
|
|
50
|
+
"""The batch's ``n`` column as ints.
|
|
51
|
+
|
|
52
|
+
``sequence`` declares ``n`` non-null; ``to_pylist()`` types every element
|
|
53
|
+
optional regardless, so narrow once here instead of at each call site.
|
|
54
|
+
"""
|
|
55
|
+
return cast("list[int]", batch.column("n").to_pylist())
|
|
56
|
+
|
|
57
|
+
|
|
48
58
|
def _reference_rows(base_url: str) -> list[int]:
|
|
49
59
|
"""Read the full, ordered ``sequence`` result the normal way."""
|
|
50
60
|
with Client.from_http(base_url) as client:
|
|
51
61
|
return [
|
|
52
62
|
v
|
|
53
63
|
for b in client.table_function(function_name="sequence", schema_name="main", arguments=_ARGS)
|
|
54
|
-
for v in b
|
|
64
|
+
for v in _ns(b)
|
|
55
65
|
]
|
|
56
66
|
|
|
57
67
|
|
|
@@ -67,7 +77,7 @@ def test_resumable_scan_matches_table_function(http_base_url: str) -> None:
|
|
|
67
77
|
batch, _token = cur.next()
|
|
68
78
|
if batch is None:
|
|
69
79
|
break
|
|
70
|
-
rows.extend(batch
|
|
80
|
+
rows.extend(_ns(batch))
|
|
71
81
|
cur.close()
|
|
72
82
|
|
|
73
83
|
assert rows == expected
|
|
@@ -85,7 +95,7 @@ def test_resume_on_fresh_client_after_node_hop(http_base_url: str) -> None:
|
|
|
85
95
|
for _ in range(3):
|
|
86
96
|
batch, token = cur.next()
|
|
87
97
|
assert batch is not None
|
|
88
|
-
rows.extend(batch
|
|
98
|
+
rows.extend(_ns(batch))
|
|
89
99
|
assert token is not None # per-batch tokens are the default
|
|
90
100
|
cur.close()
|
|
91
101
|
|
|
@@ -98,7 +108,7 @@ def test_resume_on_fresh_client_after_node_hop(http_base_url: str) -> None:
|
|
|
98
108
|
batch, token = cur2.next()
|
|
99
109
|
if batch is None:
|
|
100
110
|
break
|
|
101
|
-
rows.extend(batch
|
|
111
|
+
rows.extend(_ns(batch))
|
|
102
112
|
cur2.close()
|
|
103
113
|
|
|
104
114
|
assert rows == expected # contiguous, complete, no duplicates
|
|
@@ -122,7 +132,7 @@ def test_continue_on_fresh_client_skips_rebind(http_base_url: str) -> None:
|
|
|
122
132
|
for _ in range(3):
|
|
123
133
|
batch, token = cur.next()
|
|
124
134
|
assert batch is not None
|
|
125
|
-
rows.extend(batch
|
|
135
|
+
rows.extend(_ns(batch))
|
|
126
136
|
assert token is not None
|
|
127
137
|
cur.close()
|
|
128
138
|
|
|
@@ -133,7 +143,7 @@ def test_continue_on_fresh_client_skips_rebind(http_base_url: str) -> None:
|
|
|
133
143
|
batch, token = cur2.next()
|
|
134
144
|
if batch is None:
|
|
135
145
|
break
|
|
136
|
-
rows.extend(batch
|
|
146
|
+
rows.extend(_ns(batch))
|
|
137
147
|
cur2.close()
|
|
138
148
|
|
|
139
149
|
assert rows == expected
|
|
@@ -15,13 +15,12 @@ from typing import Annotated, Any
|
|
|
15
15
|
|
|
16
16
|
import pyarrow as pa
|
|
17
17
|
|
|
18
|
-
from vgi.arguments import Arguments
|
|
19
|
-
from vgi.
|
|
18
|
+
from vgi.arguments import Arguments, Param, Returns
|
|
19
|
+
from vgi.invocation import FunctionType
|
|
20
|
+
from vgi.protocol import BindRequest
|
|
20
21
|
from vgi.scalar_function import (
|
|
21
22
|
BindParameters,
|
|
22
23
|
BindResult,
|
|
23
|
-
Param,
|
|
24
|
-
Returns,
|
|
25
24
|
ScalarFunction,
|
|
26
25
|
)
|
|
27
26
|
|