vgi-python 0.8.2__tar.gz → 0.8.3__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.8.2 → vgi_python-0.8.3}/PKG-INFO +1 -1
- {vgi_python-0.8.2 → vgi_python-0.8.3}/pyproject.toml +1 -1
- vgi_python-0.8.3/tests/test_union_argument.py +111 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/__init__.py +2 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/arguments.py +55 -2
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.gitattributes +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.github/dependabot.yml +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.github/workflows/ci.yml +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.github/workflows/docs.yml +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.github/workflows/integration.yml +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.github/workflows/release.yml +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.gitignore +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.python-version +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/.vale.ini +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/CLAUDE.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/DOCS_REVIEW_RUBRIC.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/DOCS_USABILITY_TEST.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/LICENSE +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/README.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/SECURITY.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/ci/README.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/ci/preprocess-require.awk +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/ci/run-integration.sh +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/dist-vgi/.gitignore +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/aggregate-functions.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/arguments.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/auth.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/catalogs.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/client.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/exceptions.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/filters.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/functions.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/http.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/index.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/metadata.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/observability.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/storage.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/transactor.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/api/worker.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/argument-serialization.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/apple-touch-icon.png +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/favicon-16x16.png +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/favicon-32x32.png +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/favicon.ico +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/kinds/aggregate.svg +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/kinds/buffering.svg +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/kinds/scalar.svg +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/kinds/table-in-out.svg +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/kinds/table.svg +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/logo.png +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/assets/social-card.png +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/authentication.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/catalog-interface.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/cli.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/column-statistics.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/concepts/index.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/contributing-docs.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/filter-pushdown.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/generator-api.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/how-to/catalogs.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/how-to/function-patterns.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/how-to/http-auth.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/how-to/index.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/how-to/pushdown-and-statistics.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/how-to/state-storage.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/index.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/lifecycle.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/metadata.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/overrides/main.html +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/robots.txt +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/shared-storage.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/stylesheets/extra.css +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/tutorial/index.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/tutorial/scalar.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/tutorial/table.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/docs/vgi-logo.png +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/examples/calc_scalar_worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/examples/calc_worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/examples/filter_worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/examples/greeting_scalar_worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/examples/row_count_worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/examples/series_streaming_worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/examples/sum_worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/mkdocs.yml +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/packages/vgi-fixtures/LICENSE +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/packages/vgi-fixtures/README.md +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/packages/vgi-fixtures/pyproject.toml +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/scripts/measure_startup.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/scripts/run_all_tests.sh +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/test-data/generate.sh +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/_http_fixtures.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_catalog_interface.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_client_catalog.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_column_statistics.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_declarative.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_example_worker_catalog.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_integration.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_required_field_filter_paths.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_scan_branches.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_serialization.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_setting.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_storage.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_time_travel.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/catalog/test_writable_table.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/client/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/client/test_broken_pipe.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/client/test_cli.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/client/test_cli_catalog_functions.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/client/test_worker_debug.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/_stub.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/conftest.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_accumulate.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_aggregate.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_attach.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_bearer_auth.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_directory_parity.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_function_inventory.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_http_client.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_http_external_location.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_http_upload_url.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_macro.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_overload.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_protocol_inventory.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_protocol_version.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_resumable_scan.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_scalar.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_secret.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_settings.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_table.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_table_in_out.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_view.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conformance/test_writable.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/conftest.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/test_bernoulli_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/test_binary_packet_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/test_client.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/test_conditional_message_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/test_hash_seed_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/test_multiply_by_setting_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/test_multiply_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/test_random_bytes_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/scalar/test_return_secret_value_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_constant_columns_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_double_sequence_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_exception_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_filter_echo_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_logging_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_nested_sequence_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_partitioned_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_projected_data_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_sequence_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_settings_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_struct_settings_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_ten_thousand_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table_in_out/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table_in_out/generator/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table_in_out/generator/test_echo_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table_in_out/generator/test_exception_functions.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table_in_out/test_client.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_access_log_audit.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_aggregate_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_argument_spec.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_auth.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_bind_exceptions.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_bind_request_at_clause.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_bound_storage_conformance.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_catalog_auth_binding.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_docstrings.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_documentation_examples.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_example_function_arg_types.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_examples_workers.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_exception_handling.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_exceptions.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_filter_pushdown.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_filter_pushdown_extension.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_function_storage.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_function_storage_azure_sql.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_function_storage_cf_do.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_function_storage_cf_do_integration.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_function_storage_conformance.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_cpp_constants.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_cpp_protocol_version.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_cpp_request_builders.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_cpp_schemas.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_cpp_secret.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_go_schemas.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_protocol_version.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_schemas_cross_lang.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_ts_client.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_generated_ts_schemas.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_http_demo_storage.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_http_s3_offload_input.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_http_s3_offload_output.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_metadata.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_mypy_consolidated.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_nest_tensor.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_otel.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_projection_enforcement.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_projection_repro.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_protocol_classes.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_schema_utils.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_serve.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_setting_secret_annotations.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_table_buffering_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_table_function_dynamic_to_string.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_type_bounds.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_worker_cli.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/test_worker_page.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/transactor/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/tests/transactor/test_transactor.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/uv.lock +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_duckdb.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_storage_profile.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/accumulate/worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/_common.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/basic.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/generic.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/aggregate/window.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/attach_options.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/bad_enum.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/bad_protocol.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/cancellable.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/catalog.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/http_server.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/nest_tensor.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/orchard_catalog.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/_common.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/binary.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/formatting.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/geo.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/scalar/type_info.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/simple_writable.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/_common.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/batch_index.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/filters.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/late_materialization.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/make_series.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/misc.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/order_modes.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/pairs.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/partition_columns.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/profiling_example.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/required_filters.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/sequence.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/settings.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/typed_probe.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table/versioned.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/table_in_out.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/versioned.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/versioned_tables.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/writable/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/writable/generic.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/writable/table.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/_test_fixtures/writable/worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/aggregate_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/argument_spec.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/auth.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/catalog/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/catalog/_descriptor_spec.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/catalog/attach_option.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/catalog/catalog_interface.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/catalog/descriptors.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/catalog/duckdb_statistics.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/catalog/secret_type.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/catalog/setting.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/catalog/storage.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/catalog_mixin.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/cli.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/cli_catalog.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/cli_schema.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/cli_table.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/cli_transaction.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/cli_utils.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/cli_view.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/client/client.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/_common.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/cpp_constants.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/cpp_protocol_version.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/cpp_request_builders.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/cpp_schemas.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/cpp_secret_request_builders.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/cpp_secret_schemas.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/go_schemas.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/protocol_version.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/ts_client.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/codegen/ts_schemas.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/exceptions.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/function_storage.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/function_storage_azure_sql.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/function_storage_cf_do.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/http/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/http/demo_storage.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/http/worker_page.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/invocation.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/logging_config.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/meta_worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/metadata.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/otel.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/protocol.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/protocol_version.txt +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/py.typed +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/scalar_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/schema_utils.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/secret_protocol.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/secret_service.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/serve.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/table_buffering_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/table_filter_pushdown.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/table_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/table_in_out_function.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/transactor/__init__.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/transactor/_duckdb_compat.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/transactor/client.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/transactor/protocol.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/transactor/server.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/vgi/worker.py +0 -0
- {vgi_python-0.8.2 → vgi_python-0.8.3}/wrangler.jsonc +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vgi-python
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.3
|
|
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
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Union-typed argument decoding.
|
|
4
|
+
|
|
5
|
+
A DuckDB ``UNION`` / Arrow union argument is tagged: the discriminator lives in
|
|
6
|
+
``UnionScalar.type_code``, which plain ``Scalar.as_py()`` discards. ``Arguments``
|
|
7
|
+
decodes such scalars to ``TaggedUnion`` so the active member name is preserved.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import pyarrow as pa
|
|
13
|
+
|
|
14
|
+
from vgi.arguments import Arguments, TaggedUnion
|
|
15
|
+
|
|
16
|
+
_RF = pa.struct([pa.field("n_estimators", pa.list_(pa.int64())), pa.field("max_depth", pa.list_(pa.int64()))])
|
|
17
|
+
_SVC = pa.struct([pa.field("C", pa.list_(pa.float64())), pa.field("kernel", pa.list_(pa.string()))])
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _union_scalar(code: int, members: dict) -> pa.UnionScalar:
|
|
21
|
+
"""Build a one-element sparse-union scalar with named members, active = ``code``."""
|
|
22
|
+
arr = pa.UnionArray.from_sparse(
|
|
23
|
+
pa.array([code], type=pa.int8()),
|
|
24
|
+
[
|
|
25
|
+
pa.array([members.get("random_forest_classifier")], type=_RF),
|
|
26
|
+
pa.array([members.get("svc")], type=_SVC),
|
|
27
|
+
],
|
|
28
|
+
field_names=["random_forest_classifier", "svc"],
|
|
29
|
+
type_codes=[0, 1],
|
|
30
|
+
)
|
|
31
|
+
return arr[0]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_union_arg_preserves_tag() -> None:
|
|
35
|
+
"""A union argument decodes to a TaggedUnion carrying the active member name."""
|
|
36
|
+
scalar = _union_scalar(0, {"random_forest_classifier": {"n_estimators": [100, 300], "max_depth": [3, 5]}})
|
|
37
|
+
got = Arguments(named={"config": scalar}).get("config")
|
|
38
|
+
assert isinstance(got, TaggedUnion)
|
|
39
|
+
assert got.tag == "random_forest_classifier"
|
|
40
|
+
assert got.value == {"n_estimators": [100, 300], "max_depth": [3, 5]}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_union_arg_other_member() -> None:
|
|
44
|
+
"""The tag reflects whichever union member is set."""
|
|
45
|
+
scalar = _union_scalar(1, {"svc": {"C": [1.0, 10.0], "kernel": ["rbf", "linear"]}})
|
|
46
|
+
got = Arguments(named={"config": scalar}).get("config")
|
|
47
|
+
assert got.tag == "svc"
|
|
48
|
+
assert got.value == {"C": [1.0, 10.0], "kernel": ["rbf", "linear"]}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_union_arg_null_payload() -> None:
|
|
52
|
+
"""A null union slot decodes its value to None (the ``inner is None`` branch).
|
|
53
|
+
|
|
54
|
+
Note: pyarrow reports ``type_code == 0`` for any null union slot regardless of
|
|
55
|
+
the codes buffer, so the active member's tag is not recoverable at the scalar
|
|
56
|
+
level for a null payload — only the value is. (Tag preservation for a
|
|
57
|
+
non-null payload of a non-zero-code member is covered above and through the
|
|
58
|
+
batch-level round-trip in the echo integration suite.)
|
|
59
|
+
"""
|
|
60
|
+
scalar = _union_scalar(1, {"svc": None})
|
|
61
|
+
got = Arguments(named={"config": scalar}).get("config")
|
|
62
|
+
assert isinstance(got, TaggedUnion)
|
|
63
|
+
assert got.value is None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_union_arg_non_contiguous_type_codes() -> None:
|
|
67
|
+
"""Tag resolution maps via type_codes, not member position.
|
|
68
|
+
|
|
69
|
+
Type codes need not be 0,1,2,...; ``_scalar_to_py`` must locate the active
|
|
70
|
+
member by ``type_codes.index(code)`` rather than treating the code as a
|
|
71
|
+
positional index.
|
|
72
|
+
"""
|
|
73
|
+
arr = pa.UnionArray.from_sparse(
|
|
74
|
+
pa.array([9], type=pa.int8()),
|
|
75
|
+
[
|
|
76
|
+
pa.array([{"n_estimators": [1], "max_depth": [2]}], type=_RF),
|
|
77
|
+
pa.array([{"C": [1.0], "kernel": ["rbf"]}], type=_SVC),
|
|
78
|
+
],
|
|
79
|
+
field_names=["random_forest_classifier", "svc"],
|
|
80
|
+
type_codes=[5, 9],
|
|
81
|
+
)
|
|
82
|
+
got = Arguments(named={"config": arr[0]}).get("config")
|
|
83
|
+
assert isinstance(got, TaggedUnion)
|
|
84
|
+
assert got.tag == "svc"
|
|
85
|
+
assert got.value == {"C": [1.0], "kernel": ["rbf"]}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_union_arg_dense_union() -> None:
|
|
89
|
+
"""Dense unions (what DuckDB emits) decode the same as sparse."""
|
|
90
|
+
arr = pa.UnionArray.from_dense(
|
|
91
|
+
pa.array([1], type=pa.int8()),
|
|
92
|
+
pa.array([0], type=pa.int32()),
|
|
93
|
+
[
|
|
94
|
+
pa.array([], type=_RF),
|
|
95
|
+
pa.array([{"C": [2.0], "kernel": ["linear"]}], type=_SVC),
|
|
96
|
+
],
|
|
97
|
+
field_names=["random_forest_classifier", "svc"],
|
|
98
|
+
type_codes=[0, 1],
|
|
99
|
+
)
|
|
100
|
+
got = Arguments(named={"config": arr[0]}).get("config")
|
|
101
|
+
assert isinstance(got, TaggedUnion)
|
|
102
|
+
assert got.tag == "svc"
|
|
103
|
+
assert got.value == {"C": [2.0], "kernel": ["linear"]}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_non_union_args_unchanged() -> None:
|
|
107
|
+
"""Non-union arguments still decode via plain as_py()."""
|
|
108
|
+
args = Arguments(named={"n": pa.scalar(5), "s": pa.scalar("hi")}, positional=(pa.scalar(1.5),))
|
|
109
|
+
assert args.get("n") == 5
|
|
110
|
+
assert args.get("s") == "hi"
|
|
111
|
+
assert args.get(0) == 1.5
|
|
@@ -39,6 +39,7 @@ from vgi.arguments import (
|
|
|
39
39
|
Param,
|
|
40
40
|
Returns,
|
|
41
41
|
TableInput,
|
|
42
|
+
TaggedUnion,
|
|
42
43
|
)
|
|
43
44
|
from vgi.auth import AuthContext, CallContext
|
|
44
45
|
from vgi.metadata import (
|
|
@@ -143,6 +144,7 @@ __all__ = [
|
|
|
143
144
|
"TableInOutGenerator",
|
|
144
145
|
"TableInput",
|
|
145
146
|
"TableInputValidationError",
|
|
147
|
+
"TaggedUnion",
|
|
146
148
|
"TypeMismatchError",
|
|
147
149
|
"Worker",
|
|
148
150
|
"functions_to_arrow",
|
|
@@ -159,6 +159,7 @@ __all__ = [
|
|
|
159
159
|
"PYTHON_TO_ARROW",
|
|
160
160
|
"Returns",
|
|
161
161
|
"TableInput",
|
|
162
|
+
"TaggedUnion",
|
|
162
163
|
"TypeBoundPredicate",
|
|
163
164
|
"OutputLength",
|
|
164
165
|
"Setting",
|
|
@@ -168,6 +169,58 @@ __all__ = [
|
|
|
168
169
|
]
|
|
169
170
|
|
|
170
171
|
|
|
172
|
+
@dataclass(frozen=True, slots=True)
|
|
173
|
+
class TaggedUnion:
|
|
174
|
+
"""A decoded union-typed argument: which member is set (``tag``) and its ``value``.
|
|
175
|
+
|
|
176
|
+
DuckDB ``UNION`` / Arrow union arguments are *tagged*: the discriminator
|
|
177
|
+
(which member is present) lives in the Arrow ``UnionScalar.type_code``, not
|
|
178
|
+
in the member value. Plain ``Scalar.as_py()`` returns only the member value
|
|
179
|
+
and drops that tag, so union arguments are decoded into this wrapper
|
|
180
|
+
instead — ``tag`` is the active member's field name and ``value`` is its
|
|
181
|
+
Python value.
|
|
182
|
+
|
|
183
|
+
Example::
|
|
184
|
+
|
|
185
|
+
config: Annotated[TaggedUnion, Arg("config", arrow_type=pa.sparse_union([...]))]
|
|
186
|
+
...
|
|
187
|
+
cfg = params.args.config # TaggedUnion(tag=..., value=...)
|
|
188
|
+
if cfg.tag == "random_forest_classifier":
|
|
189
|
+
grid = cfg.value # the member struct, as a dict
|
|
190
|
+
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
tag: str | None
|
|
194
|
+
value: Any
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _scalar_to_py(scalar: "Scalar[Any]") -> Any:
|
|
198
|
+
"""Convert an argument scalar to a Python value, preserving union tags.
|
|
199
|
+
|
|
200
|
+
Identical to ``scalar.as_py()`` for every type except unions: a
|
|
201
|
+
``UnionScalar`` is decoded to a [`TaggedUnion`][] so the member
|
|
202
|
+
discriminator (which ``as_py()`` discards) is retained.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
scalar: The argument scalar to convert.
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
``scalar.as_py()`` for non-union scalars; a [`TaggedUnion`][] for unions.
|
|
209
|
+
|
|
210
|
+
"""
|
|
211
|
+
if isinstance(scalar, pa.UnionScalar):
|
|
212
|
+
# Map the active ``type_code`` to its member field name via the union
|
|
213
|
+
# type's parallel ``type_codes`` / ``field()``. (``type_code`` is coerced
|
|
214
|
+
# to int — it is an integer at runtime regardless of the stub's typing.)
|
|
215
|
+
union_type = scalar.type
|
|
216
|
+
type_codes = list(union_type.type_codes)
|
|
217
|
+
code = int(scalar.type_code)
|
|
218
|
+
tag = union_type.field(type_codes.index(code)).name if code in type_codes else None
|
|
219
|
+
inner = scalar.value
|
|
220
|
+
return TaggedUnion(tag=tag, value=inner.as_py() if inner is not None else None)
|
|
221
|
+
return scalar.as_py()
|
|
222
|
+
|
|
223
|
+
|
|
171
224
|
class TableInput:
|
|
172
225
|
"""Sentinel type for table input parameters in table-in-out functions.
|
|
173
226
|
|
|
@@ -377,7 +430,7 @@ class Arguments:
|
|
|
377
430
|
else:
|
|
378
431
|
raise TypeError(f"Argument '{key}': expected {type}, got {scalar.type}")
|
|
379
432
|
|
|
380
|
-
return scalar
|
|
433
|
+
return _scalar_to_py(scalar)
|
|
381
434
|
|
|
382
435
|
def get_varargs(
|
|
383
436
|
self,
|
|
@@ -410,7 +463,7 @@ class Arguments:
|
|
|
410
463
|
if type is not None and scalar.type != type:
|
|
411
464
|
raise TypeError(f"Argument {i}: expected {type}, got {scalar.type}")
|
|
412
465
|
|
|
413
|
-
values.append(scalar
|
|
466
|
+
values.append(_scalar_to_py(scalar))
|
|
414
467
|
|
|
415
468
|
return tuple(values)
|
|
416
469
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_constant_columns_function.py
RENAMED
|
File without changes
|
{vgi_python-0.8.2 → vgi_python-0.8.3}/tests/table/generator/test_double_sequence_function.py
RENAMED
|
File without changes
|
|
File without changes
|