From 0f93a23113addb2fe9225be9b4bf41dd9f975676 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 05:12:22 +0100 Subject: [PATCH 01/19] build: guard native bindings against new Python crossings, Python-typed storage and native test patches --- fensu.toml | 903 +++++++++++++++++- .../fensu_policy/_helpers/native_crossings.py | 145 +++ .../fensu_policy/_helpers/native_patches.py | 69 ++ scripts/fensu_policy/constants.py | 49 + scripts/fensu_policy/rules/native_boundary.py | 89 ++ .../scripts/fensu_policy/rules/_test_types.py | 15 + .../rules/test_native_boundary.py | 187 ++++ 7 files changed, 1456 insertions(+), 1 deletion(-) create mode 100644 scripts/fensu_policy/_helpers/native_crossings.py create mode 100644 scripts/fensu_policy/_helpers/native_patches.py create mode 100644 scripts/fensu_policy/rules/native_boundary.py create mode 100644 tests/unit/scripts/fensu_policy/rules/test_native_boundary.py diff --git a/fensu.toml b/fensu.toml index cb01221719..51eb8842ce 100644 --- a/fensu.toml +++ b/fensu.toml @@ -8,6 +8,7 @@ rule_modules = [ "scripts.fensu_policy.rules.canonical_operations", "scripts.fensu_policy.rules.execution_observability", "scripts.fensu_policy.rules.module_boundaries", + "scripts.fensu_policy.rules.native_boundary", "scripts.fensu_policy.rules.orchestration_dataflow", "scripts.fensu_policy.rules.source_hygiene", ] @@ -23,6 +24,28 @@ exclude = ["tests/e2e/fixtures/**"] [targets.python.thresholds] max_positional_args = 1 +[targets.python.rule_options.XSB074] +pending_budgets = [ + "tests/e2e/src/sqlbuild/cli/commands/main/compile/helpers.py=6", + "tests/integration/src/sqlbuild/adapter/type_system/test_native_type_normalization.py=1", + "tests/integration/src/sqlbuild/cli/commands/main/compile_outputs/helpers.py=3", + "tests/integration/src/sqlbuild/cli/commands/main/helpers.py=6", + "tests/integration/src/sqlbuild/cli/commands/main/test_rules.py=1", + "tests/integration/src/sqlbuild/compiler/contracts/helpers.py=1", + "tests/integration/src/sqlbuild/compiler/model_config/helpers.py=1", + "tests/integration/src/sqlbuild/compiler/pipeline/test_native_binding_catalog.py=1", + "tests/integration/src/sqlbuild/compiler/project_assembly/helpers.py=1", + "tests/unit/src/sqlbuild/cli/commands/main/compile/test_compile_command.py=2", + "tests/unit/src/sqlbuild/cli/commands/main/compile/test_compile_target_writer.py=10", + "tests/unit/src/sqlbuild/cli/commands/main/dbt/test_dbt.py=4", + "tests/unit/src/sqlbuild/cli/commands/main/init/test_run.py=2", + "tests/unit/src/sqlbuild/integrations/dbt/test_execute.py=14", + "tests/unit/src/sqlbuild/lint/test_cli_format.py=1", + "tests/unit/src/sqlbuild/rule_engine/_helpers/engine/test_custom_rule_reads.py=1", + "tests/unit/src/sqlbuild/rule_engine/_helpers/host/helpers.py=1", + "tests/unit/src/sqlbuild/rule_engine/_helpers/run/helpers.py=1", +] + [[targets.python.rule_exceptions]] rule = "FFR309" path = "src/sqlbuild/cost/models.py" @@ -368,7 +391,8 @@ roots = ["crates"] tests = [] tooling = [] rule_packs = ["rust"] -select = ["FPRS"] +rule_modules = ["scripts.fensu_policy.rules.native_boundary"] +select = ["FPRS", "XSB072", "XSB073"] [[targets.rust.rule_exceptions]] rule = "FPRSR307" @@ -459,3 +483,880 @@ rule = "XSB051" path = "src/sqlbuild/executor/old_name_views/_helpers/janitor.py" symbols = ["apply_old_name_view_drops"] reason = "Janitor reads each compatibility view's stored definition right before deciding to drop it, so a relation that replaced the view is never dropped; a project has few live old names." + +[targets.rust.rule_options.XSB072] +edge_paths = [ + "crates/sqlbuild-python/src/bindings/_helpers/native_host", + "crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs", + "crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs", + "crates/sqlbuild-python/src/bindings/_helpers/records/registry.rs", +] +pending_budgets = [ + "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=24", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/model_reads.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/nullability_rules.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/outcome_objects.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/attachments/reference_markers.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs=29", + "crates/sqlbuild-python/src/bindings/_helpers/auditing/identity.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/auditing/render.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/auditing/schema_audits.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/authored_values/fields.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/authored_values/project_vars.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/boundary/config_values.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs=32", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs=24", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/support.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/plan_facts.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs=23", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/cache/native_store.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs=28", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/cli/argv.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs=21", + "crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs=35", + "crates/sqlbuild-python/src/bindings/_helpers/cli/launch_state.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/cli/surrogates.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_pipeline.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/connection.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/invocation.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/preview_target.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/runtime_errors.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouse_scope.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/storage_policies.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/constants.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs=44", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs=42", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs=50", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs=43", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/runtime_identity.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/startup_inputs.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/surrogates.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=33", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs=24", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs=28", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/compile_timings.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/artifacts.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/reuse.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_loop.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_analysis.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_loop.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_calls.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_config.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_contracts.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_external.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_header.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_hooks.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_host.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_macros.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_named.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_opt_out.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_python_hooks.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_schema.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_visibility.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs=25", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/scenario_loop.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/sql_test_loop.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compute_logs/conversion.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs=23", + "crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/resource_identities.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/sql_values.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/state_literals.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/bounds.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refusal.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/cost_report/degradation.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/cost_report/functions.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/cost_report/records.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/cost_report/store.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/allocation.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/context.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/health.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/snowflake.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/values.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/cursor/conversion.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/cursor/durations.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/cursor/intervals.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/cursor/overrides.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/cursor/scalars.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/cursor/values.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/artifact.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/translator.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/debug.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init_project.rs=28", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/support.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_events/results.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_phases.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_coercion.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_connection.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_load.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs=19", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_results.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs=29", + "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/console_records.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/registration.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/tolerances.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/faults.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/header_values.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/hook_entries.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_providers.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/locations.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_records.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_files.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_validation.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/python_function_files.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/python_hook_files.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/raised.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/scope_snapshot.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/snapshot.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_records.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_records.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs=30", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/models.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/registration.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/values.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/workers.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/execution_history/functions.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs=29", + "crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs=36", + "crates/sqlbuild-python/src/bindings/_helpers/execution_history/statements.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/exported_constants/registration.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/query_hashes.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_sql.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/config.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/state_io.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/support.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/frontier/compile_frontier.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/frontier/python_types.rs=29", + "crates/sqlbuild-python/src/bindings/_helpers/frontier/stage_capture.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/graph/keys.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/init_command/scaffold.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_keys.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs=23", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_plan.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/validation.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_cache.rs=28", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/load/ingestr_command.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs=21", + "crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs=28", + "crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/microbatches/projection.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/authored_nodes.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_templates.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/described_models.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/errors.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/header_columns.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/header_metadata.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/model_config_builder.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/native_threads/exit_signal.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/output_capture/context.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/output_capture/dispatcher.rs=33", + "crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/plan_command/rules.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/plan_output/cursor_details.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/plan_output/display.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_json.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/plan_output/python_identity.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/actions.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/metadata.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/execution_plan.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/models.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/json_values.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_candidates.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_objects.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_warnings.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/columns.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/compatibility.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_events.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/fingerprint.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_handover.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_overlay.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_warnings.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_entries.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_objects.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_planning.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_references.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_names.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_execution.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/full_refresh.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/models.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/warehouse_state.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_records/constants.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_bounds.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/artifacts.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/entries.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/execution.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/sources.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/values.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/unit_tests.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audits.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/constants.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_types.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_metadata.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_preparation.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_reads.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_sql.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_values.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatch_limits.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatches.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/models.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_columns.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/document.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/functions.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/style.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/terminal.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/declared_relations.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/models.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_checks.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/python_values/values.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/query_command/dag.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/query_command/project.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/query_command/query_values.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/auditing.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/cursors.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/durations.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/macros.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/migrations.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/python_nodes.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/records/constants.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/records/error_classes.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/records/models.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/records/registration.rs=26", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_edits.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/python_strings.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_facts.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/references/source_relations.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/relation_naming/fitting.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_expansion.rs=24", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs=19", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_arguments.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_memo.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_calls.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_evaluation.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/aggregation.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/checks.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/event_writer.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_records.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_values.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/projection.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/resource_ids.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/rules/builtin_catalogue.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/catalogue.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_host_observation.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_cache.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_encoder.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_replay.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_tree.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/findings.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_facts.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_verdict.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fixture_formatting.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_headers.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_inputs.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_preparation.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_sql_bodies.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/native_header_parser.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/rules/results.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rows.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_cache.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_dispatch.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_plan.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_run.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rules_config.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/rules/selection.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/rules/sql_test_objects.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/capture_command.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/conversions.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs=29", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/relationship_names.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_cache.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_command.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_errors.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs=35", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_loading.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_lookup.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_report_objects.rs=23", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_tolerant.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_visibility.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/completion.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/declarations.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/compiled_tests.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/constants.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_fixtures.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_values.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/planning.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/sqltext/authored_values.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sqltext/code_scanner.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sqltext/static_sql.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/constants.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/events.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/freshness.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_io.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_projections.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/state_tables.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/timestamps.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/type_system/equality.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/type_system/normalization.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs=9", + "crates/sqlbuild-python/src/bindings/models.rs=7", +] + +[targets.rust.rule_options.XSB073] +edge_paths = [ + "crates/sqlbuild-python/src/bindings/_helpers/native_host", + "crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs", + "crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs", + "crates/sqlbuild-python/src/bindings/_helpers/records/registry.rs", +] +pending_budgets = [ + "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/schema_request.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/authored_values/fields.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/boundary/keyword_request.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/support.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/cli/argv.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_pipeline.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouse_scope.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs=25", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/target_defaults.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_loop.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_analysis.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_loop.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs=24", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs=25", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_config.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_contracts.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_header.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_hooks.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_host.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_macros.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_opt_out.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_python_hooks.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_schema.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_visibility.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/sql_test_loop.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/sql_values.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/cost_report/records.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/context.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/snowflake.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/cursor/conversion.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/cursor/intervals.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init_project.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/faults.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs=23", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_records.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/python_function_files.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/scope_snapshot.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/models.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/files.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/state_io.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/frontier/python_types.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/graph/keys.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_templates.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/header_metadata.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/model_config_builder.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/output_capture/context.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/output_capture/dispatcher.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/plan_command/rules.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/plan_output/cursor_details.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/models.rs=57", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/json_values.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/models.rs=66", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/models.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/models.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/models.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_completion.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_preparation.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_sql.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/models.rs=34", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs=19", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/functions.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/models.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/query_command/project.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/records/error_classes.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/records/models.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_expansion.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_arguments.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_evaluation.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion.rs=26", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_facts.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/event_writer.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_host_observation.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_encoder.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_replay.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/rules/findings.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fixture_schemas.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rows.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_dispatch.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_tolerant.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/compiled_tests.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/models.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/planning.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/models.rs=3", + "crates/sqlbuild-python/src/bindings/models.rs=4", +] diff --git a/scripts/fensu_policy/_helpers/native_crossings.py b/scripts/fensu_policy/_helpers/native_crossings.py new file mode 100644 index 0000000000..41064e6977 --- /dev/null +++ b/scripts/fensu_policy/_helpers/native_crossings.py @@ -0,0 +1,145 @@ +"""Locate Rust-to-Python crossings and Python-typed storage in the native bindings crate.""" + +from __future__ import annotations + +import re +from collections.abc import Callable, Iterable + +from fensu import Fault, RuleContext + +from scripts.fensu_policy.constants import ( + NATIVE_BINDINGS_ROOT, + NATIVE_BUDGET_SEPARATOR, + NATIVE_CROSSING_PATTERNS, + NATIVE_EDGE_PATHS, + NATIVE_LINE_COMMENT, + NATIVE_PENDING_BUDGETS, + NATIVE_PYTHON_FIELD_PATTERN, + NATIVE_RUST_SUFFIX, + NATIVE_SKIPPED_LINE_PREFIXES, + NATIVE_STRING_QUOTE, + NATIVE_TEST_DIRECTORY, + NATIVE_TEST_FILE_NAME, + NATIVE_TEST_FILE_PREFIX, + NATIVE_TEST_MODULE_MARKER, +) + +_CROSSING: re.Pattern[str] = re.compile("|".join(NATIVE_CROSSING_PATTERNS)) +_PYTHON_FIELD: re.Pattern[str] = re.compile(NATIVE_PYTHON_FIELD_PATTERN) +_STRUCT_OPEN: re.Pattern[str] = re.compile(r"^\s*(?:pub(?:\([^)]*\))?\s+)?struct\s+\w+[^;]*\{\s*$") +_FIELD: re.Pattern[str] = re.compile(r"^\s*(?:pub(?:\([^)]*\))?\s+)?\w+\s*:") + + +def is_checked_binding(*, path: str) -> bool: + """Whether `path` is non-test source of the native bindings crate.""" + + if not path.startswith(NATIVE_BINDINGS_ROOT) or not path.endswith(NATIVE_RUST_SUFFIX): + return False + parts: list[str] = path.split("/") + name: str = parts[-1] + return ( + NATIVE_TEST_DIRECTORY not in parts[:-1] + and name != NATIVE_TEST_FILE_NAME + and not name.startswith(NATIVE_TEST_FILE_PREFIX) + ) + + +def is_edge_path(*, path: str, edge_paths: Iterable[str]) -> bool: + """Whether `path` lies under one of the configured edge prefixes.""" + + return any(path == edge or path.startswith(edge.rstrip("/") + "/") for edge in edge_paths) + + +def budgets_by_path(*, entries: Iterable[str]) -> dict[str, int]: + """Parse `path=count` budget entries.""" + + budgets: dict[str, int] = {} + entry: str + for entry in entries: + path, _, count = entry.rpartition(NATIVE_BUDGET_SEPARATOR) + budgets[path.strip()] = int(count) + return budgets + + +def _code_lines(*, source: str) -> list[tuple[int, str]]: + lines: list[tuple[int, str]] = [] + number: int + line: str + for number, line in enumerate(source.splitlines(), start=1): + stripped: str = line.strip() + if stripped.startswith(NATIVE_TEST_MODULE_MARKER): + break + if stripped.startswith(NATIVE_SKIPPED_LINE_PREFIXES): + continue + code: str = line if NATIVE_STRING_QUOTE in line else line.split(NATIVE_LINE_COMMENT, 1)[0] + lines.append((number, code)) + return lines + + +def crossing_lines(*, source: str) -> list[int]: + """Line numbers of Rust-to-Python crossings, one entry per crossing.""" + + found: list[int] = [] + number: int + line: str + for number, line in _code_lines(source=source): + found.extend([number] * len(_CROSSING.findall(line))) + return found + + +def python_field_lines(*, source: str) -> list[int]: + """Line numbers of struct fields that hold Python objects.""" + + found: list[int] = [] + in_struct: bool = False + number: int + line: str + for number, line in _code_lines(source=source): + if _STRUCT_OPEN.match(line): + in_struct = True + continue + if in_struct and line.strip().startswith("}"): + in_struct = False + continue + if in_struct and _FIELD.match(line) and _PYTHON_FIELD.search(line): + found.append(number) + return found + + +def budgeted_faults( + *, + ctx: RuleContext, + lines: Callable[..., list[int]], + what: str, +) -> list[Fault]: + """Faults for a bindings file whose `lines` exceed, or fall below, its pending budget.""" + + path: str = "/".join(ctx.repo_relative_parts()) + if not is_checked_binding(path=path) or is_edge_path( + path=path, edge_paths=ctx.option(NATIVE_EDGE_PATHS) + ): + return [] + found: list[int] = lines(source=ctx.source) + budget: int | None = budgets_by_path(entries=ctx.option(NATIVE_PENDING_BUDGETS)).get(path) + if budget is None: + return [ctx.fault_for(path=ctx.path, line=line, column=0) for line in found] + if len(found) > budget: + return [ + ctx.fault_for( + path=ctx.path, + line=found[0], + column=0, + message=f"{len(found)} {what}, above the pending budget of {budget}", + ) + ] + if len(found) < budget: + return [ + ctx.fault_for( + path=ctx.path, + line=1, + column=0, + message=f"{len(found)} {what}, below the pending budget of {budget}; lower it", + remediation="Lower this file's pending_budgets entry to the new count.", + ) + ] + return [] diff --git a/scripts/fensu_policy/_helpers/native_patches.py b/scripts/fensu_policy/_helpers/native_patches.py new file mode 100644 index 0000000000..22baf88040 --- /dev/null +++ b/scripts/fensu_policy/_helpers/native_patches.py @@ -0,0 +1,69 @@ +"""Locate tests that replace attributes of the native extension module.""" + +from __future__ import annotations + +import ast + +from scripts.fensu_policy.constants import ( + NATIVE_MODULE_NAME, + NATIVE_MODULE_PACKAGE, + NATIVE_MODULE_PATH, + NATIVE_PATCH_CALL_NAMES, + NATIVE_STRING_PATCH_CALL_NAMES, +) + + +def _native_names(*, tree: ast.Module) -> frozenset[str]: + names: set[str] = set() + node: ast.AST + for node in ast.walk(tree): + if isinstance(node, ast.Import): + names.update( + alias.asname + for alias in node.names + if alias.name == NATIVE_MODULE_PATH and alias.asname + ) + elif isinstance(node, ast.ImportFrom) and node.module == NATIVE_MODULE_PACKAGE: + names.update( + alias.asname or alias.name + for alias in node.names + if alias.name == NATIVE_MODULE_NAME + ) + return frozenset(names) + + +def _call_name(*, call: ast.Call) -> str | None: + if isinstance(call.func, ast.Attribute): + return call.func.attr + if isinstance(call.func, ast.Name): + return call.func.id + return None + + +def _patches_native(*, call: ast.Call, native_names: frozenset[str]) -> bool: + if not call.args: + return False + target: ast.expr = call.args[0] + name: str | None = _call_name(call=call) + if name in NATIVE_PATCH_CALL_NAMES: + if isinstance(target, ast.Name) and target.id in native_names: + return True + if isinstance(target, ast.Attribute) and ast.unparse(target) == NATIVE_MODULE_PATH: + return True + return ( + name in NATIVE_STRING_PATCH_CALL_NAMES + and isinstance(target, ast.Constant) + and isinstance(target.value, str) + and target.value.startswith(NATIVE_MODULE_PATH + ".") + ) + + +def native_patch_lines(*, tree: ast.Module) -> list[int]: + """Line numbers of calls that replace an attribute of `sqlbuild._native`.""" + + native_names: frozenset[str] = _native_names(tree=tree) + return [ + node.lineno + for node in ast.walk(tree) + if isinstance(node, ast.Call) and _patches_native(call=node, native_names=native_names) + ] diff --git a/scripts/fensu_policy/constants.py b/scripts/fensu_policy/constants.py index 0c6594ebd2..79ed9a218a 100644 --- a/scripts/fensu_policy/constants.py +++ b/scripts/fensu_policy/constants.py @@ -1,5 +1,7 @@ """Stable constants for SQLBuild custom Fensu rules.""" +from fensu import RuleOption + ADAPTER_CLASS_BOUNDARIES: frozenset[str] = frozenset( {"_helpers", "classes", "models", "types", "constants", "exceptions", "shared"} ) @@ -294,3 +296,50 @@ ("sqlbuild", "runtime", "observability", "models"), ) PUBLIC_EVENT_EXPORTER_MODULE_PARTS: tuple[str, ...] = ("sqlbuild", "sinks") +NATIVE_BINDINGS_ROOT: str = "crates/sqlbuild-python/src/" +NATIVE_CROSSING_PATTERNS: tuple[str, ...] = ( + r"\.getattr\(", + r"\.setattr\(", + r"\.call_method[01]?\(", + r"\.call[01]?\(", + r"\bregistry::(?:native|error)\(", + r"\bimported\(", + r"\.import\(", + r"\bPyModule::import\(", + r"\"dataclasses\"", + r"\"sqlbuild\.", +) +NATIVE_PYTHON_FIELD_PATTERN: str = ( + r"\b(?:Py|Bound|Borrowed)<[^;]*?\b(?:PyAny|PyDict|PyList|PyTuple|PySet|PyFrozenSet" + r"|PyString|PyType|PyModule)\b" +) +NATIVE_TEST_MODULE_MARKER: str = "#[cfg(test)]" +NATIVE_RUST_SUFFIX: str = ".rs" +NATIVE_TEST_DIRECTORY: str = "tests" +NATIVE_TEST_FILE_NAME: str = "tests.rs" +NATIVE_TEST_FILE_PREFIX: str = "test_" +NATIVE_LINE_COMMENT: str = "//" +NATIVE_STRING_QUOTE: str = '"' +NATIVE_SKIPPED_LINE_PREFIXES: tuple[str, ...] = ("//", "use ", "pub use ", "pub(crate) use ") +NATIVE_BUDGET_SEPARATOR: str = "=" +NATIVE_EDGE_PATHS: RuleOption[tuple[str, ...]] = RuleOption.string_list( + name="edge_paths", + default=(), + description="Path prefixes that own the real Python edges and may cross freely.", +) +NATIVE_PENDING_BUDGETS: RuleOption[tuple[str, ...]] = RuleOption.string_list( + name="pending_budgets", + default=(), + description="`path=count` budgets for files that still cross; each may only fall.", +) +NATIVE_MODULE_PATH: str = "sqlbuild._native" +NATIVE_MODULE_PACKAGE: str = "sqlbuild" +NATIVE_MODULE_NAME: str = "_native" +NATIVE_PATCH_CALL_NAMES: frozenset[str] = frozenset({"setattr", "object", "delattr"}) +NATIVE_STRING_PATCH_CALL_NAMES: frozenset[str] = frozenset({"setattr", "patch", "delattr"}) +NATIVE_TEST_PATH_PREFIX: str = "tests/" +NATIVE_TEST_PATCH_BUDGETS: RuleOption[tuple[str, ...]] = RuleOption.string_list( + name="pending_budgets", + default=(), + description="`path=count` budgets for test files that still patch the native module.", +) diff --git a/scripts/fensu_policy/rules/native_boundary.py b/scripts/fensu_policy/rules/native_boundary.py new file mode 100644 index 0000000000..4736d563a1 --- /dev/null +++ b/scripts/fensu_policy/rules/native_boundary.py @@ -0,0 +1,89 @@ +"""Rules keeping the native bindings crate from calling back into Python outside its edges.""" + +from __future__ import annotations + +import ast + +from fensu import AnalyzerId, Family, Fault, File, RuleContext, rule + +from scripts.fensu_policy._helpers.native_crossings import ( + budgeted_faults, + budgets_by_path, + crossing_lines, + python_field_lines, +) +from scripts.fensu_policy._helpers.native_patches import native_patch_lines +from scripts.fensu_policy.constants import ( + NATIVE_EDGE_PATHS, + NATIVE_PENDING_BUDGETS, + NATIVE_TEST_PATCH_BUDGETS, + NATIVE_TEST_PATH_PREFIX, +) + + +@rule( + code="XSB072", + family=Family.CUSTOM, + slug="native-python-crossing", + message="native bindings must not call back into Python outside the configured edges", + remediation=( + "Read native records with records::fields::field, build them with records::construct, " + "call Rust functions directly, or route a real edge through bindings/_helpers/native_host." + ), + analyzers=(AnalyzerId.RUST,), + options=(NATIVE_EDGE_PATHS, NATIVE_PENDING_BUDGETS), +) +def native_python_crossing(*, file: File, ctx: RuleContext) -> list[Fault]: + del file + return budgeted_faults(ctx=ctx, lines=crossing_lines, what="Python crossings") + + +@rule( + code="XSB073", + family=Family.CUSTOM, + slug="native-python-storage", + message="native bindings must not store Python objects outside the configured edges", + remediation=( + "Store Rust values or typed native records; keep Python objects only in " + "bindings/_helpers/native_host for user values, adapters, hooks and streams." + ), + analyzers=(AnalyzerId.RUST,), + options=(NATIVE_EDGE_PATHS, NATIVE_PENDING_BUDGETS), +) +def native_python_storage(*, file: File, ctx: RuleContext) -> list[Fault]: + del file + return budgeted_faults(ctx=ctx, lines=python_field_lines, what="Python-typed fields") + + +@rule( + code="XSB074", + family=Family.CUSTOM, + slug="native-module-test-patch", + message="tests must not replace attributes of sqlbuild._native", + remediation=( + "Assert observable behaviour or native work counters instead; native code calls its own " + "functions directly, so a patched module attribute is not seen." + ), + options=(NATIVE_TEST_PATCH_BUDGETS,), +) +def native_module_test_patch(*, module: object, ctx: RuleContext) -> list[Fault]: + path: str = "/".join(ctx.repo_relative_parts()) + if not path.startswith(NATIVE_TEST_PATH_PREFIX): + return [] + tree: ast.Module = module if isinstance(module, ast.Module) else ast.parse(ctx.text.source) + found: list[int] = native_patch_lines(tree=tree) + budget: int = budgets_by_path(entries=ctx.option(NATIVE_TEST_PATCH_BUDGETS)).get(path, 0) + if len(found) == budget: + return [] + if len(found) < budget: + return [ + ctx.fault_for( + path=ctx.path, + line=1, + column=0, + message=( + f"{len(found)} native patches, below the pending budget of {budget}; lower it" + ), + ) + ] + return [ctx.fault_for(path=ctx.path, line=line, column=0) for line in found[budget:]] diff --git a/tests/unit/scripts/fensu_policy/rules/_test_types.py b/tests/unit/scripts/fensu_policy/rules/_test_types.py index 414755318d..684e28318b 100644 --- a/tests/unit/scripts/fensu_policy/rules/_test_types.py +++ b/tests/unit/scripts/fensu_policy/rules/_test_types.py @@ -12,3 +12,18 @@ class CustomRuleTestCase: files: tuple[RuleFile, ...] = () scope: str = "root" scope_root: str | None = "src/sqlbuild" + + +@dataclass(frozen=True) +class NativeLinesTestCase: + description: str + source: str + expected_lines: tuple[int, ...] + + +@dataclass(frozen=True) +class NativePatchTestCase: + description: str + source: str + expected_fault_count: int + budgets: tuple[str, ...] = () diff --git a/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py b/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py new file mode 100644 index 0000000000..18ccab3e7c --- /dev/null +++ b/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py @@ -0,0 +1,187 @@ +from textwrap import dedent + +import pytest +from fensu import RuleCase, RuleResult, evaluate_rule + +from scripts.fensu_policy._helpers.native_crossings import crossing_lines, python_field_lines +from scripts.fensu_policy.rules.native_boundary import native_module_test_patch +from tests.unit.scripts.fensu_policy.rules._test_types import ( + NativeLinesTestCase, + NativePatchTestCase, +) + +TEST_PATH: str = "tests/unit/src/sqlbuild/example/test_example.py" + + +@pytest.mark.parametrize( + "test_case", + [ + NativePatchTestCase( + description="aliased native module patch faults", + source=dedent( + """ + import sqlbuild._native as native_module + + + def test_example(monkeypatch: object) -> None: + monkeypatch.setattr(native_module, "plan", None) + """ + ), + expected_fault_count=1, + ), + NativePatchTestCase( + description="from-imported native module patch faults", + source=dedent( + """ + from unittest import mock + + from sqlbuild import _native + + + def test_example() -> None: + with mock.patch.object(_native, "plan"): + pass + """ + ), + expected_fault_count=1, + ), + NativePatchTestCase( + description="string native patch target faults", + source=dedent( + """ + from unittest import mock + + + def test_example() -> None: + with mock.patch("sqlbuild._native.plan"): + pass + """ + ), + expected_fault_count=1, + ), + NativePatchTestCase( + description="patching another module passes", + source=dedent( + """ + import sqlbuild.executor.runtime as runtime_module + + + def test_example(monkeypatch: object) -> None: + monkeypatch.setattr(runtime_module, "run", None) + """ + ), + expected_fault_count=0, + ), + NativePatchTestCase( + description="budgeted native patch passes", + source=dedent( + """ + import sqlbuild._native as native_module + + + def test_example(monkeypatch: object) -> None: + monkeypatch.setattr(native_module, "plan", None) + """ + ), + expected_fault_count=0, + budgets=(f"{TEST_PATH}=1",), + ), + ], + ids=lambda case: case.description, +) +def test_given_test_module_when_checking_native_patches_then_matches_contract( + test_case: NativePatchTestCase, +) -> None: + result: RuleResult = evaluate_rule( + rule=native_module_test_patch, + test_case=RuleCase( + description=test_case.description, + source=test_case.source, + expected_fault_count=test_case.expected_fault_count, + path=TEST_PATH, + scope_root=None, + ), + rule_options={"pending_budgets": test_case.budgets}, + ) + + assert result.fault_count == test_case.expected_fault_count + + +@pytest.mark.parametrize( + "test_case", + [ + NativeLinesTestCase( + description="attribute reads, calls, imports and module strings count", + source=dedent( + """ + fn read(py: Python<'_>, value: &Bound<'_, PyAny>) -> PyResult<()> { + let name = value.getattr("name")?; + let _ = value.call_method1("get", ("x",))?; + let _ = imported(py, "pathlib", "Path")?.call1((name,))?; + let _ = py.import("sqlbuild.compiler")?; + Ok(()) + } + """ + ), + expected_lines=(3, 4, 5, 5, 6, 6), + ), + NativeLinesTestCase( + description="comments, imports and test modules are skipped", + source=dedent( + """ + use pyo3::types::PyAnyMethods; + // value.getattr("name") + fn read() {} + + #[cfg(test)] + mod tests { + fn probe(value: &Bound<'_, PyAny>) { let _ = value.getattr("x"); } + } + """ + ), + expected_lines=(), + ), + ], + ids=lambda case: case.description, +) +def test_given_rust_source_when_finding_crossings_then_reports_each_crossing( + test_case: NativeLinesTestCase, +) -> None: + assert tuple(crossing_lines(source=test_case.source)) == test_case.expected_lines + + +@pytest.mark.parametrize( + "test_case", + [ + NativeLinesTestCase( + description="Python-typed struct fields count and Rust fields do not", + source=dedent( + """ + pub(crate) struct Request<'py> { + pub(crate) project: Bound<'py, PyAny>, + pub(crate) options: Py, + pub(crate) name: String, + pub(crate) adapter: Option>, + } + """ + ), + expected_lines=(3, 4, 6), + ), + NativeLinesTestCase( + description="Python-typed function parameters do not count", + source=dedent( + """ + fn read(value: &Bound<'_, PyAny>) -> PyResult { + Ok(String::new()) + } + """ + ), + expected_lines=(), + ), + ], + ids=lambda case: case.description, +) +def test_given_rust_source_when_finding_python_fields_then_reports_struct_fields( + test_case: NativeLinesTestCase, +) -> None: + assert tuple(python_field_lines(source=test_case.source)) == test_case.expected_lines From e764a3762bbb7305eb4c5547d2cd3d9fd84123d9 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 05:27:01 +0100 Subject: [PATCH 02/19] refactor: read native pyclass getters directly when reading fields by name --- .../_helpers/analysis_session/session.rs | 2 +- .../build_progress/build_callbacks.rs | 2 +- .../compile_command/prepared_artifacts.rs | 2 +- .../compile_command/reuse_recording.rs | 6 +- .../compile_driver/diagnostic_collector.rs | 2 +- .../_helpers/compile_driver/input_reads.rs | 6 +- .../_helpers/compiled_project/audit_views.rs | 48 +- .../compiled_project/compiled_model_view.rs | 37 +- .../compiled_project/function_views.rs | 58 +- .../_helpers/compiled_project/inputs_view.rs | 56 +- .../compiled_project/model_input_view.rs | 40 +- .../_helpers/compiled_project/project_view.rs | 70 +- .../_helpers/compiled_project/seed_views.rs | 22 +- .../_helpers/compiled_project/source_views.rs | 18 +- .../bindings/_helpers/compute_logs/storage.rs | 2 +- .../bindings/_helpers/dbt_interop/graph.rs | 6 +- .../dbt_interop/reference_resolver.rs | 2 +- .../_helpers/discovery/model_file_record.rs | 26 +- .../bindings/_helpers/discovery/snapshot.rs | 4 +- .../_helpers/event_exporting/dispatcher.rs | 4 +- .../_helpers/event_exporting/models.rs | 52 +- .../_helpers/event_exporting/scope.rs | 12 +- .../_helpers/execution_history/postgres.rs | 2 +- .../_helpers/execution_history/sqlite.rs | 4 +- .../bindings/_helpers/graph/project_graph.rs | 16 +- .../_helpers/lineage/column_lineage_graph.rs | 4 +- .../_helpers/planner_migrations/mod.rs | 2 +- .../planner_migrations/state_inspection.rs | 8 +- .../src/bindings/_helpers/records/fields.rs | 3 + .../src/bindings/_helpers/records/getters.rs | 1137 +++++++++++++++++ .../src/bindings/_helpers/records/mod.rs | 1 + .../result_output/integration_envelope.rs | 4 +- .../bindings/_helpers/scopes/scope_index.rs | 4 +- 33 files changed, 1406 insertions(+), 256 deletions(-) create mode 100644 crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs index 836ef0433d..ae07bd9735 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs @@ -261,7 +261,7 @@ impl NativeModelAnalysisSession { /// `(shared members, shared members re-analysed alone)` as of the last step. #[getter] - fn sharing(&self) -> (usize, usize) { + pub(crate) fn sharing(&self) -> (usize, usize) { self.sharing } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs index 58cafc25bb..f0d8d137c0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs @@ -450,7 +450,7 @@ impl BuildProgressCallbacks { } #[getter] - fn elapsed(&self) -> f64 { + pub(crate) fn elapsed(&self) -> f64 { self.started.elapsed().as_secs_f64() } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs index c0251b1fef..02d45e76b4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs @@ -376,7 +376,7 @@ impl PreparedCompileArtifacts { } #[getter] - fn enabled(&self) -> bool { + pub(crate) fn enabled(&self) -> bool { self.enabled } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs index 5fb160c2eb..398090932a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs @@ -82,7 +82,7 @@ impl CompileArtifactWrites { impl CompileArtifactWrites { /// Every recorded artifact by absolute path, as `(digest, size, mtime_ns)`. #[getter] - fn artifacts<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn artifacts<'py>(&self, py: Python<'py>) -> PyResult> { let rows: Bound<'py, PyDict> = PyDict::new(py); for (path, artifact) in self.locked().iter() { match artifact { @@ -243,7 +243,7 @@ impl RecordedCompileOutput { } #[getter] - fn stderr_lines(&self, py: Python<'_>) -> Vec> { + pub(crate) fn stderr_lines(&self, py: Python<'_>) -> Vec> { self.locked() .0 .iter() @@ -252,7 +252,7 @@ impl RecordedCompileOutput { } #[getter] - fn stdout(&self, py: Python<'_>) -> Option> { + pub(crate) fn stdout(&self, py: Python<'_>) -> Option> { self.locked().1.as_ref().map(|text| text.clone_ref(py)) } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs index a4ce5df811..20363c150a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs @@ -69,7 +69,7 @@ impl CollectedCompileDiagnostics { /// The recorded diagnostics in deterministic key order. #[getter] - fn diagnostics<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn diagnostics<'py>(&self, py: Python<'py>) -> PyResult> { let by_key: &Bound<'py, PyDict> = self.by_key.bind(py); let keys: Bound<'py, PyAny> = imported(py, "builtins", "sorted")?.call1((by_key,))?; let diagnostics: Vec> = keys diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs index cc7bc8a336..ffe33a63f9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs @@ -169,13 +169,13 @@ impl CompileInputReads { /// The recorded environment variable names in sorted order. #[getter] - fn environment_names<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn environment_names<'py>(&self, py: Python<'py>) -> PyResult> { PyTuple::new(py, self.locked().environment_names.iter()) } /// The recorded settings classes in discovery order. #[getter] - fn settings_classes<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn settings_classes<'py>(&self, py: Python<'py>) -> PyResult> { let classes: Vec> = self .locked() .settings_classes @@ -187,7 +187,7 @@ impl CompileInputReads { /// Whether any template read the per-invocation run identity. #[getter] - fn read_run_id(&self) -> bool { + pub(crate) fn read_run_id(&self) -> bool { self.locked().read_run_id } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs index cd78b11337..2dd8c6585c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs @@ -130,28 +130,28 @@ macro_rules! audit_getters { $($extra)* #[getter] - fn audit_file(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn audit_file(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { Ok(audit.attached.audit_file.clone_ref(py)) }) } #[getter] - fn audit_block(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn audit_block(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { Ok(audit.attached.audit_block.clone_ref(py)) }) } #[getter] - fn sql_body(&self, py: Python<'_>) -> PyResult { + pub(crate) fn sql_body(&self, py: Python<'_>) -> PyResult { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit.attached.sql_body.clone()) }) } #[getter] - fn evaluation_mode(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn evaluation_mode(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { Ok(audit .attached @@ -163,7 +163,7 @@ macro_rules! audit_getters { } #[getter] - fn measurement_contract(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn measurement_contract(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { Ok(audit .attached @@ -175,21 +175,21 @@ macro_rules! audit_getters { } #[getter] - fn thresholds(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn thresholds(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { Ok(audit.attached.thresholds.clone_ref(py)) }) } #[getter] - fn minimum_samples(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn minimum_samples(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { Ok(audit.attached.minimum_samples.clone_ref(py)) }) } #[getter] - fn measure_sql(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn measure_sql(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit .attached @@ -199,21 +199,21 @@ macro_rules! audit_getters { } #[getter] - fn evidence_sql(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn evidence_sql(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit.attached.evidence_sql.clone()) }) } #[getter] - fn evidence_limit(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn evidence_limit(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { Ok(audit.attached.evidence_limit.clone_ref(py)) }) } #[getter] - fn references(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn references(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; read_audit(&self.owner, self.index, py, |audit, _| { reference_tuple(&classes, &audit.attached.references, &audit.references) @@ -221,7 +221,7 @@ macro_rules! audit_getters { } #[getter] - fn attached_target_kind<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn attached_target_kind<'py>(&self, py: Python<'py>) -> PyResult> { let classes: AuditClasses<'py> = audit_classes(&self.owner, py)?; read_audit(&self.owner, self.index, py, |audit, py| { match &audit.attached.target { @@ -239,7 +239,7 @@ macro_rules! audit_getters { } #[getter] - fn attached_column_name(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn attached_column_name(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit .attached @@ -250,7 +250,7 @@ macro_rules! audit_getters { } #[getter] - fn severity<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn severity<'py>(&self, py: Python<'py>) -> PyResult> { let classes: AuditClasses<'py> = audit_classes(&self.owner, py)?; read_audit(&self.owner, self.index, py, |audit, _| { classes.audit_severity.call1((audit.attached.severity,)) @@ -258,21 +258,21 @@ macro_rules! audit_getters { } #[getter] - fn run_scope(&self, py: Python<'_>) -> PyResult { + pub(crate) fn run_scope(&self, py: Python<'_>) -> PyResult { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit.attached.run_scope.clone()) }) } #[getter] - fn always_run(&self, py: Python<'_>) -> PyResult { + pub(crate) fn always_run(&self, py: Python<'_>) -> PyResult { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit.attached.always_run) }) } #[getter] - fn description(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn description(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit.attached.description.clone()) }) @@ -296,14 +296,14 @@ impl NativeAuditInput { audit_getters!(NativeAuditInput, { #[getter] - fn declaration_usages(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn declaration_usages(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { Ok(audit.attached.usages.clone_ref(py)) }) } #[getter] - fn name(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn name(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit.attached.name.clone()) }) @@ -311,7 +311,7 @@ audit_getters!(NativeAuditInput, { /// `(references as (kind, name, package), attached (kind, name))` for project assembly. #[getter] - fn assembly_row(&self, py: Python<'_>) -> PyResult { + pub(crate) fn assembly_row(&self, py: Python<'_>) -> PyResult { read_audit(&self.owner, self.index, py, |audit, _| { let attached: &AttachedAudit = &audit.attached; Ok(( @@ -345,7 +345,7 @@ impl NativeCompiledAudit { audit_getters!(NativeCompiledAudit, { /// The audit's planner-facing `CompiledObjectKey`. #[getter] - fn key(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn key(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; read_audit(&self.owner, self.index, py, |audit, py| { audit @@ -363,7 +363,7 @@ audit_getters!(NativeCompiledAudit, { /// The planner-facing keys of the resources the audit is selected with. #[getter] - fn scope_deps<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn scope_deps<'py>(&self, py: Python<'py>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; read_audit(&self.owner, self.index, py, |audit, py| { let deps: &[ObjectKeyRow] = audit @@ -379,14 +379,14 @@ audit_getters!(NativeCompiledAudit, { } #[getter] - fn name(&self, py: Python<'_>) -> PyResult { + pub(crate) fn name(&self, py: Python<'_>) -> PyResult { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit.attached.compiled_name().to_owned()) }) } #[getter] - fn definition_name(&self, py: Python<'_>) -> PyResult { + pub(crate) fn definition_name(&self, py: Python<'_>) -> PyResult { read_audit(&self.owner, self.index, py, |audit, _| { Ok(audit.attached.definition_name.clone()) }) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs index feba71426f..f013e99645 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs @@ -482,7 +482,7 @@ impl NativeCompiledModel { } #[getter] - fn deps(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn deps(&self, py: Python<'_>) -> PyResult> { self.compiled(py, |compiled, py| { compiled .projections @@ -538,14 +538,14 @@ impl NativeCompiledModel { } #[getter] - fn references(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn references(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.read(py, |record, _| references(&classes, record)) } /// Each reference as `(kind, name, package, call argument count)`. #[getter] - fn reference_rows(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn reference_rows(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, _| Ok(record.references.clone())) } @@ -573,7 +573,7 @@ impl NativeCompiledModel { /// `(database, schema, name)` of the model's destination. #[getter] - fn destination_row(&self, py: Python<'_>) -> PyResult { + pub(crate) fn destination_row(&self, py: Python<'_>) -> PyResult { self.compiled(py, |compiled, _| { let destination: &DestinationFact = self .overlay @@ -638,7 +638,7 @@ impl NativeCompiledModel { /// Inferred columns, else the attached schema's declared columns, else zero. #[getter] - fn output_column_count(&self, py: Python<'_>) -> PyResult { + pub(crate) fn output_column_count(&self, py: Python<'_>) -> PyResult { self.read(py, |record, py| { if let Some(rows) = &compiled_of(record)?.analysis.inferred { return Ok(rows.len()); @@ -651,13 +651,13 @@ impl NativeCompiledModel { } #[getter] - fn schema_entry(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn schema_entry(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.read(py, |record, _| schema_entry(&classes, record)) } #[getter] - fn inferred_columns(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn inferred_columns(&self, py: Python<'_>) -> PyResult> { self.compiled(py, |compiled, py| { self.projections .inferred_columns @@ -688,7 +688,7 @@ impl NativeCompiledModel { } #[getter] - fn fast_lineage_columns(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn fast_lineage_columns(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.compiled(py, |compiled, py| { compiled.analysis.lineage_object(py, &classes.compiled) @@ -711,22 +711,22 @@ impl NativeCompiledModel { } #[getter] - fn authored_query_sql(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn authored_query_sql(&self, py: Python<'_>) -> PyResult> { self.model_file_attribute(py, "query_sql") } #[getter] - fn output_column_locations(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn output_column_locations(&self, py: Python<'_>) -> PyResult> { self.model_file_attribute(py, "output_column_locations") } #[getter] - fn extract_implicit_alias_columns(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn extract_implicit_alias_columns(&self, py: Python<'_>) -> PyResult> { self.model_file_attribute(py, "extract_implicit_alias_columns") } #[getter] - fn macro_deps<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn macro_deps<'py>(&self, py: Python<'py>) -> PyResult> { self.compiled(py, |compiled, py| PyTuple::new(py, &compiled.macro_deps)) } @@ -743,12 +743,12 @@ impl NativeCompiledModel { } #[getter] - fn enum_columns(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn enum_columns(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(record.enum_columns.clone_ref(py))) } #[getter] - fn binding_diagnostics(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn binding_diagnostics(&self, py: Python<'_>) -> PyResult> { if let Some(diagnostics) = &self.overlay.binding_diagnostics { return Ok(diagnostics.clone_ref(py)); } @@ -768,7 +768,7 @@ impl NativeCompiledModel { } #[getter] - fn dynamic_column_contract(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn dynamic_column_contract(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.compiled(py, |compiled, py| { compiled.analysis.proof_object(py, &classes.compiled) @@ -776,12 +776,15 @@ impl NativeCompiledModel { } #[getter] - fn unchecked_output_columns<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn unchecked_output_columns<'py>( + &self, + py: Python<'py>, + ) -> PyResult> { PyFrozenSet::new(py, &self.overlay.poisoned) } #[getter] - fn rejected_sql_analysis_opt_out(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn rejected_sql_analysis_opt_out(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(rejected_opt_out(record, py))) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs index 9049e3ccfa..ca5bc2aeb9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs @@ -184,14 +184,14 @@ macro_rules! function_getters { $($extra)* #[getter] - fn name(&self, py: Python<'_>) -> PyResult { + pub(crate) fn name(&self, py: Python<'_>) -> PyResult { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.name.clone()) }) } #[getter] - fn arguments(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn arguments(&self, py: Python<'_>) -> PyResult> { let classes: FunctionClasses<'_> = function_classes(&self.owner, py)?; read_function(&self.owner, self.index, py, |function, _| { FunctionRecord::named_types( @@ -203,21 +203,21 @@ macro_rules! function_getters { } #[getter] - fn returns(&self, py: Python<'_>) -> PyResult { + pub(crate) fn returns(&self, py: Python<'_>) -> PyResult { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.returns.clone()) }) } #[getter] - fn body_sql(&self, py: Python<'_>) -> PyResult { + pub(crate) fn body_sql(&self, py: Python<'_>) -> PyResult { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.body.clone()) }) } #[getter] - fn return_columns(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn return_columns(&self, py: Python<'_>) -> PyResult> { let classes: FunctionClasses<'_> = function_classes(&self.owner, py)?; read_function(&self.owner, self.index, py, |function, _| { FunctionRecord::named_types( @@ -229,7 +229,7 @@ macro_rules! function_getters { } #[getter] - fn references(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn references(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; read_function(&self.owner, self.index, py, |function, _| { reference_tuple( @@ -241,7 +241,7 @@ macro_rules! function_getters { } #[getter] - fn language<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn language<'py>(&self, py: Python<'py>) -> PyResult> { let classes: FunctionClasses<'py> = function_classes(&self.owner, py)?; read_function(&self.owner, self.index, py, |function, _| { function.language(&classes) @@ -249,7 +249,7 @@ macro_rules! function_getters { } #[getter] - fn runtime_version(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn runtime_version(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function .attached @@ -260,7 +260,7 @@ macro_rules! function_getters { } #[getter] - fn entry_point(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn entry_point(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function .attached @@ -271,7 +271,7 @@ macro_rules! function_getters { } #[getter] - fn packages<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn packages<'py>(&self, py: Python<'py>) -> PyResult> { read_function(&self.owner, self.index, py, |function, py| { let packages: &[String] = function .attached @@ -283,14 +283,14 @@ macro_rules! function_getters { } #[getter] - fn tags<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn tags<'py>(&self, py: Python<'py>) -> PyResult> { read_function(&self.owner, self.index, py, |function, py| { PyTuple::new(py, &function.attached.tags) }) } #[getter] - fn description(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn description(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.description.clone()) }) @@ -314,56 +314,56 @@ impl NativeFunctionInput { function_getters!(NativeFunctionInput, { #[getter] - fn function_file(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn function_file(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, py| { Ok(function.attached.function_file.clone_ref(py)) }) } #[getter] - fn database(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn database(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.destination.database.clone()) }) } #[getter] - fn schema(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn schema(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.destination.schema.clone()) }) } #[getter] - fn logical_database(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn logical_database(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.destination.logical_database.clone()) }) } #[getter] - fn logical_schema(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn logical_schema(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.destination.logical_schema.clone()) }) } #[getter] - fn fingerprint_database(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn fingerprint_database(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.fingerprint_destination.database.clone()) }) } #[getter] - fn fingerprint_schema(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn fingerprint_schema(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function.attached.fingerprint_destination.schema.clone()) }) } #[getter] - fn fingerprint_logical_database(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn fingerprint_logical_database(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function .attached @@ -374,7 +374,7 @@ function_getters!(NativeFunctionInput, { } #[getter] - fn fingerprint_logical_schema(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn fingerprint_logical_schema(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, _| { Ok(function .attached @@ -385,7 +385,7 @@ function_getters!(NativeFunctionInput, { } #[getter] - fn declaration_usages(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn declaration_usages(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, py| { Ok(function.attached.usages.clone_ref(py)) }) @@ -393,7 +393,7 @@ function_getters!(NativeFunctionInput, { /// `(node type, name, tags, references)`, what project assembly resolves dependencies from. #[getter] - fn assembly_row(&self, py: Python<'_>) -> PyResult { + pub(crate) fn assembly_row(&self, py: Python<'_>) -> PyResult { read_function(&self.owner, self.index, py, |function, _| { let attached: &AttachedFunction = &function.attached; Ok(( @@ -476,7 +476,7 @@ impl NativeCompiledFunction { function_getters!(NativeCompiledFunction, { /// The function's planner-facing `CompiledObjectKey`. #[getter] - fn key(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn key(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; read_function(&self.owner, self.index, py, |function, py| { function @@ -494,7 +494,7 @@ function_getters!(NativeCompiledFunction, { /// The planner-facing keys of the resources the function reads. #[getter] - fn deps<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn deps<'py>(&self, py: Python<'py>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; read_function(&self.owner, self.index, py, |function, py| { let deps: &[ObjectKeyRow] = function @@ -510,7 +510,7 @@ function_getters!(NativeCompiledFunction, { } #[getter] - fn relative_path(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn relative_path(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, py| { Ok(native_field( function.attached.function_file.bind(py), @@ -521,7 +521,7 @@ function_getters!(NativeCompiledFunction, { } #[getter] - fn source_file_path(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn source_file_path(&self, py: Python<'_>) -> PyResult> { read_function(&self.owner, self.index, py, |function, py| { Ok(native_field( function.attached.function_file.bind(py), @@ -533,7 +533,7 @@ function_getters!(NativeCompiledFunction, { /// The function's planner-facing `CompiledRelationLocation`. #[getter] - fn destination(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn destination(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.destination .get_or_try_init(py, || { @@ -544,7 +544,7 @@ function_getters!(NativeCompiledFunction, { /// The destination the function's fingerprint reads. #[getter] - fn fingerprint_destination(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn fingerprint_destination(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.fingerprint_destination .get_or_try_init(py, || { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs index 0845ff43ef..9cfb2af044 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs @@ -230,92 +230,92 @@ impl NativeInputsView { } #[getter] - fn run_id(&self) -> String { + pub(crate) fn run_id(&self) -> String { self.fields.run_id.clone() } #[getter] - fn effective_target_name(&self) -> Option { + pub(crate) fn effective_target_name(&self) -> Option { self.fields.effective_target_name.clone() } #[getter(no_sql_validation)] - fn is_sql_validation_skipped(&self) -> bool { + pub(crate) fn is_sql_validation_skipped(&self) -> bool { self.fields.no_sql_validation } #[getter] - fn model_inputs(&self, py: Python<'_>) -> Py { + pub(crate) fn model_inputs(&self, py: Python<'_>) -> Py { self.fields.model_inputs.clone_ref(py) } #[getter] - fn native_project(&self, py: Python<'_>) -> Py { + pub(crate) fn native_project(&self, py: Python<'_>) -> Py { self.owner.clone_ref(py) } #[getter] - fn project_config(&self, py: Python<'_>) -> Py { + pub(crate) fn project_config(&self, py: Python<'_>) -> Py { self.fields.boundary.project_config.clone_ref(py) } #[getter] - fn local_config(&self, py: Python<'_>) -> Py { + pub(crate) fn local_config(&self, py: Python<'_>) -> Py { self.fields.boundary.local_config.clone_ref(py) } #[getter] - fn discovered_inputs(&self, py: Python<'_>) -> Py { + pub(crate) fn discovered_inputs(&self, py: Python<'_>) -> Py { self.fields.boundary.discovered_inputs.clone_ref(py) } #[getter] - fn sql_lexical_syntax(&self, py: Python<'_>) -> Py { + pub(crate) fn sql_lexical_syntax(&self, py: Python<'_>) -> Py { self.fields.boundary.sql_lexical_syntax.clone_ref(py) } #[getter] - fn effective_target(&self, py: Python<'_>) -> Py { + pub(crate) fn effective_target(&self, py: Python<'_>) -> Py { self.fields.boundary.effective_target.clone_ref(py) } #[getter] - fn compile_cache_dir(&self, py: Python<'_>) -> Py { + pub(crate) fn compile_cache_dir(&self, py: Python<'_>) -> Py { self.fields.boundary.compile_cache_dir.clone_ref(py) } #[getter] - fn effective_connection(&self, py: Python<'_>) -> Py { + pub(crate) fn effective_connection(&self, py: Python<'_>) -> Py { self.fields.boundary.effective_connection.clone_ref(py) } #[getter] - fn effective_vars(&self, py: Python<'_>) -> Py { + pub(crate) fn effective_vars(&self, py: Python<'_>) -> Py { self.fields.boundary.effective_vars.clone_ref(py) } #[getter] - fn macro_context(&self, py: Python<'_>) -> Py { + pub(crate) fn macro_context(&self, py: Python<'_>) -> Py { self.fields.boundary.macro_context.clone_ref(py) } #[getter] - fn loaded_macros(&self, py: Python<'_>) -> Py { + pub(crate) fn loaded_macros(&self, py: Python<'_>) -> Py { self.fields.boundary.loaded_macros.clone_ref(py) } #[getter] - fn public_enums(&self, py: Python<'_>) -> Py { + pub(crate) fn public_enums(&self, py: Python<'_>) -> Py { self.fields.boundary.public_enums.clone_ref(py) } #[getter] - fn public_constants(&self, py: Python<'_>) -> Py { + pub(crate) fn public_constants(&self, py: Python<'_>) -> Py { self.fields.boundary.public_constants.clone_ref(py) } #[getter] - fn external_sql_reference_resolver(&self, py: Python<'_>) -> Py { + pub(crate) fn external_sql_reference_resolver(&self, py: Python<'_>) -> Py { self.fields .boundary .external_sql_reference_resolver @@ -323,52 +323,52 @@ impl NativeInputsView { } #[getter] - fn effective_settings(&self, py: Python<'_>) -> Py { + pub(crate) fn effective_settings(&self, py: Python<'_>) -> Py { self.fields.compiler.effective_settings.clone_ref(py) } #[getter] - fn seed_inputs(&self, py: Python<'_>) -> Py { + pub(crate) fn seed_inputs(&self, py: Python<'_>) -> Py { self.fields.compiler.seed_inputs.clone_ref(py) } #[getter] - fn source_inputs(&self, py: Python<'_>) -> Py { + pub(crate) fn source_inputs(&self, py: Python<'_>) -> Py { self.fields.compiler.source_inputs.clone_ref(py) } #[getter] - fn sql_function_inputs(&self, py: Python<'_>) -> Py { + pub(crate) fn sql_function_inputs(&self, py: Python<'_>) -> Py { self.fields.compiler.sql_function_inputs.clone_ref(py) } #[getter] - fn test_inputs(&self, py: Python<'_>) -> Py { + pub(crate) fn test_inputs(&self, py: Python<'_>) -> Py { self.fields.compiler.test_inputs.clone_ref(py) } #[getter] - fn scenario_inputs(&self, py: Python<'_>) -> Py { + pub(crate) fn scenario_inputs(&self, py: Python<'_>) -> Py { self.fields.compiler.scenario_inputs.clone_ref(py) } #[getter] - fn audit_inputs(&self, py: Python<'_>) -> Py { + pub(crate) fn audit_inputs(&self, py: Python<'_>) -> Py { self.fields.compiler.audit_inputs.clone_ref(py) } #[getter] - fn diagnostics(&self, py: Python<'_>) -> Py { + pub(crate) fn diagnostics(&self, py: Python<'_>) -> Py { self.fields.compiler.diagnostics.clone_ref(py) } #[getter] - fn scope_index(&self, py: Python<'_>) -> Py { + pub(crate) fn scope_index(&self, py: Python<'_>) -> Py { self.fields.compiler.scope_index.clone_ref(py) } #[getter] - fn declaration_scope(&self, py: Python<'_>) -> Py { + pub(crate) fn declaration_scope(&self, py: Python<'_>) -> Py { self.fields.compiler.declaration_scope.clone_ref(py) } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs index 327d5a0fa0..c9b27dc42c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs @@ -165,46 +165,46 @@ pub(crate) fn view_classes<'py>( #[pymethods] impl NativeModelInput { #[getter] - fn model_file(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn model_file(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(record.model_file.clone_ref(py))) } #[getter] - fn config(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn config(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(record.config.clone_ref(py))) } #[getter] - fn query_sql(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn query_sql(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(record.query_sql.clone_ref(py))) } #[getter] - fn macro_source_sql(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn macro_source_sql(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(record.macro_source_sql.clone_ref(py))) } #[getter] - fn references(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn references(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.read(py, |record, _| references(&classes, record)) } #[getter] - fn schema_entry(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn schema_entry(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.read(py, |record, _| schema_entry(&classes, record)) } /// Each reference as `(kind, name, package, call argument count)`. #[getter] - fn reference_rows(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn reference_rows(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, _| Ok(record.references.clone())) } /// The model's declared key facts, for deriving its unique keys. #[getter] - fn relation_key_row(&self, py: Python<'_>) -> PyResult { + pub(crate) fn relation_key_row(&self, py: Python<'_>) -> PyResult { self.read_with_owner(py, |owner, record| { model_relation_key_row(owner, record, py) }) @@ -212,54 +212,54 @@ impl NativeModelInput { /// The name of the schema entry attached to the model, or `None`. #[getter] - fn attached_schema_name(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn attached_schema_name(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, _| Ok(attached_schema_name(record))) } #[getter] - fn schema_file(&self, py: Python<'_>) -> Py { + pub(crate) fn schema_file(&self, py: Python<'_>) -> Py { py.None() } #[getter] - fn sql_validation_enabled(&self, py: Python<'_>) -> PyResult { + pub(crate) fn sql_validation_enabled(&self, py: Python<'_>) -> PyResult { self.read(py, |record, _| Ok(record.sql_validation_enabled)) } #[getter] - fn rejected_sql_analysis_opt_out(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn rejected_sql_analysis_opt_out(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(rejected_opt_out(record, py))) } #[getter] - fn enum_declarations(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn enum_declarations(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(record.enum_declarations.clone_ref(py))) } #[getter] - fn constant_declarations(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn constant_declarations(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| { Ok(record.constant_declarations.clone_ref(py)) }) } #[getter] - fn enum_columns(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn enum_columns(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(record.enum_columns.clone_ref(py))) } #[getter] - fn macro_deps<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn macro_deps<'py>(&self, py: Python<'py>) -> PyResult> { self.read(py, |record, py| PyTuple::new(py, &record.macro_deps)) } #[getter] - fn macro_usages(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn macro_usages(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(record.macro_usages.clone_ref(py))) } #[getter] - fn declaration_usages(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn declaration_usages(&self, py: Python<'_>) -> PyResult> { self.read(py, |record, py| Ok(record.declaration_usages.clone_ref(py))) } @@ -281,14 +281,14 @@ impl NativeModelInput { /// The authored-to-expanded passes, when interpolation left the authored query unchanged. #[getter] - fn sql_expansion(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn sql_expansion(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.read(py, |record, _| authored_expansion(&classes, record)) } /// The whole expansion, variables included, which early SQL lint reuses. #[getter] - fn lint_expansion(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn lint_expansion(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.read(py, |record, py| { record diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs index 53b1b9adb0..846e81a8c6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs @@ -323,107 +323,107 @@ impl NativeProjectView { } #[getter] - fn run_id(&self) -> String { + pub(crate) fn run_id(&self) -> String { self.fields.run_id.clone() } #[getter] - fn effective_target_name(&self) -> Option { + pub(crate) fn effective_target_name(&self) -> Option { self.fields.effective_target_name.clone() } #[getter] - fn effective_target_database(&self) -> Option { + pub(crate) fn effective_target_database(&self) -> Option { self.fields.effective_target_database.clone() } #[getter] - fn effective_target_schema(&self) -> Option { + pub(crate) fn effective_target_schema(&self) -> Option { self.fields.effective_target_schema.clone() } #[getter] - fn sql_analysis_dialect(&self) -> Option { + pub(crate) fn sql_analysis_dialect(&self) -> Option { self.fields.sql_analysis_dialect.clone() } #[getter(enforce_explicit_references)] - fn is_explicit_reference_enforced(&self) -> bool { + pub(crate) fn is_explicit_reference_enforced(&self) -> bool { self.fields.enforce_explicit_references } #[getter] - fn models(&self, py: Python<'_>) -> Py { + pub(crate) fn models(&self, py: Python<'_>) -> Py { self.fields.models.clone_ref(py) } #[getter] - fn native_project(&self, py: Python<'_>) -> Py { + pub(crate) fn native_project(&self, py: Python<'_>) -> Py { self.owner.clone_ref(py) } #[getter] - fn effective_connection(&self, py: Python<'_>) -> Py { + pub(crate) fn effective_connection(&self, py: Python<'_>) -> Py { self.fields.boundary.effective_connection.clone_ref(py) } #[getter] - fn effective_vars(&self, py: Python<'_>) -> Py { + pub(crate) fn effective_vars(&self, py: Python<'_>) -> Py { self.fields.boundary.effective_vars.clone_ref(py) } #[getter] - fn binding_catalog(&self, py: Python<'_>) -> Py { + pub(crate) fn binding_catalog(&self, py: Python<'_>) -> Py { self.fields.boundary.binding_catalog.clone_ref(py) } #[getter] - fn sql_lexical_syntax(&self, py: Python<'_>) -> Py { + pub(crate) fn sql_lexical_syntax(&self, py: Python<'_>) -> Py { self.fields.boundary.sql_lexical_syntax.clone_ref(py) } #[getter] - fn compile_cache_dir(&self, py: Python<'_>) -> Py { + pub(crate) fn compile_cache_dir(&self, py: Python<'_>) -> Py { self.fields.boundary.compile_cache_dir.clone_ref(py) } #[getter] - fn loader_functions(&self, py: Python<'_>) -> Py { + pub(crate) fn loader_functions(&self, py: Python<'_>) -> Py { self.fields.boundary.loader_functions.clone_ref(py) } #[getter] - fn hook_functions(&self, py: Python<'_>) -> Py { + pub(crate) fn hook_functions(&self, py: Python<'_>) -> Py { self.fields.boundary.hook_functions.clone_ref(py) } #[getter] - fn sql_hook_files(&self, py: Python<'_>) -> Py { + pub(crate) fn sql_hook_files(&self, py: Python<'_>) -> Py { self.fields.boundary.sql_hook_files.clone_ref(py) } #[getter] - fn materialization_files(&self, py: Python<'_>) -> Py { + pub(crate) fn materialization_files(&self, py: Python<'_>) -> Py { self.fields.boundary.materialization_files.clone_ref(py) } #[getter] - fn public_enums(&self, py: Python<'_>) -> Py { + pub(crate) fn public_enums(&self, py: Python<'_>) -> Py { self.fields.boundary.public_enums.clone_ref(py) } #[getter] - fn public_constants(&self, py: Python<'_>) -> Py { + pub(crate) fn public_constants(&self, py: Python<'_>) -> Py { self.fields.boundary.public_constants.clone_ref(py) } #[getter] - fn loaded_macros(&self, py: Python<'_>) -> Py { + pub(crate) fn loaded_macros(&self, py: Python<'_>) -> Py { self.fields.boundary.loaded_macros.clone_ref(py) } #[getter] - fn external_sql_reference_resolver(&self, py: Python<'_>) -> Py { + pub(crate) fn external_sql_reference_resolver(&self, py: Python<'_>) -> Py { self.fields .boundary .external_sql_reference_resolver @@ -431,57 +431,57 @@ impl NativeProjectView { } #[getter] - fn native_session(&self, py: Python<'_>) -> Py { + pub(crate) fn native_session(&self, py: Python<'_>) -> Py { self.fields.boundary.native_session.clone_ref(py) } #[getter] - fn settings(&self, py: Python<'_>) -> Py { + pub(crate) fn settings(&self, py: Python<'_>) -> Py { self.fields.compiler.settings.clone_ref(py) } #[getter] - fn scenario(&self, py: Python<'_>) -> Py { + pub(crate) fn scenario(&self, py: Python<'_>) -> Py { self.fields.compiler.scenario.clone_ref(py) } #[getter] - fn sources(&self, py: Python<'_>) -> Py { + pub(crate) fn sources(&self, py: Python<'_>) -> Py { self.fields.compiler.sources.clone_ref(py) } #[getter] - fn seeds(&self, py: Python<'_>) -> Py { + pub(crate) fn seeds(&self, py: Python<'_>) -> Py { self.fields.compiler.seeds.clone_ref(py) } #[getter] - fn functions(&self, py: Python<'_>) -> Py { + pub(crate) fn functions(&self, py: Python<'_>) -> Py { self.fields.compiler.functions.clone_ref(py) } #[getter] - fn audits(&self, py: Python<'_>) -> Py { + pub(crate) fn audits(&self, py: Python<'_>) -> Py { self.fields.compiler.audits.clone_ref(py) } #[getter] - fn sql_tests(&self, py: Python<'_>) -> Py { + pub(crate) fn sql_tests(&self, py: Python<'_>) -> Py { self.fields.compiler.sql_tests.clone_ref(py) } #[getter] - fn sql_scenarios(&self, py: Python<'_>) -> Py { + pub(crate) fn sql_scenarios(&self, py: Python<'_>) -> Py { self.fields.compiler.sql_scenarios.clone_ref(py) } #[getter] - fn diagnostics(&self, py: Python<'_>) -> Py { + pub(crate) fn diagnostics(&self, py: Python<'_>) -> Py { self.fields.compiler.diagnostics.clone_ref(py) } #[getter] - fn unmatched_literal_sql_relations(&self, py: Python<'_>) -> Py { + pub(crate) fn unmatched_literal_sql_relations(&self, py: Python<'_>) -> Py { self.fields .compiler .unmatched_literal_sql_relations @@ -489,13 +489,13 @@ impl NativeProjectView { } #[getter] - fn scope_index(&self, py: Python<'_>) -> Py { + pub(crate) fn scope_index(&self, py: Python<'_>) -> Py { self.fields.compiler.scope_index.clone_ref(py) } /// Each model's authored-to-expanded passes by file path, where interpolation kept the query. #[getter] - fn sql_expansions(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn sql_expansions(&self, py: Python<'_>) -> PyResult> { self.sql_expansions .get_or_try_init(py, || { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; @@ -516,7 +516,7 @@ impl NativeProjectView { /// The lineage edges, tags, model folders and names, indexed natively once per project. #[getter] - fn lineage_graph(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn lineage_graph(&self, py: Python<'_>) -> PyResult> { self.lineage_graph .get_or_try_init(py, || { let mut rows: Vec = Vec::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs index 197bacdc21..4e775cf3cb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs @@ -153,21 +153,21 @@ impl NativeSeedInput { #[pymethods] impl NativeSeedInput { #[getter] - fn seed_file(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn seed_file(&self, py: Python<'_>) -> PyResult> { read_seed(&self.owner, self.index, py, |seed, py| { Ok(seed.seed_file.clone_ref(py)) }) } #[getter] - fn schema_entry(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn schema_entry(&self, py: Python<'_>) -> PyResult> { read_seed(&self.owner, self.index, py, |seed, py| { Ok(seed.schema_entry.clone_ref(py)) }) } #[getter] - fn schema_file(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn schema_file(&self, py: Python<'_>) -> PyResult> { read_seed(&self.owner, self.index, py, |seed, py| { Ok(seed.schema_file.clone_ref(py)) }) @@ -226,7 +226,7 @@ impl NativeCompiledSeed { impl NativeCompiledSeed { /// The seed's planner-facing `CompiledObjectKey`. #[getter] - fn key(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn key(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; read_seed(&self.owner, self.index, py, |seed, py| { seed.key @@ -238,31 +238,31 @@ impl NativeCompiledSeed { } #[getter] - fn deps<'py>(&self, py: Python<'py>) -> Bound<'py, PyTuple> { + pub(crate) fn deps<'py>(&self, py: Python<'py>) -> Bound<'py, PyTuple> { PyTuple::empty(py) } #[getter] - fn name(&self, py: Python<'_>) -> PyResult { + pub(crate) fn name(&self, py: Python<'_>) -> PyResult { read_seed(&self.owner, self.index, py, |seed, _| Ok(seed.name.clone())) } #[getter] - fn seed_file(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn seed_file(&self, py: Python<'_>) -> PyResult> { read_seed(&self.owner, self.index, py, |seed, py| { Ok(seed.seed_file.clone_ref(py)) }) } #[getter] - fn schema_entry(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn schema_entry(&self, py: Python<'_>) -> PyResult> { read_seed(&self.owner, self.index, py, |seed, py| { Ok(seed.schema_entry.clone_ref(py)) }) } #[getter] - fn schema_file(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn schema_file(&self, py: Python<'_>) -> PyResult> { read_seed(&self.owner, self.index, py, |seed, py| { Ok(seed.schema_file.clone_ref(py)) }) @@ -270,7 +270,7 @@ impl NativeCompiledSeed { /// The seed's planner-facing `CompiledRelationLocation`. #[getter] - fn destination(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn destination(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; self.destination .get_or_try_init(py, || { @@ -297,7 +297,7 @@ impl NativeCompiledSeed { } #[getter(external)] - fn is_external(&self) -> bool { + pub(crate) fn is_external(&self) -> bool { false } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs index d90df591db..59d85a8209 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs @@ -150,21 +150,21 @@ impl NativeSourceInput { #[pymethods] impl NativeSourceInput { #[getter] - fn source_entry(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn source_entry(&self, py: Python<'_>) -> PyResult> { read_source(&self.owner, self.index, py, |source, py| { source.attached_entry(py) }) } #[getter] - fn source_file(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn source_file(&self, py: Python<'_>) -> PyResult> { read_source(&self.owner, self.index, py, |source, py| { Ok(source.attached.source_file.clone_ref(py)) }) } #[getter] - fn declaration_usages(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn declaration_usages(&self, py: Python<'_>) -> PyResult> { read_source(&self.owner, self.index, py, |source, py| { Ok(source.attached.usages.clone_ref(py)) }) @@ -172,7 +172,7 @@ impl NativeSourceInput { /// `(name, has a loader, database, schema)`, what project assembly resolves a namespace from. #[getter] - fn assembly_row( + pub(crate) fn assembly_row( &self, py: Python<'_>, ) -> PyResult<(String, bool, Option, Option)> { @@ -217,7 +217,7 @@ impl NativeCompiledSource { impl NativeCompiledSource { /// The source's planner-facing `CompiledObjectKey`. #[getter] - fn key(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn key(&self, py: Python<'_>) -> PyResult> { let classes: InputViewClasses<'_> = view_classes(&self.owner, py)?; read_source(&self.owner, self.index, py, |source, py| { source @@ -230,26 +230,26 @@ impl NativeCompiledSource { } #[getter] - fn deps<'py>(&self, py: Python<'py>) -> Bound<'py, PyTuple> { + pub(crate) fn deps<'py>(&self, py: Python<'py>) -> Bound<'py, PyTuple> { PyTuple::empty(py) } #[getter] - fn name(&self, py: Python<'_>) -> PyResult { + pub(crate) fn name(&self, py: Python<'_>) -> PyResult { read_source(&self.owner, self.index, py, |source, _| { Ok(source.attached.name.clone()) }) } #[getter] - fn source_entry(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn source_entry(&self, py: Python<'_>) -> PyResult> { read_source(&self.owner, self.index, py, |source, py| { source.assembled_entry(py) }) } #[getter] - fn source_file(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn source_file(&self, py: Python<'_>) -> PyResult> { read_source(&self.owner, self.index, py, |source, py| { Ok(source.attached.source_file.clone_ref(py)) }) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs index 407cda8b7e..0a7f1c73ac 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs @@ -169,7 +169,7 @@ impl LocalFilesystemComputeLogStorage { /// Return the resolved configured log root. #[getter] - fn root<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn root<'py>(&self, py: Python<'py>) -> PyResult> { imported(py, "pathlib", "Path")?.call1((self.root.as_path(),)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs index 040dab6785..5a0da4985a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs @@ -67,7 +67,7 @@ impl DbtCombinedGraph { impl DbtCombinedGraph { /// Every node's stable ID. #[getter] - fn nodes<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn nodes<'py>(&self, py: Python<'py>) -> PyResult> { PyFrozenSet::new( py, self.graph.upstream.order.iter().map(|key| key.stable_id()), @@ -76,13 +76,13 @@ impl DbtCombinedGraph { /// Upstream edges by stable ID. #[getter] - fn upstream_deps<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn upstream_deps<'py>(&self, py: Python<'py>) -> PyResult> { stable_edges(py, &self.graph.upstream) } /// Downstream edges by stable ID. #[getter] - fn downstream_deps<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn downstream_deps<'py>(&self, py: Python<'py>) -> PyResult> { stable_edges(py, &self.graph.downstream) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs index 60b5e714f9..849fb98867 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs @@ -98,7 +98,7 @@ impl DbtCompileReferenceResolver { } #[getter(_dbt_manifest)] - fn dbt_manifest<'py>(&self, py: Python<'py>) -> Bound<'py, PyAny> { + pub(crate) fn dbt_manifest<'py>(&self, py: Python<'py>) -> Bound<'py, PyAny> { self.dbt_manifest.as_ref().map_or_else( || py.None().into_bound(py), |manifest| manifest.bind(py).clone(), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs index 5f2b073cee..8106673ec7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs @@ -257,52 +257,58 @@ impl NativeModelFile { } #[getter] - fn file_path(&self, py: Python<'_>) -> Py { + pub(crate) fn file_path(&self, py: Python<'_>) -> Py { self.file_path.clone_ref(py) } #[getter] - fn relative_path(&self, py: Python<'_>) -> Py { + pub(crate) fn relative_path(&self, py: Python<'_>) -> Py { self.relative_path.clone_ref(py) } #[getter] - fn contents(&self, py: Python<'_>) -> Py { + pub(crate) fn contents(&self, py: Python<'_>) -> Py { self.contents.clone_ref(py) } #[getter] - fn header_values(&self, py: Python<'_>) -> Py { + pub(crate) fn header_values(&self, py: Python<'_>) -> Py { self.header_values.clone_ref(py) } #[getter] - fn header_column_locations<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn header_column_locations<'py>( + &self, + py: Python<'py>, + ) -> PyResult> { self.header_locations(py) } #[getter] - fn output_column_locations<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn output_column_locations<'py>( + &self, + py: Python<'py>, + ) -> PyResult> { self.output_column_locations.dict(py, &self.relative_path) } #[getter] - fn query_sql(&self, py: Python<'_>) -> Py { + pub(crate) fn query_sql(&self, py: Python<'_>) -> Py { self.query_sql.clone_ref(py) } #[getter] - fn enum_declarations(&self, py: Python<'_>) -> Py { + pub(crate) fn enum_declarations(&self, py: Python<'_>) -> Py { self.enum_declarations.clone_ref(py) } #[getter] - fn constant_declarations(&self, py: Python<'_>) -> Py { + pub(crate) fn constant_declarations(&self, py: Python<'_>) -> Py { self.constant_declarations.clone_ref(py) } #[getter] - fn extract_implicit_alias_columns(&self) -> bool { + pub(crate) fn extract_implicit_alias_columns(&self) -> bool { self.extract_implicit_alias_columns } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/snapshot.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/snapshot.rs index 54668afd05..efa49d21c9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/snapshot.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/snapshot.rs @@ -116,13 +116,13 @@ pub(crate) fn snapshot_memo<'py>(project_dir: &Bound<'py, PyAny>) -> PyResult) -> Py { + pub(crate) fn project_dir(&self, py: Python<'_>) -> Py { self.project_dir.clone_ref(py) } /// The values the pass's native calls share. #[getter] - fn memo(&self, py: Python<'_>) -> Py { + pub(crate) fn memo(&self, py: Python<'_>) -> Py { self.memo.clone_ref(py) } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs index 87e2c5175d..51c55c94e3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs @@ -712,12 +712,12 @@ impl EventExporterDispatcher { } #[getter] - fn thread(&self, py: Python<'_>) -> Py { + pub(crate) fn thread(&self, py: Python<'_>) -> Py { self.thread.clone_ref(py) } #[getter] - fn notification_thread(&self, py: Python<'_>) -> Option> { + pub(crate) fn notification_thread(&self, py: Python<'_>) -> Option> { self.notification_thread .as_ref() .map(|thread| thread.clone_ref(py)) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/models.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/models.rs index bc12c285e0..9170225d62 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/models.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/models.rs @@ -57,27 +57,27 @@ pub(crate) struct BoundEventExporter { #[pymethods] impl EventExporterCounts { #[getter] - fn accepted(&self) -> u64 { + pub(crate) fn accepted(&self) -> u64 { self.counts.accepted } #[getter] - fn filtered(&self) -> u64 { + pub(crate) fn filtered(&self) -> u64 { self.counts.filtered } #[getter] - fn delivered(&self) -> u64 { + pub(crate) fn delivered(&self) -> u64 { self.counts.delivered } #[getter] - fn failed(&self) -> u64 { + pub(crate) fn failed(&self) -> u64 { self.counts.failed } #[getter] - fn dropped(&self) -> u64 { + pub(crate) fn dropped(&self) -> u64 { self.counts.dropped } @@ -89,12 +89,12 @@ impl EventExporterCounts { #[pymethods] impl EventExporterAccounting { #[getter] - fn exporter_name(&self) -> &str { + pub(crate) fn exporter_name(&self) -> &str { &self.exporter_name } #[getter] - fn counts(&self) -> EventExporterCounts { + pub(crate) fn counts(&self) -> EventExporterCounts { EventExporterCounts { counts: self.counts, } @@ -108,14 +108,14 @@ impl EventExporterAccounting { #[pymethods] impl EventExportSummary { #[getter] - fn aggregate(&self) -> EventExporterCounts { + pub(crate) fn aggregate(&self) -> EventExporterCounts { EventExporterCounts { counts: self.snapshot.aggregate, } } #[getter] - fn per_exporter<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn per_exporter<'py>(&self, py: Python<'py>) -> PyResult> { let items: Vec = self .snapshot .per_exporter @@ -129,42 +129,42 @@ impl EventExportSummary { } #[getter] - fn queue_depth(&self) -> usize { + pub(crate) fn queue_depth(&self) -> usize { self.snapshot.queue_depth } #[getter] - fn queue_capacity(&self) -> usize { + pub(crate) fn queue_capacity(&self) -> usize { self.snapshot.queue_capacity } #[getter] - fn flush_complete(&self) -> bool { + pub(crate) fn flush_complete(&self) -> bool { self.snapshot.flush_complete } #[getter] - fn accepted(&self) -> u64 { + pub(crate) fn accepted(&self) -> u64 { self.snapshot.aggregate.accepted } #[getter] - fn filtered(&self) -> u64 { + pub(crate) fn filtered(&self) -> u64 { self.snapshot.aggregate.filtered } #[getter] - fn delivered(&self) -> u64 { + pub(crate) fn delivered(&self) -> u64 { self.snapshot.aggregate.delivered } #[getter] - fn failed(&self) -> u64 { + pub(crate) fn failed(&self) -> u64 { self.snapshot.aggregate.failed } #[getter] - fn dropped(&self) -> u64 { + pub(crate) fn dropped(&self) -> u64 { self.snapshot.aggregate.dropped } @@ -197,22 +197,22 @@ impl EventExportSummary { #[pymethods] impl EventExporterFailure { #[getter] - fn exporter_name(&self) -> &str { + pub(crate) fn exporter_name(&self) -> &str { &self.exporter_name } #[getter] - fn error_type(&self) -> &str { + pub(crate) fn error_type(&self) -> &str { &self.error_type } #[getter] - fn event_kind(&self) -> &str { + pub(crate) fn event_kind(&self) -> &str { &self.event_kind } #[getter] - fn event_severity<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn event_severity<'py>(&self, py: Python<'py>) -> PyResult> { severity_object(py, self.event_severity) } @@ -254,27 +254,27 @@ impl BoundEventExporter { } #[getter] - fn name(&self) -> &str { + pub(crate) fn name(&self) -> &str { &self.name } #[getter] - fn function(&self, py: Python<'_>) -> Py { + pub(crate) fn function(&self, py: Python<'_>) -> Py { self.function.clone_ref(py) } #[getter] - fn provider_arguments(&self, py: Python<'_>) -> Py { + pub(crate) fn provider_arguments(&self, py: Python<'_>) -> Py { self.provider_arguments.clone_ref(py) } #[getter] - fn event_kinds<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn event_kinds<'py>(&self, py: Python<'py>) -> PyResult> { PyFrozenSet::new(py, self.filter.event_kinds.iter()) } #[getter] - fn min_severity<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn min_severity<'py>(&self, py: Python<'py>) -> PyResult> { severity_object(py, self.filter.min_severity) } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs index be96283bf9..c8b7a81b3d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs @@ -218,22 +218,22 @@ impl EventExporterCommandScope { } #[getter] - fn dispatcher(&self, py: Python<'_>) -> Py { + pub(crate) fn dispatcher(&self, py: Python<'_>) -> Py { self.dispatcher.clone_ref(py) } #[getter] - fn provider_session(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn provider_session(&self, py: Python<'_>) -> PyResult> { Ok(optional(py, self.locked()?.provider_session.as_ref())) } #[getter] - fn project_dir(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn project_dir(&self, py: Python<'_>) -> PyResult> { Ok(optional(py, self.locked()?.project_dir.as_ref())) } #[getter] - fn providers(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn providers(&self, py: Python<'_>) -> PyResult> { let state = self.locked()?; Ok(state .providers @@ -242,7 +242,7 @@ impl EventExporterCommandScope { } #[getter] - fn event_exporters(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn event_exporters(&self, py: Python<'_>) -> PyResult> { let state = self.locked()?; Ok(state .event_exporters @@ -251,7 +251,7 @@ impl EventExporterCommandScope { } #[getter] - fn command_output_sinks(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn command_output_sinks(&self, py: Python<'_>) -> PyResult> { let state = self.locked()?; Ok(state .command_output_sinks diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs index b32426de73..80a83d040c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs @@ -585,7 +585,7 @@ impl PostgresExecutionHistory { /// The number of incremental projection calls. #[getter] - fn project_calls(&self) -> i64 { + pub(crate) fn project_calls(&self) -> i64 { self.project_calls.load(Ordering::SeqCst) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs index b7717fc98c..b5963128f7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs @@ -552,7 +552,7 @@ impl SqliteExecutionHistory { /// The database path, or `None` for an in-memory database. #[getter] - fn path<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn path<'py>(&self, py: Python<'py>) -> PyResult> { let path: &str = self.database_path(); if path == MEMORY_PATH { return Ok(py.None().into_bound(py)); @@ -562,7 +562,7 @@ impl SqliteExecutionHistory { /// The number of incremental projection calls. #[getter] - fn project_calls(&self) -> i64 { + pub(crate) fn project_calls(&self) -> i64 { self.project_calls.load(Ordering::SeqCst) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs index 80be21806a..6a951e4a9b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs @@ -117,18 +117,18 @@ impl CompiledProjectGraph { } #[getter(project)] - fn project_attribute(&self, py: Python<'_>) -> Py { + pub(crate) fn project_attribute(&self, py: Python<'_>) -> Py { self.project.clone_ref(py) } #[getter(native)] - fn native_attribute(&self, py: Python<'_>) -> Py { + pub(crate) fn native_attribute(&self, py: Python<'_>) -> Py { self.native.clone_ref(py) } /// Lineage edges and selector indexes, converted once. #[getter] - fn lineage_views(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn lineage_views(&self, py: Python<'_>) -> PyResult> { self.views .get_or_try_init(py, || { Ok(lineage_graph_views(py, self.native.bind(py).borrow())?.unbind()) @@ -137,27 +137,27 @@ impl CompiledProjectGraph { } #[getter] - fn upstream_deps(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn upstream_deps(&self, py: Python<'_>) -> PyResult> { self.view(py, "upstream_deps") } #[getter] - fn downstream_deps(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn downstream_deps(&self, py: Python<'_>) -> PyResult> { self.view(py, "downstream_deps") } #[getter] - fn tag_index(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn tag_index(&self, py: Python<'_>) -> PyResult> { self.view(py, "tag_index") } #[getter] - fn path_index(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn path_index(&self, py: Python<'_>) -> PyResult> { self.view(py, "path_index") } #[getter] - fn all_keys(&self, py: Python<'_>) -> PyResult> { + pub(crate) fn all_keys(&self, py: Python<'_>) -> PyResult> { self.view(py, "all_keys") } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs index 2bea132814..6afa1bafe9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs @@ -131,7 +131,7 @@ impl ProjectColumnLineage { /// Return model lineage, expanding compact model facts on first access. #[getter] - fn models(mut slf: PyRefMut<'_, Self>) -> PyResult> { + pub(crate) fn models(mut slf: PyRefMut<'_, Self>) -> PyResult> { let py: Python<'_> = slf.py(); if !slf.compact.is_empty() { let classes: LineageClasses<'_> = LineageClasses::new(py)?; @@ -154,7 +154,7 @@ impl ProjectColumnLineage { /// Return all graph edges, expanding compact edge records on first access. #[getter] - fn edges(mut slf: PyRefMut<'_, Self>) -> PyResult> { + pub(crate) fn edges(mut slf: PyRefMut<'_, Self>) -> PyResult> { let py: Python<'_> = slf.py(); if let Some(edges) = &slf.edges { return Ok(edges.clone_ref(py)); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/mod.rs index 9b2da1d432..9d72a99976 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/mod.rs @@ -31,4 +31,4 @@ mod planning_execution; mod planning_origin; pub(crate) mod projections; pub(crate) mod registration; -mod state_inspection; +pub(crate) mod state_inspection; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs index ebbc7073c1..6e2c14a385 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs @@ -255,25 +255,25 @@ impl MigrationStateInspection { /// The database whose namespaces this inspection reads. #[getter] - fn database(&self, py: Python<'_>) -> Py { + pub(crate) fn database(&self, py: Python<'_>) -> Py { self.database.clone_ref(py) } /// Every migration event read so far. #[getter] - fn events<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn events<'py>(&self, py: Python<'py>) -> PyResult> { tuple_of(py, &self.events) } /// Every column migration event read so far. #[getter] - fn column_events<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn column_events<'py>(&self, py: Python<'py>) -> PyResult> { tuple_of(py, &self.column_events) } /// The old-name history of every move read by `inspect_old_name_views`. #[getter] - fn old_name_histories<'py>(&self, py: Python<'py>) -> PyResult> { + pub(crate) fn old_name_histories<'py>(&self, py: Python<'py>) -> PyResult> { old_name_views( tuple_of(py, &self.old_name_moves)?.as_any(), tuple_of(py, &self.old_name_facts)?.as_any(), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs index b722ead7da..08b333423b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs @@ -17,6 +17,7 @@ use crate::bindings::_helpers::records::constants::{ FROZEN_INSTANCE_ERROR, ORDERED_RECORDS, RECORD_FINISHERS, RECORD_SPEC_ATTRIBUTE, RECORDS, }; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; +use crate::bindings::_helpers::records::getters::getter_field; use crate::bindings::_helpers::records::models::{FieldDefault, NativeRecord, RecordSpec}; /// Every registered record spec, in registration order. @@ -51,6 +52,8 @@ pub(crate) fn field<'py>(value: &Bound<'py, PyAny>, name: &str) -> PyResult fn(&Bound<'py, PyAny>, &str) -> Option>>; + +static DISPATCH: PyOnceLock> = PyOnceLock::new(); + +/// The `#[getter]` `name` of a native pyclass instance read in Rust, or `None` when not generated here. +pub(crate) fn getter_field<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let table: &HashMap = DISPATCH.get_or_init(py, || { + let mut table: HashMap = HashMap::new(); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_model_analysis_session, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_build_progress_callbacks, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_prepared_compile_artifacts, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_compile_artifact_writes, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_recorded_compile_output, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_collected_compile_diagnostics, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_compile_input_reads, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_compiled_model, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_inputs_view, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_model_input, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_project_view, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_compiled_seed, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_seed_input, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_compiled_source, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_source_input, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_local_filesystem_compute_log_storage, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_dbt_combined_graph, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_dbt_compile_reference_resolver, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_model_file, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_directory_snapshot, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_event_exporter_dispatcher, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_bound_event_exporter, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_event_export_summary, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_event_exporter_accounting, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_event_exporter_counts, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_event_exporter_failure, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_event_exporter_command_scope, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_postgres_execution_history, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_sqlite_execution_history, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_compiled_project_graph, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_migration_state_inspection, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_integration_result_envelope, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_scope_index, + ); + table + }); + let dispatch: &Dispatch = table.get(&(value.get_type().as_ptr() as usize))?; + dispatch(value, name) +} + +fn read_native_model_analysis_session<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "fact_models" => this.fact_models().into_bound_py_any(py), + "cache_stats" => this.cache_stats().into_bound_py_any(py), + "sharing" => this.sharing().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_build_progress_callbacks<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "elapsed" => this.elapsed().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_prepared_compile_artifacts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "enabled" => this.enabled().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_compile_artifact_writes<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "artifacts" => this + .artifacts(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_recorded_compile_output<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "stderr_lines" => this.stderr_lines(py).into_bound_py_any(py), + "stdout" => this.stdout(py).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_collected_compile_diagnostics<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "diagnostics" => this + .diagnostics(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_compile_input_reads<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "environment_names" => this + .environment_names(py) + .and_then(|value| value.into_bound_py_any(py)), + "settings_classes" => this + .settings_classes(py) + .and_then(|value| value.into_bound_py_any(py)), + "read_run_id" => this.read_run_id().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_compiled_model<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "relative_path" => this + .relative_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "query_sql" => this + .query_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "config" => this + .config(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination" => this + .destination(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "reference_rows" => this + .reference_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "relation_key_row" => this + .relation_key_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "key_row" => this + .key_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "dep_rows" => this + .dep_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination_row" => this + .destination_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "inferred_rows" => this + .inferred_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_column_rows" => this + .schema_column_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "has_dynamic_columns" => this + .dynamic_columns_declared(py) + .and_then(|value| value.into_bound_py_any(py)), + "output_column_count" => this + .output_column_count(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "inferred_columns" => this + .inferred_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "fast_lineage_columns" => this + .fast_lineage_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "fast_lineage_has_star" => this + .fast_lineage_has_star(py) + .and_then(|value| value.into_bound_py_any(py)), + "fast_lineage_star_resolved" => this + .fast_lineage_star_resolved(py) + .and_then(|value| value.into_bound_py_any(py)), + "authored_sql" => this + .authored_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "authored_query_sql" => this + .authored_query_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "output_column_locations" => this + .output_column_locations(py) + .and_then(|value| value.into_bound_py_any(py)), + "extract_implicit_alias_columns" => this + .extract_implicit_alias_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_deps" => this + .macro_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_declarations" => this + .enum_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "constant_declarations" => this + .constant_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_columns" => this + .enum_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "binding_diagnostics" => this + .binding_diagnostics(py) + .and_then(|value| value.into_bound_py_any(py)), + "binding_validated" => this + .binding_validated(py) + .and_then(|value| value.into_bound_py_any(py)), + "dynamic_column_contract" => this + .dynamic_column_contract(py) + .and_then(|value| value.into_bound_py_any(py)), + "unchecked_output_columns" => this + .unchecked_output_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "rejected_sql_analysis_opt_out" => this + .rejected_sql_analysis_opt_out(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_inputs_view<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "run_id" => this.run_id().into_bound_py_any(py), + "effective_target_name" => this.effective_target_name().into_bound_py_any(py), + "no_sql_validation" => this.is_sql_validation_skipped().into_bound_py_any(py), + "model_inputs" => this.model_inputs(py).into_bound_py_any(py), + "native_project" => this.native_project(py).into_bound_py_any(py), + "project_config" => this.project_config(py).into_bound_py_any(py), + "local_config" => this.local_config(py).into_bound_py_any(py), + "discovered_inputs" => this.discovered_inputs(py).into_bound_py_any(py), + "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), + "effective_target" => this.effective_target(py).into_bound_py_any(py), + "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), + "effective_connection" => this.effective_connection(py).into_bound_py_any(py), + "effective_vars" => this.effective_vars(py).into_bound_py_any(py), + "macro_context" => this.macro_context(py).into_bound_py_any(py), + "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), + "public_enums" => this.public_enums(py).into_bound_py_any(py), + "public_constants" => this.public_constants(py).into_bound_py_any(py), + "external_sql_reference_resolver" => this + .external_sql_reference_resolver(py) + .into_bound_py_any(py), + "effective_settings" => this.effective_settings(py).into_bound_py_any(py), + "seed_inputs" => this.seed_inputs(py).into_bound_py_any(py), + "source_inputs" => this.source_inputs(py).into_bound_py_any(py), + "sql_function_inputs" => this.sql_function_inputs(py).into_bound_py_any(py), + "test_inputs" => this.test_inputs(py).into_bound_py_any(py), + "scenario_inputs" => this.scenario_inputs(py).into_bound_py_any(py), + "audit_inputs" => this.audit_inputs(py).into_bound_py_any(py), + "diagnostics" => this.diagnostics(py).into_bound_py_any(py), + "scope_index" => this.scope_index(py).into_bound_py_any(py), + "declaration_scope" => this.declaration_scope(py).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_model_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "model_file" => this + .model_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "config" => this + .config(py) + .and_then(|value| value.into_bound_py_any(py)), + "query_sql" => this + .query_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_source_sql" => this + .macro_source_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "reference_rows" => this + .reference_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "relation_key_row" => this + .relation_key_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_schema_name" => this + .attached_schema_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_file" => this.schema_file(py).into_bound_py_any(py), + "sql_validation_enabled" => this + .sql_validation_enabled(py) + .and_then(|value| value.into_bound_py_any(py)), + "rejected_sql_analysis_opt_out" => this + .rejected_sql_analysis_opt_out(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_declarations" => this + .enum_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "constant_declarations" => this + .constant_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_columns" => this + .enum_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_deps" => this + .macro_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_usages" => this + .macro_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "sql_expansion" => this + .sql_expansion(py) + .and_then(|value| value.into_bound_py_any(py)), + "lint_expansion" => this + .lint_expansion(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_project_view<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "run_id" => this.run_id().into_bound_py_any(py), + "effective_target_name" => this.effective_target_name().into_bound_py_any(py), + "effective_target_database" => this.effective_target_database().into_bound_py_any(py), + "effective_target_schema" => this.effective_target_schema().into_bound_py_any(py), + "sql_analysis_dialect" => this.sql_analysis_dialect().into_bound_py_any(py), + "enforce_explicit_references" => { + this.is_explicit_reference_enforced().into_bound_py_any(py) + } + "models" => this.models(py).into_bound_py_any(py), + "native_project" => this.native_project(py).into_bound_py_any(py), + "effective_connection" => this.effective_connection(py).into_bound_py_any(py), + "effective_vars" => this.effective_vars(py).into_bound_py_any(py), + "binding_catalog" => this.binding_catalog(py).into_bound_py_any(py), + "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), + "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), + "loader_functions" => this.loader_functions(py).into_bound_py_any(py), + "hook_functions" => this.hook_functions(py).into_bound_py_any(py), + "sql_hook_files" => this.sql_hook_files(py).into_bound_py_any(py), + "materialization_files" => this.materialization_files(py).into_bound_py_any(py), + "public_enums" => this.public_enums(py).into_bound_py_any(py), + "public_constants" => this.public_constants(py).into_bound_py_any(py), + "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), + "external_sql_reference_resolver" => this + .external_sql_reference_resolver(py) + .into_bound_py_any(py), + "native_session" => this.native_session(py).into_bound_py_any(py), + "settings" => this.settings(py).into_bound_py_any(py), + "scenario" => this.scenario(py).into_bound_py_any(py), + "sources" => this.sources(py).into_bound_py_any(py), + "seeds" => this.seeds(py).into_bound_py_any(py), + "functions" => this.functions(py).into_bound_py_any(py), + "audits" => this.audits(py).into_bound_py_any(py), + "sql_tests" => this.sql_tests(py).into_bound_py_any(py), + "sql_scenarios" => this.sql_scenarios(py).into_bound_py_any(py), + "diagnostics" => this.diagnostics(py).into_bound_py_any(py), + "unmatched_literal_sql_relations" => this + .unmatched_literal_sql_relations(py) + .into_bound_py_any(py), + "scope_index" => this.scope_index(py).into_bound_py_any(py), + "sql_expansions" => this + .sql_expansions(py) + .and_then(|value| value.into_bound_py_any(py)), + "lineage_graph" => this + .lineage_graph(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_compiled_seed<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).into_bound_py_any(py), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "seed_file" => this + .seed_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_file" => this + .schema_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination" => this + .destination(py) + .and_then(|value| value.into_bound_py_any(py)), + "external" => this.is_external().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_seed_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "seed_file" => this + .seed_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_file" => this + .schema_file(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_compiled_source<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).into_bound_py_any(py), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "source_entry" => this + .source_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "source_file" => this + .source_file(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_source_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "source_entry" => this + .source_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "source_file" => this + .source_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "assembly_row" => this + .assembly_row(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_local_filesystem_compute_log_storage<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "root" => this.root(py).and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_dbt_combined_graph<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "nodes" => this.nodes(py).and_then(|value| value.into_bound_py_any(py)), + "upstream_deps" => this + .upstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "downstream_deps" => this + .downstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_dbt_compile_reference_resolver<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "_dbt_manifest" => this.dbt_manifest(py).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_model_file<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "file_path" => this.file_path(py).into_bound_py_any(py), + "relative_path" => this.relative_path(py).into_bound_py_any(py), + "contents" => this.contents(py).into_bound_py_any(py), + "header_values" => this.header_values(py).into_bound_py_any(py), + "header_column_locations" => this + .header_column_locations(py) + .and_then(|value| value.into_bound_py_any(py)), + "output_column_locations" => this + .output_column_locations(py) + .and_then(|value| value.into_bound_py_any(py)), + "query_sql" => this.query_sql(py).into_bound_py_any(py), + "enum_declarations" => this.enum_declarations(py).into_bound_py_any(py), + "constant_declarations" => this.constant_declarations(py).into_bound_py_any(py), + "extract_implicit_alias_columns" => { + this.extract_implicit_alias_columns().into_bound_py_any(py) + } + _ => return None, + }) +} + +fn read_native_directory_snapshot<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project_dir" => this.project_dir(py).into_bound_py_any(py), + "memo" => this.memo(py).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_event_exporter_dispatcher<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "thread" => this.thread(py).into_bound_py_any(py), + "notification_thread" => this.notification_thread(py).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_bound_event_exporter<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "name" => this.name().into_bound_py_any(py), + "function" => this.function(py).into_bound_py_any(py), + "provider_arguments" => this.provider_arguments(py).into_bound_py_any(py), + "event_kinds" => this + .event_kinds(py) + .and_then(|value| value.into_bound_py_any(py)), + "min_severity" => this + .min_severity(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_event_export_summary<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "aggregate" => this.aggregate().into_bound_py_any(py), + "per_exporter" => this + .per_exporter(py) + .and_then(|value| value.into_bound_py_any(py)), + "queue_depth" => this.queue_depth().into_bound_py_any(py), + "queue_capacity" => this.queue_capacity().into_bound_py_any(py), + "flush_complete" => this.flush_complete().into_bound_py_any(py), + "accepted" => this.accepted().into_bound_py_any(py), + "filtered" => this.filtered().into_bound_py_any(py), + "delivered" => this.delivered().into_bound_py_any(py), + "failed" => this.failed().into_bound_py_any(py), + "dropped" => this.dropped().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_event_exporter_accounting<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "exporter_name" => this.exporter_name().into_bound_py_any(py), + "counts" => this.counts().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_event_exporter_counts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "accepted" => this.accepted().into_bound_py_any(py), + "filtered" => this.filtered().into_bound_py_any(py), + "delivered" => this.delivered().into_bound_py_any(py), + "failed" => this.failed().into_bound_py_any(py), + "dropped" => this.dropped().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_event_exporter_failure<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "exporter_name" => this.exporter_name().into_bound_py_any(py), + "error_type" => this.error_type().into_bound_py_any(py), + "event_kind" => this.event_kind().into_bound_py_any(py), + "event_severity" => this + .event_severity(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_event_exporter_command_scope<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "dispatcher" => this.dispatcher(py).into_bound_py_any(py), + "provider_session" => this + .provider_session(py) + .and_then(|value| value.into_bound_py_any(py)), + "project_dir" => this + .project_dir(py) + .and_then(|value| value.into_bound_py_any(py)), + "providers" => this + .providers(py) + .and_then(|value| value.into_bound_py_any(py)), + "event_exporters" => this + .event_exporters(py) + .and_then(|value| value.into_bound_py_any(py)), + "command_output_sinks" => this + .command_output_sinks(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_postgres_execution_history<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project_calls" => this.project_calls().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_sqlite_execution_history<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "path" => this.path(py).and_then(|value| value.into_bound_py_any(py)), + "project_calls" => this.project_calls().into_bound_py_any(py), + _ => return None, + }) +} + +fn read_compiled_project_graph<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project" => this.project_attribute(py).into_bound_py_any(py), + "native" => this.native_attribute(py).into_bound_py_any(py), + "lineage_views" => this + .lineage_views(py) + .and_then(|value| value.into_bound_py_any(py)), + "upstream_deps" => this + .upstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "downstream_deps" => this + .downstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "tag_index" => this + .tag_index(py) + .and_then(|value| value.into_bound_py_any(py)), + "path_index" => this + .path_index(py) + .and_then(|value| value.into_bound_py_any(py)), + "all_keys" => this + .all_keys(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_migration_state_inspection<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "database" => this.database(py).into_bound_py_any(py), + "events" => this + .events(py) + .and_then(|value| value.into_bound_py_any(py)), + "column_events" => this + .column_events(py) + .and_then(|value| value.into_bound_py_any(py)), + "old_name_histories" => this + .old_name_histories(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_integration_result_envelope<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "asset" => this.asset(py).into_bound_py_any(py), + "checks" => this.checks(py).into_bound_py_any(py), + _ => return None, + }) +} + +fn read_native_scope_index<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "index" => this.index(py).into_bound_py_any(py), + "has_scoped_relationship_declarations" => this + .has_scoped_relationship_declarations() + .into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs index ea4f36f1a0..0fe9d05585 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs @@ -2,6 +2,7 @@ pub(crate) mod constants; pub(crate) mod construct; pub(crate) mod error_classes; pub(crate) mod fields; +pub(crate) mod getters; pub(crate) mod ids; pub(crate) mod models; pub(crate) mod registration; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs index 3c0b433103..984d750c31 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs @@ -173,12 +173,12 @@ impl IntegrationResultEnvelope { } #[getter] - fn asset(&self, py: Python<'_>) -> Option> { + pub(crate) fn asset(&self, py: Python<'_>) -> Option> { self.asset.as_ref().map(|asset| asset.clone_ref(py)) } #[getter] - fn checks(&self, py: Python<'_>) -> Py { + pub(crate) fn checks(&self, py: Python<'_>) -> Py { self.checks.clone_ref(py) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs index 372ecbce62..751bae85e8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs @@ -821,13 +821,13 @@ fn scenario_row(scenario: &Bound<'_, PyAny>) -> PyResult { impl NativeScopeIndex { /// The static index, without grants. #[getter] - fn index(&self, py: Python<'_>) -> Py { + pub(crate) fn index(&self, py: Python<'_>) -> Py { self.index.clone_ref(py) } /// Whether any macro, enum or constant is scoped, which makes relationship grants matter. #[getter] - fn has_scoped_relationship_declarations(&self) -> bool { + pub(crate) fn has_scoped_relationship_declarations(&self) -> bool { self.native.has_scoped_relationship_declarations } From 6e4fc155b001e576a2e53c37d03c442d8526226a Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 05:36:50 +0100 Subject: [PATCH 03/19] refactor: compute native record properties directly when reading fields by name --- .../src/bindings/_helpers/records/fields.rs | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs index 08b333423b..f9b97a1544 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs @@ -1,5 +1,8 @@ //! Construction, comparison and display of native record field values. +use std::collections::HashMap; +use std::sync::OnceLock; + use pyo3::IntoPyObjectExt; use pyo3::exceptions::{PyAttributeError, PyRuntimeError, PyTypeError}; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyResult, Python}; @@ -14,11 +17,13 @@ use sqlbuild_rules::project_tree::main::pure_path_posix::pure_path_posix; use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::constants::{ - FROZEN_INSTANCE_ERROR, ORDERED_RECORDS, RECORD_FINISHERS, RECORD_SPEC_ATTRIBUTE, RECORDS, + CACHED_PROPERTIES, CLASS_PROPERTIES, FROZEN_INSTANCE_ERROR, ORDERED_RECORDS, RECORD_FINISHERS, + RECORD_SPEC_ATTRIBUTE, RECORDS, }; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::getters::getter_field; use crate::bindings::_helpers::records::models::{FieldDefault, NativeRecord, RecordSpec}; +use crate::bindings::_helpers::records::types::ClassProperty; /// Every registered record spec, in registration order. pub(crate) fn all_specs() -> impl Iterator { @@ -41,8 +46,8 @@ pub(crate) fn record_spec(cls: &Bound<'_, PyType>) -> PyResult<&'static RecordSp /// A declared field of a native record read from its values; any other attribute, or object, by `getattr`. pub(crate) fn field<'py>(value: &Bound<'py, PyAny>, name: &str) -> PyResult> { - if let Ok(record) = value.cast::() { - let record: &NativeRecord = record.get(); + if let Ok(cell) = value.cast::() { + let record: &NativeRecord = cell.get(); if let Some(found) = record .spec .fields @@ -52,12 +57,51 @@ pub(crate) fn field<'py>(value: &Bound<'py, PyAny>, name: &str) -> PyResult)>; + +/// A record property's function by class and attribute name, with its cache key when cached. +fn record_properties() -> &'static PropertyTable { + static TABLE: OnceLock = OnceLock::new(); + TABLE.get_or_init(|| { + let mut table: PropertyTable = HashMap::new(); + for &(class, name, property) in CLASS_PROPERTIES.iter().flat_map(|group| group.iter()) { + let _ = table.insert((class, name), (property, None)); + } + for &(class, name, property) in CACHED_PROPERTIES.iter().flat_map(|group| group.iter()) { + let _ = table.insert((class, name), (property, Some(name))); + } + table + }) +} + +/// A record property computed as its descriptor computes it, cached ones computed once. +fn property_value( + record: &Bound<'_, NativeRecord>, + property: ClassProperty, + cached_name: Option<&'static str>, +) -> PyResult> { + let Some(cached_name) = cached_name else { + return property(record.as_any()); + }; + if let Some(value) = cached_value(record, cached_name)? { + return Ok(value); + } + let value: Py = property(record.as_any())?; + store_cached(record, cached_name, &value)?; + Ok(value) +} + /// `dataclasses.replace(value, **changes)`: a native record is rebuilt from its own values. pub(crate) fn replaced<'py>( value: &Bound<'py, PyAny>, From 9f1e8c1b23d31ff801f8fc14b4f832dfd61e0738 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 05:47:21 +0100 Subject: [PATCH 04/19] refactor: capture native error classes at module load instead of looking them up per raise --- .../_helpers/analysis/explicit_references.rs | 4 ++-- .../_helpers/attachments/cursor_intrinsics.rs | 4 ++-- .../_helpers/attachments/reference_markers.rs | 4 ++-- .../bindings/_helpers/auditing/measurement.rs | 4 ++-- .../_helpers/auditing/schema_audits.rs | 14 ++++++++----- .../_helpers/build_command/policies.rs | 4 ++-- .../bindings/_helpers/check/check_command.rs | 4 ++-- .../src/bindings/_helpers/cli/dispatch.rs | 3 ++- .../src/bindings/_helpers/cli/entry.rs | 18 ++++++++-------- .../bindings/_helpers/clone/clone_command.rs | 4 ++-- .../_helpers/command_runtime/adapters.rs | 4 ++-- .../command_runtime/runtime_errors.rs | 14 ++++++------- .../compile_attachment/declaration_scope.rs | 6 +++--- .../compile_attachment/effective_config.rs | 4 ++-- .../compile_attachment/model_inputs.rs | 4 ++-- .../_helpers/compile_command/target_writer.rs | 5 +++-- .../compile_driver/assembly_sql_tests.rs | 5 ++--- .../compile_driver/config_validation.rs | 6 +++--- .../_helpers/compile_driver/deferral.rs | 4 ++-- .../compile_driver/diagnostic_collector.rs | 4 ++-- .../bindings/_helpers/compile_driver/diff.rs | 4 ++-- .../_helpers/compile_driver/phases.rs | 8 +++---- .../_helpers/compile_driver/pipeline.rs | 6 +++--- .../_helpers/compile_driver/targets.rs | 4 ++-- .../_helpers/compiled_project/attachment.rs | 5 +++-- .../_helpers/compiled_project/loop_classes.rs | 6 +++--- .../_helpers/contract_command/command.rs | 4 ++-- .../_helpers/contracts/project_config.rs | 3 ++- .../_helpers/contracts/resource_identities.rs | 4 ++-- .../_helpers/contracts/spec_resolution.rs | 4 ++-- .../bindings/_helpers/cost_command/refusal.rs | 4 ++-- .../_helpers/dag_artifact/artifact.rs | 4 ++-- .../src/bindings/_helpers/dbt_command/init.rs | 4 ++-- .../src/bindings/_helpers/dbt_interop/cli.rs | 4 ++-- .../bindings/_helpers/dbt_interop/graph.rs | 4 ++-- .../bindings/_helpers/dbt_interop/manifest.rs | 4 ++-- .../_helpers/dbt_interop/orchestration.rs | 4 ++-- .../bindings/_helpers/dbt_interop/pipeline.rs | 3 ++- .../_helpers/dbt_interop/pipeline_prologue.rs | 4 ++-- .../_helpers/dbt_interop/plan_output.rs | 4 ++-- .../dbt_interop/reference_resolver.rs | 4 ++-- .../bindings/_helpers/dbt_interop/runner.rs | 6 +++--- .../bindings/_helpers/diff_report/command.rs | 4 ++-- .../bindings/_helpers/diff_report/support.rs | 6 +++--- .../_helpers/discovery/header_declarations.rs | 7 +++---- .../_helpers/discovery/header_values.rs | 4 ++-- .../_helpers/discovery/imported_modules.rs | 4 ++-- .../discovery/python_function_files.rs | 6 +++--- .../src/bindings/_helpers/discovery/raised.rs | 4 ++-- .../_helpers/discovery/sql_test_blocks.rs | 4 ++-- .../_helpers/discovery/yaml_entries.rs | 6 +++--- .../_helpers/fingerprints/latest_rows.rs | 4 ++-- .../_helpers/fingerprints/query_hashes.rs | 4 ++-- .../bindings/_helpers/format_command/run.rs | 4 ++-- .../_helpers/format_command/selection.rs | 4 ++-- .../_helpers/freshness/freshness_command.rs | 4 ++-- .../_helpers/graph/python_selection.rs | 4 ++-- .../bindings/_helpers/init_command/command.rs | 4 ++-- .../_helpers/janitor/janitor_command.rs | 4 ++-- .../_helpers/janitor/janitor_phases.rs | 4 ++-- .../_helpers/lineage/lineage_command.rs | 5 +++-- .../_helpers/lineage/project_lineage.rs | 4 ++-- .../bindings/_helpers/load/load_command.rs | 4 ++-- .../bindings/_helpers/load/load_selection.rs | 4 ++-- .../src/bindings/_helpers/manifest/builder.rs | 4 ++-- .../_helpers/model_config/config_errors.rs | 4 ++-- .../_helpers/model_config/config_values.rs | 4 ++-- .../_helpers/model_config/header_columns.rs | 4 ++-- .../_helpers/model_config/template_data.rs | 4 ++-- .../model_config/unicode_environment.rs | 4 ++-- .../_helpers/planner_changes/results.rs | 6 ++---- .../_helpers/planner_entries/values.rs | 4 ++-- .../_helpers/planner_identity/graph.rs | 4 ++-- .../_helpers/planner_identity/hashing.rs | 4 ++-- .../planner_migrations/model_entries.rs | 4 ++-- .../planner_migrations/planning_origin.rs | 4 ++-- .../_helpers/planner_phases/objects.rs | 4 ++-- .../planner_resolution/cursor_model.rs | 4 ++-- .../planner_resolution/cursor_overrides.rs | 4 ++-- .../planner_resolution/cursor_ranges.rs | 4 ++-- .../planner_resolution/cursor_safety.rs | 4 ++-- .../planner_resolution/cursor_windows.rs | 4 ++-- .../planner_resolution/maximum_safety.rs | 4 ++-- .../planner_resolution/orchestration.rs | 4 ++-- .../bindings/_helpers/planner_scenario/cli.rs | 4 ++-- .../_helpers/planner_scenario/values.rs | 4 ++-- .../_helpers/planner_selection/carrier.rs | 4 ++-- .../_helpers/planner_strategy/values.rs | 4 ++-- .../project_assembly/native_resources.rs | 9 ++++---- .../project_assembly/syntax_validation.rs | 4 ++-- .../bindings/_helpers/query_command/query.rs | 6 +++--- .../_helpers/record_behaviours/auditing.rs | 4 ++-- .../_helpers/record_behaviours/compiled.rs | 4 ++-- .../_helpers/record_behaviours/lexical.rs | 4 ++-- .../_helpers/record_behaviours/planner.rs | 4 ++-- .../bindings/_helpers/records/construct.rs | 21 +++++++++++++++++-- .../src/bindings/_helpers/records/registry.rs | 12 ----------- .../_helpers/refactor/contract_edits.rs | 4 ++-- .../_helpers/refactor/offline_compile.rs | 6 +++--- .../_helpers/refactor/refactor_command.rs | 6 +++--- .../bindings/_helpers/render/authored_sql.rs | 5 +++-- .../_helpers/render/declaration_indexes.rs | 4 ++-- .../_helpers/render/declaration_values.rs | 10 ++++----- .../bindings/_helpers/render/macro_calls.rs | 4 ++-- .../_helpers/render/macro_expansion_result.rs | 8 +++---- .../bindings/_helpers/rules/custom_hosts.rs | 4 ++-- .../_helpers/rules/custom_rule_cache.rs | 4 ++-- .../_helpers/rules/custom_rule_evidence.rs | 8 +++---- .../src/bindings/_helpers/rules/findings.rs | 4 ++-- .../bindings/_helpers/rules/fix_session.rs | 6 +++--- .../bindings/_helpers/rules/lint_expansion.rs | 8 +++---- .../bindings/_helpers/rules/lint_pipeline.rs | 12 +++++------ .../_helpers/rules/native_header_parser.rs | 6 +++--- .../_helpers/rules/project_tree_queries.rs | 8 +++---- .../src/bindings/_helpers/rules/rule_api.rs | 6 +++--- .../bindings/_helpers/rules/rules_config.rs | 6 +++--- .../src/bindings/_helpers/rules/selection.rs | 4 ++-- .../src/bindings/_helpers/rules/sql_rules.rs | 4 ++-- .../_helpers/scenario_command/setup.rs | 4 ++-- .../_helpers/scopes/compile_usages.rs | 4 ++-- .../_helpers/scopes/relationship_names.rs | 4 ++-- .../bindings/_helpers/scopes/scope_command.rs | 4 ++-- .../bindings/_helpers/scopes/scope_index.rs | 4 ++-- .../bindings/_helpers/scopes/scope_lookup.rs | 4 ++-- .../bindings/_helpers/scopes/scope_reports.rs | 4 ++-- .../_helpers/scopes/scope_validation.rs | 4 ++-- .../_helpers/scopes/scope_visibility.rs | 4 ++-- .../_helpers/semantic_checks/resource_sql.rs | 4 ++-- .../_helpers/sql_test_command/test_command.rs | 4 ++-- .../_helpers/sql_test_glue/authored_ctes.rs | 4 ++-- .../_helpers/sql_test_glue/plan_driver.rs | 4 ++-- .../_helpers/sql_test_glue/plan_errors.rs | 6 +++--- .../_helpers/sql_test_glue/plan_rendering.rs | 4 ++-- .../bindings/_helpers/sqltext/code_scanner.rs | 4 ++-- .../_helpers/sqltext/sql_references.rs | 4 ++-- .../_helpers/state_rows/migration_objects.rs | 4 ++-- .../_helpers/workspace_commands/commands.rs | 4 ++-- 137 files changed, 346 insertions(+), 339 deletions(-) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs index c3027e71e0..841d124650 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs @@ -29,10 +29,10 @@ use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::graph::execution_gates::model_python_hook_names; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::types::CompilerDetach; const EXPLICIT_REFERENCES_CONTEXT: &str = "native explicit-reference checks"; @@ -141,7 +141,7 @@ pub(crate) fn explicit_reference_report<'py>( { Ok(report) => python_report(py, &report, &owners), Err(ReferenceFailure::CompileInput(message)) => Err(PyErr::from_value( - registry::error(py, ErrorId::CompileInput)?.call1((message,))?, + error_class(py, ErrorId::CompileInput)?.call1((message,))?, )), Err(ReferenceFailure::UnknownDialect(message)) => Err(compiler_error(message)), Err(ReferenceFailure::Internal(reason)) => Err(compiler_error(native_failure( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs b/crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs index 158acd1818..a607828e60 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs @@ -8,8 +8,8 @@ use sqlbuild_attachments::cursor_intrinsics::main::validated_model_intrinsics::v use sqlbuild_attachments::cursor_intrinsics::models::IntrinsicModel; use crate::bindings::_helpers::boundary::panics::compiler_guard; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const INCREMENTAL_MATERIALIZATION: &str = "incremental"; const CURSOR_START: &str = "__cursor_start"; @@ -37,7 +37,7 @@ pub(crate) fn reserved_cursor_markers() -> Vec { /// A `CompileInputError` carrying `message`. pub(crate) fn compile_input_error(py: Python<'_>, message: String) -> PyResult { Ok(PyErr::from_value( - registry::error(py, ErrorId::CompileInput)?.call1((message,))?, + error_class(py, ErrorId::CompileInput)?.call1((message,))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/attachments/reference_markers.rs b/crates/sqlbuild-python/src/bindings/_helpers/attachments/reference_markers.rs index 827bd3bc77..b11251c5b4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/attachments/reference_markers.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/attachments/reference_markers.rs @@ -8,8 +8,8 @@ use sqlbuild_attachments::reference_markers::main::unresolved_reference_marker:: use sqlbuild_attachments::sql_lexing::main::unclosed_message::unclosed_message; use crate::bindings::_helpers::boundary::panics::compiler_guard; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; /// The reference function and diagnostic code of each marker kind, in the scanner's order. const MARKER_KINDS: [(&str, &str); 5] = [ @@ -46,7 +46,7 @@ pub(crate) fn assert_no_unresolved_sql_markers( })?; match outcome { (_, Some(unclosed)) => Err(PyErr::from_value( - registry::error(py, ErrorId::CompileInput)?.call1((unclosed,))?, + error_class(py, ErrorId::CompileInput)?.call1((unclosed,))?, )), (Some(marker), None) => { let (function, code) = MARKER_KINDS.get(marker).copied().ok_or_else(|| { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs b/crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs index fc6ded71a8..fbf561bba0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs @@ -10,11 +10,11 @@ use sqlbuild_analysis::auditing::models::{MeasurementOutcome, Thresholds}; use crate::bindings::_helpers::auditing::identity::thresholds as read_thresholds; use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; fn measurement_error(py: Python<'_>, message: &str) -> PyErr { - match registry::error(py, ErrorId::MeasurementAudit).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::MeasurementAudit).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/auditing/schema_audits.rs b/crates/sqlbuild-python/src/bindings/_helpers/auditing/schema_audits.rs index 0504011309..7b1c66567e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/auditing/schema_audits.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/auditing/schema_audits.rs @@ -13,20 +13,24 @@ use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::model_config::authored_nodes::PyNode; use crate::bindings::_helpers::model_config::contract_classes::contract_classes; use crate::bindings::_helpers::model_config::header_metadata::{ContractClasses, audit_tuple}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; -/// A resource identity error as `ResourceIdentityError`, anything else as `error_class(message)`. -fn raised(py: Python<'_>, error: ConfigError, error_class: &Bound<'_, PyAny>) -> PyResult { +/// A resource identity error as `ResourceIdentityError`, anything else as `fallback_class(message)`. +fn raised( + py: Python<'_>, + error: ConfigError, + fallback_class: &Bound<'_, PyAny>, +) -> PyResult { let keywords: Bound<'_, PyDict> = PyDict::new(py); let class: Bound<'_, PyAny> = match error.class { ErrorClass::ResourceIdentity => { if let Some(help) = error.help { keywords.set_item("help", help)?; } - registry::error(py, ErrorId::ResourceIdentity)? + error_class(py, ErrorId::ResourceIdentity)? } - _ => error_class.clone(), + _ => fallback_class.clone(), }; Ok(PyErr::from_value( class.call((error.message,), Some(&keywords))?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs index 599fc01b40..7bfc43886a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs @@ -17,9 +17,9 @@ use sqlbuild_core::build_command::models::{ }; use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const SNAPSHOT_VALUE: &str = "snapshot"; const FULL_REFRESH_REASON: &str = "full_refresh"; @@ -47,7 +47,7 @@ pub(crate) fn build_command_error(py: Python<'_>, error: BuildCommandError) -> P let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", error.code)?; options.set_item("help", error.help)?; - registry::error(py, ErrorId::CliUser)?.call((error.message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((error.message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs index 5752f51a3c..8ec2b5b892 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs @@ -44,9 +44,9 @@ use crate::bindings::_helpers::graph::python_selection::python_node_names; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::result_output::event_writer::ExecutionEventWriter; const GRAPH_OPERATOR_CODE: &str = "C681"; @@ -70,7 +70,7 @@ fn user_error(py: Python<'_>, (code, message): (&str, &str)) -> PyErr { let raised = (|| { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", code)?; - registry::error(py, ErrorId::CliUser)?.call((message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs index af30bf6975..0fb68d52d9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs @@ -52,6 +52,7 @@ use sqlbuild_core::format_command::main::format_path_selectors::format_path_sele use sqlbuild_core::text::main::python_strip::python_strip; use crate::bindings::_helpers::compile_driver::python_calls::{imported, within}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::records::registry; @@ -233,7 +234,7 @@ fn user_error(py: Python<'_>, failure: DispatchFailure) -> PyErr { let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("code", failure.code)?; keywords.set_item("help", failure.help)?; - registry::error(py, ErrorId::CliUser)?.call((failure.message,), Some(&keywords)) + error_class(py, ErrorId::CliUser)?.call((failure.message,), Some(&keywords)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs index c1d76e4726..6323521345 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs @@ -27,10 +27,10 @@ use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::output_capture::records::invocation_context; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::workspace_commands::commands::maintain_sqlbuild_skills; use sqlbuild_cli::launcher::constants::LAUNCH_RECORD_OPTION; use sqlbuild_core::cli_text::main::format_coded_error::format_coded_error; @@ -246,7 +246,7 @@ fn write_diff_machine_error<'py>( } let keywords: Bound<'py, PyDict> = PyDict::new(py); keywords.set_item("code", DIFF_PUBLICATION_CODE)?; - let publication: Bound<'py, PyAny> = registry::error(py, ErrorId::QueryDiffExecution)? + let publication: Bound<'py, PyAny> = error_class(py, ErrorId::QueryDiffExecution)? .call( (format!( "failed to publish query diff output: {}", @@ -291,12 +291,12 @@ fn exit<'py>(py: Python<'py>, code: i64) -> PyResult> { /// The kind of expected failure `error` is, or `None` when it propagates. fn failure_kind(py: Python<'_>, error: &Bound<'_, PyAny>) -> PyResult> { - if error.is_instance(®istry::error(py, ErrorId::CliUser)?)? - || error.is_instance(®istry::error(py, ErrorId::Rules)?)? + if error.is_instance(&error_class(py, ErrorId::CliUser)?)? + || error.is_instance(&error_class(py, ErrorId::Rules)?)? { return Ok(Some(CommandFailure::User)); } - if error.is_instance(®istry::error(py, ErrorId::Lint)?)? { + if error.is_instance(&error_class(py, ErrorId::Lint)?)? { return Ok(Some(CommandFailure::Lint)); } if error.is_instance_of::() { @@ -308,7 +308,7 @@ fn failure_kind(py: Python<'_>, error: &Bound<'_, PyAny>) -> PyResult( let py: Python<'py> = invocation.py(); let (fallback_code, log_message) = failure_report(kind); log_failure(py, log_message, &error)?; - let user_error_class: Bound<'py, PyAny> = registry::error(py, ErrorId::CliUser)?; + let user_error_class: Bound<'py, PyAny> = error_class(py, ErrorId::CliUser)?; let is_user_error: bool = error.is_instance(&user_error_class)?; let effective: Bound<'py, PyAny> = if is_user_error { write_diff_machine_error(invocation, &error)?.unwrap_or(error) @@ -332,7 +332,7 @@ fn report_failure<'py>( error }; write_compile_machine_error(invocation, &effective, fallback_code)?; - if effective.is_instance(®istry::error(py, ErrorId::QueryDiffOutcome)?)? { + if effective.is_instance(&error_class(py, ErrorId::QueryDiffOutcome)?)? { let line: Bound<'py, PyAny> = PyString::new(py, DIFF_OUTCOME_PREFIX) .into_any() .add(native_field(&effective, "status")?.str()?)?; @@ -360,7 +360,7 @@ fn report_skill_freshness(invocation: &Invocation<'_>, policy: InvocationPolicy) Ok(result) => result, Err(error) => { let value: Bound<'_, PyAny> = error.value(py).clone().into_any(); - if value.is_instance(®istry::error(py, ErrorId::CliUser)?)? + if value.is_instance(&error_class(py, ErrorId::CliUser)?)? || value.is_instance_of::() || value.is_instance_of::() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs index 162fa825b8..5dbe51c1f0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs @@ -37,10 +37,10 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::result_output::documents::format_clone_execution_json; use crate::bindings::_helpers::result_output::documents::write_execution_json_output; @@ -67,7 +67,7 @@ fn user_error(py: Python<'_>, (code, message): (&str, &str)) -> PyErr { let raised = (|| { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", code)?; - registry::error(py, ErrorId::CliUser)?.call((message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs index 45a417cefb..d142cba47f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs @@ -9,9 +9,9 @@ use pyo3::{pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::compile_driver::python_calls::call_with; use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const ADAPTER_CONFIGURATION_CODE: &str = "C601"; @@ -22,7 +22,7 @@ fn cli_adapter_error(py: Python<'_>, error: &PyErr) -> PyResult { keywords.set_item("code", ADAPTER_CONFIGURATION_CODE)?; keywords.set_item("help", native_field(&value, "help")?)?; let raised: PyErr = PyErr::from_value( - registry::error(py, ErrorId::CliUser)? + error_class(py, ErrorId::CliUser)? .call((native_field(&value, "message")?,), Some(&keywords))?, ); raised.set_cause(py, Some(error.clone_ref(py))); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/runtime_errors.rs b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/runtime_errors.rs index e872c84cb1..c36ab9771c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/runtime_errors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/runtime_errors.rs @@ -4,9 +4,9 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods}; use sqlbuild_config::command_connection::errors::CommandConnectionError; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; /// The `CliUserError` or `ProjectConfigError` for `error`. pub(crate) fn raised(py: Python<'_>, error: CommandConnectionError) -> PyErr { @@ -20,10 +20,10 @@ pub(crate) fn raised(py: Python<'_>, error: CommandConnectionError) -> PyErr { let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("code", code)?; keywords.set_item("help", help)?; - registry::error(py, ErrorId::CliUser)?.call((message,), Some(&keywords))? + error_class(py, ErrorId::CliUser)?.call((message,), Some(&keywords))? } CommandConnectionError::ProjectConfig(message) => { - registry::error(py, ErrorId::ProjectConfig)?.call1((message,))? + error_class(py, ErrorId::ProjectConfig)?.call1((message,))? } }; Ok(PyErr::from_value(instance)) @@ -33,16 +33,14 @@ pub(crate) fn raised(py: Python<'_>, error: CommandConnectionError) -> PyErr { /// Whether `error` is a `CompileInputError` or a `CliUserError`, the failures resolution reports. pub(crate) fn expected_resolution_error(py: Python<'_>, error: &PyErr) -> PyResult { - Ok( - error.is_instance(py, ®istry::error(py, ErrorId::CliUser)?) - || error.is_instance(py, ®istry::error(py, ErrorId::CompileInput)?), - ) + Ok(error.is_instance(py, &error_class(py, ErrorId::CliUser)?) + || error.is_instance(py, &error_class(py, ErrorId::CompileInput)?)) } /// The message a resolution error shows: `CliUserError.message`, else `str(error)`. pub(crate) fn resolution_message(py: Python<'_>, error: &PyErr) -> PyResult { let value: Bound<'_, PyAny> = error.value(py).clone().into_any(); - if error.is_instance(py, ®istry::error(py, ErrorId::CliUser)?) { + if error.is_instance(py, &error_class(py, ErrorId::CliUser)?) { return native_field(&value, "message")?.str()?.extract(); } value.str()?.extract() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs index ac7a4d5791..804f6c5adc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs @@ -7,10 +7,10 @@ use pyo3::types::PyTuple; use crate::bindings::_helpers::cache::sql_test_scan_store::SqlTestScanCache; use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; use crate::bindings::_helpers::compile_driver::stage_work::{DECLARATION_SCOPES, count_stage}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::render::declaration_values::declaration_scope_resolver; use crate::bindings::_helpers::scopes::scope_index::open_native_scope_index; use crate::bindings::_helpers::scopes::scope_lookup::build_scope_lookup; @@ -21,7 +21,7 @@ use crate::bindings::_helpers::sqltext::lexical_syntax::LexicalSyntaxInput; fn compile_error(py: Python<'_>, message: Bound<'_, PyAny>) -> PyResult { Ok(PyErr::from_value( - registry::error(py, ErrorId::CompileInput)?.call1((message,))?, + error_class(py, ErrorId::CompileInput)?.call1((message,))?, )) } @@ -82,7 +82,7 @@ pub(crate) fn build_declaration_scope<'py>( .into_any(); let validated: Result<(), PyErr> = validate_scope_index(&native_field(&native, "index")?); if let Err(error) = validated { - if !error.is_instance(py, ®istry::error(py, ErrorId::ScopeValidation)?) { + if !error.is_instance(py, &error_class(py, ErrorId::ScopeValidation)?) { return Err(error); } let raised: PyErr = compile_error(py, error.value(py).str()?.into_any())?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs index 73b307a1f3..26c7721cb9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs @@ -16,10 +16,10 @@ use crate::bindings::_helpers::contracts::spec_resolution::{ use crate::bindings::_helpers::model_config::template_data::{ expanded_effective_vars, expanded_template_data, run_id, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const CONNECTION_LABEL: &str = "effective connection"; @@ -39,7 +39,7 @@ pub(crate) fn build_effective_connection<'py>( .extract()?; if connection.is_none() { let raised: Bound<'py, PyAny> = - registry::error(py, ErrorId::CompileInput)?.call1((error.unwrap_or_default(),))?; + error_class(py, ErrorId::CompileInput)?.call1((error.unwrap_or_default(),))?; return Err(PyErr::from_value(raised)); } expanded_template_data( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs index 564ae1f492..9cd15c7890 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs @@ -26,9 +26,9 @@ use crate::bindings::_helpers::render::macro_expansion_result::macro_expansion_c use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use sqlbuild_core::constants::PROJECT_CONFIG_FILENAME; /// The explicit reference call kinds and the `SqlResourceRefKind` member each resolves to. const EXPLICIT_REFERENCE_KINDS: [(&str, &str); 3] = @@ -97,7 +97,7 @@ fn macro_inputs<'py>(context: &Bound<'py, PyAny>) -> PyResult ), ( "macro_argument_error", - registry::error(py, ErrorId::MacroArgument)?, + error_class(py, ErrorId::MacroArgument)?, ), ("expansion", macro_expansion_classes(py)?.into_any()), ( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs index 9e86cc4dec..6475162b5f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs @@ -34,6 +34,7 @@ use crate::bindings::_helpers::compile_outputs::runtime_target::{ }; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; @@ -492,7 +493,7 @@ fn artifact_diagnostics<'py>( ("severity", "error".into_bound_py_any(py)?), ( "code", - registry::error(py, ErrorId::PlannerInput)?.getattr("code")?, + error_class(py, ErrorId::PlannerInput)?.getattr("code")?, ), ("message", message?), ("resource_type", "sql_test".into_bound_py_any(py)?), @@ -702,7 +703,7 @@ pub(crate) fn publish_staged_target<'py>( /// `StagedArtifactsChangedError(message, help=...)`. pub(crate) fn staging_changed(py: Python<'_>, message: &str) -> PyResult { - let error: Bound<'_, PyAny> = registry::error(py, ErrorId::StagedArtifactsChanged)?.call( + let error: Bound<'_, PyAny> = error_class(py, ErrorId::StagedArtifactsChanged)?.call( (message,), Some(&keywords( py, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs index ad639f770d..7cbe8f77b0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs @@ -8,10 +8,10 @@ use crate::bindings::_helpers::compile_driver::assembly_checks::test_model_query use crate::bindings::_helpers::compile_driver::diagnostic_collector::report_compile_diagnostic; use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; use crate::bindings::_helpers::compile_driver::stage_work::{SQL_TEST_ASSEMBLY, count_stage}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sql_test_glue::compiled_tests::assemble_native_sql_tests; const DECIMAL_MODULE: &str = "decimal"; @@ -85,8 +85,7 @@ fn assembly_error( native_field(failure, "message")?.extract()? }; if kind == Some(SQL_TEST_INPUT_FAILURE) { - let error: Bound<'_, PyAny> = - registry::error(py, ErrorId::CompileInput)?.call1((message,))?; + let error: Bound<'_, PyAny> = error_class(py, ErrorId::CompileInput)?.call1((message,))?; return Ok(PyErr::from_value(error)); } Ok(NativeCompilerError::new_err(message)) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs index c39a14c5bd..9e90a353ef 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs @@ -14,9 +14,9 @@ use crate::bindings::_helpers::contracts::spec_resolution::{ }; use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use pyo3::IntoPyObjectExt; use sqlbuild_core::constants::PROJECT_CONFIG_FILENAME; const LOCAL_CONFIG_FILENAME: &str = "sqlbuild_local.toml"; @@ -35,7 +35,7 @@ fn project_config_error(py: Python<'_>, message: &str, help: Option<&str>) -> Py let raised = (|| -> PyResult> { let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("help", help)?; - registry::error(py, ErrorId::ProjectConfig)?.call((message,), Some(&keywords)) + error_class(py, ErrorId::ProjectConfig)?.call((message,), Some(&keywords)) })(); match raised { Ok(instance) => PyErr::from_value(instance), @@ -171,7 +171,7 @@ fn reject_invalid_target_connections(config: &ProjectConfiguration<'_, '_>) -> P names.extend(target_names(config.local_config)?); names.sort(); names.dedup(); - let spec_error: Bound<'_, PyAny> = registry::error(py, ErrorId::SpecConfig)?; + let spec_error: Bound<'_, PyAny> = error_class(py, ErrorId::SpecConfig)?; for name in names { let resolved: PyResult> = resolve_target_config( py, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs index 220cab538d..be68d51d2c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs @@ -11,10 +11,10 @@ use sqlbuild_model_config::templates::models::DeferredSegment; use crate::bindings::_helpers::authored_values::project_vars::render_project_var_text; use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, call_with}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const PRESERVE_TARGET_VALUE: &str = "preserve"; /// `sorted(DEFERRED_TARGET_CONTEXT_KEYS)`. @@ -172,7 +172,7 @@ fn target_field<'py>( /// A `PlannerInputError` with `message` and the default code. fn planner_error(py: Python<'_>, message: String) -> PyErr { - match registry::error(py, ErrorId::PlannerInput).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::PlannerInput).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs index 20363c150a..d533ab80a3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs @@ -8,9 +8,9 @@ use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use pyo3::{PyErr, pyclass, pyfunction, pymethods, wrap_pyfunction}; use crate::bindings::_helpers::compile_driver::python_calls::{context_variable, imported}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const CONTEXT_VARIABLE_NAME: &str = "sqlbuild_collected_compile_diagnostics"; @@ -126,7 +126,7 @@ pub(crate) fn report_compile_diagnostic( keywords.set_item("help", native_field(diagnostic, "help")?)?; let message: String = format!("{}{pointer}", native_field(diagnostic, "message")?.str()?); Err(PyErr::from_value( - registry::error(py, ErrorId::CompileInput)?.call((message,), Some(&keywords))?, + error_class(py, ErrorId::CompileInput)?.call((message,), Some(&keywords))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs index 234caaeea8..09d6af07ec 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs @@ -17,10 +17,10 @@ use crate::bindings::_helpers::compile_driver::project::build_compiled_project; use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, keywords}; use crate::bindings::_helpers::graph::views::project_lineage_views; use crate::bindings::_helpers::records::construct::enum_member; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; use crate::bindings::_helpers::records::ids::RecordId; -use crate::bindings::_helpers::records::registry; /// Indexes of the `CompiledObjectKey`s a diff graph names, assigned on first sight. struct KeyIndexes<'py> { @@ -113,7 +113,7 @@ fn diff_graph<'py>(project: &Bound<'py, PyAny>, keys: &KeyIndexes<'py>) -> PyRes /// The `PlannerInputError` a rejected selector raises. fn selector_error(py: Python<'_>, error: SelectorError) -> PyErr { let raised: PyResult> = (|| { - registry::error(py, ErrorId::PlannerInput)?.call( + error_class(py, ErrorId::PlannerInput)?.call( (error.message,), Some(&keywords( py, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs index 0e61ba02be..708701b576 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs @@ -15,10 +15,10 @@ use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_ada use crate::bindings::_helpers::dag_artifact::artifact::build_dag_json; use crate::bindings::_helpers::graph::python_node_graph::python_node_graph; use crate::bindings::_helpers::manifest::builder::build_manifest; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const EMPTY_DAG_PATH: &str = ""; const TARGET_DIRECTORY: &str = "target"; @@ -164,13 +164,13 @@ pub(crate) fn sql_test_planning_diagnostics<'py>( Ok(diagnostics) => return Ok(diagnostics), Err(error) => error, }; - let compile_input_error: Bound<'py, PyAny> = registry::error(py, ErrorId::CompileInput)?; - let planner_input_error: Bound<'py, PyAny> = registry::error(py, ErrorId::PlannerInput)?; + let compile_input_error: Bound<'py, PyAny> = error_class(py, ErrorId::CompileInput)?; + let planner_input_error: Bound<'py, PyAny> = error_class(py, ErrorId::PlannerInput)?; let value: Bound<'py, PyAny> = error.value(py).clone().into_any(); if !(value.is_instance(&compile_input_error)? || value.is_instance(&planner_input_error)?) { return Err(error); } - let reference_error: Bound<'py, PyAny> = registry::error(py, ErrorId::SqlTestReference)?; + let reference_error: Bound<'py, PyAny> = error_class(py, ErrorId::SqlTestReference)?; let location: Bound<'py, PyAny> = if value.is_instance(&reference_error)? { native_field(&value, "location")? } else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs index bddb0345ed..f9fea09a33 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs @@ -21,11 +21,11 @@ use crate::bindings::_helpers::diagnostics::trackers::current_tracker; use crate::bindings::_helpers::frontier::stage_capture::write_plan_capture; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::rules::results::{format_rules_result, rules_progress}; use crate::bindings::_helpers::rules::rule_dispatch::evaluate_rules; use crate::bindings::_helpers::rules::rules_config::load_rules_config; @@ -196,7 +196,7 @@ fn reject_compile_errors( } else { py.None().into_bound(py) }; - let error: Bound<'_, PyAny> = registry::error(py, ErrorId::CompileInput)?.call( + let error: Bound<'_, PyAny> = error_class(py, ErrorId::CompileInput)?.call( (lines.join("\n"),), Some(&keywords( py, @@ -249,7 +249,7 @@ fn run_rules_gate<'py>( (project, graph): (&Bound<'py, PyAny>, &Bound<'py, PyAny>), ) -> PyResult<()> { let py: Python<'py> = discovered.py(); - let rules_error: Bound<'py, PyAny> = registry::error(py, ErrorId::Rules)?; + let rules_error: Bound<'py, PyAny> = error_class(py, ErrorId::Rules)?; let project_dir: Bound<'py, PyAny> = native_field(discovered, "project_dir")?; if project_dir.is_none() { return Err(PyErr::from_value( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs index dde70832c8..9d5e4dccfa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs @@ -42,9 +42,9 @@ use crate::bindings::_helpers::compile_attachment::effective_config::build_effec use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_config; use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_name; use crate::bindings::_helpers::discovery::guidance::setting_help; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use pyo3::IntoPyObjectExt; use sqlbuild_core::constants::PROJECT_CONFIG_FILENAME; const DEFAULTS_SECTION: &str = "defaults"; @@ -57,7 +57,7 @@ type TargetNamespaces = (Vec<(String, String)>, Vec); /// A `PlannerInputError` with `message`, `code` and optional `help`. fn planner_error(py: Python<'_>, message: String, code: &str, help: Option) -> PyErr { let raised: PyResult> = (|| { - registry::error(py, ErrorId::PlannerInput)?.call( + error_class(py, ErrorId::PlannerInput)?.call( (message,), Some(&keywords( py, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs index b53e51251e..07808a85bf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs @@ -26,6 +26,7 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; @@ -171,7 +172,7 @@ pub(crate) fn attach_resources<'py>( .into_iter() .map(Bound::unbind) .collect(), - ®istry::error(py, ErrorId::CompileInput)?, + &error_class(py, ErrorId::CompileInput)?, )?; let defaults: Bound<'py, PyAny> = discovered_inputs .getattr("project_config")? @@ -514,7 +515,7 @@ fn diagnostic_settings<'py>( "compiler_diagnostic", record_class(py, RecordId::CompilerDiagnostic)?, )?; - settings.set_item("compile_error", registry::error(py, ErrorId::CompileInput)?)?; + settings.set_item("compile_error", error_class(py, ErrorId::CompileInput)?)?; settings.set_item( "source_location", record_class(py, RecordId::SourceLocation)?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs index 89e4f36fa5..42d13900c7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs @@ -7,10 +7,10 @@ use pyo3::{IntoPyObjectExt, pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; /// The materializations a model's storage policies are inherited for, besides none. const TABLE_BACKED_MATERIALIZATIONS: [&str; 3] = ["TABLE", "INCREMENTAL", "SNAPSHOT"]; @@ -405,14 +405,14 @@ pub(crate) fn model_loop_classes<'py>( py, vec![ ("usage_record", record_class(py, RecordId::UsageRecord)?), - ("compile_error", registry::error(py, ErrorId::CompileInput)?), + ("compile_error", error_class(py, ErrorId::CompileInput)?), ("syntax_help", host("syntax_help")?), ("source_syntax_help", host("source_syntax_help")?), ("macros", host("macros")?), ("sql_hooks", host("sql_hooks")?), ( "scope_path_error", - registry::error(py, ErrorId::InvalidScopePath)?, + error_class(py, ErrorId::InvalidScopePath)?, ), ("sql_hook_entry", record_class(py, RecordId::SqlHookEntry)?), ( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs index b4de29494e..b8903f5802 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs @@ -30,10 +30,10 @@ use crate::bindings::_helpers::contract_command::write::{ContractWrite, write_co use crate::bindings::_helpers::planner_selection::selectors::select_project_graph; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::refactor::contract_compare::compare_contracts; const GENERATE_ACTION: &str = "generate"; @@ -43,7 +43,7 @@ fn user_error(py: Python<'_>, message: &str, code: &str) -> PyErr { let raised = (|| { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", code)?; - registry::error(py, ErrorId::CliUser)?.call((message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs index c370bfe172..6d105a3a13 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs @@ -16,6 +16,7 @@ use sqlbuild_config::project::main::resolve_config_file::resolve_config_file; use sqlbuild_config::project::models::{Built, ConfigFile, ConfigPaths}; use crate::bindings::_helpers::boundary::config_values::config_value_to_python; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, record_class}; use crate::bindings::_helpers::records::ids::ErrorId; use crate::bindings::_helpers::records::registry; @@ -85,7 +86,7 @@ fn config_error(py: Python<'_>, failure: &ConfigFailure, files: &Files<'_>) -> P } let keywords = PyDict::new(py); keywords.set_item("help", failure.help.as_deref())?; - let error = registry::error(py, ErrorId::ProjectConfig)?.call((message,), Some(&keywords))?; + let error = error_class(py, ErrorId::ProjectConfig)?.call((message,), Some(&keywords))?; Ok(PyErr::from_value(error)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/resource_identities.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/resource_identities.rs index 212835ff19..3d3c34ddfc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/resource_identities.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/resource_identities.rs @@ -1,7 +1,7 @@ //! Canonical snake_case resource identity checks and SQL function node types. +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{ Bound, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, }; @@ -34,7 +34,7 @@ pub(crate) fn validate_resource_identity( let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("help", help_text)?; let error: Bound<'_, PyAny> = - registry::error(py, ErrorId::ResourceIdentity)?.call((message,), Some(&keywords))?; + error_class(py, ErrorId::ResourceIdentity)?.call((message,), Some(&keywords))?; Err(PyErr::from_value(error)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs index 46f14fc301..fb6455288c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs @@ -15,10 +15,10 @@ use sqlbuild_model_config::name_patterns::models::NamePattern; use crate::bindings::_helpers::contracts::effective_config::{ effective_config_target_fields, effective_config_target_name, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const TARGET_GROUPS: [(&str, RecordId); 4] = [ ("clone", RecordId::ClonePolicy), @@ -43,7 +43,7 @@ thread_local! { fn spec_error<'py>(py: Python<'py>, message: Bound<'py, PyString>) -> PyResult { Ok(PyErr::from_value( - registry::error(py, ErrorId::SpecConfig)?.call1((message,))?, + error_class(py, ErrorId::SpecConfig)?.call1((message,))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refusal.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refusal.rs index 72b2d7bd69..1a3cf0c7ba 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refusal.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refusal.rs @@ -4,15 +4,15 @@ use pyo3::prelude::{Bound, PyAnyMethods, PyErr, Python}; use pyo3::types::{PyDict, PyDictMethods}; use sqlbuild_core::cost_command::errors::CostCommandError; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; /// The `CliUserError` for a refused cost request. pub(crate) fn cost_error(py: Python<'_>, error: &CostCommandError) -> PyErr { let raised = (|| { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", error.code)?; - registry::error(py, ErrorId::CliUser)?.call((error.message.as_str(),), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((error.message.as_str(),), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/artifact.rs b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/artifact.rs index 84e847763f..f79ecd9cb9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/artifact.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/artifact.rs @@ -11,12 +11,12 @@ use sqlbuild_core::json::errors::JsonEmitError; use crate::bindings::_helpers::boundary::panics::compiler_guard; use crate::bindings::_helpers::dag_artifact::rows::{project_input, python_graph_input}; use crate::bindings::_helpers::graph::project_graph::CompiledProjectGraph; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; fn python_error(error: DagArtifactError, py: pyo3::Python<'_>) -> PyErr { match error { - DagArtifactError::LoaderDestination(message) => registry::error(py, ErrorId::SpecConfig) + DagArtifactError::LoaderDestination(message) => error_class(py, ErrorId::SpecConfig) .and_then(|class| class.call1((message,))) .map_or_else(|error| error, PyErr::from_value), DagArtifactError::MissingParameterType(name) => PyKeyError::new_err(name), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs index d79bb6cbb3..5563332f79 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs @@ -16,16 +16,16 @@ use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::dbt_command::init_project::build_dbt_init_project; use crate::bindings::_helpers::dbt_command::init_project::validate_dbt_init_project; use crate::bindings::_helpers::dbt_command::support::{color_enabled, flag, path, stream}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; fn missing_project(py: Python<'_>) -> PyErr { let raised = (|| { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", "C242")?; - registry::error(py, ErrorId::CliUser)?.call( + error_class(py, ErrorId::CliUser)?.call( ("sqb dbt init requires --project-dir pointing at a dbt project",), Some(&options), ) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs index eb2dcac4de..979b588dbd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs @@ -21,12 +21,12 @@ use sqlbuild_core::text::main::python_strip::python_strip; use crate::bindings::_helpers::compile_driver::python_calls::{ KeywordArguments, call_with, imported, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{ enum_from_value, new_record_with, record_class, }; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const DBT_EXECUTABLE_ENV_VAR: &str = "DBT_EXECUTABLE"; const COMMAND_ARGV_OPTIONS: (&[&str], &[&str]) = @@ -257,7 +257,7 @@ pub(crate) fn raised(py: Python<'_>, class_name: ErrorId, error: DbtCliError) -> keywords.set_item("help", help)?; } let instance: Bound<'_, PyAny> = - registry::error(py, class_name)?.call((error.message,), Some(&keywords))?; + error_class(py, class_name)?.call((error.message,), Some(&keywords))?; Ok(PyErr::from_value(instance)) }; created().unwrap_or_else(|failure| failure) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs index 5a0da4985a..9046f69ceb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs @@ -24,10 +24,10 @@ use crate::bindings::_helpers::dbt_interop::manifest::resolve_sqlbuild_model_dbt use crate::bindings::_helpers::planner_selection::model_selectors::{ resolve_sqlbuild_model_selector_names, split_selector_expansion, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const MODEL_RESOURCE_TYPE: &str = "model"; const SELECTION_OPTIONS: (&[&str], &[&str]) = ( @@ -217,7 +217,7 @@ fn selection_error(py: Python<'_>, error: DbtSelectionError) -> PyErr { let raised = || -> PyResult { let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("code", PATH_SELECTOR_ERROR_CODE)?; - let error: Bound<'_, PyAny> = registry::error(py, ErrorId::DbtInteropArgument)? + let error: Bound<'_, PyAny> = error_class(py, ErrorId::DbtInteropArgument)? .call((message,), Some(&keywords))?; Ok(PyErr::from_value(error)) }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs index 36b7047a13..257ecf0861 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs @@ -20,10 +20,10 @@ use sqlbuild_config::dbt_manifest::models::{ }; use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const DBT_REF_KIND: &str = "dbt_ref"; const RELATION_OPTIONS: (&[&str], &[&str]) = @@ -35,7 +35,7 @@ fn raised(py: Python<'_>, error: ManifestError) -> PyErr { keywords.set_item("code", error.code)?; keywords.set_item("help", error.help)?; let instance: Bound<'_, PyAny> = - registry::error(py, ErrorId::CompileInput)?.call((error.message,), Some(&keywords))?; + error_class(py, ErrorId::CompileInput)?.call((error.message,), Some(&keywords))?; Ok(PyErr::from_value(instance)) }; created().unwrap_or_else(|failure| failure) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs index 79de03a7da..c901f5ca89 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs @@ -23,9 +23,9 @@ use crate::bindings::_helpers::dbt_interop::graph::{ use crate::bindings::_helpers::dbt_interop::manifest::resolve_sqlbuild_model_dbt_refs; use crate::bindings::_helpers::dbt_interop::plan::build_dbt_interop_plan; use crate::bindings::_helpers::records::construct::enum_from_value; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const PLAN_OPTIONS: (&[&str], &[&str]) = ( &[ @@ -67,7 +67,7 @@ fn listed<'py>( || py.None().into_bound(py), |detail| PyString::new(py, &detail).into_any(), ); - let error: Bound<'py, PyAny> = registry::error(py, ErrorId::DbtInteropRuntime)? + let error: Bound<'py, PyAny> = error_class(py, ErrorId::DbtInteropRuntime)? .call(("dbt ls failed",), Some(&keywords(py, &[("help", help)])?))?; Err(PyErr::from_value(error)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs index ccf2edf5de..1ab8952417 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs @@ -22,6 +22,7 @@ use crate::bindings::_helpers::dbt_interop::pipeline_phases::run_dbt_sqlbuild_wo use crate::bindings::_helpers::dbt_interop::pipeline_prologue::progress; use crate::bindings::_helpers::dbt_interop::runner::DbtRunner; use crate::bindings::_helpers::dbt_interop::runtime_config::config_overrides; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; @@ -118,7 +119,7 @@ fn execute_dbt_interop_from_project(request: &Bound<'_, PyAny>) -> PyResult let kind = record_class(py, RecordId::DbtInteropCommand)?; if !command.eq(native_field(&kind, "RUN")?)? && !command.eq(native_field(&kind, "BUILD")?)? { return Err(PyErr::from_value( - registry::error(py, ErrorId::DbtInteropArgument)?.call1((format!( + error_class(py, ErrorId::DbtInteropArgument)?.call1((format!( "unsupported dbt interop execution command: {}", command.str()? ),))?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs index 7e9690b162..32e77e9d58 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs @@ -22,9 +22,9 @@ use crate::bindings::_helpers::dbt_interop::reference_resolver::DbtCompileRefere use crate::bindings::_helpers::dbt_interop::runtime_config::{ interop_adapter, manifest_path, parse_dbt_execution_args, plan_options, vars_mapping, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::{pyfunction, wrap_pyfunction}; use std::time::Instant; @@ -159,7 +159,7 @@ pub(crate) fn load_compiled_dbt_manifest<'py>( )?; if native_field(&result, "returncode")?.extract::()? != 0 { let detail = dbt_failure_detail(&result)?; - let error = registry::error(py, ErrorId::DbtInteropRuntime)?.call( + let error = error_class(py, ErrorId::DbtInteropRuntime)?.call( ("dbt compile failed",), Some(&keywords(py, &[("help", detail)])?), )?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs index ce896e3a80..9fce70fbaf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs @@ -19,11 +19,11 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_entries::display_plan::build_display_only_sqlbuild_plan; use crate::bindings::_helpers::planner_entries::execution_plan::build_execution_plan; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const BUILD_OPTIONS: (&[&str], &[&str]) = (&["environment", "request", "hooks"], &[]); const ATTACH_OPTIONS: (&[&str], &[&str]) = ( @@ -225,7 +225,7 @@ pub(crate) fn build_sqlbuild_plan_output<'py>( )?), ); match result { - Err(error) if error.is_instance(py, ®istry::error(py, ErrorId::PlannerInput)?) => { + Err(error) if error.is_instance(py, &error_class(py, ErrorId::PlannerInput)?) => { build_display_only_sqlbuild_plan( &native_field(&environment, "project")?, &selected, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs index 849fb98867..debd848a0a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs @@ -16,10 +16,10 @@ use crate::bindings::_helpers::dbt_interop::manifest::validate_compile_dbt_model use crate::bindings::_helpers::dbt_interop::manifest::validate_compile_dbt_model_reference; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const VALIDATE_OPTIONS: (&[&str], &[&str]) = ( &[ @@ -37,7 +37,7 @@ const SEED_CONFLICT_CODE: &str = "C217"; fn compile_input_error(py: Python<'_>, message: String, code: &str) -> PyErr { let created = || -> PyResult { - let error: Bound<'_, PyAny> = registry::error(py, ErrorId::CompileInput)?.call( + let error: Bound<'_, PyAny> = error_class(py, ErrorId::CompileInput)?.call( (message,), Some(&keywords( py, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs index 59581f6a0d..25e58142b1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs @@ -22,10 +22,10 @@ use crate::bindings::_helpers::dbt_interop::cli::{ }; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::types::CompilerDetach; const LAUNCH_FAILURE: &str = "failed to execute dbt"; @@ -288,8 +288,8 @@ pub(crate) fn launch_failure(py: Python<'_>, error: PyErr) -> PyErr { let created = || -> PyResult { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("help", error.value(py).str()?)?; - let instance: Bound<'_, PyAny> = registry::error(py, ErrorId::DbtInteropRuntime)? - .call((LAUNCH_FAILURE,), Some(&options))?; + let instance: Bound<'_, PyAny> = + error_class(py, ErrorId::DbtInteropRuntime)?.call((LAUNCH_FAILURE,), Some(&options))?; let raised: PyErr = PyErr::from_value(instance); raised.set_cause(py, Some(error.clone_ref(py))); Ok(raised) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs index 5d3313059e..bfee2edf09 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs @@ -40,9 +40,9 @@ use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const DEFAULT_DIFF_MAX_FULL_ROWS: i64 = 10_000_000; const ADAPTER_ERRORS: AdapterHost = AdapterHost::AdapterUserError; @@ -335,7 +335,7 @@ fn size_guard_error( keywords.set_item("details", details)?; keywords.set_item("code", "C270")?; keywords.set_item("help", report.help)?; - let replacement: Bound<'_, PyAny> = registry::error(py, ErrorId::DiffSizeGuard)? + let replacement: Bound<'_, PyAny> = error_class(py, ErrorId::DiffSizeGuard)? .call((report.message.as_str(),), Some(&keywords))?; Ok(caused(py, PyErr::from_value(replacement), error)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs index 636bde0e65..f7a1696932 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs @@ -9,9 +9,9 @@ use sqlbuild_cli::diff_report::models::DiffRequestFacts; use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::models::HostId; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; /// `name(**pairs)` with keyword arguments. pub(crate) fn call<'py>( @@ -43,7 +43,7 @@ pub(crate) fn cli_error(py: Python<'_>, class: ErrorId, error: &DiffUserError) - let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("code", error.code.as_str())?; keywords.set_item("help", help)?; - registry::error(py, class)?.call((error.message.as_str(),), Some(&keywords)) + error_class(py, class)?.call((error.message.as_str(),), Some(&keywords)) })(); match raised { Ok(instance) => PyErr::from_value(instance), @@ -81,7 +81,7 @@ pub(crate) fn matches_class( /// Whether `error` is an instance of the native error class `class`. pub(crate) fn matches_native(py: Python<'_>, error: &PyErr, class: ErrorId) -> PyResult { - error.value(py).is_instance(®istry::error(py, class)?) + error.value(py).is_instance(&error_class(py, class)?) } /// Whether `error` is an `Exception` rather than a `BaseException` such as an interrupt. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs index 6db76378e9..6ee384b9a7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs @@ -18,21 +18,20 @@ use sqlbuild_model_config::sql_values::models::RawSqlValue; use crate::bindings::_helpers::contracts::sql_values::{ SqlValueClasses, raw_value, sql_value, sql_value_error, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record}; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; fn declaration_error(py: Python<'_>, failure: DeclarationFailure) -> PyResult { Ok(match failure { DeclarationFailure::Parse(message) => { - PyErr::from_value(registry::error(py, ErrorId::DeclarationParse)?.call1((message,))?) + PyErr::from_value(error_class(py, ErrorId::DeclarationParse)?.call1((message,))?) } DeclarationFailure::Identity(message, help) => { let keywords = PyDict::new(py); keywords.set_item("help", help)?; PyErr::from_value( - registry::error(py, ErrorId::ResourceIdentity)? - .call((message,), Some(&keywords))?, + error_class(py, ErrorId::ResourceIdentity)?.call((message,), Some(&keywords))?, ) } DeclarationFailure::DecimalOverflow => { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_values.rs index 602b483475..605837e2c8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/header_values.rs @@ -6,9 +6,9 @@ use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::boundary::keyword_request::Request; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sqltext::model_headers::{ ColumnLocation, ParsedModelHeader, header_failure, model_output_columns, parse_model_headers, }; @@ -83,7 +83,7 @@ fn parse_header_values<'py>(request: Option<&Bound<'py, PyDict>>) -> PyResult = match request.optional("error_class")? { Some(class) if !class.is_none() => class, - _ => registry::error(py, ErrorId::ModelSqlParse)?, + _ => error_class(py, ErrorId::ModelSqlParse)?, }; let keywords: Bound<'py, PyDict> = PyDict::new(py); keywords.set_item("help", help)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs index 400c8c0c51..3c1e89c048 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs @@ -10,10 +10,10 @@ use crate::bindings::_helpers::discovery::python_module_files::discover_python_m use crate::bindings::_helpers::event_exporting::scope::current_scope; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::IntoPyObjectExt; /// One project directory under discovery. @@ -111,7 +111,7 @@ pub(crate) fn discovered<'py>( /// `sqlbuild._native.(message)`. pub(crate) fn discovery_error(py: Python<'_>, class_name: ErrorId, message: String) -> PyErr { - registry::error(py, class_name) + error_class(py, class_name) .and_then(|class| class.call1((message,))) .map_or_else(|error| error, PyErr::from_value) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/python_function_files.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/python_function_files.rs index b28b116fa7..af9d8ec4e1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/python_function_files.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/python_function_files.rs @@ -21,10 +21,10 @@ use crate::bindings::_helpers::discovery::declaration_records::path_class; use crate::bindings::_helpers::discovery::project_files::path_object; use crate::bindings::_helpers::discovery::raised::{failure_error, read_error, stage_error}; use crate::bindings::_helpers::discovery::snapshot::{in_snapshot, project_root, project_tree}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::models::NativeProjectTree; const AST_MODULE: &str = "ast"; @@ -44,7 +44,7 @@ fn parse_error(source: &FunctionSource<'_>, detail: &str, cause: Option) let py: Python<'_> = source.file_path.py(); let raised = (|| { let message: String = format!("Python function '{}' {detail}", source.file_path.str()?); - registry::error(py, ErrorId::ModelSqlParse)?.call1((message,)) + error_class(py, ErrorId::ModelSqlParse)?.call1((message,)) })(); match raised { Ok(instance) => { @@ -128,7 +128,7 @@ fn unsupported_keys(source: &FunctionSource<'_>, function: &UdfFunction) -> PyRe let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("help", help)?; let error: Bound<'_, PyAny> = - registry::error(py, ErrorId::ModelSqlParse)?.call((message,), Some(&keywords))?; + error_class(py, ErrorId::ModelSqlParse)?.call((message,), Some(&keywords))?; Err(PyErr::from_value(error)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/raised.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/raised.rs index ab2421b739..aca3587556 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/raised.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/raised.rs @@ -10,9 +10,9 @@ use sqlbuild_discovery::models::{DiscoveryFailure, ReadFailure, StageFailure}; use sqlbuild_discovery::tree::models::ProjectTree; use crate::bindings::_helpers::discovery::project_files::path_object; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const BUILTINS_MODULE: &str = "builtins"; const OS_MODULE: &str = "os"; @@ -55,7 +55,7 @@ pub(crate) fn discovery_error( raised((|| { let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("help", help)?; - registry::error(py, *class)?.call((message,), Some(&keywords)) + error_class(py, *class)?.call((message,), Some(&keywords)) })()) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs index 7b28d86fc3..55c95a0e56 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs @@ -11,15 +11,15 @@ use sqlbuild_model_config::sql_values::models::{RawKey, RawSqlValue}; use crate::bindings::_helpers::contracts::sql_values::{SqlValueClasses, raw_value, sql_value}; use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record}; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; pub(crate) type NativeBlock<'py> = (Bound<'py, PyDict>, String, Bound<'py, PyAny>); fn parse_error(py: Python<'_>, message: String) -> PyResult { Ok(PyErr::from_value( - registry::error(py, ErrorId::SqlTestParse)?.call1((message,))?, + error_class(py, ErrorId::SqlTestParse)?.call1((message,))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs index 66b0625650..0f354cfde5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs @@ -16,8 +16,8 @@ use sqlbuild_model_config::errors::{ConfigError, ErrorClass}; use crate::bindings::_helpers::model_config::authored_nodes::PyNode; use crate::bindings::_helpers::model_config::contract_classes::yaml_entry_classes; use crate::bindings::_helpers::model_config::header_metadata::{ContractClasses, audit_tuple}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; /// The directory whose schema YAML files may declare seeds. const SEEDS_DIRECTORY: &str = "seeds"; @@ -47,8 +47,8 @@ pub(crate) struct YamlClasses<'py> { /// The Python error `error` raises: a resource identity error, else the file kind's parse error. fn parse_error(py: Python<'_>, error: ConfigError, parse_class: ErrorId) -> PyResult { let class: Bound<'_, PyAny> = match error.class { - ErrorClass::ResourceIdentity => registry::error(py, ErrorId::ResourceIdentity)?, - _ => registry::error(py, parse_class)?, + ErrorClass::ResourceIdentity => error_class(py, ErrorId::ResourceIdentity)?, + _ => error_class(py, parse_class)?, }; let keywords: Bound<'_, PyDict> = PyDict::new(py); if let Some(help) = error.help { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs index 407544c18f..993b715210 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs @@ -2,10 +2,10 @@ use std::ffi::CString; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::exceptions::{PyUnicodeDecodeError, PyValueError}; use pyo3::prelude::{ Bound, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, @@ -25,7 +25,7 @@ const TIMESTAMP_COLUMN: usize = 11; /// `FingerprintInputError(message)`. pub(crate) fn fingerprint_input_error(py: Python<'_>, message: &str) -> PyErr { - match registry::error(py, ErrorId::FingerprintInput).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::FingerprintInput).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/query_hashes.rs b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/query_hashes.rs index 743cc60100..904c200223 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/query_hashes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/query_hashes.rs @@ -9,8 +9,8 @@ use sqlbuild_analysis::sql_tokens::main::normalized_query_text::normalized_query use sqlbuild_core::panics::main::is_compiler_panic::is_compiler_panic; use crate::bindings::_helpers::boundary::panics::compiler_error; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::types::CompilerDetach; /// `QueryFingerprintError(message)`, or the compiler error a native panic becomes. @@ -18,7 +18,7 @@ fn query_fingerprint_error(py: Python<'_>, message: String) -> PyErr { if is_compiler_panic(&message) { return compiler_error(message); } - match registry::error(py, ErrorId::QueryFingerprint).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::QueryFingerprint).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs b/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs index 341895c43e..5b1b7778bb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs @@ -16,9 +16,9 @@ use crate::bindings::_helpers::discovery::description_inputs::externally_describ use crate::bindings::_helpers::format_command::files::{ FormatChange, file_dictionary, overlaid, persist_changes, sorted_items, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::rules::dsl_headers::format_native_headers; use crate::bindings::_helpers::rules::dsl_headers::reject_unparseable_header_rewrites; use crate::bindings::_helpers::rules::dsl_headers::safe_format_files; @@ -258,7 +258,7 @@ pub(crate) fn run_format<'py>(request: &FormatRequest<'_, 'py>) -> PyResult
{ - return Err(registry::error(py, ErrorId::Lint)? + return Err(error_class(py, ErrorId::Lint)? .call1(("fixture-null formatting requires the project adapter",)) .map(pyo3::PyErr::from_value)?); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs index dc6ccc1413..cd4e8a8edb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs @@ -31,10 +31,10 @@ use crate::bindings::_helpers::discovery::yaml_records::{ }; use crate::bindings::_helpers::planner_selection::selectors::select_project_graph; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const SELECTION_CODE: &str = "S007"; @@ -56,7 +56,7 @@ fn planner_error(py: Python<'_>, message: &str, code: &str) -> PyErr { let raised = (|| -> PyResult> { let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("code", code)?; - registry::error(py, ErrorId::PlannerInput)?.call((message,), Some(&keywords)) + error_class(py, ErrorId::PlannerInput)?.call((message,), Some(&keywords)) })(); match raised { Ok(instance) => PyErr::from_value(instance), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs index 4f79813aa6..0569d4a058 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs @@ -33,9 +33,9 @@ use crate::bindings::_helpers::result_output::documents::write_execution_json_ou use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use sqlbuild_core::constants::SOURCE_FRESHNESS_TABLE_NAME as STATE_TABLE_NAME; const STALE_REQUIRES_STATE_MESSAGE: &str = "freshness --fail-on-stale requires --state"; const STALE_REQUIRES_STATE_CODE: &str = "C238"; @@ -59,7 +59,7 @@ fn user_error(py: Python<'_>, (message, code): (&str, &str)) -> PyErr { let raised = (|| { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", code)?; - registry::error(py, ErrorId::CliUser)?.call((message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs index ac2aef966f..6240cbb36d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs @@ -18,9 +18,9 @@ use sqlbuild_analysis::python_selection::models::{ use crate::bindings::_helpers::boundary::panics::compiler_guard; use crate::bindings::_helpers::graph::project_graph::{CompiledProjectGraph, NativeProjectGraph}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; type NameRows = Vec<(String, Vec)>; /// `(name, tags, POSIX relative path, upstream node names)` of one discovered node. @@ -40,7 +40,7 @@ fn planner_error(py: Python<'_>, error: SelectorError) -> PyErr { let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("code", error.code)?; keywords.set_item("help", error.help)?; - registry::error(py, ErrorId::PlannerInput)?.call((error.message,), Some(&keywords)) + error_class(py, ErrorId::PlannerInput)?.call((error.message,), Some(&keywords)) })(); match raised { Ok(instance) => PyErr::from_value(instance), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs index a434d5a90d..9ca684d2eb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs @@ -16,9 +16,9 @@ use sqlbuild_core::init_command::main::render_init_summary::render_init_summary; use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords}; use crate::bindings::_helpers::init_command::scaffold::scaffold_blank_project; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::workspace_commands::commands::update_sqlbuild_skills; const EXISTS_MESSAGE: &str = "sqlbuild_project.toml already exists in this directory"; @@ -27,7 +27,7 @@ fn exists_error(py: Python<'_>) -> PyErr { let raised = (|| { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", "C900")?; - registry::error(py, ErrorId::CliUser)?.call((EXISTS_MESSAGE,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((EXISTS_MESSAGE,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs index f53d9c36ec..1dcc08bb82 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs @@ -31,10 +31,10 @@ use crate::bindings::_helpers::janitor::janitor_phases::{ use crate::bindings::_helpers::janitor::janitor_plan::{janitor_plan_text, janitor_result_counts}; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const COMMAND_NAME: &str = "janitor"; @@ -57,7 +57,7 @@ fn settings_error(py: Python<'_>, error: JanitorSettingsError) -> PyErr { let raised = (|| { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", error.code)?; - registry::error(py, ErrorId::CliUser)?.call((error.message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((error.message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs index 021334fc12..6e3ecc5947 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs @@ -19,9 +19,9 @@ use crate::bindings::_helpers::janitor::janitor_planning::{ }; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const UNKNOWN_VIEW_CODE: &str = "C503"; const UNKNOWN_VIEW_HELP: &str = @@ -201,7 +201,7 @@ fn unknown_view_error(py: Python<'_>, requests: &Bound<'_, PyAny>) -> PyResult

= PyDict::new(py); options.set_item("code", UNKNOWN_VIEW_CODE)?; options.set_item("help", UNKNOWN_VIEW_HELP)?; - let error: Bound<'_, PyAny> = registry::error(py, ErrorId::CliUser)?.call( + let error: Bound<'_, PyAny> = error_class(py, ErrorId::CliUser)?.call( (format!( "no compatibility view is recorded at {}", names.join(", ") diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs index 2d25b5cc21..79671147a0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs @@ -49,6 +49,7 @@ use crate::bindings::_helpers::planner_selection::selectors::{ }; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; @@ -103,7 +104,7 @@ fn user_error(py: Python<'_>, error: LineageError) -> PyErr { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", error.code)?; options.set_item("help", error.help)?; - registry::error(py, ErrorId::CliUser)?.call((error.message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((error.message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), @@ -584,7 +585,7 @@ fn selector_failure( error: PyErr, ) -> PyErr { let check = || -> PyResult<()> { - let planner_error: Bound<'_, PyAny> = registry::error(py, ErrorId::PlannerInput)?; + let planner_error: Bound<'_, PyAny> = error_class(py, ErrorId::PlannerInput)?; if !matches!(source, LineageSource::Cached(_)) || !error.is_instance(py, &planner_error) || native_field(error.value(py), "code")?.extract::()? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs index ea01075063..d32bde3d05 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs @@ -23,9 +23,9 @@ use crate::bindings::_helpers::lineage::lineage_objects::{LineageClasses, log_li use crate::bindings::_helpers::lineage::project_schema::{ fast_schema, inferred_names, rich_schema, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::models::ProjectCatalog; use crate::bindings::types::CompilerDetach; @@ -266,7 +266,7 @@ fn output_columns(classes: &LineageClasses<'_>, facts: &Bound<'_, PyAny>) -> PyR } fn unknown_dialect_error(py: Python<'_>, dialect: &str) -> PyErr { - match registry::error(py, ErrorId::UnknownLineageDialect) + match error_class(py, ErrorId::UnknownLineageDialect) .and_then(|class| class.call1((format!("Unknown dialect: {dialect}"),))) { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs index 88ba6f7884..348540b14c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs @@ -41,10 +41,10 @@ use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::planner_resolution::cursor_overrides::type_cursor_overrides; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::references::source_relations::render_source_relation; use crate::bindings::_helpers::result_output::documents::format_load_execution_json; use crate::bindings::_helpers::result_output::documents::write_execution_json_output; @@ -139,7 +139,7 @@ fn invocation<'py>(py: Python<'py>, request: &Bound<'py, PyAny>) -> PyResult, message: String) -> PyErr { - match registry::error(py, ErrorId::CliUser).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::CliUser).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs index 52dd1441a9..68a03441de 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs @@ -18,11 +18,11 @@ use crate::bindings::_helpers::contracts::spec_resolution::loader_destination_pa use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const LOADER_NODE_KEY: &str = "sqlbuild_loader_node"; const LOADER_TABLE_PREFIX: &str = "__loader__"; @@ -207,7 +207,7 @@ fn unknown_selector(py: Python<'_>, error: &UnknownLoadSelector) -> PyErr { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", UNKNOWN_SELECTOR_CODE)?; options.set_item("help", UNKNOWN_SELECTOR_HELP)?; - registry::error(py, ErrorId::CliUser)?.call( + error_class(py, ErrorId::CliUser)?.call( (format!( "sqb load selector '{}' does not match any managed source or loader", error.name diff --git a/crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs b/crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs index fc23adf7b1..db04cdb028 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs @@ -21,9 +21,9 @@ use crate::bindings::_helpers::manifest::rows::{ }; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const DATETIME_MODULE: &str = "datetime"; @@ -54,7 +54,7 @@ impl NativeManifest { fn python_error(error: ManifestError, py: Python<'_>) -> PyErr { match error { - ManifestError::QueryFingerprint(message) => registry::error(py, ErrorId::QueryFingerprint) + ManifestError::QueryFingerprint(message) => error_class(py, ErrorId::QueryFingerprint) .and_then(|class| class.call1((message,))) .map_or_else(|error| error, PyErr::from_value), ManifestError::MissingParameterType(name) => PyKeyError::new_err(name), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs index 8b0f142fd9..64c535d0a9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs @@ -7,8 +7,8 @@ use sqlbuild_model_config::errors::{ConfigError, ErrorClass}; use crate::bindings::_helpers::model_config::config_values::config_value_type_error; use crate::bindings::_helpers::model_config::errors::NativeConfigError; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const EXPECTED_STRING: &str = "a string"; @@ -88,7 +88,7 @@ impl NativeConfigError { ErrorId::CompileInput } }; - registry::error(py, class)?.call((&self.message,), Some(&keywords)) + error_class(py, class)?.call((&self.message,), Some(&keywords)) } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs index 8b3caf15ae..b58accdc7d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs @@ -5,8 +5,8 @@ use pyo3::types::{PyBool, PyInt, PyList, PyString, PyTuple}; use pyo3::{pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const DATETIME_MODULE: &str = "datetime"; @@ -33,7 +33,7 @@ pub(crate) fn config_value_type_error<'py>( let py = actual_type.py(); let type_name: String = actual_type.getattr("__name__")?.extract()?; call_with( - ®istry::error(py, ErrorId::ConfigValueType)?, + &error_class(py, ErrorId::ConfigValueType)?, &[ ( "message", diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/header_columns.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/header_columns.rs index 815c84dfbb..39992ecedb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/header_columns.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/header_columns.rs @@ -15,8 +15,8 @@ use crate::bindings::_helpers::model_config::config_errors::config_exception; use crate::bindings::_helpers::model_config::config_errors::native_config_error; use crate::bindings::_helpers::model_config::contract_classes::contract_classes; use crate::bindings::_helpers::model_config::header_metadata::{ContractClasses, column_tuple}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; /// `(file_path, label)`: the path and label every message names. pub(crate) type ColumnSite<'a> = (&'a str, &'a str); @@ -60,7 +60,7 @@ fn parse_schema_columns<'py>( fn raised(py: Python<'_>, error: ConfigError, declaration_errors: bool) -> PyErr { let built = (|| { if declaration_errors && error.class == ErrorClass::CompileInput { - return registry::error(py, ErrorId::DeclarationParse)?.call1((error.message,)); + return error_class(py, ErrorId::DeclarationParse)?.call1((error.message,)); } let native = native_config_error(py, error)?.into_bound(py).into_any(); config_exception(&native, None) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs index b31a0e0bd2..984795e66c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs @@ -19,8 +19,8 @@ use crate::bindings::_helpers::model_config::config_templates::{ resolve_effective_vars, }; use crate::bindings::_helpers::model_config::unicode_environment::unicode_environment; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const UUID_MODULE: &str = "uuid"; const ENVIRONMENT_READ: &str = "env"; @@ -83,7 +83,7 @@ pub(crate) fn expanded_effective_vars<'py>( ) -> PyResult> { let py: Python<'py> = raw_values.py(); if let Some((name, path, byte_offset)) = lone_surrogate_site(raw_values)? { - let error: Bound<'py, PyAny> = registry::error(py, ErrorId::CompileInput)?.call( + let error: Bound<'py, PyAny> = error_class(py, ErrorId::CompileInput)?.call( (format!( "Variable '{name}' holds a lone surrogate in {path} at UTF-8 byte \ {byte_offset}, which is not valid Unicode text" diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs index 2d3195aea4..39a2480d3f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs @@ -7,8 +7,8 @@ use pyo3::types::{PyBytes, PyBytesMethods, PyDict, PyDictMethods, PyString}; use pyo3::{pyclass, pymethods}; use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; /// `os.environ`, raising a clear error for a value holding undecodable bytes. #[pyclass(module = "sqlbuild._native", frozen, mapping)] @@ -46,7 +46,7 @@ impl UnicodeEnvironment { ), )?; Err(PyErr::from_value( - registry::error(py, ErrorId::CompileInput)?.call( + error_class(py, ErrorId::CompileInput)?.call( (format!( "Environment variable '{name}' is not valid UTF-8 text: byte {byte_offset} \ starts an invalid UTF-8 sequence" diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs index 576dead32b..3de755ced5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs @@ -9,15 +9,13 @@ use sqlbuild_analysis::planner_changes::models::{ Backfill, BackfillAction, ChangeKind, SchemaChangeKind, SchemaColumnSource, SchemaFindingRow, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; /// `PlannerInputError(message)` for an unknown replay policy. pub(crate) fn replay_policy_error(py: Python<'_>, error: UnknownReplayPolicy) -> PyErr { - match registry::error(py, ErrorId::PlannerInput) - .and_then(|class| class.call1((error.message(),))) - { + match error_class(py, ErrorId::PlannerInput).and_then(|class| class.call1((error.message(),))) { Ok(value) => PyErr::from_value(value), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs index f8b62f1a38..3d7a4f9dda 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs @@ -1,10 +1,10 @@ //! Python boundary values shared by plan entry and plan output assembly. use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::IntoPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::PyString; @@ -69,7 +69,7 @@ pub(super) fn error_of( message: &str, fields: &[(&str, Bound<'_, PyAny>)], ) -> PyErr { - match registry::error(py, class) + match error_class(py, class) .and_then(|class| class.call((message,), Some(&keywords(py, fields)?))) { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs index 4d2c2da06c..338a159255 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs @@ -26,10 +26,10 @@ use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::graph::algorithms::{closure, inverted}; use crate::bindings::_helpers::graph::keys::KeyCache; use crate::bindings::_helpers::planner_identity::hashing::graph_key; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const TABLE_FN_TEST_MODE: &str = "table_fn"; const INLINE_SQL_HOOK: &str = "inline SQL"; @@ -247,7 +247,7 @@ pub(crate) fn build_downstream_deps<'py>( } fn planner_input_error(py: Python<'_>, message: String) -> PyErr { - match registry::error(py, ErrorId::PlannerInput).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::PlannerInput).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs index 932af40c79..b053c04bd5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs @@ -14,9 +14,9 @@ use sqlbuild_core::panics::main::is_compiler_panic::is_compiler_panic; use crate::bindings::_helpers::boundary::panics::compiler_error; use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::types::CompilerDetach; /// The query fingerprint of a model, or the planner input error naming the model. @@ -45,7 +45,7 @@ fn fingerprint_error(py: Python<'_>, subject: &str, message: String) -> PyErr { } let text = |value: &str| PyString::new(py, value).into_any(); let raised: PyResult> = - registry::error(py, ErrorId::PlannerInput).and_then(|class| { + error_class(py, ErrorId::PlannerInput).and_then(|class| { class.call( (format!( "{subject} cannot be fingerprinted for change detection: {message}" diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs index 7d74bf6b36..ddcd356b04 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs @@ -11,10 +11,10 @@ use crate::bindings::_helpers::planner_migrations::model_handover::{ use crate::bindings::_helpers::planner_migrations::models::{ CompatibilityCheck, MigrationDecisionRequest, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_from_value, enum_member}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::state_rows::migration_projections::newest_move; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::PyBool; @@ -80,7 +80,7 @@ pub(super) fn decide<'py>( if key(&origin)? == key(&destination)? { let name: String = native_field(&item, "name")?.extract()?; return Err(pyo3::PyErr::from_value( - registry::error(py, ErrorId::PlannerInput)?.call1((format!( + error_class(py, ErrorId::PlannerInput)?.call1((format!( "model '{name}': migrate_from names the model's own relation" ),))?, )); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs index 4b325ae02c..7328e691be 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs @@ -4,10 +4,10 @@ use crate::bindings::_helpers::compile_driver::python_calls::call_with; use crate::bindings::_helpers::planner_migrations::constants::QUALIFIED_RELATION_MAX_PARTS; use crate::bindings::_helpers::planner_migrations::models::ModelMigrationRequest; use crate::bindings::_helpers::planner_phases::runtime::runtime_field; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::PyErr; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PySet, PySetMethods}; @@ -65,7 +65,7 @@ fn named<'py>( fn input_error(py: Python<'_>, message: String) -> PyResult { Ok(PyErr::from_value( - registry::error(py, ErrorId::PlannerInput)?.call1((message,))?, + error_class(py, ErrorId::PlannerInput)?.call1((message,))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs index c66284f8e2..8a25585108 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs @@ -4,11 +4,11 @@ use crate::bindings::_helpers::compile_driver::python_calls::{call_with, keyword use crate::bindings::_helpers::model_config::config_values::config_str as authored_config_str; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::models::HostId; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyFrozenSet, PyString, PyTuple}; use pyo3::{BoundObject, IntoPyObject}; @@ -82,7 +82,7 @@ pub(crate) fn planner_error( message: &str, (code, help): (Option<&str>, Option<&str>), ) -> PyErr { - let raised = registry::error(py, ErrorId::PlannerInput).and_then(|class| { + let raised = error_class(py, ErrorId::PlannerInput).and_then(|class| { let fields = keywords( py, &[ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs index 98c8ccb4f9..7108b75d93 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs @@ -27,10 +27,10 @@ use crate::bindings::_helpers::planner_resolution::cursor_windows::without_desti use crate::bindings::_helpers::planner_resolution::future_safety::resolve_future_cursor_safety; use crate::bindings::_helpers::planner_resolution::models::ModelSqlRequest; use crate::bindings::_helpers::planner_resolution::values::string; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::{IntoPyObject, PyErr}; @@ -155,7 +155,7 @@ pub(crate) fn compute_model_cursor_bounds<'py>( ), )?; return Err(PyErr::from_value(call_with( - ®istry::error(py, ErrorId::PlannerInput)?, + &error_class(py, ErrorId::PlannerInput)?, &[ ("message", refusal.get_item(0)?), ("code", string(py, "S302")), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs index fc58ce0f19..6757d9996c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs @@ -5,9 +5,9 @@ use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, use crate::bindings::_helpers::model_config::config_values::config_str as authored_config_str; use crate::bindings::_helpers::planner_resolution::values::{method, string}; use crate::bindings::_helpers::records::construct::enum_from_value; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{ Bound, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, }; @@ -77,7 +77,7 @@ pub(crate) fn type_cursor_overrides<'py>( } } let kind = override_kind(&models, integer_literals).map_err(|message| { - match registry::error(py, ErrorId::PlannerInput).and_then(|class| call_with(&class, &[ + match error_class(py, ErrorId::PlannerInput).and_then(|class| call_with(&class, &[ ("message", string(py, &message)), ("code", string(py, "S303")), ("help", string(py, "select models with one cursor type, or set each type explicitly with --start-cursor-ts/--end-cursor-ts and --start-cursor-int/--end-cursor-int")), ])) { Ok(error) => PyErr::from_value(error), Err(error) => error } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs index ec9d3d7352..ce480daf28 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs @@ -29,10 +29,10 @@ use crate::bindings::_helpers::planner_resolution::cursor_windows::without_desti use crate::bindings::_helpers::planner_resolution::future_safety::resolve_future_cursor_safety; use crate::bindings::_helpers::planner_resolution::values::string; use crate::bindings::_helpers::planner_strategy::model_entries::resolve_microbatch_lookback; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyString, PyTuple}; use pyo3::{IntoPyObject, PyErr, pyfunction, wrap_pyfunction}; @@ -526,7 +526,7 @@ pub(crate) fn cursor_safety_configs<'py>( } fn compile_input_error(py: Python<'_>, message: String) -> PyErr { - match registry::error(py, ErrorId::CompileInput).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::CompileInput).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs index ce18e918e7..2222e558a9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs @@ -3,17 +3,17 @@ use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported, keywords}; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::planner_resolution::cursor_bounds::duration; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use sqlbuild_cursor::algebra::models::{DurationSpan, Grain, Scalar}; use sqlbuild_cursor::planner::main::safety_horizon::safety_horizon; pub(super) fn safety_error(py: Python<'_>, class: ErrorId, message: &str) -> PyErr { - match registry::error(py, class).and_then(|class| class.call1((message,))) { + match error_class(py, class).and_then(|class| class.call1((message,))) { Ok(value) => PyErr::from_value(value), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs index df8eb54a4d..3d2061bdd9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs @@ -4,11 +4,11 @@ use crate::bindings::_helpers::compile_driver::python_calls::call_with; use crate::bindings::_helpers::cursor::conversion::CursorSession; use crate::bindings::_helpers::cursor::scalars::parse_value; use crate::bindings::_helpers::planner_resolution::values::string; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use pyo3::{IntoPyObject, pyfunction, wrap_pyfunction}; @@ -142,7 +142,7 @@ pub(crate) fn unreadable_cursor_inputs_error<'py>( input_names: Vec, ) -> PyResult> { call_with( - ®istry::error(py, ErrorId::PlannerInput)?, + &error_class(py, ErrorId::PlannerInput)?, &[ ( "message", diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs index 776e136cfb..4289e3a46e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs @@ -13,10 +13,10 @@ use crate::bindings::_helpers::planner_resolution::cursor_safety::{ horizon, replace, safety_duration, safety_error, timestamp_bound, utc_clock, }; use crate::bindings::_helpers::planner_resolution::values::string; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{ Bound, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, }; @@ -225,7 +225,7 @@ pub(crate) fn apply_maximum_start_policy<'py>( )?; let error = |non_idempotent: bool| -> PyResult> { Err(PyErr::from_value(call_with( - ®istry::error(py, ErrorId::MaximumAutomaticStart)?, + &error_class(py, ErrorId::MaximumAutomaticStart)?, &[ ( "message", diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs index 41b40b77f5..c14d9d7bd2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs @@ -16,11 +16,11 @@ use crate::bindings::_helpers::planner_resolution::refs::{ resolve_udf_references, }; use crate::bindings::_helpers::planner_resolution::sources::resolve_sources; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyList, PyString, PyTuple}; use pyo3::{PyErr, pyfunction, wrap_pyfunction}; @@ -268,7 +268,7 @@ fn intrinsic_bounds<'py>( } fn unresolved_bounds_error(py: Python<'_>, name: &str, cause: Option<&str>) -> PyResult { - let error = registry::error(py, ErrorId::PlannerInput)?; + let error = error_class(py, ErrorId::PlannerInput)?; let kwargs = PyDict::new(py); let message = if let Some(cause) = cause { kwargs.set_item("help", "rebuild it with an explicit cursor interval (--start-cursor-ts and --end-cursor-ts, or the -int forms), or make it a microbatch model so a full rebuild can run batch by batch")?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs index f8d04366c5..a7344e0805 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs @@ -12,10 +12,10 @@ use crate::bindings::_helpers::planner_scenario::graph::plan_scenario_graph; use crate::bindings::_helpers::planner_scenario::models::ScenarioRelations; use crate::bindings::_helpers::planner_scenario::relations::build_scenario_relation_plan; use crate::bindings::_helpers::planner_scenario::values::string; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python, pyfunction}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; @@ -177,7 +177,7 @@ fn raise_for_warnings(warnings: &Bound<'_, PyAny>) -> PyResult<()> { } if let Some(code) = code { return Err(PyErr::from_value(call_with( - ®istry::error(py, ErrorId::PlannerInput)?, + &error_class(py, ErrorId::PlannerInput)?, &[ ("message", string(py, &messages.join("\n"))), ("code", code), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs index ac7486a74d..3c431e35cf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs @@ -1,8 +1,8 @@ //! Existing Python model constructors and scenario diagnostics. use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{Bound, PyAny, PyErr, PyResult, Python}; use pyo3::types::PyString; @@ -21,7 +21,7 @@ pub(super) fn error( args.push(("help", string(py, help))); } Ok(PyErr::from_value(call_with( - ®istry::error(py, ErrorId::PlannerInput)?, + &error_class(py, ErrorId::PlannerInput)?, &args, )?)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs index 95dbc9e71d..7b505b24b1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs @@ -6,8 +6,8 @@ use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyString, PyStringMethods}; use sqlbuild_analysis::graph::errors::SelectorError; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const PRIVATE_USE: std::ops::Range = 0xF0000..0xFFFFE; @@ -107,7 +107,7 @@ impl<'py> Carrier<'py> { .map(|help| self.back(help)) .transpose()?; keywords.set_item("help", help)?; - registry::error(self.py, ErrorId::PlannerInput)? + error_class(self.py, ErrorId::PlannerInput)? .call((self.back(&error.message)?,), Some(&keywords)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs index 2e7b609e08..301b939fea 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs @@ -14,9 +14,9 @@ use sqlbuild_analysis::planner_strategy::models::{ ChangeFacts, MaterializationType, PlanChangeKind, WarningRow, WarningSeverity, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const YML_SOURCE: &str = "yml"; const FULL_BACKFILL: &str = "full"; @@ -154,7 +154,7 @@ pub(crate) fn input_error( message: &str, code: Option<&str>, ) -> PyErr { - let raised: PyResult> = registry::error(py, class).and_then(|class| { + let raised: PyResult> = error_class(py, class).and_then(|class| { let options: Bound<'_, PyDict> = PyDict::new(py); if let Some(code) = code { options.set_item("code", code)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs index 2386aa0130..c75f0aa00b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs @@ -24,9 +24,9 @@ use crate::bindings::_helpers::model_config::template_data::record_reads; use crate::bindings::_helpers::project_assembly::models::{ NativeProjectResources, NativeResourceFailure, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::types::CompilerDetach; const OS_MODULE: &str = "os"; @@ -334,15 +334,14 @@ fn failure_error<'py>( held: &[Bound<'py, PyAny>], ) -> PyResult> { match error { - AssemblyError::CompileInput { message, help } => { - registry::error(py, ErrorId::CompileInput)?.call( + AssemblyError::CompileInput { message, help } => error_class(py, ErrorId::CompileInput)? + .call( (message,), Some(&keywords( py, &[("help", help.into_pyobject(py)?.into_any())], )?), - ) - } + ), AssemblyError::Value(message) => { Ok(PyValueError::new_err(message).value(py).clone().into_any()) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs index dc5226d709..b36fb23fb4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs @@ -11,10 +11,10 @@ use sqlbuild_analysis::assembly::project::main::sql_analysis_opt_out_help::sql_a use sqlbuild_analysis::assembly::project::models::{SyntaxCheck, SyntaxMode}; use crate::bindings::_helpers::project_assembly::resources::syntax_error_message; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const GENERIC_DIALECT: &str = "generic"; @@ -44,7 +44,7 @@ fn syntax_error(py: Python<'_>, message: String) -> PyErr { let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("help", sql_analysis_opt_out_help(true))?; let error: Bound<'_, PyAny> = - registry::error(py, ErrorId::CompileInput)?.call((message,), Some(&keywords))?; + error_class(py, ErrorId::CompileInput)?.call((message,), Some(&keywords))?; Ok(PyErr::from_value(error)) }; raised().unwrap_or_else(|error| error) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs b/crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs index 4d8b471f14..9b72b40611 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs @@ -22,9 +22,9 @@ use crate::bindings::_helpers::query_command::project::{ProjectAdapter, project_ use crate::bindings::_helpers::query_command::query_values::{ csv_text, display_text, json_cell, python_json_rows, strict_width, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const LONG_FORMAT: &str = "long"; const TABLE_FORMAT: &str = "table"; @@ -43,7 +43,7 @@ fn user_error(py: Python<'_>, message: &str, code: Option<&str>, help: Option<&s if let Some(help) = help { options.set_item("help", help)?; } - registry::error(py, ErrorId::CliUser)?.call((message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), @@ -189,7 +189,7 @@ fn run_sql<'py>( Err(_) => value.str().map(Bound::into_any), }; let wrapped: PyErr = match message - .and_then(|message| registry::error(py, ErrorId::QueryExecution)?.call1((message,))) + .and_then(|message| error_class(py, ErrorId::QueryExecution)?.call1((message,))) { Ok(raised) => PyErr::from_value(raised), Err(failure) => failure, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/auditing.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/auditing.rs index 1a0b1dee3c..fb2ddfe579 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/auditing.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/auditing.rs @@ -8,13 +8,13 @@ use sqlbuild_model_config::header_metadata::main::check_threshold_bound::check_t use sqlbuild_model_config::header_metadata::main::check_threshold_pair::check_threshold_pair; use sqlbuild_model_config::header_metadata::models::{ThresholdBound, ThresholdInput}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; /// The `MeasurementAuditError` carrying `message`. fn measurement_error(py: Python<'_>, message: &str) -> PyErr { - match registry::error(py, ErrorId::MeasurementAudit).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::MeasurementAudit).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs index c164b65794..c3ee9d27eb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs @@ -4,10 +4,10 @@ use pyo3::IntoPyObjectExt; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyTuple}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::rules::relation_keys::entry_relation_key_row; /// `CompilerDiagnostic` positions. @@ -385,6 +385,6 @@ pub(crate) fn build_context_declaration_expansion( /// A `CompileInputError` carrying `message`. pub(crate) fn compile_input_error(py: Python<'_>, message: &str) -> PyResult { Ok(PyErr::from_value( - registry::error(py, ErrorId::CompileInput)?.call1((message,))?, + error_class(py, ErrorId::CompileInput)?.call1((message,))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs index 3d65e47dca..51478550f0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs @@ -10,9 +10,9 @@ use sqlbuild_sqltext::sql_scan::main::reads_differently_from_generic::reads_diff use sqlbuild_sqltext::sql_scan::main::unsupported_line_comment_prefixes::unsupported_line_comment_prefixes; use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; /// `SqlLexicalSyntax.line_comment_prefixes` position. const LINE_COMMENT_PREFIXES_FIELD: usize = 5; @@ -57,7 +57,7 @@ pub(crate) fn finish_lexical_syntax( PyList::new(py, &supported)?.repr()? ); let error: Bound<'_, PyAny> = - registry::error(py, ErrorId::UnsupportedLexicalSyntax)?.call1((message,))?; + error_class(py, ErrorId::UnsupportedLexicalSyntax)?.call1((message,))?; Err(PyErr::from_value(error)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs index 9d23534fc3..423bfd3e90 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs @@ -12,12 +12,12 @@ use sqlbuild_core::migration_values::models::{DecisionTraits, ModelMigrationFact use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::cursor::scalars::parse_value; use crate::bindings::_helpers::record_behaviours::call_arguments::call_argument; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{ enum_from_value, enum_member, new_record, record_class, }; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const DECREASING_DIRECTIONS: [&str; 2] = ["decrease", "mixed"]; const STEP_ACTIONS: [&str; 2] = ["archive_and_view", "view_only"]; @@ -157,7 +157,7 @@ pub(crate) fn column_migration_blocks_build(entry: &Bound<'_, PyAny>) -> PyResul /// The `PlannerInputError` carrying `message`. fn planner_error(py: Python<'_>, message: String) -> PyErr { - match registry::error(py, ErrorId::PlannerInput).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::PlannerInput).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs index 1375da8705..7b2e3ddb86 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/construct.rs @@ -8,12 +8,15 @@ use pyo3::sync::PyOnceLock; use pyo3::types::PyDict; use crate::bindings::_helpers::compile_driver::python_calls::keywords; -use crate::bindings::_helpers::records::ids::RecordId; +use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; /// Each `RecordId`'s class, captured when the extension module is initialised. static CLASSES: PyOnceLock>> = PyOnceLock::new(); -/// Hold every registered record class and string enum, read once while the module initialises. +/// Each `ErrorId`'s exception class, captured when the extension module is initialised. +static ERROR_CLASSES: PyOnceLock>> = PyOnceLock::new(); + +/// Hold every registered record class, string enum and error class, read once while the module initialises. pub(crate) fn capture(module: &Bound<'_, PyModule>) -> PyResult<()> { CLASSES.get_or_try_init(module.py(), || { RecordId::ALL @@ -21,9 +24,23 @@ pub(crate) fn capture(module: &Bound<'_, PyModule>) -> PyResult<()> { .map(|id| module.getattr(id.name()).map(Bound::unbind)) .collect::>>>() })?; + ERROR_CLASSES.get_or_try_init(module.py(), || { + ErrorId::ALL + .iter() + .map(|id| module.getattr(id.name()).map(Bound::unbind)) + .collect::>>>() + })?; Ok(()) } +/// The native error class `id` as registered, ignoring later attribute replacement. +pub(crate) fn error_class(py: Python<'_>, id: ErrorId) -> PyResult> { + let classes: &Vec> = ERROR_CLASSES + .get(py) + .ok_or_else(|| PyRuntimeError::new_err("native error classes are not registered"))?; + Ok(classes[id as usize].bind(py).clone()) +} + /// The native record class or string enum `id` as registered, ignoring later attribute replacement. pub(crate) fn record_class(py: Python<'_>, id: RecordId) -> PyResult> { let classes: &Vec> = CLASSES diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/registry.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/registry.rs index 0d0d3c3c17..a1e1e5dbc9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/registry.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/registry.rs @@ -13,8 +13,6 @@ use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; /// The extension module, imported once for attribute lookups. static MODULE: PyOnceLock> = PyOnceLock::new(); -/// Each `ErrorId`'s interned attribute name, by variant position. -static ERROR_NAMES: PyOnceLock>> = PyOnceLock::new(); /// Each `NativeAttr`'s interned attribute name, by variant position. static ATTRIBUTE_NAMES: PyOnceLock>> = PyOnceLock::new(); @@ -96,16 +94,6 @@ pub(crate) fn verify_attributes(module: &Bound<'_, PyModule>) -> PyResult<()> { ))) } -/// The native error class `id`, read now so a replaced attribute is seen. -pub(crate) fn error(py: Python<'_>, id: ErrorId) -> PyResult> { - attribute( - py, - &ERROR_NAMES, - ErrorId::ALL.iter().map(|id| id.name()), - id as usize, - ) -} - /// The module attribute `id`, read now so a replaced attribute is seen. pub(crate) fn native(py: Python<'_>, id: NativeAttr) -> PyResult> { attribute( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_edits.rs b/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_edits.rs index b91f063a45..279819647b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_edits.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_edits.rs @@ -15,10 +15,10 @@ use sqlbuild_refactor::refactoring::models::{ use sqlbuild_refactor::refactoring::types::PhysicalColumn; use crate::bindings::_helpers::boundary::panics::compiler_guard; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; /// Finding kinds an edit resolves without overwrite, then the ones overwrite also resolves. const RESOLVED_KINDS: ([&str; 1], [&str; 2]) = ( @@ -41,7 +41,7 @@ fn edit_row(result: Result) -> PyResult { /// `ContractAdoptionError(message)`. fn adoption_error(py: Python<'_>, message: String) -> PyErr { - match registry::error(py, ErrorId::ContractAdoption).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::ContractAdoption).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs b/crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs index a4c6bef6a6..0f031959a8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs @@ -10,10 +10,10 @@ use pyo3::types::{PyBool, PyString, PyTuple}; use crate::bindings::_helpers::compile_command::target_writer::static_sql_test_planning_diagnostics; use crate::bindings::_helpers::compile_driver::analysis::analyze_compile_project; use crate::bindings::_helpers::compile_driver::python_calls::keywords; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const DEFAULT_ERROR_CODE: &str = "E001"; @@ -25,7 +25,7 @@ pub(crate) struct OfflineCompile<'py> { fn matches_any_class(py: Python<'_>, error: &PyErr, classes: &[ErrorId]) -> PyResult { for class in classes { - if error.value(py).is_instance(®istry::error(py, *class)?)? { + if error.value(py).is_instance(&error_class(py, *class)?)? { return Ok(true); } } @@ -67,7 +67,7 @@ fn compile_error_diagnostic<'py>(py: Python<'py>, error: &PyErr) -> PyResult(py: Python<'py>, error: &PyErr) -> PyResult> { let value: Bound<'py, PyAny> = error.value(py).clone().into_any(); let location: Bound<'py, PyAny> = - if value.is_instance(®istry::error(py, ErrorId::SqlTestReference)?)? { + if value.is_instance(&error_class(py, ErrorId::SqlTestReference)?)? { native_field(&value, "location")? } else { py.None().into_bound(py) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs index 93aa40f975..de3d384d87 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs @@ -36,9 +36,9 @@ use crate::bindings::_helpers::boundary::panics::{NativeCompilerError, compiler_ use crate::bindings::_helpers::build_progress::transient_status::status_reporter; use crate::bindings::_helpers::lineage::lineage_index::lineage_key; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::refactor::offline_compile::{OfflineCompile, compile_for_refactor}; use crate::bindings::_helpers::refactor::refactor_facts::{ declaration_placement, model_facts, refactor_facts, @@ -59,7 +59,7 @@ fn user_error(py: Python<'_>, (message, code, help): (String, &str, Option = PyDict::new(py); options.set_item("code", code)?; options.set_item("help", help)?; - registry::error(py, ErrorId::CliUser)?.call((message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), @@ -70,7 +70,7 @@ fn user_error(py: Python<'_>, (message, code, help): (String, &str, Option, error: RefactorError) -> PyErr { let class = |name: ErrorId| -> PyErr { - match registry::error(py, name).and_then(|class| class.call1((error.message.clone(),))) { + match error_class(py, name).and_then(|class| class.call1((error.message.clone(),))) { Ok(raised) => PyErr::from_value(raised), Err(failure) => failure, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs index 16158a20b5..498e99529b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs @@ -10,6 +10,7 @@ use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::compile_attachment::sql_expansion_context::SqlExpansionInputs; use crate::bindings::_helpers::model_config::template_data::record_reads; use crate::bindings::_helpers::model_config::unicode_environment::unicode_environment; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; @@ -58,7 +59,7 @@ fn substituted<'py>( record_reads(py, reads.iter().map(|(kind, name)| (*kind, name.as_str())))?; if let Some(message) = error { return Err(PyErr::from_value( - registry::error(py, ErrorId::CompileInput)?.call1((message,))?, + error_class(py, ErrorId::CompileInput)?.call1((message,))?, )); } Ok((rendered.unwrap_or(text), spans)) @@ -116,7 +117,7 @@ fn declarations_expanded<'py>( ); let classes = ExpansionClasses { usage_record: record_class(py, RecordId::UsageRecord)?, - compile_error: registry::error(py, ErrorId::CompileInput)?, + compile_error: error_class(py, ErrorId::CompileInput)?, }; let path: String = file_path.str()?.extract()?; let expanded: ExpandedDeclarations<'py> = expand_declarations(&DeclarationExpansion { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs index 081322332f..c104887ce5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs @@ -2,10 +2,10 @@ use std::collections::HashMap; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{ Bound, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyResult, Python, }; @@ -14,7 +14,7 @@ use pyo3::{pyfunction, wrap_pyfunction}; /// `CompileInputError(message)`. fn compile_input_error(py: Python<'_>, message: String) -> PyErr { - match registry::error(py, ErrorId::CompileInput).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::CompileInput).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs index 368dce5d64..0c0534206d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs @@ -9,6 +9,7 @@ use pyo3::{IntoPyObject, pyclass, pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{ enum_member, new_record, new_record_with, record_class, }; @@ -298,12 +299,9 @@ pub(crate) fn native_declaration_contexts<'py>( )?; lookups.set_item( "identity_error", - registry::error(py, ErrorId::InvalidQualifiedIdentity)?, - )?; - lookups.set_item( - "path_error", - registry::error(py, ErrorId::InvalidScopePath)?, + error_class(py, ErrorId::InvalidQualifiedIdentity)?, )?; + lookups.set_item("path_error", error_class(py, ErrorId::InvalidScopePath)?)?; let global_positions: Bound<'py, PyList> = PyList::new( py, native_field(&index, "global_positions")? @@ -415,7 +413,7 @@ pub(crate) fn constant_declaration_sql<'py>( None => relative_path.str()?.to_string(), }; let compile_error: Bound<'py, PyAny> = - registry::error(py, ErrorId::CompileInput)?.call1((format!( + error_class(py, ErrorId::CompileInput)?.call1((format!( "{} constant '{}' could not be rendered in '{}' by adapter '{}' as {}: {}", relative_path.str()?, native_field(declaration, "name")?.str()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_calls.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_calls.rs index 30dd1f7d1f..356fd854c3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_calls.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_calls.rs @@ -10,8 +10,8 @@ use sqlbuild_render::macro_calls::main::splice_macro_calls::splice_macro_calls a use sqlbuild_render::macro_calls::models::{MacroCallScan, MacroScanFailure}; use crate::bindings::_helpers::boundary::panics::compiler_error; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::render::macro_call_memo::MacroCallMemo; use crate::bindings::_helpers::render::macro_call_rows::{SiteRow, SpanRow, site_row, span_row}; use crate::bindings::_helpers::render::macro_expansion::raised; @@ -60,7 +60,7 @@ pub(crate) fn top_level_macro_call_names<'py>( .collect::>(), ), Err(error) => Err(raised( - ®istry::error(py, ErrorId::CompileInput)?, + &error_class(py, ErrorId::CompileInput)?, error.message(), )), } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs index 28650810ba..51cc966680 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs @@ -12,12 +12,12 @@ use crate::bindings::_helpers::compile_driver::python_calls::{ use crate::bindings::_helpers::discovery::guidance::explicit_references_help; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{ enum_member, new_record, new_record_with, record_class, }; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::render::declaration_values::resolved_declaration_context; use crate::bindings::_helpers::render::macro_call_rows::span_row; use crate::bindings::_helpers::render::macro_expansion::{ @@ -98,14 +98,14 @@ fn built_classes(py: Python<'_>) -> PyResult> { keywords( py, &[ - ("compile_error", registry::error(py, ErrorId::CompileInput)?), + ("compile_error", error_class(py, ErrorId::CompileInput)?), ( "macro_argument_error", - registry::error(py, ErrorId::MacroArgument)?, + error_class(py, ErrorId::MacroArgument)?, ), ( "mismatch_error", - registry::error(py, ErrorId::NativeStageMismatch)?, + error_class(py, ErrorId::NativeStageMismatch)?, ), ( "declaration_identity", diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs index da3c4f08cb..4026874001 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs @@ -28,11 +28,11 @@ use sqlbuild_rules::engine::main::custom_host::run_custom_host_json; use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::compiled_project::records::compiled_project_record; use crate::bindings::_helpers::native_host::constants::CUSTOM_HOST_LAUNCH_MODULE; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::rules::constants::{ CUSTOM_HOST_ABANDONED_SUFFIX, CUSTOM_HOST_CANCELLED_MARKER, CUSTOM_HOST_RUNTIME_VERSION, }; @@ -490,7 +490,7 @@ fn text(path: &Path) -> String { } fn rules_error(py: Python<'_>, message: String) -> PyErr { - match registry::error(py, ErrorId::Rules).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::Rules).and_then(|class| class.call1((message,))) { Ok(instance) => PyErr::from_value(instance), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_cache.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_cache.rs index cc5d761e9f..b971ea26ac 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_cache.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_cache.rs @@ -23,8 +23,8 @@ use sqlbuild_rules::custom_rule_cache::types::{ReadSet, StoredRules, SubjectResu use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::compiled_project::values::plain_value; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::rules::findings::{FindingClasses, invalid_finding}; /// One custom rule's cache identity from its metadata, source fingerprint and settings. @@ -49,7 +49,7 @@ pub(crate) fn custom_rule_identity(request: Option<&Bound<'_, PyDict>>) -> PyRes } fn rules_error(py: Python<'_>, message: String) -> PyResult { - let class: Bound<'_, PyAny> = registry::error(py, ErrorId::Rules)?; + let class: Bound<'_, PyAny> = error_class(py, ErrorId::Rules)?; Ok(pyo3::PyErr::from_value(class.call1((message,))?)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs index 108536a0e1..52734f0837 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs @@ -17,9 +17,9 @@ use sqlbuild_pysource::rule_evidence::models::{ }; use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const PATHLIB_MODULE: &str = "pathlib"; const INSPECT_MODULE: &str = "inspect"; @@ -132,9 +132,9 @@ fn custom_rule_test_evidence<'py>( .collect()) } -/// `error_class(message)` from the native module. -fn rules_error(py: Python<'_>, error_class: ErrorId, message: String) -> PyErr { - match registry::error(py, error_class).and_then(|class| class.call1((message,))) { +/// The native `error_id` exception raised with `message`. +fn rules_error(py: Python<'_>, error_id: ErrorId, message: String) -> PyErr { + match error_class(py, error_id).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/findings.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/findings.rs index bd70da9235..a099ff0d55 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/findings.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/findings.rs @@ -1,9 +1,9 @@ //! Rule findings converted between the Python `Finding` model and native rows and payloads. +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods}; use serde_json::Value; @@ -97,7 +97,7 @@ pub(crate) fn finding_fault(finding: &Bound<'_, PyAny>) -> PyResult { /// The `RulesError` a malformed native or custom-rule finding raises. pub(crate) fn invalid_finding(py: Python<'_>) -> PyErr { let raised = || -> PyResult { - let class: Bound<'_, PyAny> = registry::error(py, ErrorId::Rules)?; + let class: Bound<'_, PyAny> = error_class(py, ErrorId::Rules)?; Ok(PyErr::from_value(class.call1((INVALID_FINDING,))?)) }; raised().unwrap_or_else(|error| error) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs index 7acfa28d88..dc31b364be 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs @@ -20,11 +20,11 @@ use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::{field, replaced}; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::rules::constants::SAFE_RULE_FIX_CODES; use crate::bindings::_helpers::rules::fix_facts::compile_facts; use crate::bindings::_helpers::rules::fix_verdict::fix_verdict; @@ -94,7 +94,7 @@ pub(crate) fn plan_rule_fixes<'py>( let inputs = args.value("discovered_inputs")?; if !adapter.is_instance(&host::entry(py, AdapterHost::BaseAdapter)?)? || inputs.is_none() { return Err(PyErr::from_value( - registry::error(py, ErrorId::ProjectCompile)? + error_class(py, ErrorId::ProjectCompile)? .call1(("format --fix requires discovered compiler inputs and an adapter",))?, )); } @@ -396,7 +396,7 @@ impl<'py> FixSession<'py> { Err(error) if error .value(py) - .is_instance(®istry::error(py, ErrorId::CompileInput)?)? => + .is_instance(&error_class(py, ErrorId::CompileInput)?)? => { return Ok(RelationKeys::new()); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs index 58fccc2ad9..fe0fc58faa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs @@ -15,9 +15,9 @@ use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, use crate::bindings::_helpers::contracts::spec_resolution::resolve_effective_adapter_name; use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; const COMPILE_FIRST_MESSAGE: &str = "compiler-integrated Rules check the SQL your project \ actually produces, so the project must compile first"; @@ -121,14 +121,14 @@ fn expansion_inputs(sources: LintExpansionSources<'_>) -> PyResult, error: PyErr) -> PyResult { let value: Bound<'_, PyAny> = error.value(py).clone().into_any(); let reported: bool = value.is_instance(&host::entry(py, AdapterHost::AdapterUserError)?)? - || value.is_instance(®istry::error(py, ErrorId::CompileInput)?)? - || value.is_instance(®istry::error(py, ErrorId::Discovery)?)?; + || value.is_instance(&error_class(py, ErrorId::CompileInput)?)? + || value.is_instance(&error_class(py, ErrorId::Discovery)?)?; if !reported { return Ok(error); } let message: String = format!("{COMPILE_FIRST_MESSAGE}: {}", value.str()?); let raised: PyErr = - PyErr::from_value(registry::error(py, ErrorId::ProjectCompile)?.call1((message,))?); + PyErr::from_value(error_class(py, ErrorId::ProjectCompile)?.call1((message,))?); raised.set_cause(py, Some(error)); Ok(raised) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs index 9c64ee4dc4..d9986069f2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs @@ -36,10 +36,10 @@ use sqlbuild_rules::sql_lint::types::PreparedSql; use crate::bindings::_helpers::boundary::panics::value_error; use crate::bindings::_helpers::compile_attachment::sql_expansion_context::SqlExpansionInputs; use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as record_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::render::authored_sql::{AuthoredExpansion, expand_with_inputs}; use crate::bindings::_helpers::render::declaration_expansion::SpanRow; use crate::bindings::_helpers::rules::dsl_headers::header_violations; @@ -481,7 +481,7 @@ pub(crate) fn lint_sources( fn check_stop(py: Python<'_>, stop: Option<&AtomicBool>) -> PyResult<()> { if stop.is_some_and(|stop| stop.load(Ordering::Acquire)) { return Err(PyErr::from_value( - registry::error(py, ErrorId::LintStopped)?.call0()?, + error_class(py, ErrorId::LintStopped)?.call0()?, )); } Ok(()) @@ -863,7 +863,7 @@ pub(crate) fn prepare_single_body(request: &SingleBodyRequest<'_, '_>) -> PyResu /// The `NativeLintError` of a body native preparation declined. fn not_prepared(py: Python<'_>, path: &Path) -> PyResult { Ok(PyErr::from_value( - registry::error(py, ErrorId::NativeLint)?.call1((format!( + error_class(py, ErrorId::NativeLint)?.call1((format!( "{} could not be prepared for native SQL lint", path.display() ),))?, @@ -951,7 +951,7 @@ fn expand_bodies( let error: PyErr = expansion_error(file_path, error); if !error .value(py) - .is_instance(®istry::error(py, ErrorId::ProjectCompile)?)? + .is_instance(&error_class(py, ErrorId::ProjectCompile)?)? { return Err(error); } @@ -983,7 +983,7 @@ fn expansion_error(file_path: &Bound<'_, PyAny>, error: PyErr) -> PyErr { let wrapped = (|| -> PyResult> { if !error .value(py) - .is_instance(®istry::error(py, ErrorId::CompileInput)?)? + .is_instance(&error_class(py, ErrorId::CompileInput)?)? { return Ok(None); } @@ -993,7 +993,7 @@ fn expansion_error(file_path: &Bound<'_, PyAny>, error: PyErr) -> PyErr { error.value(py).str()? ); Ok(Some(PyErr::from_value( - registry::error(py, ErrorId::ProjectCompile)?.call1((message,))?, + error_class(py, ErrorId::ProjectCompile)?.call1((message,))?, ))) })(); match wrapped { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/native_header_parser.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/native_header_parser.rs index 118e082fc6..8e73fc1c8a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/native_header_parser.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/native_header_parser.rs @@ -11,8 +11,8 @@ use sqlbuild_sqltext::compiler::main::model_header_parsing::parse_batch; use sqlbuild_sqltext::compiler::models::{AuthoredValue, HeaderWord}; use crate::bindings::_helpers::boundary::panics::value_error; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sqltext::model_headers::header_failure; /// The path header rules report header syntax errors at. @@ -32,8 +32,8 @@ pub(crate) fn rejection(py: Python<'_>, failure: ParseFailure) -> PyErr { let raised: PyResult = (|| { let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("help", failure.help)?; - let error: Bound<'_, PyAny> = registry::error(py, ErrorId::ModelSqlParse)? - .call((failure.message,), Some(&keywords))?; + let error: Bound<'_, PyAny> = + error_class(py, ErrorId::ModelSqlParse)?.call((failure.message,), Some(&keywords))?; Ok(PyErr::from_value(error)) })(); raised.unwrap_or_else(|error| error) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs index 7303f28cc9..7cd3411a79 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs @@ -22,9 +22,9 @@ use sqlbuild_rules::project_tree::main::read_project_text::read_project_text; use sqlbuild_rules::project_tree::main::resolve_project_path::resolve_project_path; use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::rules::rule_api::{usage_error_for, validate_project_relative}; const PATHLIB_MODULE: &str = "pathlib"; @@ -115,7 +115,7 @@ fn not_beneath(path: &Bound<'_, PyAny>, under: &Bound<'_, PyAny>) -> PyErr { .add(under_text) }); match message.and_then(|message| { - registry::error(py, ErrorId::RuleUsage).and_then(|class| class.call1((message,))) + error_class(py, ErrorId::RuleUsage).and_then(|class| class.call1((message,))) }) { Ok(error) => PyErr::from_value(error), Err(error) => error, @@ -176,7 +176,7 @@ fn project_tree_read_text(root: PathBuf, path: &Bound<'_, PyAny>) -> PyResult, file: &Path, text: &str) -> PyErr { error.value(py).str()? ); let usage: PyErr = - PyErr::from_value(registry::error(py, ErrorId::RuleUsage)?.call1((message,))?); + PyErr::from_value(error_class(py, ErrorId::RuleUsage)?.call1((message,))?); usage.set_cause(py, Some(error)); Ok(usage) }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs index bb591563ad..fba9d659fa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs @@ -17,17 +17,17 @@ use sqlbuild_rules::project_tree::main::project_tree_entries::project_tree_entri use sqlbuild_rules::project_tree::models::ProjectTreeEntry; use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const BUILTINS_MODULE: &str = "builtins"; const DEFAULT_POSITION: i64 = 1; /// `RuleUsageError(message)`. fn usage_error(py: Python<'_>, message: String) -> PyErr { - match registry::error(py, ErrorId::RuleUsage).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::RuleUsage).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } @@ -40,7 +40,7 @@ pub(crate) fn usage_error_for(prefix: &str, value: &Bound<'_, PyAny>) -> PyErr { .str() .and_then(|text| PyString::new(py, prefix).as_any().add(text)); match message.and_then(|message| { - registry::error(py, ErrorId::RuleUsage).and_then(|class| class.call1((message,))) + error_class(py, ErrorId::RuleUsage).and_then(|class| class.call1((message,))) }) { Ok(error) => PyErr::from_value(error), Err(error) => error, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/rules_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/rules_config.rs index 784f7ef243..83d3585991 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/rules_config.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/rules_config.rs @@ -13,9 +13,9 @@ use sqlbuild_rules::configuration::main::load_rules_config::load_rules_config as use sqlbuild_rules::models::RulesConfig; use crate::bindings::_helpers::boundary::panics::compiler_guard; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; struct Models<'py> { py: Python<'py>, @@ -224,7 +224,7 @@ fn config_object<'py>(py: Python<'py>, config: &RulesConfig) -> PyResult, class: ErrorId, message: String, help: Option) -> PyErr { let raised = || -> PyResult { - let error_class: Bound<'_, PyAny> = registry::error(py, class)?; + let error_class: Bound<'_, PyAny> = error_class(py, class)?; let error: Bound<'_, PyAny> = match help { Some(help) => { let arguments: Bound<'_, PyDict> = PyDict::new(py); @@ -294,7 +294,7 @@ pub(crate) fn rules_config_of( fn valid_rules_config(py: Python<'_>, project_dir: PathBuf) -> PyResult>> { match load_rules_config(py, project_dir) { Ok(config) => Ok(Some(config)), - Err(error) if error.is_instance(py, ®istry::error(py, ErrorId::Rules)?) => Ok(None), + Err(error) if error.is_instance(py, &error_class(py, ErrorId::Rules)?) => Ok(None), Err(error) => Err(error), } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/selection.rs index 205764a1c6..ebe0c454aa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/selection.rs @@ -9,9 +9,9 @@ use pyo3::{pyfunction, wrap_pyfunction}; use sqlbuild_rules::rules::main::selected_codes::selected_codes_json; use crate::bindings::_helpers::boundary::panics::compiler_guard; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as record_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::rules::config_json::{asdict_json, dumped_json}; use crate::bindings::_helpers::rules::constants::RULES_NATIVE_API_VERSION; @@ -99,7 +99,7 @@ pub(crate) fn rule_selected(config: &Bound<'_, PyAny>, code: &str) -> PyResult, message: &str, cause: Option) -> PyErr { let raised = || -> PyResult { - let error: Bound<'_, PyAny> = registry::error(py, ErrorId::Rules)?.call1((message,))?; + let error: Bound<'_, PyAny> = error_class(py, ErrorId::Rules)?.call1((message,))?; Ok(PyErr::from_value(error)) }; let error: PyErr = raised().unwrap_or_else(|error| error); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs index 1d5f4dafbd..c8ec03de86 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs @@ -22,11 +22,11 @@ use crate::bindings::_helpers::compile_driver::python_calls::{imported, keywords use crate::bindings::_helpers::compiled_project::compiled_model_view::{ NativeCompiledModel, SqlRuleInputs, SqlRuleKey, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::rules::constants::SAFE_RULE_FIX_CODES; use crate::bindings::_helpers::rules::early_sql_lint::{ EarlyLintResult, EarlySqlLint, PreparedSqlLint, sql_lint_settings, sql_rule_cache_path, @@ -610,7 +610,7 @@ fn violation_findings( model_paths: &BTreeSet, ) -> PyResult> { let py: Python<'_> = run.project.py(); - let engine_error: String = registry::error(py, ErrorId::NativeLint)? + let engine_error: String = error_class(py, ErrorId::NativeLint)? .getattr("code")? .extract()?; let resolved_dir: PathBuf = resolved(&run.project_dir); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs index c5e47f3d11..2c128fe959 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs @@ -36,11 +36,11 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_selection::unit_tests::reject_unit_test_selectors; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const METADATA_MODULE: &str = "importlib.metadata"; const DISTRIBUTION_NAME: &str = "sqlbuild"; @@ -60,7 +60,7 @@ pub(crate) fn cli_user_error(py: Python<'_>, error: ScenarioCommandError) -> PyE let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", error.code)?; options.set_item("help", error.help)?; - registry::error(py, ErrorId::CliUser)?.call((error.message,), Some(&options)) + error_class(py, ErrorId::CliUser)?.call((error.message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs index 053d61bc1b..dde2957f73 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs @@ -20,10 +20,10 @@ use sqlbuild_scopes::scope_index::models::{ use crate::bindings::_helpers::compile_driver::diagnostic_collector::report_compile_diagnostic; use crate::bindings::_helpers::compiled_project::model_loop_named::scope_path_message; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const INACCESSIBLE_DECLARATION_CODE: &str = "S006"; const SCHEMA_USAGE_KINDS: [&str; 2] = ["schema", "enum"]; @@ -144,7 +144,7 @@ pub(crate) fn model_schema_scope_usages<'py>( let (usages, diagnostics, error) = scope_schema_usages(schemas, record_rows)?; if let Some(message) = error { return Err(PyErr::from_value( - registry::error(py, ErrorId::InvalidScopePath)?.call1((message,))?, + error_class(py, ErrorId::InvalidScopePath)?.call1((message,))?, )); } report_inaccessible(py, diagnostics)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/relationship_names.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/relationship_names.rs index e8652d8e54..61e73a50dc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/relationship_names.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/relationship_names.rs @@ -13,10 +13,10 @@ use sqlbuild_scopes::relationship_names::models::{ use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; use crate::bindings::_helpers::boundary::panics::compiler_error; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sqltext::lexical_syntax::LexicalSyntaxInput; use crate::bindings::types::CompilerDetach; @@ -105,7 +105,7 @@ fn extract_sql_test_ctes<'py>( TopLevelCtes::Scanned(ctes) => ctes, TopLevelCtes::Failed(message) => { let error: Bound<'py, PyAny> = - registry::error(py, ErrorId::CompileInput)?.call1((message,))?; + error_class(py, ErrorId::CompileInput)?.call1((message,))?; return Err(PyErr::from_value(error)); } }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_command.rs index 6d817d96f2..e0e672910c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_command.rs @@ -14,11 +14,11 @@ use sqlbuild_scopes::scope_text::main::scope_result_failed::scope_result_failed; use sqlbuild_scopes::scope_text::models::ScopeTextRequest; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::scopes::scope_loading::load_or_build_scope_index; use crate::bindings::_helpers::scopes::scope_lookup::build_scope_lookup; use crate::bindings::_helpers::scopes::scope_objects::ScopeClasses; @@ -51,7 +51,7 @@ fn user_error(py: Python<'_>, message: String) -> PyResult { options.set_item("code", TARGET_ERROR_CODE)?; options.set_item("help", BARE_USAGE)?; let error: Bound<'_, PyAny> = - registry::error(py, ErrorId::CliUser)?.call((message,), Some(&options))?; + error_class(py, ErrorId::CliUser)?.call((message,), Some(&options))?; Ok(PyErr::from_value(error)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs index 751bae85e8..81e5b98805 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs @@ -20,9 +20,9 @@ use sqlbuild_scopes::scope_index::models::{ }; use crate::bindings::_helpers::boundary::panics::compiler_error; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::scopes::relationship_scan::{ RelationshipScanSettings, ScenarioRow, TestFileRow, scanned_relationships, }; @@ -625,7 +625,7 @@ fn normalized(py: Python<'_>, path: &Bound<'_, PyAny>) -> PyResult { fn unindexable(py: Python<'_>) -> PyResult { Ok(PyErr::from_value( - registry::error(py, ErrorId::UnindexableScope)?.call1((UNINDEXABLE_SCOPE_MESSAGE,))?, + error_class(py, ErrorId::UnindexableScope)?.call1((UNINDEXABLE_SCOPE_MESSAGE,))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_lookup.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_lookup.rs index 7e06318cc3..0cc73f0663 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_lookup.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_lookup.rs @@ -17,9 +17,9 @@ use sqlbuild_scopes::scope_index::models::{ }; use crate::bindings::_helpers::boundary::panics::compiler_error; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::scopes::placement::{QualifiedRow, qualified_identity}; use crate::bindings::_helpers::scopes::scope_objects::{ ScopeClasses, read_index, report_records, resource_identity_object, tuple_attribute, @@ -263,7 +263,7 @@ fn visibility_index<'py>( pub(crate) fn scope_path_error(py: Python<'_>, message: String) -> PyResult { Ok(PyErr::from_value( - registry::error(py, ErrorId::InvalidScopePath)?.call1((message,))?, + error_class(py, ErrorId::InvalidScopePath)?.call1((message,))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs index 46e3030a70..94fdc75d68 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs @@ -21,9 +21,9 @@ use sqlbuild_scopes::scope_report::models::{ }; use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::scopes::scope_lookup::{ NativeScopeLookup, identity_message, path_message, }; @@ -108,7 +108,7 @@ fn lookup_reports(lookup: &Bound<'_, PyAny>) -> PyResult { fn scope_error(py: Python<'_>, class: ErrorId, message: String) -> PyResult { Ok(PyErr::from_value( - registry::error(py, class)?.call1((message,))?, + error_class(py, class)?.call1((message,))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs index bd9a5be4d8..f1672c0545 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs @@ -15,10 +15,10 @@ use sqlbuild_scopes::scope_index::models::ResourceIdentity; use crate::bindings::_helpers::boundary::panics::compiler_error; use crate::bindings::_helpers::records::construct::enum_member; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::scopes::compile_usages::{ MergeRows, SourceRow, UsageRow, merged_usage_rows, model_schema_scope_usages, }; @@ -403,7 +403,7 @@ pub(crate) fn validate_scope_index(index: &Bound<'_, PyAny>) -> Result<(), PyErr let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("diagnostics", PyTuple::new(py, errors)?)?; Err(PyErr::from_value( - registry::error(py, ErrorId::ScopeValidation)?.call((message,), Some(&options))?, + error_class(py, ErrorId::ScopeValidation)?.call((message,), Some(&options))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_visibility.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_visibility.rs index 403dd2c93d..40d9e18fbf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_visibility.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_visibility.rs @@ -10,9 +10,9 @@ use sqlbuild_scopes::scope_index::models::{ OwnershipRoot, OwnershipRootKind, RejectedPath, ResourceIdentity, ResourceKind, ResourceRecord, }; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::scopes::scope_lookup::{ NativeScopeLookup, ResolvedRows, TargetRows, path_message, scope_path_error, }; @@ -51,7 +51,7 @@ fn target_query<'py>( native_lookup(lookup)?.get().target(row, &raw)?; if let Some(message) = identity_error { return Err(PyErr::from_value( - registry::error(py, ErrorId::InvalidQualifiedIdentity)?.call1((message,))?, + error_class(py, ErrorId::InvalidQualifiedIdentity)?.call1((message,))?, )); } if let Some(message) = path_error { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs index f0a57820b7..59cb6f0514 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs @@ -16,10 +16,10 @@ use sqlbuild_analysis::semantic_checks::models::{ use crate::bindings::_helpers::boundary::panics::compiler_error; use crate::bindings::_helpers::compiled_project::audit_views::audit_reference_rows; use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::models::ProjectCatalog; use crate::bindings::types::CompilerDetach; @@ -348,7 +348,7 @@ fn python_diagnostic<'py>( fn failure_error(py: Python<'_>, failure: ResourceSqlFailure) -> PyResult { Ok(match failure { ResourceSqlFailure::CursorIntrinsic(message) => { - PyErr::from_value(registry::error(py, ErrorId::CompileInput)?.call1((message,))?) + PyErr::from_value(error_class(py, ErrorId::CompileInput)?.call1((message,))?) } ResourceSqlFailure::Normalization(message) | ResourceSqlFailure::Internal(message) => { compiler_error(message) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs index 9b5c626bcb..6b3dc8a185 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs @@ -40,10 +40,10 @@ use crate::bindings::_helpers::dbt_interop::reference_resolver::resolve_external use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_entries::command_plans::build_test_command_plan; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::result_output::documents::format_test_execution_json; use crate::bindings::_helpers::result_output::documents::write_execution_json_output; use crate::bindings::_helpers::result_output::event_writer::ExecutionEventWriter; @@ -306,7 +306,7 @@ fn unknown_case(py: Python<'_>, message: String) -> PyErr { let raised = (|| { let options: Bound<'_, PyDict> = PyDict::new(py); options.set_item("code", UNKNOWN_CASE_CODE)?; - registry::error(py, ErrorId::PlannerInput)?.call((message,), Some(&options)) + error_class(py, ErrorId::PlannerInput)?.call((message,), Some(&options)) })(); match raised { Ok(error) => PyErr::from_value(error), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs index b5055426ea..d98cac5025 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs @@ -12,9 +12,9 @@ use sqlbuild_analysis::compiler::models::{SqlTestExtractionFailure, SqlTestReque use sqlbuild_analysis::sql_test_attachment::main::authored_test_offset::authored_test_offset; use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sqltext::lexical_syntax::LexicalSyntaxInput; const MODEL_MODE: &str = "model"; @@ -82,7 +82,7 @@ fn located_error(py: Python<'_>, failure: &SqlTestExtractionFailure, body: &Auth let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("help", failure.help.as_deref())?; let error: Bound<'_, PyAny> = - registry::error(py, ErrorId::CompileInput)?.call((message,), Some(&keywords))?; + error_class(py, ErrorId::CompileInput)?.call((message,), Some(&keywords))?; Ok(PyErr::from_value(error)) }; raised().unwrap_or_else(|error| error) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs index a9f5107290..428f284d3a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs @@ -4,10 +4,10 @@ use crate::bindings::_helpers::compile_driver::compile_timings::add_compile_timi use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::planner_strategy::fixture_context::count_chain_resolution; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sql_test_glue::models::SqlTestPlanOptions; use crate::bindings::_helpers::sql_test_glue::plan_values::tuple; use crate::bindings::_helpers::sql_test_glue::planning::{ @@ -127,7 +127,7 @@ pub(crate) fn planned<'py>( let sql = native_field(&plan, "sql")?; if sql.is_none() { return Err(PyErr::from_value( - registry::error(py, ErrorId::NativeSqlTestPlanning)? + error_class(py, ErrorId::NativeSqlTestPlanning)? .call1(("native SQL-test planning omitted rendered SQL",))?, )); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs index 3a823683c2..956ed039f2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs @@ -1,10 +1,10 @@ //! Project native planning failures into existing located diagnostic exceptions. use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sql_test_glue::plan_values::string; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods}; @@ -76,7 +76,7 @@ pub(super) fn planning_error( ErrorId::CompileInput }; return Ok(PyErr::from_value( - registry::error(py, class)?.call((message,), Some(&kwargs))?, + error_class(py, class)?.call((message,), Some(&kwargs))?, )); } let (class, message) = if let Some(message) = message.strip_prefix("compile_input:") { @@ -90,6 +90,6 @@ pub(super) fn planning_error( ) }; Ok(PyErr::from_value( - registry::error(py, class)?.call1((string(py, &message),))?, + error_class(py, class)?.call1((string(py, &message),))?, )) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs index 33632f4654..f2681f10c1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs @@ -6,9 +6,9 @@ use crate::bindings::_helpers::sql_test_glue::plan_values::{model_payload, strin use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sql_test_glue::constants::SENTINEL; use crate::bindings::_helpers::sql_test_glue::cursor_window::{ declared_window_cursor_models, declares_cursor_window, render_test_cursor_intrinsics, @@ -162,7 +162,7 @@ pub(super) fn functions<'py>( .filter(|(_, suffix)| !suffix.contains(SENTINEL)) else { return Err(PyErr::from_value( - registry::error(py, ErrorId::NativeSqlTestPlanning)? + error_class(py, ErrorId::NativeSqlTestPlanning)? .call1(("adapter SQL function call template is not deterministic",))?, )); }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sqltext/code_scanner.rs b/crates/sqlbuild-python/src/bindings/_helpers/sqltext/code_scanner.rs index 22ff949e69..c8bca560a7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sqltext/code_scanner.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sqltext/code_scanner.rs @@ -10,8 +10,8 @@ use sqlbuild_sqltext::code_scanner::main::scanner_non_code_end::scanner_non_code use sqlbuild_sqltext::code_scanner::models::CodeScanner; use sqlbuild_sqltext::sql_scan::models::Unclosed; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sqltext::lexical_syntax::LexicalSyntaxInput; /// One SQL text scanned under an adapter's lexical rules, or the generic compiler rules. @@ -54,7 +54,7 @@ impl SqlCodeScanner { let message: String = format!("{} contains an unclosed {construct}", self.context); let raised = || -> PyResult { let error: Bound<'_, PyAny> = - registry::error(py, ErrorId::CompileInput)?.call1((message,))?; + error_class(py, ErrorId::CompileInput)?.call1((message,))?; Ok(PyErr::from_value(error)) }; raised().unwrap_or_else(|error| error) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs b/crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs index edba303dd2..a365dde1bc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs @@ -13,12 +13,12 @@ use sqlbuild_sqltext::sql_scan::models::LexicalSyntax; use crate::bindings::_helpers::boundary::panics::compiler_guard; use crate::bindings::_helpers::compile_driver::diagnostic_collector::report_compile_diagnostic; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{ enum_from_value, enum_member, new_record_with, }; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::sqltext::lexical_syntax::LexicalSyntaxInput; const REFERENCE_CALL_SYNTAX_CODE: &str = "P012"; @@ -108,7 +108,7 @@ fn scanned<'py>( ReferenceExtraction::Extracted(scan) => scan, ReferenceExtraction::Failed(failure) => { let error: Bound<'py, PyAny> = - registry::error(py, ErrorId::CompileInput)?.call1((failure.message,))?; + error_class(py, ErrorId::CompileInput)?.call1((failure.message,))?; return Err(PyErr::from_value(error)); } }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs index 44484a7016..3a249183eb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs @@ -12,9 +12,9 @@ use sqlbuild_state::events::constants::{ use sqlbuild_state::events::models::EventOrder; use crate::bindings::_helpers::compile_driver::python_calls::call_with; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::ErrorId; -use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::state_rows::constants::{COLUMN_KIND, MODEL_KIND, OLD_NAME_KIND}; use crate::bindings::_helpers::state_rows::models::{EventTable, EventTableLayout}; use crate::bindings::_helpers::state_rows::timestamps::presumed_utc; @@ -57,7 +57,7 @@ pub(crate) fn layout(kind: &str) -> PyResult { /// `MigrationStateError(message)`. pub(crate) fn state_error(py: Python<'_>, message: &str) -> PyErr { - match registry::error(py, ErrorId::MigrationState).and_then(|class| class.call1((message,))) { + match error_class(py, ErrorId::MigrationState).and_then(|class| class.call1((message,))) { Ok(error) => PyErr::from_value(error), Err(error) => error, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs b/crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs index a097a9b844..8b44bb8a1e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs @@ -23,10 +23,10 @@ use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; +use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; -use crate::bindings::_helpers::records::registry; const SKILLS_DIRECTORY: &str = ".agents/skills/sqlbuild"; const TEMPLATES_DIRECTORY: &str = "playground_templates"; @@ -50,7 +50,7 @@ fn raised(py: Python<'_>, error: WorkspaceError) -> PyErr { keywords.set_item("code", code)?; keywords.set_item("help", help)?; let instance: Bound<'_, PyAny> = - registry::error(py, ErrorId::CliUser)?.call((message,), Some(&keywords))?; + error_class(py, ErrorId::CliUser)?.call((message,), Some(&keywords))?; Ok(PyErr::from_value(instance)) }; created().unwrap_or_else(|failure| failure) From 25173553e9e45fc4a33cc0646117fbd5db1881d2 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 06:35:01 +0100 Subject: [PATCH 05/19] refactor: read multi-line and interned record field chains natively --- .../_helpers/analysis/binding_catalog.rs | 4 +- .../_helpers/analysis/explicit_references.rs | 6 +- .../bindings/_helpers/analysis/model_reads.rs | 3 +- .../_helpers/analysis/reference_facts.rs | 6 +- .../_helpers/analysis/sql_test_comparisons.rs | 6 +- .../analysis_session/model_analyses.rs | 8 +- .../analysis_session/profile_inputs.rs | 12 +- .../_helpers/audit_command/command.rs | 13 +- .../_helpers/authored_values/python_nodes.rs | 3 +- .../_helpers/boundary/config_values.rs | 9 +- .../_helpers/build_command/command.rs | 6 +- .../_helpers/build_command/defer_clone.rs | 40 +- .../_helpers/build_command/execution.rs | 3 +- .../_helpers/build_command/invocation.rs | 11 +- .../_helpers/build_command/lifecycle.rs | 20 +- .../_helpers/build_progress/result_text.rs | 7 +- .../bindings/_helpers/check/check_command.rs | 22 +- .../src/bindings/_helpers/check/check_core.rs | 10 +- .../bindings/_helpers/check/check_results.rs | 12 +- .../src/bindings/_helpers/cli/dispatch.rs | 3 +- .../bindings/_helpers/clone/clone_command.rs | 3 +- .../_helpers/clone/clone_execution.rs | 17 +- .../bindings/_helpers/clone/clone_progress.rs | 3 +- .../command_runtime/preview_target.rs | 3 +- .../_helpers/command_runtime/warehouses.rs | 10 +- .../compile_attachment/declaration_scope.rs | 8 +- .../compile_attachment/model_inputs.rs | 11 +- .../sql_expansion_context.rs | 7 +- .../compile_attachment/storage_policies.rs | 3 +- .../_helpers/compile_attachment/target.rs | 6 +- .../_helpers/compile_command/report.rs | 39 +- .../_helpers/compile_command/reuse_attempt.rs | 6 +- .../compile_command/reuse_recording.rs | 8 +- .../_helpers/compile_command/target_writer.rs | 11 +- .../_helpers/compile_driver/analysis.rs | 28 +- .../_helpers/compile_driver/analysis_cache.rs | 15 +- .../_helpers/compile_driver/assembly.rs | 3 +- .../compile_driver/assembly_analysis.rs | 26 +- .../compile_driver/assembly_checks.rs | 4 +- .../compile_driver/assembly_models.rs | 4 +- .../compile_driver/assembly_project.rs | 7 +- .../compile_driver/assembly_sql_tests.rs | 3 +- .../_helpers/compile_driver/command.rs | 12 +- .../compile_driver/config_validation.rs | 12 +- .../bindings/_helpers/compile_driver/diff.rs | 6 +- .../_helpers/compile_driver/discovery.rs | 7 +- .../_helpers/compile_driver/inputs.rs | 7 +- .../_helpers/compile_driver/phases.rs | 3 +- .../compile_driver/pipeline_entries.rs | 8 +- .../_helpers/compile_driver/plan_result.rs | 5 +- .../_helpers/compile_driver/project.rs | 17 +- .../compile_driver/python_plan_entries.rs | 11 +- .../compile_driver/relation_targets.rs | 10 +- .../compile_driver/selection_phases.rs | 10 +- .../_helpers/compile_driver/targets.rs | 14 +- .../compile_outputs/runtime_target.rs | 6 +- .../_helpers/compiled_project/attachment.rs | 11 +- .../_helpers/compiled_project/audit_views.rs | 11 +- .../compiled_project/compiled_model_view.rs | 5 +- .../_helpers/compiled_project/loop_classes.rs | 3 +- .../compiled_project/model_input_view.rs | 6 +- .../_helpers/compiled_project/records.rs | 46 +- .../compiled_project/resource_diagnostics.rs | 6 +- .../_helpers/compiled_project/source_loop.rs | 3 +- .../_helpers/contract_command/command.rs | 12 +- .../contracts/contract_diagnostics.rs | 18 +- .../_helpers/contracts/effective_config.rs | 6 +- .../_helpers/contracts/spec_resolution.rs | 10 +- .../bindings/_helpers/cost_command/command.rs | 3 +- .../bindings/_helpers/cost_command/refresh.rs | 3 +- .../bindings/_helpers/cost_command/sorting.rs | 6 +- .../_helpers/dbt_command/auto_init.rs | 3 +- .../src/bindings/_helpers/dbt_command/init.rs | 3 +- .../_helpers/dbt_command/init_project.rs | 3 +- .../bindings/_helpers/dbt_events/results.rs | 3 +- .../bindings/_helpers/dbt_interop/graph.rs | 8 +- .../bindings/_helpers/dbt_interop/manifest.rs | 6 +- .../_helpers/dbt_interop/pipeline_prologue.rs | 3 +- .../src/bindings/_helpers/dbt_interop/plan.rs | 3 +- .../_helpers/dbt_interop/plan_output.rs | 4 +- .../dbt_interop/reference_resolver.rs | 12 +- .../_helpers/dbt_interop/runtime_config.rs | 5 +- .../_helpers/debug_command/run_debug.rs | 13 +- .../bindings/_helpers/diff_report/command.rs | 8 +- .../bindings/_helpers/diff_report/facts.rs | 11 +- .../bindings/_helpers/diff_report/query.rs | 3 +- .../bindings/_helpers/discovery/guidance.rs | 5 +- .../_helpers/discovery/project_facts.rs | 3 +- .../_helpers/event_exporting/dispatcher.rs | 11 +- .../_helpers/execution_history/conversion.rs | 3 +- .../_helpers/execution_history/postgres.rs | 3 +- .../_helpers/execution_history/sqlite.rs | 3 +- .../_helpers/fingerprints/storage_sql.rs | 3 +- .../_helpers/format_command/command.rs | 14 +- .../bindings/_helpers/format_command/run.rs | 3 +- .../_helpers/format_command/selection.rs | 5 +- .../_helpers/freshness/freshness_command.rs | 11 +- .../_helpers/freshness/freshness_observe.rs | 8 +- .../_helpers/freshness/observation.rs | 4 +- .../bindings/_helpers/freshness/planning.rs | 15 +- .../_helpers/freshness/publication.rs | 5 +- .../_helpers/graph/python_lifecycle.rs | 9 +- .../_helpers/graph/python_node_graph.rs | 3 +- .../_helpers/graph/python_selection.rs | 12 +- .../_helpers/janitor/janitor_command.rs | 3 +- .../_helpers/janitor/janitor_facts.rs | 13 +- .../_helpers/janitor/janitor_old_names.rs | 6 +- .../_helpers/janitor/janitor_phases.rs | 22 +- .../bindings/_helpers/janitor/janitor_plan.rs | 3 +- .../_helpers/janitor/janitor_planning.rs | 5 +- .../_helpers/lineage/column_lineage_graph.rs | 9 +- .../_helpers/lineage/lineage_command.rs | 3 +- .../_helpers/lineage/lineage_index.rs | 9 +- .../_helpers/lineage/project_lineage.rs | 14 +- .../bindings/_helpers/load/load_command.rs | 15 +- .../bindings/_helpers/load/load_progress.rs | 9 +- .../bindings/_helpers/load/load_selection.rs | 3 +- .../_helpers/planner_entries/clone_plans.rs | 4 +- .../_helpers/planner_phases/retention.rs | 4 +- .../planner_warehouse/fingerprint_cache.rs | 3 +- .../_helpers/planner_warehouse/snapshot.rs | 6 +- .../_helpers/record_behaviours/rule_shapes.rs | 3 +- .../_helpers/render/macro_expansion_result.rs | 5 +- .../_helpers/result_output/documents.rs | 4 +- .../src/bindings/_helpers/rules/sql_rules.rs | 5 +- .../_helpers/scopes/declaration_contexts.rs | 12 +- .../_helpers/scopes/declaration_resolution.rs | 35 +- fensu.toml | 443 +++++++++--------- 128 files changed, 603 insertions(+), 949 deletions(-) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs index 5345f27c3c..9969ef8868 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs @@ -295,9 +295,7 @@ pub(crate) fn schema_validations<'py>( for (index, request) in requests.iter().enumerate() { let key: CatalogKey = ( native_dialect(&native_field(request, "dialect")?)?, - request - .getattr("quoted_identifiers_ignore_case")? - .extract()?, + native_field(request, "quoted_identifiers_ignore_case")?.extract()?, native_field(request, "known_functions")?.extract()?, native_field(request, "known_types")?.extract()?, ); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs index 841d124650..3dc00e2171 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs @@ -100,8 +100,7 @@ pub(crate) fn explicit_reference_report<'py>( { path_order.set_item(path?, index)?; } - let retains_old_names: bool = !discovered_inputs - .getattr("project_config")? + let retains_old_names: bool = !native_field(discovered_inputs, "project_config")? .getattr("migrations")? .getattr("old_name_views")? .is_none(); @@ -205,8 +204,7 @@ fn loader_owners<'py>( let mut sources_by_loader: BTreeMap> = BTreeMap::new(); for source in native_field(project, "sources")?.try_iter()? { let source: Bound<'py, PyAny> = source?; - let loader: Option = source - .getattr("source_entry")? + let loader: Option = native_field(&source, "source_entry")? .getattr("loader")? .extract()?; if let Some(loader) = loader { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/model_reads.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/model_reads.rs index 87f5a5e8fb..f14f73c13e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/model_reads.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/model_reads.rs @@ -83,8 +83,7 @@ pub(crate) fn unchecked_columns(model: &Bound<'_, PyAny>) -> PyResult() { return Ok(view.get().unchecked_columns().to_vec()); } - model - .getattr("unchecked_output_columns")? + native_field(model, "unchecked_output_columns")? .try_iter()? .map(|column| column?.extract()) .collect() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs index dbdc3b4589..8dd71239b9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs @@ -82,8 +82,7 @@ pub(crate) fn project_facts( let hook: Bound<'_, PyAny> = hook?; hooks.push(PythonHook { name: native_field(&hook, "name")?.extract()?, - path: hook - .getattr("relative_path")? + path: native_field(&hook, "relative_path")? .call_method0("as_posix")? .extract()?, reads: ref_keys(&native_field(&hook, "reads")?)?, @@ -225,8 +224,7 @@ fn audit_gate(audit: &Bound<'_, PyAny>) -> PyResult { }; Ok(AuditGate { name: native_field(audit, "name")?.extract()?, - path: audit - .getattr("audit_file")? + path: native_field(audit, "audit_file")? .getattr("relative_path")? .str()? .extract()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs index f0680c0d38..8d0f62592e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs @@ -123,13 +123,11 @@ pub(crate) fn comparison_request( set_difference_operator: &str, sql_analysis_dialect: Option<&str>, ) -> PyResult { - let chain: Vec = entry - .getattr("chain")? + let chain: Vec = native_field(entry, "chain")? .try_iter()? .map(|step| chain_step_request(&step?)) .collect::>()?; - let assertions: Vec = entry - .getattr("assertions")? + let assertions: Vec = native_field(entry, "assertions")? .try_iter()? .map(|assertion| { let assertion: Bound<'_, PyAny> = assertion?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs index ce409db471..3eaadc1496 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs @@ -198,9 +198,7 @@ fn record_catalog_changes<'py>( } schemas.call_method1("update", (&additions,))?; if !additions.is_empty() { - catalog - .getattr("native")? - .call_method1("update_relations", (&additions,))?; + native_field(catalog, "native")?.call_method1("update_relations", (&additions,))?; } let selected_types: Bound<'py, PyDict> = PyDict::new(py); let selected_nullability: Bound<'py, PyDict> = PyDict::new(py); @@ -217,9 +215,7 @@ fn record_catalog_changes<'py>( let arguments: Bound<'py, PyDict> = PyDict::new(py); arguments.set_item("types", selected_types)?; arguments.set_item("nullability", selected_nullability)?; - catalog - .getattr("prepare_analysis")? - .call((), Some(&arguments))?; + native_field(catalog, "prepare_analysis")?.call((), Some(&arguments))?; Ok(()) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs index 1cf052871d..4107fd024d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs @@ -37,8 +37,7 @@ pub(crate) fn nullability_rules(profile: &Bound<'_, PyAny>) -> PyResult<(Pairs, } let adapter: Bound<'_, PyDict> = PyDict::new(py); let mut rows: Pairs = Vec::new(); - for item in profile - .getattr("function_nullability_rules")? + for item in native_field(profile, "function_nullability_rules")? .call_method0("items")? .try_iter()? { @@ -109,10 +108,7 @@ pub(crate) fn case_sensitive_shapes( profile: &Bound<'_, PyAny>, dialect: &Bound<'_, PyAny>, ) -> PyResult { - if profile - .getattr("quoted_identifiers_ignore_case")? - .is_truthy()? - { + if native_field(profile, "quoted_identifiers_ignore_case")?.is_truthy()? { return Ok(false); } if dialect.is_none() { @@ -136,9 +132,7 @@ pub(crate) fn profile_catalog<'py>( py, ( dialect.to_owned(), - profile - .getattr("quoted_identifiers_ignore_case")? - .extract()?, + native_field(profile, "quoted_identifiers_ignore_case")?.extract()?, Vec::new(), Vec::new(), ), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs index a5278bae9f..c6047e2bd5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs @@ -148,9 +148,7 @@ fn compile_audits<'py>( ("options", options), ( "on_progress", - invocation - .getattr("planning_progress")? - .getattr("on_progress")?, + native_field(invocation, "planning_progress")?.getattr("on_progress")?, ), ], )?))?; @@ -188,8 +186,7 @@ fn prepare_run<'py>( native_field(pipeline, "plan_output")?.getattr("audit_entries")?; let requested: Bound<'py, PyAny> = native_field(request, "concurrency")?; let concurrency: i64 = if requested.is_none() { - pipeline - .getattr("project")? + native_field(pipeline, "project")? .getattr("settings")? .getattr("concurrency")? .extract::()? @@ -322,8 +319,7 @@ fn execute<'py>( )?; } let run_id: Bound<'py, PyAny> = native_field(&project, "run_id")?; - let ledger_path: Bound<'py, PyAny> = invocation - .getattr("effective_project_dir")? + let ledger_path: Bound<'py, PyAny> = native_field(invocation, "effective_project_dir")? .call_method1("__truediv__", ("target",))? .call_method1("__truediv__", ("executions",))? .call_method1("__truediv__", (&run_id,))? @@ -471,8 +467,7 @@ fn complete( ..AuditCounts::default() }; for result in results { - match result - .getattr("outcome")? + match native_field(result, "outcome")? .getattr("value")? .extract::()? .as_str() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs b/crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs index 708459ad89..dafe233301 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs @@ -106,8 +106,7 @@ fn retry_delay_seconds<'py>( retry_index: &Bound<'py, PyAny>, ) -> PyResult> { let initial: Bound<'py, PyAny> = native_field(retry_policy, "initial_delay_seconds")?; - let growth: Bound<'py, PyAny> = retry_policy - .getattr("backoff_multiplier")? + let growth: Bound<'py, PyAny> = native_field(retry_policy, "backoff_multiplier")? .pow(retry_index, retry_policy.py().None())?; let mut delay: Bound<'py, PyAny> = initial.mul(growth)?; let maximum: Bound<'py, PyAny> = native_field(retry_policy, "max_delay_seconds")?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/boundary/config_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/boundary/config_values.rs index 91c04cf357..5f2f304c6b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/boundary/config_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/boundary/config_values.rs @@ -16,15 +16,13 @@ fn object<'py, T: IntoPyObject<'py>>(py: Python<'py>, value: T) -> PyResult, value: ConfigDate) -> PyResult { - Ok(datetime - .getattr("date")? + Ok(native_field(datetime, "date")? .call1((value.year, value.month, value.day))? .unbind()) } fn time(datetime: &Bound<'_, PyModule>, value: ConfigTime) -> PyResult { - Ok(datetime - .getattr("time")? + Ok(native_field(datetime, "time")? .call1((value.hour, value.minute, value.second, value.microsecond))? .unbind()) } @@ -41,8 +39,7 @@ fn date_time(datetime: &Bound<'_, PyModule>, value: ConfigDateTime) -> PyResult< None => None, }; let (date, time) = (value.date, value.time); - Ok(datetime - .getattr("datetime")? + Ok(native_field(datetime, "datetime")? .call1(( date.year, date.month, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs index 31db14c22d..c9ebbe86e0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs @@ -100,12 +100,10 @@ pub(crate) fn run_build_command(py: Python<'_>, request: &Bound<'_, PyAny>) -> P within(&tracker.call_method0("scope")?, |_| { let started: Instant = Instant::now(); run_within_limits(request, &tracker, started).inspect_err(|_| { - let verbose: bool = request - .getattr("verbose") + let verbose: bool = native_field(request, "verbose") .and_then(|value| value.is_truthy()) .unwrap_or(false) - || request - .getattr("debug") + || native_field(request, "debug") .and_then(|value| value.is_truthy()) .unwrap_or(false); if verbose { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs index 9ec6a15e48..92b84c8e88 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs @@ -62,14 +62,12 @@ fn recreated_over_clones(scope: &Bound<'_, PyAny>, key: &Bound<'_, PyAny>) -> Py if RECREATED_TYPES.contains(&resource_type(key)?.as_str()) { return Ok(true); } - let model: Bound<'_, PyAny> = scope - .getattr("models_by_name")? + let model: Bound<'_, PyAny> = native_field(scope, "models_by_name")? .call_method1("get", (native_field(key, "name")?,))?; if model.is_none() { return Ok(false); } - let materialized: Bound<'_, PyAny> = model - .getattr("config")? + let materialized: Bound<'_, PyAny> = native_field(&model, "config")? .getattr("values")? .call_method1("get", ("materialized", VIEW_MATERIALIZATION))?; let lowered: String = materialized.str()?.call_method0("lower")?.extract()?; @@ -78,12 +76,10 @@ fn recreated_over_clones(scope: &Bound<'_, PyAny>, key: &Bound<'_, PyAny>) -> Py /// Every key the scope's traversal can visit: the selection and the upstream graph. fn scope_keys<'py>(scope: &Bound<'py, PyAny>) -> PyResult>> { - let mut keys: Vec> = scope - .getattr("selected_keys")? + let mut keys: Vec> = native_field(scope, "selected_keys")? .try_iter()? .collect::>()?; - for item in scope - .getattr("upstream_deps")? + for item in native_field(scope, "upstream_deps")? .call_method0("items")? .try_iter()? { @@ -152,8 +148,7 @@ fn selected_executable_model_count(scope: &Bound<'_, PyAny>) -> PyResult } let model: Bound<'_, PyAny> = models.call_method1("get", (native_field(&key, "name")?,))?; if !model.is_none() - && model - .getattr("config")? + && native_field(&model, "config")? .getattr("values")? .call_method1("get", ("enabled",))? .is(false.into_pyobject(scope.py())?.to_owned().into_any()) @@ -253,8 +248,7 @@ fn clone_input<'py>( ), ], )?; - let allow_decrease: bool = target - .getattr("time_travel_retention_decrease")? + let allow_decrease: bool = native_field(&target, "time_travel_retention_decrease")? .eq(enum_member(py, RecordId::RetentionDecreasePolicy, "ALLOW")?)?; let sources: Bound<'py, PyAny> = call_with( &host::entry(py, ExecutorHost::CloneSourceEntries)?, @@ -297,9 +291,7 @@ fn clone_input<'py>( ("run_id", native_field(&project, "run_id")?), ( "query_change_tracking", - project - .getattr("settings")? - .getattr("query_change_tracking")?, + native_field(&project, "settings")?.getattr("query_change_tracking")?, ), ( "destination_transient_models", @@ -411,10 +403,8 @@ fn clone_boundaries<'py>( connection: &Bound<'py, PyAny>, ) -> PyResult<()> { let py: Python<'py> = context.py(); - let on_progress: Bound<'py, PyAny> = context - .invocation - .getattr("planning_progress")? - .getattr("on_progress")?; + let on_progress: Bound<'py, PyAny> = + native_field(&context.invocation, "planning_progress")?.getattr("on_progress")?; let start: Instant = Instant::now(); let request: &Bound<'py, PyAny> = &context.request; let pipeline: Bound<'py, PyAny> = run_clone_pipeline_with_options(Some(&keywords( @@ -505,9 +495,7 @@ fn clone_boundaries<'py>( ("run_id", native_field(&project, "run_id")?), ( "query_change_tracking", - project - .getattr("settings")? - .getattr("query_change_tracking")?, + native_field(&project, "settings")?.getattr("query_change_tracking")?, ), ], )?; @@ -538,10 +526,7 @@ fn run_prephase(context: &BuildContext<'_>, prephase: &Prephase<'_>) -> PyResult )); } progress( - &context - .invocation - .getattr("planning_progress")? - .getattr("on_progress")?, + &native_field(&context.invocation, "planning_progress")?.getattr("on_progress")?, "Preparing defer clone plan...", )?; let connection: Bound<'_, PyAny> = prephase.adapter.call_method1( @@ -566,8 +551,7 @@ pub(crate) fn run_defer_clone_boundary_prephase( &native_field(request, "exclude")?, &discovered.clone(), )?; - if !split - .getattr("sql_test_selection")? + if !native_field(&split, "sql_test_selection")? .getattr("models_selected")? .is_truthy()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs index 3ae7608e0c..02881b4200 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs @@ -91,8 +91,7 @@ fn run_context_facts( + count(pipeline, "python_plan_entries")?; let mut loaded_sources: usize = 0; for source in native_field(&project, "sources")?.try_iter()? { - if !source? - .getattr("source_entry")? + if !native_field(&source?, "source_entry")? .getattr("loader")? .is_none() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs index 000e83c016..1742421c42 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs @@ -88,8 +88,7 @@ fn execution_limits<'py>( adapter_name: adapter_name.to_owned(), configures_max_duration: !native_field(&limits, "max_duration")?.is_none(), max_duration_seconds: native_field(&limits, "max_duration_seconds")?.extract()?, - adapter_limit_seconds: adapter - .getattr("execution_duration_limit_seconds")? + adapter_limit_seconds: native_field(adapter, "execution_duration_limit_seconds")? .extract()?, remediation: native_field(&limits, "remediation")?.extract()?, }; @@ -200,9 +199,11 @@ pub(crate) fn resolve_build_context<'py>( let load_sources: Bound<'py, PyAny> = native_field(request, "load_sources")?; let should_load_sources: bool = native_field(request, "reload_sources")?.is_truthy()? || if load_sources.is_none() { - build_effective_settings_config(&discovered.clone())? - .getattr("auto_load_sources")? - .is_truthy()? + native_field( + &build_effective_settings_config(&discovered.clone())?, + "auto_load_sources", + )? + .is_truthy()? } else { load_sources.is_truthy()? }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs index f4ed49db10..9f2a8137b0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs @@ -141,12 +141,10 @@ impl DirectPythonLifecycle { /// SQL-stage loaders, keeping dependencies Python ingress already satisfied only when needed. pub(crate) fn loader_functions<'py>(&self, py: Python<'py>) -> PyResult> { - let loaders: Vec> = self - .discovered - .bind(py) - .getattr("loader_functions")? - .try_iter()? - .collect::>()?; + let loaders: Vec> = + native_field(self.discovered.bind(py), "loader_functions")? + .try_iter()? + .collect::>()?; let functions: Vec> = loaders .iter() .map(|loader| native_field(loader, "function")) @@ -171,12 +169,10 @@ impl DirectPythonLifecycle { } fn ingress_keys<'py>(&self, py: Python<'py>, failed_only: bool) -> PyResult> { - let entries: Vec> = self - .plan - .bind(py) - .getattr("source_load_entries")? - .try_iter()? - .collect::>()?; + let entries: Vec> = + native_field(self.plan.bind(py), "source_load_entries")? + .try_iter()? + .collect::>()?; let mut keys: Vec> = Vec::new(); for result in self.ingress_load_results.bind(py).try_iter()? { let result: Bound<'py, PyAny> = result?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs index 96bf33a0d5..d54cfcf1cf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs @@ -132,11 +132,8 @@ pub(crate) fn model_text(model: &Bound<'_, PyAny>) -> PyResult cursor_range: cursor_range(model)?, empty_cursor_inputs: texts(model, "empty_cursor_inputs")?, waiting_on_empty_inputs: native_field(model, "waiting_on_empty_inputs")?.is_truthy()?, - recovery_batch_count: model - .getattr("microbatch_recovery_batch_count")? - .extract()?, - synthetic_completion_count: model - .getattr("microbatch_synthetic_completion_count")? + recovery_batch_count: native_field(model, "microbatch_recovery_batch_count")?.extract()?, + synthetic_completion_count: native_field(model, "microbatch_synthetic_completion_count")? .extract()?, replay_requirement_state: optional(model, "microbatch_replay_requirement_state")?, audits: audits(model, "audit_results")?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs index 8ec2b5b892..98d7fd7328 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs @@ -120,8 +120,7 @@ fn node_kind<'py>( graph: &Bound<'py, PyAny>, name: &Bound<'py, PyAny>, ) -> PyResult> { - graph - .getattr("nodes_by_name")? + native_field(graph, "nodes_by_name")? .get_item(name)? .getattr("kind") } @@ -252,9 +251,7 @@ fn compile_pipeline<'py>( ("relation_keys", keys), ( "on_progress", - invocation - .getattr("planning_progress")? - .getattr("on_progress")?, + native_field(invocation, "planning_progress")?.getattr("on_progress")?, ), ], )?))?; @@ -452,15 +449,11 @@ fn run_checks<'py>( ("python_graph", prepared.python_graph.clone()), ( "selected_python_names", - prepared - .lifecycle_plan - .getattr("ingress_python_node_names")?, + native_field(&prepared.lifecycle_plan, "ingress_python_node_names")?, ), ( "loader_functions", - invocation - .getattr("discovered_inputs")? - .getattr("loader_functions")?, + native_field(invocation, "discovered_inputs")?.getattr("loader_functions")?, ), ("source_map", source_map.clone()), ( @@ -631,8 +624,7 @@ fn complete<'py>( stream.call_method0("flush")?; let tuple: Bound<'py, PyAny> = PyTuple::new(py, results)?.into_any(); write_python_check_runtime_target( - &invocation - .getattr("effective_project_dir")? + &native_field(invocation, "effective_project_dir")? .call_method1("__truediv__", ("target",))?, &tuple, )?; @@ -671,9 +663,7 @@ pub(crate) fn run_check_command(py: Python<'_>, request: &Bound<'_, PyAny>) -> P &host::entry(py, UserCodeHost::BuildProviderSession)?, &[( "discovered_providers", - invocation - .getattr("discovered_inputs")? - .getattr("providers")?, + native_field(&invocation, "discovered_inputs")?.getattr("providers")?, )], )?; let outcome: PyResult = (|| { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs b/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs index 94e3060651..8f2bdb166c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs @@ -271,9 +271,8 @@ fn table_source<'py>( plan_output: &Bound<'py, PyAny>, name: &Bound<'py, PyAny>, ) -> PyResult>> { - let source: Bound<'py, PyAny> = plan_output - .getattr("python_source_entries")? - .call_method1("get", (name,))?; + let source: Bound<'py, PyAny> = + native_field(plan_output, "python_source_entries")?.call_method1("get", (name,))?; if source.is_none() || !native_field(&source, "expression")?.is_none() || native_field(&source, "table")?.is_none() @@ -470,9 +469,8 @@ pub(crate) fn run_read_side_dependencies<'py>( inputs: &ReadSideInputs<'py>, ) -> PyResult> { let py: Python<'py> = inputs.adapter.py(); - let read_side_names: Bound<'py, PyAny> = inputs - .lifecycle_plan - .getattr("read_side_python_node_names")?; + let read_side_names: Bound<'py, PyAny> = + native_field(&inputs.lifecycle_plan, "read_side_python_node_names")?; let to_validate: Bound<'py, PyAny> = if inputs.validation_refs.is_none() { read_side_references(&inputs.python_graph, &read_side_names)? } else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs b/crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs index ea94881054..04acf9bd3a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs @@ -95,14 +95,10 @@ fn grouping( } let py: Python<'_> = python_graph.py(); let empty: Bound<'_, PyAny> = pyo3::types::PyTuple::empty(py).into_any(); - let mut dependencies: Vec = names( - python_graph - .getattr("upstream_deps")? - .call_method1("get", (name, empty))?, - )?; - let node: Bound<'_, PyAny> = python_graph - .getattr("nodes_by_name")? - .call_method1("get", (name,))?; + let mut dependencies: Vec = + names(native_field(python_graph, "upstream_deps")?.call_method1("get", (name, empty))?)?; + let node: Bound<'_, PyAny> = + native_field(python_graph, "nodes_by_name")?.call_method1("get", (name,))?; if !node.is_none() { for reference in native_field(&node, "sql_deps")?.try_iter()? { dependencies.push(native_field(&reference?, "name")?.extract()?); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs index 0fb68d52d9..32abc9ad06 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs @@ -247,8 +247,7 @@ fn selector_inputs<'py>( args: &Bound<'py, PyAny>, ) -> PyResult<(Bound<'py, PyTuple>, Bound<'py, PyTuple>)> { let py: Python<'py> = args.py(); - let mut selectors: Vec> = args - .getattr("select")? + let mut selectors: Vec> = native_field(args, "select")? .try_iter()? .collect::>()?; let mut files: Vec> = Vec::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs index 5dbe51c1f0..de1ab3c393 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs @@ -324,8 +324,7 @@ pub(crate) fn run_clone_command(py: Python<'_>, request: &Bound<'_, PyAny>) -> P invocation.adapter.call_method1("close", (&connection,)); let (pipeline, result, elapsed) = outcome?; closed?; - let items: Vec = result - .getattr("item_results")? + let items: Vec = native_field(&result, "item_results")? .try_iter()? .map(|item| clone_item_text(&item?)) .collect::>()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs index f19ce6d00e..b0d107735f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs @@ -58,8 +58,7 @@ pub(crate) fn resource_types_by_name( .map(|entry| { Ok(( native_field(entry, "name")?.extract()?, - entry - .getattr("key")? + native_field(entry, "key")? .getattr("resource_type")? .str()? .extract()?, @@ -175,8 +174,7 @@ fn execution_input<'py>( let project: Bound<'py, PyAny> = native_field(pipeline, "destination_project")?; let plan: Bound<'py, PyAny> = native_field(pipeline, "clone_plan")?; let config: Bound<'py, PyAny> = target_config(invocation)?; - let selected: Vec> = pipeline - .getattr("destination_model_entries")? + let selected: Vec> = native_field(pipeline, "destination_model_entries")? .try_iter()? .map(|entry| native_field(&entry?, "name")) .collect::>()?; @@ -198,8 +196,7 @@ fn execution_input<'py>( ), ], )?; - let allow_decrease: bool = config - .getattr("time_travel_retention_decrease")? + let allow_decrease: bool = native_field(&config, "time_travel_retention_decrease")? .eq(enum_member(py, RecordId::RetentionDecreasePolicy, "ALLOW")?)?; let source_entries: Bound<'py, PyAny> = call_with( &host::entry(py, ExecutorHost::CloneSourceEntries)?, @@ -233,9 +230,7 @@ fn execution_input<'py>( ("run_id", native_field(&project, "run_id")?), ( "query_change_tracking", - project - .getattr("settings")? - .getattr("query_change_tracking")?, + native_field(&project, "settings")?.getattr("query_change_tracking")?, ), ("upstream_deps", native_field(&plan, "upstream_deps")?), ( @@ -287,9 +282,7 @@ fn copy_fingerprints<'py>( ("run_id", native_field(&project, "run_id")?), ( "query_change_tracking", - project - .getattr("settings")? - .getattr("query_change_tracking")?, + native_field(&project, "settings")?.getattr("query_change_tracking")?, ), ("on_progress", reporter.clone().into_any()), ]); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs index ed3a45c08f..d67bfd1f94 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs @@ -27,8 +27,7 @@ pub(crate) fn clone_item_text(item: &Bound<'_, PyAny>) -> PyResult()?, ), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/preview_target.rs b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/preview_target.rs index 91992b5df3..8f83b4db8c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/preview_target.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/preview_target.rs @@ -10,8 +10,7 @@ use crate::bindings::_helpers::command_runtime::runtime_errors::raised; use crate::bindings::_helpers::records::fields::field as native_field; fn target_names(config: &Bound<'_, PyAny>) -> PyResult> { - config - .getattr("targets")? + native_field(config, "targets")? .try_iter()? .map(|name| name?.extract()) .collect() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs index 2f6767aa0d..2e13b87f48 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs @@ -155,12 +155,10 @@ pub(crate) fn find_authored<'py>( if target_name.is_none() { return Ok(None); } - let local_target: Bound<'py, PyAny> = local_config - .getattr("targets")? - .call_method1("get", (&target_name,))?; - let project_target: Bound<'py, PyAny> = project_config - .getattr("targets")? - .call_method1("get", (&target_name,))?; + let local_target: Bound<'py, PyAny> = + native_field(&local_config, "targets")?.call_method1("get", (&target_name,))?; + let project_target: Bound<'py, PyAny> = + native_field(&project_config, "targets")?.call_method1("get", (&target_name,))?; let target_name: String = target_name.extract()?; let group_name: String = native_field(group, "value")?.extract()?; Ok(authored_warehouse( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs index 804f6c5adc..c9360aca51 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs @@ -89,9 +89,7 @@ pub(crate) fn build_declaration_scope<'py>( raised.set_cause(py, Some(error)); return Err(raised); } - if native - .getattr("has_scoped_relationship_declarations")? - .is_truthy()? + if native_field(&native, "has_scoped_relationship_declarations")?.is_truthy()? && (test_files.is_truthy()? || scenario_files.is_truthy()?) { let faults: Bound<'py, PyAny> = call_with( @@ -144,9 +142,7 @@ fn indexed_macro_metadata<'py>(loaded_macros: &Bound<'py, PyAny>) -> PyResult = PyTuple::new( py, - signature - .call1((&function,))? - .getattr("parameters")? + native_field(&signature.call1((&function,))?, "parameters")? .try_iter()? .collect::>>()?, )?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs index 9cd15c7890..7b371a1eb9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs @@ -102,7 +102,10 @@ fn macro_inputs<'py>(context: &Bound<'py, PyAny>) -> PyResult ("expansion", macro_expansion_classes(py)?.into_any()), ( "generic_syntax", - new_record(py, RecordId::SqlLexicalSyntax, (), None)?.getattr("native_mapping")?, + native_field( + &new_record(py, RecordId::SqlLexicalSyntax, (), None)?, + "native_mapping", + )?, ), ], ) @@ -218,8 +221,7 @@ pub(crate) fn build_model_inputs<'py>( ], )?; let session: Bound<'py, PyAny> = native_model_config_session(&config_inputs, &validator)?; - let provider_names: Vec> = discovered_inputs - .getattr("providers")? + let provider_names: Vec> = native_field(discovered_inputs, "providers")? .try_iter()? .map(|provider| native_field(&provider?, "name")) .collect::>()?; @@ -284,8 +286,7 @@ pub(crate) fn build_model_inputs<'py>( ) .and_then(|value| pyo3::Bound::new(py, value)) .map(pyo3::Bound::into_any)?; - let files: Vec> = discovered_inputs - .getattr("model_files")? + let files: Vec> = native_field(discovered_inputs, "model_files")? .try_iter()? .map(|file| file?.extract()) .collect::>()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs index bb19a08ff2..4dfc17cce2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs @@ -107,8 +107,7 @@ impl SqlExpansionInputs { constants: field("constants")?, value_renderer: field("value_renderer")?, collection_rendering: field("collection_rendering")?, - local_declarations: record - .getattr("local_declarations")? + local_declarations: native_field(record, "local_declarations")? .downcast_into::()? .unbind(), declaration_resolver: field("declaration_resolver")?, @@ -225,9 +224,7 @@ pub(crate) fn sql_expansion_inputs(sources: ExpansionSources<'_>) -> PyResult( } if !target.is_none() && let Some(found) = present( - target - .getattr("time_travel_retention_by_materialization")? + native_field(target, "time_travel_retention_by_materialization")? .call_method1("get", (materialized,))?, ) { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs index 9a3d602dae..04843b64d5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs @@ -80,8 +80,7 @@ fn compile_cache_root<'py>( if no_cache || project_dir.is_none() || (!target_config.is_none() - && target_config - .getattr("compile_cache")? + && native_field(target_config, "compile_cache")? .is(pyo3::types::PyBool::new(py, false))) || disabled { @@ -100,8 +99,7 @@ fn remove_retired_caches(root: &Bound<'_, PyAny>) -> PyResult<()> { ignore.set_item("ignore_errors", true)?; for suffix in RETIRED_CACHE_NAMESPACE_SUFFIXES { for name in RETIRED_CACHE_DIRECTORY_NAMES { - let retired: Bound<'_, PyAny> = root - .getattr("parent")? + let retired: Bound<'_, PyAny> = native_field(root, "parent")? .div(format!("{COMPILER_CACHE_DIRECTORY_NAME}{suffix}"))? .div(name)?; if retired.call_method0("is_dir")?.is_truthy()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs index 2248a6f9fa..a29f926377 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs @@ -111,9 +111,7 @@ impl<'py> ReportInputs<'py> { /// The project's models, kept to the selected ones. fn selected_models(&self) -> PyResult>> { - let models: Vec> = self - .project - .getattr("models")? + let models: Vec> = native_field(&self.project, "models")? .try_iter()? .collect::>()?; let Some(names) = self.selected_names(MODEL_TYPE)? else { @@ -132,9 +130,7 @@ impl<'py> ReportInputs<'py> { fn selected_count(&self, types: &[&str]) -> PyResult { let mut count: usize = 0; if self.selected_keys.is_none() { - for key in self - .graph - .getattr("native")? + for key in native_field(&self.graph, "native")? .call_method0("keys")? .try_iter()? { @@ -192,10 +188,8 @@ impl<'py> ReportInputs<'py> { /// `written.target_dir / "compiled"` relative to its `target` directory, POSIX style. fn compiled_dir(&self) -> PyResult> { let py: Python<'py> = self.py(); - let path: Bound<'py, PyAny> = self - .written - .getattr("target_dir")? - .div(COMPILED_DIRECTORY)?; + let path: Bound<'py, PyAny> = + native_field(&self.written, "target_dir")?.div(COMPILED_DIRECTORY)?; let parts: Bound<'py, PyTuple> = native_field(&path, "parts")?.downcast_into()?; for (index, part) in parts.iter().enumerate() { if part.eq(TARGET_DIRECTORY)? { @@ -373,9 +367,7 @@ pub(crate) fn format_compile_text<'py>( let lineage: LineageNote = if !inputs.lineage.is_none() && inputs.lineage_mode == RICH_LINEAGE { LineageNote::Rich } else if inputs.lineage.is_none() - && inputs - .project - .getattr("settings")? + && native_field(&inputs.project, "settings")? .getattr("sql_analysis")? .is_truthy()? && inputs.lineage_mode != NO_LINEAGE @@ -596,9 +588,7 @@ fn model_resource<'py>( let py: Python<'py> = model.py(); let key: Bound<'py, PyAny> = native_field(model, "key")?; let mut depends_on: Vec> = Vec::new(); - for upstream in inputs - .graph - .getattr("native")? + for upstream in native_field(&inputs.graph, "native")? .call_method1( "upstream", (( @@ -749,8 +739,7 @@ fn audit_resource<'py>(audit: &Bound<'py, PyAny>) -> PyResult ("name", native_field(audit, "name")?), ( "relative_path", - audit - .getattr("audit_file")? + native_field(audit, "audit_file")? .getattr("relative_path")? .str()? .into_any(), @@ -783,8 +772,7 @@ fn test_resource<'py>(test: &Bound<'py, PyAny>) -> PyResult> if payload.is_instance(&record_class(py, RecordId::CompiledModelSqlTestPayload)?)? { PyList::new( py, - payload - .getattr("expected_model_names")? + native_field(&payload, "expected_model_names")? .try_iter()? .collect::>>()?, )? @@ -805,8 +793,7 @@ fn test_resource<'py>(test: &Bound<'py, PyAny>) -> PyResult> if case_name.is_none() { return Ok(item); } - let schema: Vec> = test - .getattr("parameter_schema")? + let schema: Vec> = native_field(test, "parameter_schema")? .try_iter()? .collect::>()?; let types: Bound<'py, PyDict> = PyDict::new(py); @@ -888,8 +875,7 @@ fn source_resource<'py>(source: &Bound<'py, PyAny>) -> PyResult) -> PyResult<()> { for part in LAUNCH_RECORD_DIRECTORY { directory = directory.call_method1("__truediv__", (part,))?; } - if path - .getattr("parent")? + if native_field(&path, "parent")? .call_method0("resolve")? .ne(directory.call_method0("resolve")?)? { @@ -464,8 +463,7 @@ fn reuse_request<'py>(request: &Bound<'py, PyAny>) -> PyResult } fields.push(( "lineage_mode", - request - .getattr("lineage_mode")? + native_field(request, "lineage_mode")? .getattr("value")? .str()? .into_any(), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs index 398090932a..00f2e51c8d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs @@ -406,9 +406,7 @@ fn record<'py>(facts: &CompileFacts<'py>) -> PyResult { "stderr_lines", PyList::new( py, - facts - .output - .getattr("stderr_lines")? + native_field(&facts.output, "stderr_lines")? .try_iter()? .collect::>>()?, )? @@ -425,9 +423,7 @@ fn record<'py>(facts: &CompileFacts<'py>) -> PyResult { "template_environment_names", PyList::new( py, - facts - .input_reads - .getattr("environment_names")? + native_field(&facts.input_reads, "environment_names")? .try_iter()? .collect::>>()?, )? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs index 6475162b5f..d69a1860aa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs @@ -140,8 +140,7 @@ fn function_sql(adapter: &Bound<'_, PyAny>, function: &Bound<'_, PyAny>) -> PyRe ] { arguments.push((field, native_field(function, field)?)); } - let statements: Vec = adapter - .getattr("render_create_function")? + let statements: Vec = native_field(adapter, "render_create_function")? .call((), Some(&keywords(py, &arguments)?))? .extract()?; Ok(statements.join(";\n\n")) @@ -247,8 +246,7 @@ fn write_planned_target<'py>( batch.flush(py)?; for entry in native_field(plan_output, "function_entries")?.try_iter()? { let entry: Bound<'py, PyAny> = entry?; - if entry - .getattr("destination")? + if native_field(&entry, "destination")? .getattr("qualified_name")? .is_none() { @@ -493,7 +491,7 @@ fn artifact_diagnostics<'py>( ("severity", "error".into_bound_py_any(py)?), ( "code", - error_class(py, ErrorId::PlannerInput)?.getattr("code")?, + native_field(&error_class(py, ErrorId::PlannerInput)?, "code")?, ), ("message", message?), ("resource_type", "sql_test".into_bound_py_any(py)?), @@ -582,8 +580,7 @@ pub(crate) fn write_static_target<'py>( batch.flush(py)?; for function in native_field(project, "functions")?.try_iter()? { let function: Bound<'py, PyAny> = function?; - if function - .getattr("destination")? + if native_field(&function, "destination")? .getattr("qualified_name")? .is_none() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs index 712cbf6f59..9384073940 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs @@ -208,8 +208,7 @@ fn analyzed<'py>( select_project_graph(&graph, &driver.select, &driver.exclude)?.into_any(); let core_diagnostics: Bound<'py, PyTuple> = PyTuple::new( py, - project - .getattr("diagnostics")? + native_field(&project, "diagnostics")? .try_iter()? .chain(native_field(&contracts.result, "diagnostics")?.try_iter()?) .collect::>>()?, @@ -296,16 +295,14 @@ impl<'py> Driver<'_, 'py> { let started: Instant = Instant::now(); self.status.start("Discovering project...")?; let false_value: Bound<'py, PyAny> = PyBool::new(py, false).to_owned().into_any(); - let override_analysis: Bound<'py, PyAny> = if self - .options - .profile_flags - .getattr("skip_discovery_sql_analysis")? - .is_truthy()? - { - false_value.clone() - } else { - py.None().into_bound(py) - }; + let override_analysis: Bound<'py, PyAny> = + if native_field(&self.options.profile_flags, "skip_discovery_sql_analysis")? + .is_truthy()? + { + false_value.clone() + } else { + py.None().into_bound(py) + }; let discovered: Bound<'py, PyAny> = discover_project_inputs( py, Some(keywords( @@ -424,11 +421,8 @@ impl<'py> Driver<'_, 'py> { let thread_time: Bound<'py, PyAny> = imported(py, "time", "thread_time")?; let started: Instant = Instant::now(); let cpu_started: f64 = thread_time.call0()?.extract()?; - let skip: bool = self - .options - .profile_flags - .getattr("skip_contracts")? - .is_truthy()?; + let skip: bool = + native_field(&self.options.profile_flags, "skip_contracts")?.is_truthy()?; let result: Bound<'py, PyAny> = if skip { new_record_with( py, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs index c18fa7f098..3e92952ae7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs @@ -147,9 +147,10 @@ fn inference_profile_payload<'py>( let inspect = py.import("inspect")?; let sorted: Bound<'py, PyAny> = imported(py, "builtins", "sorted")?; let rules: Bound<'py, PyList> = PyList::empty(py); - let items: Bound<'py, PyAny> = sorted.call1((profile - .getattr("function_nullability_rules")? - .call_method0("items")?,))?; + let items: Bound<'py, PyAny> = + sorted.call1(( + native_field(profile, "function_nullability_rules")?.call_method0("items")?, + ))?; for item in items.try_iter()? { let (name, rule): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; if !inspect.call_method1("isfunction", (&rule,))?.is_truthy()? { @@ -199,9 +200,11 @@ fn inference_profile_payload<'py>( payload.set_item("function_nullability_rules", rules)?; payload.set_item( "function_return_types", - imported(py, "builtins", "dict")?.call1((sorted.call1((profile - .getattr("function_return_types")? - .call_method0("items")?,))?,))?, + imported(py, "builtins", "dict")?.call1((sorted.call1((native_field( + profile, + "function_return_types", + )? + .call_method0("items")?,))?,))?, )?; Ok(Some(payload)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs index fa3ba20617..e397f943bc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs @@ -206,8 +206,7 @@ fn referenced_project(py: Python<'_>, request: AssemblyRequest) -> PyResult(model_input: &Bound<'py, PyAny>) -> PyResult> { - model_input - .getattr("model_file")? + native_field(model_input, "model_file")? .getattr("file_path")? .getattr("stem") } @@ -83,9 +82,7 @@ pub(crate) fn analysis_context<'py>( ) -> PyResult> { let inputs: &Bound<'py, PyAny> = request.inputs.bind(py); let sql_analysis_enabled: Bound<'py, PyAny> = and_not( - &inputs - .getattr("effective_settings")? - .getattr("sql_analysis")?, + &native_field(inputs, "effective_settings")?.getattr("sql_analysis")?, request.skip_column_inference.bind(py), )?; let (column_types, nullability, complete_schemas): DeclaredRelations<'py> = @@ -115,12 +112,9 @@ pub(crate) fn analysis_context<'py>( record_expression_shapes(request, &context)?; } let catalog: Bound<'py, PyAny> = native_field(&context.profile, "binding_catalog")?; - catalog - .getattr("native")? + native_field(&catalog, "native")? .call_method1("update_relations", (&context.complete_schemas,))?; - catalog - .getattr("schemas")? - .call_method1("update", (&context.complete_schemas,))?; + native_field(&catalog, "schemas")?.call_method1("update", (&context.complete_schemas,))?; context.analyses = model_analyses(request, &context)?; Ok(context) } @@ -132,8 +126,7 @@ fn dynamic_families_by_table<'py>(inputs: &Bound<'py, PyAny>) -> PyResult = PyDict::new(py); for model_input in native_field(inputs, "model_inputs")?.try_iter()? { let model_input: Bound<'py, PyAny> = model_input?; - let contract: Bound<'py, PyAny> = model_input - .getattr("config")? + let contract: Bound<'py, PyAny> = native_field(&model_input, "config")? .getattr("values")? .call_method1("get", ("contract",))?; if !contract.eq(&enforced)? { @@ -217,9 +210,7 @@ fn profile_with_catalog<'py>( py, ( dialect, - profile - .getattr("quoted_identifiers_ignore_case")? - .extract()?, + native_field(&profile, "quoted_identifiers_ignore_case")?.extract()?, native_field(&profile, "semantic_known_functions")?.extract()?, native_field(&profile, "semantic_known_types")?.extract()?, ), @@ -266,9 +257,8 @@ fn record_expression_shapes<'py>( let mut expressions: Vec> = Vec::new(); for source_input in native_field(inputs, "source_inputs")?.try_iter()? { let source_input: Bound<'py, PyAny> = source_input?; - let expression: Bound<'py, PyAny> = source_input - .getattr("source_entry")? - .getattr("expression")?; + let expression: Bound<'py, PyAny> = + native_field(&source_input, "source_entry")?.getattr("expression")?; if expression.is_truthy()? { sources.push(source_input); expressions.push(expression); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs index 74c1228db6..187d1043e0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs @@ -126,9 +126,7 @@ fn model_macro_context<'py>(inputs: &Bound<'py, PyAny>) -> PyResult( } else { top_level_macro_call_names( py, - &model_input - .getattr("macro_source_sql")? - .extract::()?, + &native_field(model_input, "macro_source_sql")?.extract::()?, )? .into_any() }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs index 45aedec4b9..e4984502b7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs @@ -285,9 +285,7 @@ fn project_fields<'py>( } fields.set_item( "enforce_explicit_references", - project_config - .getattr("references")? - .getattr("enforce_explicit")?, + native_field(&project_config, "references")?.getattr("enforce_explicit")?, )?; for name in ["sql_hook_files", "materialization_files"] { fields.set_item(name, native_field(&discovered, name)?)?; @@ -295,8 +293,7 @@ fn project_fields<'py>( for name in ["public_enums", "public_constants", "loaded_macros"] { fields.set_item(name, native_field(inputs, name)?)?; } - let mut diagnostics: Vec> = inputs - .getattr("diagnostics")? + let mut diagnostics: Vec> = native_field(inputs, "diagnostics")? .try_iter()? .collect::>()?; diagnostics.extend(project_binding_diagnostics( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs index 7cbe8f77b0..22beebcb4b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs @@ -27,8 +27,7 @@ pub(crate) fn assembled_sql_tests<'py>( count_stage(py, SQL_TEST_ASSEMBLY, 1)?; let assemblies: Vec> = assemble_native_sql_tests(py, inputs)?.iter().collect(); - let test_inputs: Vec> = inputs - .getattr("test_inputs")? + let test_inputs: Vec> = native_field(inputs, "test_inputs")? .try_iter()? .collect::>()?; if assemblies.len() != test_inputs.len() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs index 6f06f8d174..61fa9bf4f9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs @@ -146,8 +146,7 @@ fn recorded_compile<'py>( total_start: f64, ) -> PyResult { let py: Python<'py> = request.py(); - let skip_write: bool = request - .getattr("profile_flags")? + let skip_write: bool = native_field(request, "profile_flags")? .getattr("skip_write")? .is_truthy()?; let compiled: PyResult<(CommandOutcome<'py>, Bound<'py, PyAny>, Bound<'py, PyAny>)> = @@ -250,8 +249,7 @@ fn compiled_with_status<'py>( &analysis_options(request, &project_dir, recorders, status)?, )?; let rules_failed: bool = rules_failed(&analysis)?; - let skip_write: bool = request - .getattr("profile_flags")? + let skip_write: bool = native_field(request, "profile_flags")? .getattr("skip_write")? .is_truthy()?; let manifest_requested: bool = native_field(request, "manifest")?.is_truthy()?; @@ -282,8 +280,7 @@ fn compiled_with_status<'py>( }; let diagnostics: Bound<'py, PyTuple> = PyTuple::new( py, - analysis - .getattr("diagnostics")? + native_field(&analysis, "diagnostics")? .try_iter()? .chain(native_field(&written, "diagnostics")?.try_iter()?) .chain(withheld.try_iter()?) @@ -310,8 +307,7 @@ fn compiled_with_status<'py>( }; let outcome: CommandOutcome<'py> = CommandOutcome { exit_code, - compile_cache_enabled: !analysis - .getattr("graph")? + compile_cache_enabled: !native_field(&analysis, "graph")? .getattr("project")? .getattr("compile_cache_dir")? .is_none(), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs index 9e90a353ef..d1e6f34625 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs @@ -45,8 +45,7 @@ fn project_config_error(py: Python<'_>, message: &str, help: Option<&str>) -> Py /// The target names of one configuration's `targets` mapping. fn target_names(config: &Bound<'_, PyAny>) -> PyResult> { - config - .getattr("targets")? + native_field(config, "targets")? .try_iter()? .map(|name| name?.extract()) .collect() @@ -59,13 +58,8 @@ fn reject_local_sql_analysis_opt_out(config: &ProjectConfiguration<'_, '_>) -> P let flags: Bound<'_, PyTuple> = PyTuple::new( py, [ - config - .project_config - .getattr("settings")? - .getattr("require_sql_analysis")?, - config - .local_config - .getattr("setting_overrides")? + native_field(config.project_config, "settings")?.getattr("require_sql_analysis")?, + native_field(config.local_config, "setting_overrides")? .contains(SQL_ANALYSIS_KEY) .map(|overridden| PyBool::new(py, overridden).to_owned().into_any())?, native_field(&local_settings, SQL_ANALYSIS_KEY)?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs index 09d6af07ec..10773d013d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs @@ -76,8 +76,7 @@ fn diff_graph<'py>(project: &Bound<'py, PyAny>, keys: &KeyIndexes<'py>) -> PyRes adjacency(&native_field(&lineage, "upstream_deps")?, keys)?; let downstream: Vec<(usize, Vec)> = adjacency(&native_field(&lineage, "downstream_deps")?, keys)?; - for item in lineage - .getattr("tag_index")? + for item in native_field(&lineage, "tag_index")? .call_method0("items")? .try_iter()? { @@ -87,8 +86,7 @@ fn diff_graph<'py>(project: &Bound<'py, PyAny>, keys: &KeyIndexes<'py>) -> PyRes keys.indexes(&item.get_item(1)?)?, )); } - for item in lineage - .getattr("path_index")? + for item in native_field(&lineage, "path_index")? .call_method0("items")? .try_iter()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs index e67763d24c..d747ec27e6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs @@ -239,15 +239,12 @@ fn assembled_inputs<'py>( let sql_analysis_override: &Bound<'py, PyAny> = request.sql_analysis_enabled_override.bind(py); let sql_analysis_enabled: Bound<'py, PyAny> = if !sql_analysis_override.is_none() { sql_analysis_override.clone() - } else if local_config - .getattr("setting_overrides")? + } else if native_field(&local_config, "setting_overrides")? .contains(SQL_ANALYSIS_SETTING_KEY)? { native_field(&local_config, "settings")?.getattr("sql_analysis")? } else { - project_config - .getattr("settings")? - .getattr("sql_analysis")? + native_field(&project_config, "settings")?.getattr("sql_analysis")? }; let discovered: Bound<'py, PyAny> = discovered_inputs( py, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs index 818cce8ad6..8fa39e7c42 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs @@ -131,8 +131,7 @@ pub(crate) fn attached_inputs<'py>( } let diagnostics: Bound<'py, PyTuple> = PyTuple::new( py, - built - .getattr("diagnostics")? + native_field(&built, "diagnostics")? .try_iter()? .chain(collected.try_iter()?) .collect::>>()?, @@ -298,9 +297,7 @@ fn target_context<'py>( ), ( "_enforce_explicit_references", - project_config - .getattr("references")? - .getattr("enforce_explicit")?, + native_field(&project_config, "references")?.getattr("enforce_explicit")?, ), ], )?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs index 708701b576..f05d96721a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs @@ -114,8 +114,7 @@ pub(crate) fn write_dag_artifact<'py>( let discovered: Bound<'py, PyAny> = native_field(analysis, "discovered_inputs")?; let python_graph: Bound<'py, PyAny> = python_node_graph(&discovered)?; let path: Bound<'py, PyAny> = resolved_dag_path(project_dir, dag_path)?; - let project_name: String = discovered - .getattr("project_config")? + let project_name: String = native_field(&discovered, "project_config")? .getattr("name")? .extract()?; let dag_json: String = build_dag_json( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs index b320ca6221..1ea5787e8d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs @@ -61,12 +61,8 @@ pub(crate) fn compile_analysis_selection<'py>( } } let no_cache: Bound<'py, PyAny> = native_field(options, "no_cache")?; - if (options - .getattr("resolve_python_run_selectors")? - .is_truthy()? - && has_python_nodes) - || options - .getattr("sql_test_selection")? + if (native_field(options, "resolve_python_run_selectors")?.is_truthy()? && has_python_nodes) + || native_field(options, "sql_test_selection")? .getattr("names")? .is_truthy()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs index 97309d6123..c013edc2c1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs @@ -57,10 +57,7 @@ pub(crate) fn pipeline_result<'py>( let sql_test_selection: Bound<'py, PyAny> = native_field(options, "sql_test_selection")?; if !native_field(&sql_test_selection, "models_selected")?.is_truthy()? { selected_sql_keys = empty()?; - } else if options - .getattr("resolve_python_run_selectors")? - .is_truthy()? - { + } else if native_field(options, "resolve_python_run_selectors")?.is_truthy()? { let graph: Bound<'py, PyAny> = build_project_graph_from_compiled_project( py, Some(keywords(py, &[("project", project.clone())])?), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs index f2b67b6c55..f4797bbd99 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs @@ -213,14 +213,12 @@ fn targeted_project<'py>( project_targets(&adapter_name, &project)?; let promotion_key: Bound<'py, PyAny> = pyo3::types::PyString::new(py, TABLE_PROMOTION_MODE_SETTING_KEY).into_any(); - let settings_file: Bound<'py, PyAny> = if local_config - .getattr("setting_overrides")? - .contains(promotion_key)? - { - pyo3::types::PyString::new(py, LOCAL_CONFIG_FILENAME).into_any() - } else { - pyo3::types::PyString::new(py, PROJECT_CONFIG_FILENAME).into_any() - }; + let settings_file: Bound<'py, PyAny> = + if native_field(&local_config, "setting_overrides")?.contains(promotion_key)? { + pyo3::types::PyString::new(py, LOCAL_CONFIG_FILENAME).into_any() + } else { + pyo3::types::PyString::new(py, PROJECT_CONFIG_FILENAME).into_any() + }; count_stage(py, PROMOTION_CONFLICTS, 1)?; let conflicts: Bound<'py, PyAny> = promotion_conflict_diagnostics( py, @@ -231,8 +229,7 @@ fn targeted_project<'py>( .into_any(); let diagnostics: Bound<'py, PyTuple> = PyTuple::new( py, - project - .getattr("diagnostics")? + native_field(&project, "diagnostics")? .try_iter()? .chain(conflicts.try_iter()?) .collect::>>()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs index af3a749e85..ea1bf76cb0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs @@ -47,8 +47,7 @@ impl<'py> NodeKinds<'py> { /// `python_graph.upstream_deps` as names. fn upstream_names(graph: &Bound<'_, PyAny>) -> PyResult>> { let mut upstream: HashMap> = HashMap::new(); - for item in graph - .getattr("upstream_deps")? + for item in native_field(graph, "upstream_deps")? .call_method0("items")? .try_iter()? { @@ -141,8 +140,7 @@ pub(crate) fn build_python_run_plan_outputs<'py>( } let graph: Bound<'py, PyAny> = node_graph(&arguments.value("discovered_inputs")?)?; let kinds: NodeKinds<'py> = NodeKinds::load(py)?; - let mut warnings: Vec> = plan_output - .getattr("warnings")? + let mut warnings: Vec> = native_field(&plan_output, "warnings")? .try_iter()? .collect::>()?; warnings.extend(skipped_ingress_warnings( @@ -307,10 +305,7 @@ fn identity_status<'py>( if previous.is_none() { return native_field(&statuses, "NEW"); } - if previous - .getattr("version_hash")? - .eq(native_field(identity, "version_hash")?)? - { + if native_field(&previous, "version_hash")?.eq(native_field(identity, "version_hash")?)? { return native_field(&statuses, "UNCHANGED"); } native_field(&statuses, "CHANGED") diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs index 8a4da6a5da..eec5b0bafe 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs @@ -92,10 +92,7 @@ pub(crate) fn build_project_relation_targets<'py>( (&["adapter", "plan_output"], &[]), )?; let plan_output: Bound<'py, PyAny> = arguments.value("plan_output")?; - if !plan_output - .getattr("enforce_explicit_references")? - .is_truthy()? - { + if !native_field(&plan_output, "enforce_explicit_references")?.is_truthy()? { return Ok(None); } let kinds: RefKinds<'py> = RefKinds::load(py)?; @@ -208,9 +205,8 @@ fn planned_relation<'py>( let kind: Bound<'py, PyAny> = native_field(reference, "kind")?; let name: Bound<'py, PyAny> = native_field(reference, "name")?; if kind.eq(&kinds.source)? { - let source: Bound<'py, PyAny> = plan_output - .getattr("python_source_entries")? - .call_method1("get", (name,))?; + let source: Bound<'py, PyAny> = + native_field(plan_output, "python_source_entries")?.call_method1("get", (name,))?; if source.is_none() { return Ok(source); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs index 8a1bb51bcc..c8ce32d6a5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs @@ -94,9 +94,7 @@ fn planner_scopes<'py>( /// The stale-warning scope's models of `scopes`. fn scoped_models<'py>(scopes: &Bound<'py, PyAny>) -> PyResult> { - scopes - .getattr("stale_warning_scope")? - .getattr("models_by_name") + native_field(scopes, "stale_warning_scope")?.getattr("models_by_name") } /// Return options whose selectors name only resources, with unit tests selected apart. @@ -118,8 +116,7 @@ pub(crate) fn resolve_configured_rule_selection<'py>( project: &Bound<'py, PyAny>, ) -> PyResult> { let py: Python<'py> = options.py(); - if !options - .getattr("sql_test_selection")? + if !native_field(options, "sql_test_selection")? .getattr("models_selected")? .is_truthy()? { @@ -234,8 +231,7 @@ pub(crate) fn compile_static_command_context<'py>( let mut selected_keys: Bound<'py, PyAny> = request.optional("selected_keys")?.unwrap_or_else(none); if selected_keys.is_none() - && !options - .getattr("sql_test_selection")? + && !native_field(&options, "sql_test_selection")? .getattr("models_selected")? .is_truthy()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs index 9d5e4dccfa..5ed81b7d4f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs @@ -123,10 +123,7 @@ pub(crate) fn named_target_schema_strategy( selected_target: &Bound<'_, PyAny>, ) -> PyResult<()> { let py: Python<'_> = discovered.py(); - if adapter - .getattr("allows_implicit_managed_write_schema")? - .is_truthy()? - { + if native_field(adapter, "allows_implicit_managed_write_schema")?.is_truthy()? { return Ok(()); } let project_config: Bound<'_, PyAny> = native_field(discovered, "project_config")?; @@ -498,17 +495,12 @@ pub(crate) fn managed_write_schemas( adapter: &Bound<'_, PyAny>, project: &Bound<'_, PyAny>, ) -> PyResult<()> { - if adapter - .getattr("allows_implicit_managed_write_schema")? - .is_truthy()? - { + if native_field(adapter, "allows_implicit_managed_write_schema")?.is_truthy()? { return Ok(()); } let connection_schema: Option = explicit_write_schema( text_or_none( - &project - .getattr("effective_connection")? - .call_method1("get", ("schema",))?, + &native_field(project, "effective_connection")?.call_method1("get", ("schema",))?, )? .as_deref(), ); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs index 2060ede683..1b899e2c31 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs @@ -122,8 +122,7 @@ fn entry_paths( } fn relative_posix(entry: &Bound<'_, PyAny>) -> PyResult { - entry - .getattr("relative_path")? + native_field(entry, "relative_path")? .call_method0("as_posix")? .extract() } @@ -143,8 +142,7 @@ pub(crate) fn write_runtime_target( entry_paths(&native_field(plan, "function_entries")?, |entry| { Ok(function_run_path( &relative_posix(entry)?, - &entry - .getattr("language")? + &native_field(entry, "language")? .getattr("value")? .extract::()?, )) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs index 07808a85bf..5adc9d2492 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs @@ -174,9 +174,8 @@ pub(crate) fn attach_resources<'py>( .collect(), &error_class(py, ErrorId::CompileInput)?, )?; - let defaults: Bound<'py, PyAny> = discovered_inputs - .getattr("project_config")? - .getattr("defaults")?; + let defaults: Bound<'py, PyAny> = + native_field(discovered_inputs, "project_config")?.getattr("defaults")?; let function_kind: Bound<'py, PyAny> = enum_member(py, RecordId::ResourceKind, "FUNCTION")?; let functions = NativeCompiledProject::attach_functions( native_project, @@ -494,8 +493,7 @@ fn loader_rows<'py>(discovered: &Bound<'py, PyAny>) -> PyResult()? .as_str(), ), @@ -542,8 +540,7 @@ fn diagnostic_settings<'py>( native_field(scenario, "name")?, text(scenario, "relative_path")?.into_bound_py_any(py)?, native_field(scenario, "contents")?, - scenario - .getattr("header_values")? + native_field(scenario, "header_values")? .call_method1("get", (DESCRIPTION_KEY,))?, ], ) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs index 2dd8c6585c..62e96eb2a8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs @@ -13,6 +13,7 @@ use crate::bindings::_helpers::compiled_project::model_input_view::{ }; use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; use crate::bindings::_helpers::compiled_project::project::NativeCompiledProject; +use crate::bindings::_helpers::records::fields::field as native_field; const AUDIT_RESOURCE: &str = "audit"; const AUDIT_CLASSES: &str = "audits"; @@ -153,11 +154,10 @@ macro_rules! audit_getters { #[getter] pub(crate) fn evaluation_mode(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { - Ok(audit + Ok(native_field(&audit .attached .audit_block - .bind(py) - .getattr("evaluation_mode")? + .bind(py), "evaluation_mode")? .unbind()) }) } @@ -165,11 +165,10 @@ macro_rules! audit_getters { #[getter] pub(crate) fn measurement_contract(&self, py: Python<'_>) -> PyResult> { read_audit(&self.owner, self.index, py, |audit, py| { - Ok(audit + Ok(native_field(&audit .attached .audit_block - .bind(py) - .getattr("measurement_contract")? + .bind(py), "measurement_contract")? .unbind()) }) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs index f013e99645..bfece36153 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs @@ -844,10 +844,7 @@ pub(crate) fn model_graph_row( tags.push(tag?.str()?.extract()?); } } - let folder: String = record - .model_file - .bind(py) - .getattr("relative_path")? + let folder: String = native_field(record.model_file.bind(py), "relative_path")? .getattr("parent")? .str()? .extract()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs index 42d13900c7..38343c29ec 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs @@ -152,8 +152,7 @@ fn hook_signature<'py>(function: &Bound<'py, PyAny>) -> PyResult = parameter?; parameters.push(( native_field(¶meter, "name")?.extract()?, - parameter - .getattr("kind")? + native_field(¶meter, "kind")? .call_method0("__int__")? .extract()?, !native_field(¶meter, "default")?.is(&empty), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs index c9b27dc42c..0de3a2a3d4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs @@ -507,8 +507,7 @@ pub(crate) fn input_model_name(model_input: &Bound<'_, PyAny>) -> PyResult) -> PyResult(value: &Bound<'py, PyAny>) -> PyResult(declaration: &Bound<'py, PyAny>) -> PyResult> { let py: Python<'py> = declaration.py(); - let members: Vec<(Bound<'py, PyAny>, Bound<'py, PyAny>)> = declaration - .getattr("members")? - .try_iter()? - .map(|member| { - let member: Bound<'py, PyAny> = member?; - Ok(( - native_field(&member, "name")?, - native_field(&member, "value")?, - )) - }) - .collect::>()?; + let members: Vec<(Bound<'py, PyAny>, Bound<'py, PyAny>)> = + native_field(declaration, "members")? + .try_iter()? + .map(|member| { + let member: Bound<'py, PyAny> = member?; + Ok(( + native_field(&member, "name")?, + native_field(&member, "value")?, + )) + }) + .collect::>()?; PyTuple::new( py, [ native_field(declaration, "name")?, - declaration - .getattr("relative_path")? - .call_method0("as_posix")?, + native_field(declaration, "relative_path")?.call_method0("as_posix")?, members.into_bound_py_any(py)?, py.None().into_bound(py), py.None().into_bound(py), @@ -317,14 +315,10 @@ fn constant_row<'py>(declaration: &Bound<'py, PyAny>) -> PyResult( .map(|(_, _, nullability)| nullability.eq(&nullable)) .collect::>()?, native_field(model, "fast_lineage_has_star")?.is_truthy()?, - model - .getattr("unchecked_output_columns")? + native_field(model, "unchecked_output_columns")? .try_iter()? .map(|column| column?.extract()) .collect::>()?, @@ -477,8 +470,7 @@ fn model_row<'py>(model: &Bound<'py, PyAny>) -> PyResult> { let py: Python<'py> = model.py(); let relative_path: Bound<'py, PyAny> = native_field(model, "relative_path")?; let config: Bound<'py, PyAny> = native_field(model, "config")?; - let references: Vec> = model - .getattr("references")? + let references: Vec> = native_field(model, "references")? .try_iter()? .map(|reference| { let reference: Bound<'py, PyAny> = reference?; @@ -516,8 +508,7 @@ fn model_row<'py>(model: &Bound<'py, PyAny>) -> PyResult> { native_field(&config, "values")?, PyList::new( py, - config - .getattr("model_header_keys")? + native_field(&config, "model_header_keys")? .try_iter()? .collect::>>()?, )? @@ -529,8 +520,7 @@ fn model_row<'py>(model: &Bound<'py, PyAny>) -> PyResult> { PyList::new(py, references)?.into_any(), PyList::new( py, - model - .getattr("enum_columns")? + native_field(model, "enum_columns")? .try_iter()? .collect::>>()?, )? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs index cb13b82114..8d0aeef213 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs @@ -203,10 +203,8 @@ fn orphaned_factories<'py>(diagnostics: &Diagnostics<'_, 'py>) -> PyResult = diagnostics.py; let mut referenced: HashSet = HashSet::new(); for model_file in &diagnostics.settings.model_files { - let header: Bound<'py, PyDict> = model_file - .bind(py) - .getattr("header_values")? - .downcast_into()?; + let header: Bound<'py, PyDict> = + native_field(model_file.bind(py), "header_values")?.downcast_into()?; let Some(names) = header.get_item(AUDIT_FACTORIES_KEY)? else { continue; }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs index 62fa0f7cd4..31ff88cb8c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs @@ -104,8 +104,7 @@ pub(crate) fn attached_sources<'py>( checked_expression(context, (&name, &file_path, sql))?; } } - let contract: Option = entry - .getattr("contract")? + let contract: Option = native_field(&entry, "contract")? .extract::>()? .or_else(|| default_contract.clone()); attached.push(AttachedSource { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs index b8903f5802..ff774e700f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs @@ -328,8 +328,7 @@ fn resource_text(item: Bound<'_, PyAny>) -> PyResult { resource_type: native_field(&item, "resource_type")?.str()?.to_string(), resource_name: native_field(&item, "resource_name")?.str()?.to_string(), relation: parts.join("."), - findings: item - .getattr("findings")? + findings: native_field(&item, "findings")? .try_iter()? .map(|finding| finding_text(finding?)) .collect::>()?, @@ -339,13 +338,11 @@ fn resource_text(item: Bound<'_, PyAny>) -> PyResult { fn report(result: &Bound<'_, PyAny>) -> PyResult { Ok(ContractReport { from_target: native_field(result, "from_target")?.str()?.to_string(), - resources: result - .getattr("evidence")? + resources: native_field(result, "evidence")? .try_iter()? .map(|item| resource_text(item?)) .collect::>()?, - written_paths: result - .getattr("written_paths")? + written_paths: native_field(result, "written_paths")? .try_iter()? .map(|path| Ok(path?.str()?.to_string())) .collect::>()?, @@ -394,8 +391,7 @@ pub(crate) fn run_contract_command(py: Python<'_>, request: &Bound<'_, PyAny>) - &discovered.clone(), )?; let from_target: Bound<'_, PyAny> = native_field(request, "from_target")?; - if !discovered - .getattr("project_config")? + if !native_field(&discovered, "project_config")? .getattr("targets")? .contains(&from_target)? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs index 1a4a8ff37c..c8621d2dab 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs @@ -45,17 +45,14 @@ fn output_column_location<'py>( model: &Bound<'py, PyAny>, column_name: &str, ) -> PyResult>> { - let recorded: Bound<'py, PyAny> = model - .getattr("output_column_locations")? - .call_method1("get", (column_name,))?; + let recorded: Bound<'py, PyAny> = + native_field(model, "output_column_locations")?.call_method1("get", (column_name,))?; let authored: Option = native_field(model, "authored_sql")?.extract()?; let authored: String = authored.unwrap_or_default(); if !recorded.is_none() || authored.is_empty() { return Ok(Some(recorded).filter(|location| !location.is_none())); } - let implicit: bool = model - .getattr("extract_implicit_alias_columns")? - .is_truthy()?; + let implicit: bool = native_field(model, "extract_implicit_alias_columns")?.is_truthy()?; let rows: Vec = location_rows(model_output_columns(&authored, implicit)); let Some((_, line, column, end_line, end_column)) = rows .into_iter() @@ -88,8 +85,7 @@ fn diagnostic_location<'py>( if let Some(index) = declared_index && !schema_entry.is_none() { - return schema_entry - .getattr("columns")? + return native_field(&schema_entry, "columns")? .get_item(index)? .getattr("location"); } @@ -166,8 +162,7 @@ pub(crate) fn evaluate_model_contracts<'py>( project: &Bound<'py, PyAny>, dialect: Option<&Bound<'py, PyAny>>, ) -> PyResult> { - let mode: String = project - .getattr("settings")? + let mode: String = native_field(project, "settings")? .getattr("column_contract_mode")? .str()? .extract()?; @@ -210,8 +205,7 @@ pub(crate) fn promotion_conflict_diagnostics<'py>( adapter_default: &Bound<'py, PyAny>, settings_file: String, ) -> PyResult> { - let explicit_mode: Option = project - .getattr("settings")? + let explicit_mode: Option = native_field(project, "settings")? .getattr("table_promotion_mode")? .extract()?; let native: Bound<'py, PyAny> = native_project(project)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs index 68efb2f2f2..896dcdd112 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs @@ -211,12 +211,10 @@ pub(crate) fn effective_config_target_fields<'py>( ) -> PyResult>>> { let (project_config, local_config) = configs; let name: Key<'py> = key(target_name)?; - let project_target: Option> = project_config - .getattr("targets")? + let project_target: Option> = native_field(&project_config, "targets")? .downcast::()? .get_item(&name.handle)?; - let local_target: Option> = local_config - .getattr("targets")? + let local_target: Option> = native_field(&local_config, "targets")? .downcast::()? .get_item(&name.handle)?; let local: Option> = local_target.as_ref().map(target_layer).transpose()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs index fb6455288c..9f16347f26 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs @@ -129,9 +129,7 @@ pub(crate) fn resolve_effective_collection_rendering<'py>( if !declaration_override.is_none() { return Ok(declaration_override.clone()); } - project_config - .getattr("constants")? - .getattr("collection_rendering") + native_field(project_config, "constants")?.getattr("collection_rendering") } /// `local` when set, else `project`. @@ -150,16 +148,14 @@ pub(crate) fn resolve_effective_scenario_config<'py>( let project: Bound<'py, PyAny> = native_field(project_config, "scenario")?; let local: Bound<'py, PyAny> = native_field(local_config, "scenario")?; let overrides: Bound<'py, PyDict> = PyDict::new(py); - for item in project - .getattr("local_type_overrides")? + for item in native_field(&project, "local_type_overrides")? .call_method0("items")? .try_iter()? { let (dialect, rules): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; overrides.set_item(dialect, py.get_type::().call1((rules,))?)?; } - for item in local - .getattr("local_type_overrides")? + for item in native_field(&local, "local_type_overrides")? .call_method0("items")? .try_iter()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs index e73c488da8..5ccd9be6b6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs @@ -264,8 +264,7 @@ fn run_detail(request: &CostRequest<'_>) -> PyResult { ), )?; let record: Bound<'_, PyAny> = resolve_run(request)?; - let resources: Vec> = record - .getattr("cost")? + let resources: Vec> = native_field(&record, "cost")? .getattr("resources")? .try_iter()? .collect::>()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs index fade4b27b9..9bd407bbdc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs @@ -33,8 +33,7 @@ fn coverage(summary: &Bound<'_, PyAny>) -> PyResult { expected_statement_count: native_field(summary, "expected_statement_count")?.extract()?, observed_statement_count: native_field(summary, "observed_statement_count")?.extract()?, query_count: native_field(summary, "query_count")?.extract()?, - limitations: summary - .getattr("limitations")? + limitations: native_field(summary, "limitations")? .try_iter()? .map(|limitation| limitation?.extract()) .collect::>()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs index 91bb50c231..b4096e93fd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs @@ -44,8 +44,7 @@ fn history_value(record: &Bound<'_, PyAny>, field: &str) -> PyResult> "completed" => attribute(record, "completed_at"), "cost" => attribute(record, "cost.estimated_usd"), "credits" => attribute(record, "cost.estimated_compute_credits"), - "duration" => Ok(record - .getattr("completed_at")? + "duration" => Ok(native_field(record, "completed_at")? .sub(native_field(record, "started_at")?)? .unbind()), "models" => Ok(PyInt::new( @@ -111,8 +110,7 @@ pub(crate) fn sort_history<'py>( let mut available: Vec> = Vec::new(); let mut missing: Vec> = Vec::new(); for record in records { - let status: String = record - .getattr("cost")? + let status: String = native_field(&record, "cost")? .getattr("status")? .getattr("value")? .extract()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs index a6794f07de..7a9481f474 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs @@ -71,8 +71,7 @@ pub(crate) fn ensure_twin_project<'py>( Some(raw) => resolved(&effective_dir, &raw)?, None => resolved_path(&effective_dir, effective_dir.clone())?, }; - let twin: Bound<'py, PyAny> = dbt_project_dir - .getattr("parent")? + let twin: Bound<'py, PyAny> = native_field(&dbt_project_dir, "parent")? .call_method1("__truediv__", (TWIN_PROJECT_DIR,))?; let forwarded: Vec = forwarded_args(&args, &effective_dir)?; if project_config_found(&twin)? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs index 5563332f79..74822b5420 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs @@ -51,8 +51,7 @@ fn dbt_project_dir<'py>(request: &Bound<'py, PyAny>) -> PyResult( ) .and_then(|value| pyo3::IntoPyObjectExt::into_bound_py_any(value, py))?; progress(&callbacks, "complete", "Rendered dbt profile connection.")?; - let mut warnings: Vec> = normalized - .getattr("warnings")? + let mut warnings: Vec> = native_field(&normalized, "warnings")? .try_iter()? .collect::>()?; if !native_field(request, "skip_dbt_debug")?.is_truthy()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/results.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/results.rs index f759e483c5..1d3f27c28a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/results.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/results.rs @@ -82,8 +82,7 @@ fn field pyo3::FromPyObject<'a>>(value: &Bound<'_, PyAny>, name: &str /// A Python `DbtNodeExecutionResult` as plain data. pub(crate) fn native_result(result: &Bound<'_, PyAny>) -> PyResult { - let messages: Vec = result - .getattr("messages")? + let messages: Vec = native_field(result, "messages")? .try_iter()? .map(|message| { let message: Bound<'_, PyAny> = message?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs index 9046f69ceb..bbb3d39e6d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs @@ -107,8 +107,7 @@ fn key_set(mapping: &Bound<'_, PyAny>) -> PyResult> { fn graph_manifest(manifest: &Bound<'_, PyAny>) -> PyResult { let mut models: Vec = Vec::new(); - for model in manifest - .getattr("models_by_unique_id")? + for model in native_field(manifest, "models_by_unique_id")? .call_method0("values")? .try_iter()? { @@ -148,10 +147,7 @@ fn project_models<'py>( let mut model_deps: Vec = Vec::new(); for dependency in native_field(&model, "deps")?.try_iter()? { let dependency: Bound<'py, PyAny> = dependency?; - if dependency - .getattr("resource_type")? - .eq(MODEL_RESOURCE_TYPE)? - { + if native_field(&dependency, "resource_type")?.eq(MODEL_RESOURCE_TYPE)? { model_deps.push(native_field(&dependency, "name")?.extract()?); } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs index 257ecf0861..957ff7cb24 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs @@ -421,8 +421,7 @@ fn resolved_model<'py>( ) -> PyResult> { let py: Python<'py> = manifest.py(); if let Some(package) = package_name { - let model: Bound<'py, PyAny> = manifest - .getattr("models_by_package_and_name")? + let model: Bound<'py, PyAny> = native_field(manifest, "models_by_package_and_name")? .call_method1("get", ((package, name),))?; if model.is_none() { return Err(raised( @@ -432,8 +431,7 @@ fn resolved_model<'py>( } return Ok(model); } - let matches: Bound<'py, PyAny> = manifest - .getattr("models_by_name")? + let matches: Bound<'py, PyAny> = native_field(manifest, "models_by_name")? .call_method1("get", (name, PyTuple::empty(py)))?; let matches: Vec> = matches.try_iter()?.collect::>()?; match matches.as_slice() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs index 32e77e9d58..59c7519e5f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs @@ -91,8 +91,7 @@ pub(crate) fn resolve_dbt_execution_invocation<'py>( py, Some(keywords(py, &[("project_dir", project_dir.clone())])?), )?; - let dbt_args: Vec = routed - .getattr("dbt_args")? + let dbt_args: Vec = native_field(&routed, "dbt_args")? .try_iter()? .map(|arg| arg?.extract()) .collect::>()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs index 31e7cce43b..bfec25c1c3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs @@ -83,8 +83,7 @@ fn plan_text(plan: &Bound<'_, PyAny>) -> PyResult { command: native_field(plan, "command")?.getattr("value")?.extract()?, dbt_argv: strings(&native_field(plan, "dbt_command_argv")?)?, supplemental_dbt_argvs: argvs(&native_field(plan, "supplemental_dbt_command_argvs")?)?, - dbt_nodes: plan - .getattr("dbt_selected_nodes")? + dbt_nodes: native_field(plan, "dbt_selected_nodes")? .try_iter()? .map(|node| ls_node(&node?)) .collect::>()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs index 9fce70fbaf..5c91cc2559 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs @@ -235,9 +235,7 @@ pub(crate) fn build_sqlbuild_plan_output<'py>( result => result, } })(); - environment - .getattr("adapter")? - .call_method1("close", (connection,))?; + native_field(&environment, "adapter")?.call_method1("close", (connection,))?; planned } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs index debd848a0a..85f2ccff50 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs @@ -126,8 +126,7 @@ impl DbtCompileReferenceResolver { let Some(manifest) = self.manifest(py) else { return Ok(names); }; - for item in manifest - .getattr("models_by_name")? + for item in native_field(&manifest, "models_by_name")? .call_method0("items")? .try_iter()? { @@ -175,8 +174,7 @@ impl DbtCompileReferenceResolver { let Some(manifest) = self.manifest(py) else { return Ok(names); }; - let sources: Vec> = manifest - .getattr("sources_by_unique_id")? + let sources: Vec> = native_field(&manifest, "sources_by_unique_id")? .call_method0("values")? .try_iter()? .collect::>()?; @@ -223,8 +221,7 @@ impl DbtCompileReferenceResolver { let Some(manifest) = self.manifest(py) else { return Ok(names); }; - let seeds: Vec> = manifest - .getattr("seeds_by_unique_id")? + let seeds: Vec> = native_field(&manifest, "seeds_by_unique_id")? .call_method0("values")? .try_iter()? .collect::>()?; @@ -347,8 +344,7 @@ pub(crate) fn resolve_external_sql_reference_resolver<'py>( discovered_inputs: Bound<'py, PyAny>, ) -> PyResult> { let py: Python<'py> = project_dir.py(); - let target_path: Bound<'py, PyAny> = discovered_inputs - .getattr("project_config")? + let target_path: Bound<'py, PyAny> = native_field(&discovered_inputs, "project_config")? .getattr("dbt")? .getattr("target_path")?; let contents: Bound<'py, PyAny> = if target_path.is_none() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs index 1a2e165ada..8d2a041fa7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs @@ -263,9 +263,8 @@ pub(crate) fn plan_options<'py>( args: &[String], ) -> PyResult> { let py: Python<'py> = project_dir.py(); - let project_config: Bound<'py, PyAny> = discovered_inputs - .getattr("project_config")? - .getattr("dbt")?; + let project_config: Bound<'py, PyAny> = + native_field(discovered_inputs, "project_config")?.getattr("dbt")?; let local_config: Bound<'py, PyAny> = native_field(discovered_inputs, "local_config")?.getattr("dbt")?; let resolved: Bound<'py, PyAny> = resolve_dbt_config( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs b/crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs index 869bc16d7b..88ed612454 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs @@ -113,10 +113,8 @@ fn warehouse_checks( (command_scope, base_connection): (&CommandScope<'_>, &Bound<'_, PyAny>), ) -> PyResult> { let py: Python<'_> = context.adapter.py(); - let supports_session_warehouse: bool = context - .adapter - .getattr("supports_session_warehouse")? - .is_truthy()?; + let supports_session_warehouse: bool = + native_field(&context.adapter, "supports_session_warehouse")?.is_truthy()?; let adapter_name: String = native_field(&context.adapter, "adapter_name")? .str()? .extract()?; @@ -166,8 +164,7 @@ fn providers(discovered_inputs: &Bound<'_, PyAny>) -> PyResult()?, ), ( - preparation - .getattr("effective_max_column_examples")? - .extract()?, - preparation - .getattr("effective_max_row_only_examples")? - .extract()?, + native_field(&preparation, "effective_max_column_examples")?.extract()?, + native_field(&preparation, "effective_max_row_only_examples")?.extract()?, ), (&models, Some(phases), Some(outcome)), ); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs index c5ad6e3502..11b2e71d79 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs @@ -160,12 +160,11 @@ fn coverage_differs(rows: &Bound<'_, PyAny>) -> PyResult { if left.is_none() || right.is_none() { return Ok(false); } - Ok(left - .getattr("minimum_cursor")? - .ne(native_field(&right, "minimum_cursor")?)? - || left - .getattr("maximum_cursor")? - .ne(native_field(&right, "maximum_cursor")?)?) + Ok( + native_field(&left, "minimum_cursor")?.ne(native_field(&right, "minimum_cursor")?)? + || native_field(&left, "maximum_cursor")? + .ne(native_field(&right, "maximum_cursor")?)?, + ) } fn row_facts(rows: Bound<'_, PyAny>) -> PyResult> { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs index 336d7d50aa..859a3859aa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs @@ -280,8 +280,7 @@ pub(crate) fn prepare_query_diff<'py>( ("run_id", &runtime.get_item(2)?), ( "artifact_ttl", - &discovered - .getattr("project_config")? + &native_field(discovered, "project_config")? .getattr("diff")? .getattr("query_artifact_ttl")?, ), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs index 5537bccfc0..8f6763f297 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs @@ -21,9 +21,8 @@ pub(crate) fn sql_analysis_guidance( purpose: &str, ) -> PyResult> { let local: Bound<'_, PyAny> = native_field(discovered_inputs, "local_config")?; - let local_override: bool = local - .getattr("setting_overrides")? - .contains(SQL_ANALYSIS_KEY)?; + let local_override: bool = + native_field(&local, "setting_overrides")?.contains(SQL_ANALYSIS_KEY)?; let owner: Bound<'_, PyAny> = if local_override { local } else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs index c894f0bac0..66ae0dd634 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs @@ -63,8 +63,7 @@ pub(crate) fn project_facts( hook_functions: each(inputs, "hook_functions", named)?, event_exporters: each(inputs, "event_exporters", named)?, providers: each(inputs, "providers", named)?, - path_default_keys: inputs - .getattr("project_config")? + path_default_keys: native_field(inputs, "project_config")? .getattr("path_defaults")? .try_iter()? .map(|key| key?.extract()) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs index 51c55c94e3..a736ac6130 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs @@ -207,8 +207,7 @@ fn read_exporters( continue; } filters.push(ExporterFilter { - event_kinds: exporter - .getattr("event_kinds")? + event_kinds: native_field(&exporter, "event_kinds")? .try_iter()? .map(|kind| kind.and_then(|kind| kind.extract::())) .collect::>()?, @@ -230,8 +229,7 @@ fn read_output_sinks(sinks: &Bound<'_, PyAny>) -> PyResult> { bound.push(OutputSink { function: native_field(&sink, "function")?.unbind(), provider_arguments: native_field(&sink, "provider_arguments")?.unbind(), - streams: sink - .getattr("streams")? + streams: native_field(&sink, "streams")? .try_iter()? .map(|stream| stream.and_then(|stream| stream.extract::())) .collect::>()?, @@ -818,9 +816,8 @@ impl EventExporterDispatcher { let delivered = (|| -> PyResult { for record in records.try_iter()? { let record: Bound<'_, PyAny> = record?; - let is_output: bool = record - .getattr("record_type")? - .eq(COMMAND_OUTPUT_RECORD_TYPE)?; + let is_output: bool = + native_field(&record, "record_type")?.eq(COMMAND_OUTPUT_RECORD_TYPE)?; let stream: Option = if is_output { Some(native_field(&record, "stream")?.extract()?) } else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs index 6e015d3b3c..07f47a4ebe 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs @@ -194,8 +194,7 @@ pub(crate) fn parsed_status(py: Python<'_>, text: &str) -> PyResult { /// A `RunFilter`'s fields. pub(crate) fn run_filter_spec(value: &Bound<'_, PyAny>) -> PyResult { - let statuses: Vec = value - .getattr("statuses")? + let statuses: Vec = native_field(value, "statuses")? .try_iter()? .map(|item| item.and_then(|item| run_status(&item))) .collect::>()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs index 80a83d040c..c597a017d6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs @@ -834,8 +834,7 @@ impl PostgresExecutionHistory { slf, |cursor| { Self::lock_history(cursor)?; - let stored: Bound<'py, PyAny> = slf - .getattr("_read_all_events")? + let stored: Bound<'py, PyAny> = native_field(slf, "_read_all_events")? .call((), Some(&keywords(py, &[("cursor", cursor.clone())])?))?; let projected = checked(py, project_runs(projection_facts(&stored)?, Vec::new()))?; let records: Bound<'py, PyTuple> = run_records(py, &projected)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs index b5963128f7..f978a20d2e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs @@ -849,8 +849,7 @@ impl SqliteExecutionHistory { if this.closed.load(Ordering::SeqCst) { return Ok(()); } - let closed = slf - .getattr("_connection") + let closed = native_field(slf, "_connection") .and_then(|connection| connection.call_method0("close")); this.closed.store(true, Ordering::SeqCst); closed.map(|_| ()) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_sql.rs b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_sql.rs index 15da3c0292..8445b6807d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_sql.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_sql.rs @@ -58,8 +58,7 @@ fn stored_fingerprint(fingerprint: &Bound<'_, PyAny>) -> PyResult(resolved: &Resolved<'py>) -> PyResult = native_field(discovered, "local_config")?; - let settings_owner: Bound<'py, PyAny> = if local - .getattr("setting_overrides")? - .contains(SQL_ANALYSIS_SETTING_KEY)? - { - local - } else { - native_field(discovered, "project_config")? - }; + let settings_owner: Bound<'py, PyAny> = + if native_field(&local, "setting_overrides")?.contains(SQL_ANALYSIS_SETTING_KEY)? { + local + } else { + native_field(discovered, "project_config")? + }; let enabled: bool = native_field( &native_field(&settings_owner, "settings")?, SQL_ANALYSIS_SETTING_KEY, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs b/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs index 5b1b7778bb..9826bf58d9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs @@ -197,8 +197,7 @@ fn drop_resolved_description_faults<'py>( .collect::>()?; let mut kept: Vec> = Vec::new(); for violation in violations { - let resolved: PathBuf = violation - .getattr("file_path")? + let resolved: PathBuf = native_field(&violation, "file_path")? .call_method0("resolve")? .extract()?; if !code_is(&violation, DESCRIPTION_PRESENT)? || !described.contains(&resolved) { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs index cd4e8a8edb..ad01a1efae 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs @@ -104,9 +104,8 @@ fn model_names_and_paths(scope: &Scope<'_, '_>) -> PyResult = model_file?; let relative_path: Bound<'_, PyAny> = native_field(&model_file, "relative_path")?; - let configured: Bound<'_, PyAny> = model_file - .getattr("header_values")? - .call_method1("get", ("name",))?; + let configured: Bound<'_, PyAny> = + native_field(&model_file, "header_values")?.call_method1("get", ("name",))?; let name: String = match configured.downcast::() { Ok(text) if !text.to_str()?.is_empty() => text.to_str()?.to_owned(), _ => native_field(&relative_path, "stem")?.extract()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs index 0569d4a058..c4841c9d00 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs @@ -188,9 +188,11 @@ fn previous_records<'py>( .is_truthy()?; let schema: Bound<'py, PyAny> = PyString::new(py, schema).into_any(); records.update( - read_latest(&read, (&database, &schema), table_exists, None)? - .getattr("records")? - .downcast()?, + native_field( + &read_latest(&read, (&database, &schema), table_exists, None)?, + "records", + )? + .downcast()?, )?; } Ok(records) @@ -228,8 +230,7 @@ fn observe( } else { None }; - let sources: Vec> = project - .getattr("sources")? + let sources: Vec> = native_field(&project, "sources")? .try_iter()? .map(|source| native_field(&source?, "source_entry")) .collect::>()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs index cbcdec8f8c..f7525b88a7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs @@ -109,8 +109,7 @@ fn observed_result( let tolerance: Option = lag_tolerance.extract()?; if equivalent(previous, ¤t, tolerance.as_deref())? { StateComparison::Equivalent { - same_hash: previous - .getattr("data_version_hash")? + same_hash: native_field(previous, "data_version_hash")? .eq(native_field(¤t, "data_version_hash")?)?, } } else { @@ -183,9 +182,8 @@ fn adapter_observation<'py>( optional_text(native_field(&unknown, "message")?)?, )?)); } - let observation: Bound<'py, PyAny> = batch - .getattr("observations")? - .call_method1("get", (name,))?; + let observation: Bound<'py, PyAny> = + native_field(batch, "observations")?.call_method1("get", (name,))?; if observation.is_none() { return Ok(Err(target_result( source, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs index 22e7a621a1..12a825ec75 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs @@ -201,9 +201,7 @@ fn observe_configured_inner<'py>( }; let relation: String = render_source_relation(source, Some(&observer.adapter))?; call_with( - &observer - .adapter - .getattr("render_source_freshness_max_query")?, + &native_field(&observer.adapter, "render_source_freshness_max_query")?, &[ ("column", column), ("source_relation", text(py, &relation)), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs index 8eaaf668f6..7670aa005f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs @@ -71,8 +71,7 @@ fn previous_records<'py>( { let replace: bool = match merged.get_item(&identity)? { None => true, - Some(current) => candidate - .getattr("observed_at")? + Some(current) => native_field(&candidate, "observed_at")? .gt(native_field(¤t, "observed_at")?)?, }; if replace { @@ -244,9 +243,7 @@ pub(crate) fn build_direct_source_freshness_planning_result<'py>( } else { ( native_field(&freshness, "age_policy")?, - freshness - .getattr("lag_tolerance")? - .extract::>()?, + native_field(&freshness, "lag_tolerance")?.extract::>()?, ) }; let identity: Bound<'py, PyAny> = native_field(&record, "identity")?; @@ -338,10 +335,7 @@ pub(crate) fn build_direct_source_freshness_propagation_result<'py>( stale.call_method1("update", (&models,))?; changed.set_item(identity, models)?; } - for name in source_freshness - .getattr("unknown_source_names")? - .try_iter()? - { + for name in native_field(source_freshness, "unknown_source_names")?.try_iter()? { let name: Bound<'py, PyAny> = name?; let models: Bound<'py, PyFrozenSet> = downstream_models(&name, &downstream_deps)?; stale.call_method1("update", (&models,))?; @@ -349,8 +343,7 @@ pub(crate) fn build_direct_source_freshness_propagation_result<'py>( } let error_status: Bound<'py, PyAny> = enum_member(py, RecordId::SourceFreshnessAgeStatus, "ERROR")?; - for (identity, status) in source_freshness - .getattr("age_statuses")? + for (identity, status) in native_field(source_freshness, "age_statuses")? .downcast::()? .iter() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs index d1d5fe591c..4bb7907413 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs @@ -130,9 +130,8 @@ fn eligible_records<'py>( let changes: Bound<'py, PyDict> = PyDict::new(py); changes.set_item("run_id", run_id)?; let mut grouped: RecordsByLocation<'py> = Vec::new(); - let changed: Bound<'py, PyAny> = freshness - .getattr("propagation")? - .getattr("changed_source_model_names")?; + let changed: Bound<'py, PyAny> = + native_field(&freshness, "propagation")?.getattr("changed_source_model_names")?; for item in changed.call_method0("items")?.try_iter()? { let (identity, affected): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; let affected: Bound<'py, PyAny> = affected.call_method1("__and__", (&selected,))?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs index 5cc6ca2556..33605c905c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs @@ -21,14 +21,12 @@ pub(crate) fn build_python_sql_run_lifecycle<'py>( python_graph: &Bound<'py, PyAny>, ) -> PyResult> { let py: Python<'py> = selection.py(); - let selected: BTreeSet = selection - .getattr("python_node_names")? + let selected: BTreeSet = native_field(selection, "python_node_names")? .try_iter()? .map(|name| name?.extract()) .collect::>()?; let mut nodes: HashMap = HashMap::new(); - for item in python_graph - .getattr("nodes_by_name")? + for item in native_field(python_graph, "nodes_by_name")? .call_method0("items")? .try_iter()? { @@ -36,8 +34,7 @@ pub(crate) fn build_python_sql_run_lifecycle<'py>( nodes.insert(name, lifecycle_node(&node)?); } let mut upstream: HashMap> = HashMap::new(); - for item in python_graph - .getattr("upstream_deps")? + for item in native_field(python_graph, "upstream_deps")? .call_method0("items")? .try_iter()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs index d8794c5432..b049c49cf7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs @@ -236,8 +236,7 @@ fn inventory_node(node: &Bound<'_, PyAny>, upstream: Vec) -> PyResult) -> PyResult { /// A `PythonNodeGraph` as the native selection graph. fn selection_graph(graph: &Bound<'_, PyAny>) -> PyResult { Ok(PythonSelectionGraph { - nodes: graph - .getattr("nodes")? + nodes: native_field(graph, "nodes")? .try_iter()? .map(|node| selection_node(&node?)) .collect::>()?, upstream: name_rows(&native_field(graph, "upstream_deps")?)?, downstream: name_rows(&native_field(graph, "downstream_deps")?)?, tags: name_rows(&native_field(graph, "tag_index")?)?, - paths: graph - .getattr("path_index")? + paths: native_field(graph, "path_index")? .call_method0("items")? .try_iter()? .map(|item| item?.extract()) @@ -102,15 +100,13 @@ fn selection_graph(graph: &Bound<'_, PyAny>) -> PyResult { /// `(name, loader)` of every source in the compiled project. fn project_sources(project: &Bound<'_, PyAny>) -> PyResult)>> { - project - .getattr("sources")? + native_field(project, "sources")? .try_iter()? .map(|source| { let source: Bound<'_, PyAny> = source?; Ok(( native_field(&source, "name")?.extract()?, - source - .getattr("source_entry")? + native_field(&source, "source_entry")? .getattr("loader")? .extract()?, )) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs index 1dcc08bb82..0b2d70a16e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs @@ -221,8 +221,7 @@ pub(crate) fn run_janitor_command(py: Python<'_>, request: &Bound<'_, PyAny>) -> let style: CliStyle = CliStyle { use_color: native_field(&invocation, "use_color")?.extract()?, }; - let janitor: Bound<'_, PyAny> = invocation - .getattr("discovered_inputs")? + let janitor: Bound<'_, PyAny> = native_field(&invocation, "discovered_inputs")? .getattr("project_config")? .getattr("janitor")?; if !native_field(&janitor, "enabled")?.is_truthy()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs index 2955fc5c7b..cd9266e6de 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs @@ -138,12 +138,10 @@ fn source_schemas( if !native_field(&entry, "expression")?.is_none() { continue; } - let database: Option = entry - .getattr("database")? + let database: Option = native_field(&entry, "database")? .extract::>()? .or_else(|| default_database.clone()); - let schema: Option = entry - .getattr("schema")? + let schema: Option = native_field(&entry, "schema")? .extract::>()? .or_else(|| default_schema.clone()); let name: String = native_field(&source, "name")?.extract()?; @@ -308,9 +306,7 @@ fn tracked_relation_keys( ), ( "render_read_latest_sql", - warehouse - .adapter - .getattr("render_read_latest_fingerprints_sql")?, + native_field(&warehouse.adapter, "render_read_latest_fingerprints_sql")?, ), ], )?)); @@ -340,8 +336,7 @@ fn tracked_relation_keys( } Err(error) => return Err(error), }; - for fingerprint in fingerprint_set - .getattr("fingerprints")? + for fingerprint in native_field(&fingerprint_set, "fingerprints")? .call_method0("values")? .try_iter()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs index 77ae7ba7d2..daa6ce2f1f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs @@ -63,8 +63,7 @@ fn read_histories<'py>( Some((_, listed)) => listed .iter() .map(|relation| { - Ok(relation - .getattr("name")? + Ok(native_field(relation, "name")? .extract::()? .to_lowercase()) }) @@ -362,8 +361,7 @@ pub(crate) fn pending_migration_origins( let schemas: Vec = sorted_schemas(managed); let mut pending: Vec<(Folded, String)> = Vec::new(); for (destination, model) in model_destinations(project)? { - let raw: Bound<'_, PyAny> = model - .getattr("config")? + let raw: Bound<'_, PyAny> = native_field(&model, "config")? .getattr("values")? .call_method1("get", (MIGRATE_FROM_CONFIG_KEY,))?; let Ok(raw) = raw.extract::() else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs index 6e3ecc5947..639e89515b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs @@ -221,8 +221,7 @@ pub(crate) fn build_janitor_execution_plan<'py>( let started: Instant = Instant::now(); let status: Bound<'py, PyAny> = status_reporter(&stdout(py)?, use_color(invocation)?)?; status.call_method1("start", ("Inspecting warehouse state...",))?; - let janitor: Bound<'py, PyAny> = invocation - .getattr("discovered_inputs")? + let janitor: Bound<'py, PyAny> = native_field(invocation, "discovered_inputs")? .getattr("project_config")? .getattr("janitor")?; let plan: Bound<'py, PyAny> = within( @@ -242,14 +241,14 @@ pub(crate) fn build_janitor_execution_plan<'py>( .is_truthy()?, exclude_patterns: native_field(&janitor, "exclude_patterns")?.extract()?, direct_mode: true, - state_history_versions: settings - .getattr("direct_state_history_versions")? + state_history_versions: native_field( + settings, + "direct_state_history_versions", + )? + .extract()?, + archive_retention_days: native_field(settings, "archive_retention_days")? .extract()?, - archive_retention_days: settings - .getattr("archive_retention_days")? - .extract()?, - early_old_name_view_drops: settings - .getattr("drop_old_name_views")? + early_old_name_view_drops: native_field(settings, "drop_old_name_views")? .extract()?, }, &RelationScope { @@ -276,9 +275,8 @@ pub(crate) fn build_janitor_execution_plan<'py>( )?; options.set_item("blank_line_after", true)?; status.call_method("complete", (), Some(&options))?; - let unknown: Bound<'py, PyAny> = plan - .getattr("old_name_views")? - .getattr("unknown_requests")?; + let unknown: Bound<'py, PyAny> = + native_field(&plan, "old_name_views")?.getattr("unknown_requests")?; if unknown.is_truthy()? { return Err(unknown_view_error(py, &unknown)?); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_plan.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_plan.rs index 5120fa24c3..994ac0d36c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_plan.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_plan.rs @@ -110,8 +110,7 @@ fn source_schemas(schemas: &Bound<'_, PyAny>, blocked: bool) -> PyResult>()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs index 32fabe8565..e30928a701 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs @@ -173,9 +173,8 @@ pub(crate) fn build_plan<'py>( push_artifact_schema(database.clone(), schema.clone()); } } - if let Some(schema) = project - .getattr("effective_target_schema")? - .extract::>()? + if let Some(schema) = + native_field(project, "effective_target_schema")?.extract::>()? { push_artifact_schema( native_field(project, "effective_target_database")?.extract()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs index 6afa1bafe9..77bdb1ac5c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs @@ -62,12 +62,10 @@ impl ProjectColumnLineage { for edge in edges.try_iter()? { let edge: Bound<'_, PyAny> = edge?; keys.push(EdgeKey { - source_name: edge - .getattr("source")? + source_name: native_field(&edge, "source")? .getattr("resource_name")? .extract()?, - target_model: edge - .getattr("target")? + target_model: native_field(&edge, "target")? .getattr("resource_name")? .extract()?, ..empty_key() @@ -242,8 +240,7 @@ impl ProjectColumnLineage { let mut consumers: Vec> = Vec::new(); for edge in sourced.try_iter()? { let edge: Bound<'py, PyAny> = edge?; - if edge - .getattr("source")? + if native_field(&edge, "source")? .getattr("column_name")? .eq(column_name)? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs index 79671147a0..56b1ea3f69 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs @@ -614,8 +614,7 @@ fn rendering( .map_err(|error| selector_failure(py, request, (source, project_dir), error)); } let targets: Vec = normalized_targets(py, source.index(), &targets)?; - let direction: String = request - .getattr("direction")? + let direction: String = native_field(request, "direction")? .extract::>()? .unwrap_or_else(|| UPSTREAM_DIRECTION.to_owned()); if let [target] = targets.as_slice() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs index 7806212141..eb754a9ba7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs @@ -135,8 +135,7 @@ fn project_nodes(project: &Bound<'_, PyAny>) -> PyResult) -> PyResult { let views: Bound<'_, PyAny> = native_field(graph, "lineage_views")?; let mut all_keys: Vec<(String, LineageKey)> = Vec::new(); - for item in views - .getattr("all_keys")? + for item in native_field(&views, "all_keys")? .call_method0("items")? .try_iter()? { @@ -144,8 +143,7 @@ pub(crate) fn graph_index(graph: &Bound<'_, PyAny>) -> PyResult { all_keys.push((name, lineage_key(&key)?)); } let mut tags: Vec<(String, Vec)> = Vec::new(); - for item in views - .getattr("tag_index")? + for item in native_field(&views, "tag_index")? .call_method0("items")? .try_iter()? { @@ -153,8 +151,7 @@ pub(crate) fn graph_index(graph: &Bound<'_, PyAny>) -> PyResult { tags.push((tag, lineage_keys(&keys)?)); } let mut paths: Vec<(LineageKey, String)> = Vec::new(); - for item in views - .getattr("path_index")? + for item in native_field(&views, "path_index")? .call_method0("items")? .try_iter()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs index d32bde3d05..8254b952d8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs @@ -46,8 +46,7 @@ pub(crate) fn build_project_column_lineage<'py>( return Ok(None); } let classes: LineageClasses<'py> = LineageClasses::new(project.py())?; - if !project - .getattr("settings")? + if !native_field(project, "settings")? .getattr("sql_analysis")? .is_truthy()? { @@ -253,8 +252,7 @@ fn fast_lineage<'py>( fn output_columns(classes: &LineageClasses<'_>, facts: &Bound<'_, PyAny>) -> PyResult> { if facts.is_instance(&classes.compact_facts)? { let pool: Bound<'_, PyAny> = native_field(facts, "string_pool")?; - return facts - .getattr("rows")? + return native_field(facts, "rows")? .try_iter()? .map(|row| pool.get_item(row?.get_item(0)?)?.extract()) .collect(); @@ -360,11 +358,9 @@ fn polyglot_dialect( .extract()?; match analysis_dialect(&normalized) { AnalysisDialect::Alias(value) => Ok(value.to_owned()), - AnalysisDialect::Named(name) => classes - .analysis_dialect - .call1((name,))? - .getattr("value")? - .extract(), + AnalysisDialect::Named(name) => { + native_field(&classes.analysis_dialect.call1((name,))?, "value")?.extract() + } } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs index 348540b14c..40531e77e1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs @@ -231,9 +231,7 @@ fn project_relations<'py>( adapter: &Bound<'py, PyAny>, ) -> PyResult> { let py: Python<'py> = adapter.py(); - if !invocation - .discovered - .getattr("project_config")? + if !native_field(&invocation.discovered, "project_config")? .getattr("references")? .getattr("enforce_explicit")? .is_truthy()? @@ -301,9 +299,11 @@ fn prepare<'py>( .extract()?; let requested: Bound<'py, PyAny> = native_field(request, "concurrency")?; let concurrency: i64 = if requested.is_none() { - build_effective_settings_config(&discovered.clone())? - .getattr("concurrency")? - .extract()? + native_field( + &build_effective_settings_config(&discovered.clone())?, + "concurrency", + )? + .extract()? } else { requested.extract()? }; @@ -524,8 +524,7 @@ fn write_json(request: &Bound<'_, PyAny>, results: &[Bound<'_, PyAny>]) -> PyRes fn loader_node_flag(source: &Bound<'_, PyAny>) -> PyResult { let py: Python<'_> = source.py(); - Ok(source - .getattr("meta")? + Ok(native_field(source, "meta")? .call_method1("get", (LOADER_NODE_KEY,))? .is(PyBool::new(py, true).to_owned())) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs index 37bb5f7858..aa1e1e3877 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs @@ -49,13 +49,11 @@ pub(crate) fn load_result_text(result: &Bound<'_, PyAny>) -> PyResult()?, ), @@ -230,8 +228,7 @@ impl LoadProgressReporter { if reporter.projector.is_some() || !reporter.is_tty { return Ok(()); } - let loader_node: bool = source - .getattr("meta")? + let loader_node: bool = native_field(source, "meta")? .call_method1("get", (LOADER_NODE_KEY,))? .is(PyBool::new(py, true).to_owned()); { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs index 68a03441de..1f8d7f1e04 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs @@ -84,8 +84,7 @@ impl<'py> LoadProject<'py> { .push((native_field(source, "name")?.extract()?, loader.extract()?)); } } - let functions: Vec> = discovered - .getattr("loader_functions")? + let functions: Vec> = native_field(discovered, "loader_functions")? .try_iter()? .collect::>()?; let names_by_function: Bound<'py, PyDict> = PyDict::new(py); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs index c956ad2184..5b54c2c886 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs @@ -265,9 +265,7 @@ fn clone_source_entries<'py>( kwargs.set_item("database", native_field(&entry, "database")?)?; kwargs.set_item("schema", native_field(&entry, "schema")?)?; kwargs.set_item("name", &relation_name)?; - let qualified = adapter - .getattr("render_qualified_name")? - .call((), Some(&kwargs))?; + let qualified = native_field(adapter, "render_qualified_name")?.call((), Some(&kwargs))?; let destination = new_record( py, RecordId::CompiledRelationLocation, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs index ffbf0c3b44..8001afb87b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs @@ -121,9 +121,7 @@ pub(crate) fn plan_table_types<'py>( &native_field(&materialization, "is_table_backed")?, &[( "materialized", - config - .getattr("values")? - .call_method1("get", ("materialized",))?, + native_field(&config, "values")?.call_method1("get", ("materialized",))?, )], )?; if !backed.is_truthy()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs index d1c4b85a8b..4059788791 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs @@ -253,8 +253,7 @@ impl MigrationFingerprintCache { Some(connection) => connection, None => { let created = call_with( - &match path - .getattr("parent") + &match native_field(path, "parent") .and_then(|parent| native_field(&parent, "mkdir")) { Ok(mkdir) => mkdir, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs index a31ce1cf1c..8c58f504dd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs @@ -192,11 +192,7 @@ fn metadata_name_filter( for key in selected.try_iter()? { let name = native_field(&key?, "name")?; if let Some(model) = models.get_item(&name)? { - names.insert( - model_reads::destination(&model)? - .getattr("name")? - .extract()?, - ); + names.insert(native_field(&model_reads::destination(&model)?, "name")?.extract()?); names.extend(model_upstream_names( &model, (&models, &seeds), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs index deab03422d..3610ff760b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs @@ -30,8 +30,7 @@ pub(crate) fn project_path_name(instance: &Bound<'_, PyAny>) -> PyResult) -> PyResult> { - project_path(instance)? - .getattr("parts")? + native_field(&project_path(instance)?, "parts")? .len()? .into_py_any(instance.py()) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs index 51cc966680..5bdfb03605 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs @@ -78,7 +78,10 @@ fn generated_classes(py: Python<'_>) -> PyResult> { ), ( "generic_syntax", - new_record(py, RecordId::SqlLexicalSyntax, (), None)?.getattr("native_mapping")?, + native_field( + &new_record(py, RecordId::SqlLexicalSyntax, (), None)?, + "native_mapping", + )?, ), ("generated_help", help), ("all_markers", markers), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs index 29dacfc6df..d9d92598d3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs @@ -796,9 +796,7 @@ pub(crate) fn write_execution_json_output( let keywords: Bound<'_, PyDict> = PyDict::new(py); keywords.set_item("parents", true)?; keywords.set_item("exist_ok", true)?; - json_output_path - .getattr("parent")? - .call_method("mkdir", (), Some(&keywords))?; + native_field(&json_output_path, "parent")?.call_method("mkdir", (), Some(&keywords))?; let encoding: Bound<'_, PyDict> = PyDict::new(py); encoding.set_item("encoding", "utf-8")?; json_output_path.call_method("write_text", (payload,), Some(&encoding))?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs index c8ec03de86..370ad14585 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs @@ -610,9 +610,8 @@ fn violation_findings( model_paths: &BTreeSet, ) -> PyResult> { let py: Python<'_> = run.project.py(); - let engine_error: String = error_class(py, ErrorId::NativeLint)? - .getattr("code")? - .extract()?; + let engine_error: String = + native_field(&error_class(py, ErrorId::NativeLint)?, "code")?.extract()?; let resolved_dir: PathBuf = resolved(&run.project_dir); let no_paths: BTreeSet = BTreeSet::new(); let mut evaluated: Vec = Vec::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs index 8dd5605aa1..b2f3fd5ffb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs @@ -7,6 +7,7 @@ use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use pyo3::{FromPyObject, intern, pyclass, pymethods}; use crate::bindings::_helpers::boundary::panics::{compiler_error, compiler_guard}; +use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::scopes::declaration_resolution::ResolutionInputs; use sqlbuild_scopes::scope_index::main::classify_resource::classify_resource; use sqlbuild_scopes::scope_index::models::{ @@ -117,8 +118,8 @@ impl NativeDeclarationContexts { let mut visible: Vec> = Vec::new(); let mut inaccessible: Vec = Vec::new(); for record in matches { - let identity: Bound<'py, PyAny> = record.getattr(intern!(py, "identity"))?; - let path: String = record.getattr(intern!(py, "path"))?.extract()?; + let identity: Bound<'py, PyAny> = native_field(&record, "identity")?; + let path: String = native_field(&record, "path")?.extract()?; let private: Vec = self .lookup .private_positions @@ -170,12 +171,11 @@ impl NativeDeclarationContexts { for grant in records.try_iter()? { let grant: Bound<'py, PyAny> = grant?; let Some(identity_key) = - identity_keys.get_item(grant.getattr(intern!(py, "declaration"))?)? + identity_keys.get_item(native_field(&grant, "declaration")?)? else { continue; }; - let kind: String = grant - .getattr(intern!(py, "kind"))? + let kind: String = native_field(&grant, "kind")? .getattr(intern!(py, "value"))? .extract()?; grants.push(GrantEntry { @@ -187,7 +187,7 @@ impl NativeDeclarationContexts { }, through: throughs.len(), }); - throughs.push(grant.getattr(intern!(py, "through"))?); + throughs.push(native_field(&grant, "through")?); } Ok((grants, throughs)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs index 7ad10099ab..6e8ce688a7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs @@ -69,25 +69,23 @@ impl NativeDeclarationContexts { } .try_iter()? .collect::>()?; - let cache: Bound<'py, PyDict> = resolver - .getattr(intern!(py, "contexts_by_directory"))? - .downcast_into()?; - let specific: Bound<'py, PyAny> = resolver.getattr(intern!(py, "resource_specific"))?; + let cache: Bound<'py, PyDict> = + native_field(resolver, "contexts_by_directory")?.downcast_into()?; + let specific: Bound<'py, PyAny> = native_field(resolver, "resource_specific")?; let mut cache_key: Option> = None; if let [record] = resources.as_slice() && !specific.is_none() - && !specific.contains(record.getattr(intern!(py, "identity"))?)? + && !specific.contains(native_field(record, "identity")?)? { - let path: String = record.getattr(intern!(py, "path"))?.extract()?; - let root: Bound<'py, PyAny> = record - .getattr(intern!(py, "ownership_root"))? - .getattr(intern!(py, "path"))?; + let path: String = native_field(record, "path")?.extract()?; + let root: Bound<'py, PyAny> = + native_field(record, "ownership_root")?.getattr(intern!(py, "path"))?; let key: Bound<'py, PyTuple> = PyTuple::new( py, [PyString::new(py, &posix_parent(&path)).into_any(), root], )?; if let Some(cached) = cache.get_item(&key)? { - let consumer: Bound<'py, PyAny> = record.getattr(intern!(py, "identity"))?; + let consumer: Bound<'py, PyAny> = native_field(record, "identity")?; return Ok((self.rebound_context(&cached, &consumer)?, false)); } cache_key = Some(key); @@ -104,7 +102,7 @@ impl NativeDeclarationContexts { } else { let consumer: Bound<'py, PyAny> = match resource { Some(resource) => resource.clone(), - None => resources[0].getattr(intern!(py, "identity"))?, + None => native_field(&resources[0], "identity")?, }; (resources, consumer) }; @@ -157,7 +155,7 @@ impl NativeDeclarationContexts { if !matches.is_empty() || declaration_matches > 0 { let consumer: Bound<'py, PyAny> = match (resource, matches.first()) { (Some(resource), _) => resource.clone(), - (None, Some(first)) => first.getattr(intern!(py, "identity"))?, + (None, Some(first)) => native_field(first, "identity")?, (None, None) => py.None().into_bound(py), }; return Ok((matches, consumer)); @@ -181,12 +179,11 @@ impl NativeDeclarationContexts { let private: &Bound<'_, PyAny> = inputs.private_scope.bind(py); for record in inputs.index_declarations.bind(py).try_iter()? { let record: Bound<'_, PyAny> = record?; - let path: String = record.getattr(intern!(py, "path"))?.extract()?; - if path != target || record.getattr(intern!(py, "scope"))?.is(private) { + let path: String = native_field(&record, "path")?.extract()?; + if path != target || native_field(&record, "scope")?.is(private) { continue; } - let owning_path: Option = - record.getattr(intern!(py, "owning_path"))?.extract()?; + let owning_path: Option = native_field(&record, "owning_path")?.extract()?; let owner: String = owning_path .filter(|path| !path.is_empty()) .unwrap_or_else(|| CURRENT_FOLDER.to_owned()); @@ -305,9 +302,9 @@ impl NativeDeclarationContexts { let record: Bound<'py, PyAny> = record?; items.push(self.visibility_record_for( consumer, - &record.getattr(intern!(py, "declaration"))?, - &record.getattr(intern!(py, "reason"))?, - &record.getattr(intern!(py, "through"))?, + &native_field(&record, "declaration")?, + &native_field(&record, "reason")?, + &native_field(&record, "through")?, )?); } rebound.set_item(name, PyTuple::new(py, items)?)?; diff --git a/fensu.toml b/fensu.toml index 51eb8842ce..9a3989fe42 100644 --- a/fensu.toml +++ b/fensu.toml @@ -492,54 +492,52 @@ edge_paths = [ "crates/sqlbuild-python/src/bindings/_helpers/records/registry.rs", ] pending_budgets = [ - "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=24", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/model_reads.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=21", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/nullability_rules.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/outcome_objects.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/attachments/reference_markers.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs=29", + "crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/attachments/reference_markers.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs=25", "crates/sqlbuild-python/src/bindings/_helpers/auditing/identity.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/auditing/render.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/auditing/schema_audits.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/auditing/schema_audits.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/authored_values/fields.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/authored_values/project_vars.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/boundary/config_values.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/authored_values/python_nodes.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/boundary/config_values.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs=32", - "crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs=13", - "crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs=24", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs=21", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs=22", "crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/build_command/support.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/plan_facts.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/build_progress/result_text.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs=23", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/cache/native_store.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs=28", - "crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs=13", - "crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs=21", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cli/argv.rs=18", - "crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs=21", - "crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs=35", + "crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs=19", + "crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs=27", "crates/sqlbuild-python/src/bindings/_helpers/cli/launch_state.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs=27", @@ -547,75 +545,74 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/cli/surrogates.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs=20", - "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_pipeline.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/connection.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/invocation.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/preview_target.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/runtime_errors.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/runtime_errors.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouse_scope.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/storage_policies.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/storage_policies.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/constants.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs=44", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs=42", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs=50", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs=43", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs=32", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs=48", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs=41", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/runtime_identity.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/startup_inputs.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/surrogates.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=33", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs=22", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs=24", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs=28", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs=24", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/compile_timings.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs=18", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/artifacts.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/reuse.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs=13", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/runtime_target.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_loop.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/audit_views.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_analysis.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/compiled_model_view.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_loop.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs=18", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_calls.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_config.rs=5", @@ -632,30 +629,30 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_visibility.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs=25", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/scenario_loop.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_loop.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/source_views.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/sql_test_loop.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compute_logs/conversion.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs=23", + "crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs=13", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs=17", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/resource_identities.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/resource_identities.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/contracts/sql_values.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/contracts/state_literals.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/bounds.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs=13", - "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refusal.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refusal.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/cost_report/degradation.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/cost_report/functions.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/cost_report/records.rs=12", @@ -672,7 +669,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cursor/overrides.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/cursor/scalars.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cursor/values.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/artifact.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/artifact.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs=12", @@ -680,95 +677,93 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/translator.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/debug.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init_project.rs=28", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init_project.rs=27", "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/support.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_events/results.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs=19", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_phases.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_coercion.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_connection.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_load.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs=19", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/reference_resolver.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_config.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_results.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs=29", + "crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs=26", "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/console_records.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs=15", - "crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs=13", - "crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs=21", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/registration.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/tolerances.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/discovery/faults.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/guidance.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/header_values.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/header_values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/discovery/hook_entries.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_providers.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/discovery/locations.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_records.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_files.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/discovery/project_validation.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/python_function_files.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/python_function_files.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/discovery/python_hook_files.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/raised.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/raised.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/discovery/scope_snapshot.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/discovery/snapshot.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_blocks.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/discovery/sql_test_records.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_entries.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/discovery/yaml_records.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs=30", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs=27", "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/models.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/registration.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/values.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/workers.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs=19", "crates/sqlbuild-python/src/bindings/_helpers/execution_history/functions.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs=29", - "crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs=36", + "crates/sqlbuild-python/src/bindings/_helpers/execution_history/postgres.rs=28", + "crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs=35", "crates/sqlbuild-python/src/bindings/_helpers/execution_history/statements.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/exported_constants/registration.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs=18", - "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/query_hashes.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/query_hashes.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs=17", - "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_sql.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_sql.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/format_command/config.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs=20", - "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/freshness/state_io.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/freshness/support.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/frontier/compile_frontier.rs=2", @@ -779,54 +774,54 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/graph/keys.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/init_command/scaffold.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs=18", - "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_keys.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs=23", - "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_plan.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_plan.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/validation.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_cache.rs=28", - "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs=18", - "crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/load/ingestr_command.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs=21", - "crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs=22", - "crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs=19", + "crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs=28", - "crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/projection.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/model_config/authored_nodes.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_templates.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/model_config/described_models.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/model_config/errors.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/model_config/header_columns.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/header_columns.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/header_metadata.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/model_config_builder.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/native_threads/exit_signal.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/output_capture/context.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/output_capture/dispatcher.rs=33", @@ -845,17 +840,17 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/metadata.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/execution_plan.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/models.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/json_values.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs=12", @@ -875,7 +870,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/fingerprint.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_handover.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_overlay.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs=5", @@ -886,40 +881,38 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_references.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_names.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_execution.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/full_refresh.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/models.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/warehouse_state.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_records/constants.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_bounds.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/artifacts.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/entries.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/execution.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/sources.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/values.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/unit_tests.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs=8", @@ -937,12 +930,12 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatches.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/models.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs=15", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_columns.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs=7", @@ -954,56 +947,54 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/terminal.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/declared_relations.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/models.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_checks.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/python_values/values.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/query_command/dag.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/query_command/project.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/query_command/query_values.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/auditing.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/auditing.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/cursors.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/durations.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/macros.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/migrations.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/python_nodes.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/records/constants.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/records/error_classes.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/records/models.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/records/registration.rs=26", "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_edits.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/refactor/offline_compile.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_edits.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/refactor/python_strings.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs=25", "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_facts.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/references/source_relations.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/relation_naming/fitting.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_expansion.rs=24", - "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs=19", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_arguments.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_memo.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/render/macro_calls.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_evaluation.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion.rs=17", - "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/result_output/aggregation.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/result_output/checks.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/result_output/event_writer.rs=20", "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_records.rs=5", @@ -1015,63 +1006,63 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/rules/catalogue.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_host_observation.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs=15", - "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_cache.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs=22", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_cache.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs=21", "crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_encoder.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_replay.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_tree.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/rules/findings.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/rules/findings.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_facts.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_verdict.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/rules/fixture_formatting.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_headers.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_inputs.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_preparation.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_sql_bodies.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/rules/native_header_parser.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/rules/native_header_parser.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/rules/results.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/rows.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_cache.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_dispatch.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_plan.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_run.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/rules/rules_config.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/rules/selection.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rules_config.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/rules/selection.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/rules/sql_test_objects.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/capture_command.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/conversions.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs=29", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/relationship_names.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/relationship_names.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_cache.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_command.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_command.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_errors.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs=35", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs=34", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_loading.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_lookup.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_lookup.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_report_objects.rs=23", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_reports.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_tolerant.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_visibility.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_visibility.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/completion.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs=1", @@ -1079,33 +1070,33 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/compiled_tests.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/constants.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_fixtures.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_values.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/planning.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/sqltext/authored_values.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/sqltext/code_scanner.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/sqltext/code_scanner.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sqltext/static_sql.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/constants.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/events.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/freshness.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_io.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_objects.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_projections.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/state_tables.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/timestamps.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/type_system/equality.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/type_system/normalization.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs=8", "crates/sqlbuild-python/src/bindings/models.rs=7", ] From 9739a25652da64ba000d3cf8bfa6548ec309886f Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 06:35:58 +0100 Subject: [PATCH 06/19] build: skip constant definitions when counting native Python crossings --- fensu.toml | 66 +++++++++---------- scripts/fensu_policy/constants.py | 10 ++- .../rules/test_native_boundary.py | 1 + 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/fensu.toml b/fensu.toml index 9a3989fe42..606852124e 100644 --- a/fensu.toml +++ b/fensu.toml @@ -493,11 +493,11 @@ edge_paths = [ ] pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=21", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=20", "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/nullability_rules.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/outcome_objects.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs=4", @@ -524,23 +524,23 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/build_command/support.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/plan_facts.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs=23", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/cache/native_store.rs=13", - "crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs=21", "crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cli/argv.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs=19", - "crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs=26", "crates/sqlbuild-python/src/bindings/_helpers/cli/launch_state.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs=26", "crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs=6", @@ -562,9 +562,8 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/storage_policies.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/constants.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs=44", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs=43", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs=32", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs=48", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs=41", @@ -579,7 +578,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs=24", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/compile_timings.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs=2", @@ -596,8 +595,8 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/artifacts.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs=1", @@ -629,7 +628,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_visibility.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/project_view.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/resource_diagnostics.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/scenario_loop.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/seed_views.rs=3", @@ -653,7 +652,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refusal.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/cost_report/degradation.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/cost_report/degradation.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cost_report/functions.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/cost_report/records.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/cost_report/store.rs=2", @@ -671,7 +670,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cursor/values.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/artifact.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs=9", @@ -753,7 +752,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/exported_constants/registration.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/query_hashes.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_sql.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/format_command/config.rs=2", @@ -783,7 +782,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/init_command/scaffold.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_command.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_facts.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_keys.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs=17", @@ -796,7 +795,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_cache.rs=28", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/load/ingestr_command.rs=1", @@ -837,7 +836,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/plan_output/python_identity.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/actions.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/metadata.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs=1", @@ -853,7 +852,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/json_values.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_candidates.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs=3", @@ -913,13 +912,12 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/sources.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/unit_tests.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audits.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/constants.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audits.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_types.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_types.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_metadata.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_preparation.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_reads.rs=4", @@ -931,7 +929,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/models.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs=5", @@ -950,14 +948,14 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_checks.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/python_values/values.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/python_values/values.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/query_command/dag.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/query_command/project.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/query_command/query.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/query_command/query_values.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/auditing.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/compiled.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/cursors.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/cursors.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/durations.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs=1", @@ -968,7 +966,6 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/python_nodes.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/records/constants.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/records/error_classes.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/records/models.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/records/registration.rs=26", @@ -1003,7 +1000,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/result_output/resource_ids.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/rules/builtin_catalogue.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/rules/catalogue.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/rules/catalogue.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_host_observation.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_hosts.rs=14", @@ -1011,8 +1008,6 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_rule_evidence.rs=21", "crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_encoder.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_replay.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/rules/fact_tree.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/findings.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_facts.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs=9", @@ -1028,15 +1023,15 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/rules/native_header_parser.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/rules/results.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/rules/rows.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/rules/rows.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_api.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_cache.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_dispatch.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_plan.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/rule_run.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/rules/rules_config.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/rules/selection.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/rules/selection.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/rules/sql_rules.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/rules/sql_test_objects.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/capture_command.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/conversions.rs=3", @@ -1063,7 +1058,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/completion.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/declarations.rs=2", @@ -1085,7 +1080,6 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/sqltext/code_scanner.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sqltext/sql_references.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sqltext/static_sql.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/state_rows/constants.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/events.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/freshness.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_io.rs=7", @@ -1094,7 +1088,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/state_tables.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/state_rows/timestamps.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/type_system/equality.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/type_system/equality.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/type_system/normalization.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/workspace_commands/commands.rs=8", "crates/sqlbuild-python/src/bindings/models.rs=7", diff --git a/scripts/fensu_policy/constants.py b/scripts/fensu_policy/constants.py index 79ed9a218a..738556e895 100644 --- a/scripts/fensu_policy/constants.py +++ b/scripts/fensu_policy/constants.py @@ -320,7 +320,15 @@ NATIVE_TEST_FILE_PREFIX: str = "test_" NATIVE_LINE_COMMENT: str = "//" NATIVE_STRING_QUOTE: str = '"' -NATIVE_SKIPPED_LINE_PREFIXES: tuple[str, ...] = ("//", "use ", "pub use ", "pub(crate) use ") +NATIVE_SKIPPED_LINE_PREFIXES: tuple[str, ...] = ( + "//", + "use ", + "pub use ", + "pub(crate) use ", + "const ", + "pub(crate) const ", + "pub const ", +) NATIVE_BUDGET_SEPARATOR: str = "=" NATIVE_EDGE_PATHS: RuleOption[tuple[str, ...]] = RuleOption.string_list( name="edge_paths", diff --git a/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py b/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py index 18ccab3e7c..41b3817a4f 100644 --- a/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py +++ b/tests/unit/scripts/fensu_policy/rules/test_native_boundary.py @@ -130,6 +130,7 @@ def test_given_test_module_when_checking_native_patches_then_matches_contract( source=dedent( """ use pyo3::types::PyAnyMethods; + const JSON_MODULE: &str = "dataclasses"; // value.getattr("name") fn read() {} From 15c114b29e3b50497009932acfb0f71b30abef80 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 07:02:07 +0100 Subject: [PATCH 07/19] refactor: read Python dicts through the C API instead of calling dict.get --- .../_helpers/analysis/binding_catalog.rs | 6 +- .../_helpers/analysis/reference_facts.rs | 7 +- .../analysis_session/model_analyses.rs | 3 +- .../_helpers/attachments/cursor_intrinsics.rs | 5 +- .../src/bindings/_helpers/auditing/render.rs | 3 +- .../_helpers/build_command/defer_clone.rs | 3 +- .../_helpers/build_command/execution.rs | 3 +- .../src/bindings/_helpers/check/check_core.rs | 16 +- .../src/bindings/_helpers/cli/progress.rs | 6 +- .../_helpers/command_runtime/warehouses.rs | 4 +- .../compile_attachment/cursor_roles.rs | 7 +- .../_helpers/compile_command/report.rs | 7 +- .../_helpers/compile_command/target_writer.rs | 4 +- .../compile_driver/assembly_analysis.rs | 15 +- .../compile_driver/assembly_models.rs | 5 +- .../compile_driver/assembly_project.rs | 9 +- .../compile_driver/python_plan_entries.rs | 3 +- .../compile_driver/relation_targets.rs | 3 +- .../_helpers/compile_driver/targets.rs | 5 +- .../_helpers/contract_command/write.rs | 6 +- .../_helpers/contracts/spec_resolution.rs | 9 +- .../bindings/_helpers/cost_command/refresh.rs | 3 +- .../_helpers/cost_telemetry/ledger.rs | 3 +- .../_helpers/dag_artifact/projection.rs | 23 ++- .../bindings/_helpers/dag_artifact/rows.rs | 7 +- .../_helpers/dag_artifact/selection.rs | 16 +- .../_helpers/dagster_invocation/access.rs | 8 +- .../_helpers/dagster_invocation/results.rs | 3 +- .../bindings/_helpers/dbt_events/stream.rs | 3 +- .../src/bindings/_helpers/dbt_interop/plan.rs | 3 +- .../bindings/_helpers/diff_report/query.rs | 8 +- .../_helpers/discovery/declaration_records.rs | 9 +- .../_helpers/discovery/imported_providers.rs | 8 +- .../_helpers/event_exporting/scope.rs | 3 +- .../_helpers/freshness/freshness_observe.rs | 4 +- .../_helpers/freshness/observation.rs | 4 +- .../bindings/_helpers/freshness/planning.rs | 8 +- .../src/bindings/_helpers/graph/algorithms.rs | 6 +- .../_helpers/graph/execution_gates.rs | 3 +- .../_helpers/hand_built/compiled_model.rs | 3 +- .../_helpers/lineage/column_lineage_graph.rs | 3 +- .../bindings/_helpers/load/dlt_destination.rs | 3 +- .../src/bindings/_helpers/manifest/rows.rs | 6 +- .../_helpers/model_config/config_values.rs | 3 +- .../_helpers/model_config/model_validator.rs | 3 +- .../_helpers/output_capture/records.rs | 3 +- .../_helpers/plan_output/plan_text.rs | 14 +- .../_helpers/planner_changes/actions.rs | 3 +- .../_helpers/planner_changes/detect.rs | 8 +- .../_helpers/planner_changes/renames.rs | 6 +- .../_helpers/planner_entries/command_plans.rs | 3 +- .../_helpers/planner_entries/model_entries.rs | 3 +- .../_helpers/planner_entries/plan_output.rs | 7 +- .../_helpers/planner_identity/graph.rs | 3 +- .../_helpers/planner_identity/identities.rs | 13 +- .../_helpers/planner_identity/metadata.rs | 10 +- .../_helpers/planner_identity/staleness.rs | 9 +- .../planner_migrations/column_overlay.rs | 5 +- .../planner_migrations/column_planning.rs | 8 +- .../planner_migrations/discovery_requests.rs | 3 +- .../planner_migrations/known_input_columns.rs | 3 +- .../_helpers/planner_migrations/matching.rs | 7 +- .../planner_migrations/model_planning.rs | 16 +- .../planner_migrations/state_inspection.rs | 9 +- .../_helpers/planner_phases/identities.rs | 7 +- .../_helpers/planner_phases/retention.rs | 3 +- .../planner_resolution/cursor_policies.rs | 5 +- .../planner_resolution/orchestration.rs | 6 +- .../_helpers/planner_resolution/refs.rs | 5 +- .../_helpers/planner_resolution/sources.rs | 5 +- .../_helpers/planner_resolution/values.rs | 6 +- .../_helpers/planner_scenario/fixtures.rs | 3 +- .../bindings/_helpers/planner_scenario/sql.rs | 7 +- .../planner_strategy/audit_entries.rs | 5 +- .../planner_strategy/cursor_inputs.rs | 23 +-- .../_helpers/planner_strategy/lineage.rs | 3 +- .../_helpers/planner_strategy/microbatches.rs | 5 +- .../planner_strategy/model_entries.rs | 21 +- .../planner_warehouse/semantic_sources.rs | 3 +- .../planner_warehouse/source_deferral.rs | 3 +- .../planner_warehouse/source_freshness.rs | 3 +- .../planner_warehouse/source_tables.rs | 8 +- .../_helpers/planner_warehouse/watermarks.rs | 3 +- .../project_assembly/native_resources.rs | 3 +- .../record_behaviours/lineage_facts.rs | 3 +- .../record_behaviours/python_nodes.rs | 7 +- .../src/bindings/_helpers/records/fields.rs | 26 +++ .../_helpers/refactor/contract_compare.rs | 3 +- .../_helpers/render/declaration_values.rs | 3 +- .../_helpers/render/macro_call_classes.rs | 3 +- .../bindings/_helpers/result_output/assets.rs | 3 +- .../result_output/integration_records.rs | 8 +- .../_helpers/result_output/terminal_index.rs | 5 +- .../src/bindings/_helpers/rules/guidance.rs | 3 +- .../_helpers/rules/lint_sql_bodies.rs | 3 +- .../_helpers/semantic_checks/metadata.rs | 20 +- .../_helpers/semantic_checks/resource_sql.rs | 7 +- .../_helpers/semantic_checks/type_recovery.rs | 3 +- .../_helpers/semantic_shapes/shapes.rs | 8 +- .../sql_test_glue/fixture_validation.rs | 7 +- .../_helpers/sql_test_glue/plan_fixtures.rs | 6 +- fensu.toml | 188 ++++++++---------- 102 files changed, 447 insertions(+), 391 deletions(-) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs index 9969ef8868..2c1d7d91c5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs @@ -13,6 +13,8 @@ use crate::bindings::_helpers::analysis::conversions; use crate::bindings::_helpers::boundary::panics::compiler_error; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::models::{CatalogInput, ProjectCatalog}; use crate::bindings::types::CompilerDetach; @@ -166,7 +168,7 @@ impl BindingCatalog { let updates: Bound<'_, PyDict> = PyDict::new(py); for item in nullability.call_method0("items")?.try_iter()? { let (name, columns): (Bound<'_, PyAny>, Bound<'_, PyAny>) = item?.extract()?; - let typed: Bound<'_, PyAny> = types.call_method1("get", (&name, PyDict::new(py)))?; + let typed: Bound<'_, PyAny> = mapping_get_or(types, &name, PyDict::new(py))?; let shape: Bound<'_, PyTuple> = PyTuple::new(py, [typed, columns])?; let unchanged: bool = match shapes.get_item(&name)? { Some(known) => known.eq(&shape)?, @@ -256,7 +258,7 @@ pub(crate) fn ignores_quoted_case( if dialect.is_none() || dialect.extract::()? != SNOWFLAKE_DIALECT { return Ok(false); } - let parameters: Bound<'_, PyAny> = connection.call_method1("get", (SESSION_PARAMETERS,))?; + let parameters: Bound<'_, PyAny> = mapping_get(connection, SESSION_PARAMETERS)?; let Ok(parameters) = parameters.downcast::() else { return Ok(false); }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs index 8dd71239b9..d1bccc1d01 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs @@ -2,6 +2,7 @@ use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyBool, PyList, PyTuple}; @@ -123,7 +124,7 @@ fn model_references( native_field(model, "destination_row")?.extract()?; let mut sql_hooks: Vec = Vec::new(); for hook_key in MODEL_HOOK_KEYS { - for (index, entry) in hook_items(&values.call_method1("get", (hook_key,))?)? + for (index, entry) in hook_items(&mapping_get(&values, hook_key)?)? .into_iter() .enumerate() { @@ -165,7 +166,7 @@ fn python_hook_names( ) -> PyResult> { let mut names: Vec = Vec::new(); for hook_key in MODEL_HOOK_KEYS { - let value: Bound<'_, PyAny> = values.call_method1("get", (hook_key,))?; + let value: Bound<'_, PyAny> = mapping_get(values, hook_key)?; let items: Vec> = if value.is_instance(&entries.python)? { vec![value] } else if is_sequence(&value) { @@ -200,7 +201,7 @@ fn is_sequence(value: &Bound<'_, PyAny>) -> bool { /// The `migrate_from` string when the model keeps an old-name view, as Python resolves it. fn migrate_from(values: &Bound<'_, PyAny>, retains_old_names: bool) -> PyResult> { - let raw: Bound<'_, PyAny> = values.call_method1("get", (MIGRATE_FROM_KEY,))?; + let raw: Bound<'_, PyAny> = mapping_get(values, MIGRATE_FROM_KEY)?; let Ok(text) = raw.extract::() else { return Ok(None); }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs index 3eaadc1496..a1a6677d81 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs @@ -24,6 +24,7 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::semantic_shapes::shapes::{VALID_FROM_DEFAULT, VALID_TO_DEFAULT}; @@ -256,7 +257,7 @@ fn model_rows<'py>( let mut rows: Vec> = Vec::with_capacity(model_inputs.len()); for model_input in model_inputs { let values: Bound<'py, PyAny> = native_field(model_input, "config")?.getattr("values")?; - let get = |key: &str| values.call_method1("get", (key,)); + let get = |key: &str| mapping_get(&values, key); let query_sql: Bound<'py, PyAny> = PyString::new( py, &analysis_cursor_sql( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs b/crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs index a607828e60..d75b591a5d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs @@ -9,6 +9,7 @@ use sqlbuild_attachments::cursor_intrinsics::models::IntrinsicModel; use crate::bindings::_helpers::boundary::panics::compiler_guard; use crate::bindings::_helpers::records::construct::error_class; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::ErrorId; const INCREMENTAL_MATERIALIZATION: &str = "incremental"; @@ -74,9 +75,9 @@ pub(crate) fn validated_model_cursor_sql( sql: &str, (model_name, config_values): (&str, &Bound<'_, PyAny>), ) -> PyResult { - let incremental: bool = text_value(&config_values.call_method1("get", ("materialized",))?) + let incremental: bool = text_value(&mapping_get(config_values, "materialized")?) .is_some_and(|materialized| materialized == INCREMENTAL_MATERIALIZATION); - let cursor: Option = text_value(&config_values.call_method1("get", ("cursor",))?); + let cursor: Option = text_value(&mapping_get(config_values, "cursor")?); let reserved_markers: Vec = reserved_cursor_markers(); let outcome: Result = compiler_guard(|| { Ok(validated_model_intrinsics( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/auditing/render.rs b/crates/sqlbuild-python/src/bindings/_helpers/auditing/render.rs index cdfa2b756f..488d5e3075 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/auditing/render.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/auditing/render.rs @@ -7,6 +7,7 @@ use sqlbuild_analysis::auditing::main::replace_reference_calls::replace_referenc use crate::bindings::_helpers::boundary::keyword_request::Request; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::references::source_relations::render_source_relation; const REF_FUNCTION: &str = "__ref"; @@ -15,7 +16,7 @@ const SOURCE_FUNCTION: &str = "__source"; /// `mapping.get(name)`, or `None` when absent or `None`. fn lookup<'py>(mapping: &Bound<'py, PyAny>, name: &str) -> PyResult>> { - let value: Bound<'py, PyAny> = mapping.call_method1("get", (name,))?; + let value: Bound<'py, PyAny> = mapping_get(mapping, name)?; Ok(Some(value).filter(|value| !value.is_none())) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs index 92b84c8e88..1868d5f7cc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs @@ -28,6 +28,7 @@ use crate::bindings::_helpers::planner_scope::scope::build_planner_scope; use crate::bindings::_helpers::planner_selection::unit_tests::split_unit_test_selectors; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::replaced; use crate::bindings::_helpers::records::ids::RecordId; @@ -146,7 +147,7 @@ fn selected_executable_model_count(scope: &Bound<'_, PyAny>) -> PyResult if resource_type(&key)? != MODEL_TYPE { continue; } - let model: Bound<'_, PyAny> = models.call_method1("get", (native_field(&key, "name")?,))?; + let model: Bound<'_, PyAny> = mapping_get(&models, native_field(&key, "name")?)?; if !model.is_none() && native_field(&model, "config")? .getattr("values")? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs index 02881b4200..2e7343de8f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs @@ -34,6 +34,7 @@ use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_resolution::cursor_overrides::type_cursor_overrides; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; const EXECUTION_COMMAND: &str = "sqb build"; @@ -121,7 +122,7 @@ fn run_context_facts( }; let variables: Bound<'_, PyAny> = native_field(&project, "effective_vars")?; let variable = |name: &str| -> PyResult>> { - let value: Bound<'_, PyAny> = variables.call_method1("get", (name,))?; + let value: Bound<'_, PyAny> = mapping_get(&variables, name)?; Ok((!value.is_none()).then_some(value)) }; let mut selector_files: Vec = Vec::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs b/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs index 8f2bdb166c..2af4c98083 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs @@ -20,6 +20,8 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; const MISSING_RELATION_CODE: &str = "C682"; const MODEL_KIND: &str = "model"; @@ -215,10 +217,10 @@ pub(crate) fn relevant_check_functions<'py>( if !native_field(&node, "kind")?.eq(&check_kind)? || excluded.contains(&name)? { continue; } - let upstream: Vec> = upstream_deps - .call_method1("get", (&name, PyTuple::empty(py)))? - .try_iter()? - .collect::>()?; + let upstream: Vec> = + mapping_get_or(&upstream_deps, &name, PyTuple::empty(py))? + .try_iter()? + .collect::>()?; let mut sql_names: Vec> = Vec::new(); for reference in native_field(&node, "sql_deps")?.try_iter()? { sql_names.push(native_field(&reference?, "name")?); @@ -291,8 +293,10 @@ fn located<'py>( SEED_KIND => "seed_locations", _ => return Ok(None), }; - let location: Bound<'py, PyAny> = native_field(plan_output, attribute)? - .call_method1("get", (native_field(reference, "name")?,))?; + let location: Bound<'py, PyAny> = mapping_get( + &native_field(plan_output, attribute)?, + native_field(reference, "name")?, + )?; Ok((!location.is_none()).then_some(location)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs index bbebc961d0..a1b89dd647 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs @@ -20,6 +20,8 @@ use sqlbuild_core::terminal_events::models::TerminalRequest; use crate::bindings::_helpers::build_progress::transient_lines::shared_transient_line_coordinator; use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; /// The module attribute holding the `ContextVar` of the installed projector. const CONTEXT_ATTRIBUTE: &str = "_native_progress_projector_context"; @@ -43,7 +45,7 @@ pub(crate) struct NativeProgressProjector { } fn payload_value<'py>(payload: &Bound<'py, PyAny>, key: &str) -> PyResult> { - payload.call_method1("get", (key,)) + mapping_get(payload, key) } fn text_value(value: &Bound<'_, PyAny>) -> PyResult> { @@ -86,7 +88,7 @@ fn number_value(value: &Bound<'_, PyAny>) -> PyResult> { /// `str(payload.get(key, default))`. fn display_value(payload: &Bound<'_, PyAny>, key: &str, default: &str) -> PyResult { - let value: Bound<'_, PyAny> = payload.call_method1("get", (key, default))?; + let value: Bound<'_, PyAny> = mapping_get_or(payload, key, default)?; Ok(value.str()?.to_string()) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs index 2e13b87f48..f056830088 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs @@ -32,6 +32,7 @@ use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; /// The `WarehouseGroup` whose warehouse is a target's `warehouses.build`; any other reads `query`. @@ -203,8 +204,7 @@ fn expand_authored( } fn connection_warehouse(connection_config: &Bound<'_, PyAny>) -> PyResult> { - let value: Bound<'_, PyAny> = - connection_config.call_method1("get", (CONNECTION_WAREHOUSE_KEY,))?; + let value: Bound<'_, PyAny> = mapping_get(connection_config, CONNECTION_WAREHOUSE_KEY)?; if !value.is_instance_of::() { return Ok(None); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs index 1df15a5b7a..7b662cb091 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs @@ -7,6 +7,7 @@ use pyo3::types::{PyDict, PyDictMethods, PyList, PyListMethods, PyString}; use crate::bindings::_helpers::compiled_project::model_input_view::input_reference_rows; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; const CURSOR_INPUTS_KEY: &str = "cursor_inputs"; @@ -67,8 +68,8 @@ pub(crate) fn resolve_cursor_input_roles<'py>( ) -> PyResult> { let py: Python<'py> = model.py(); let values: Bound<'py, PyAny> = native_field(model, "config")?.getattr("values")?; - let authored: Bound<'py, PyAny> = values.call_method1("get", (CURSOR_INPUTS_KEY,))?; - let strategy: Bound<'py, PyAny> = values.call_method1("get", ("microbatch_strategy",))?; + let authored: Bound<'py, PyAny> = mapping_get(&values, CURSOR_INPUTS_KEY)?; + let strategy: Bound<'py, PyAny> = mapping_get(&values, "microbatch_strategy")?; let rolling: bool = strategy.eq(ROLLING_WINDOW_STRATEGY)?; let mut filter: Bound<'py, PyDict> = PyDict::new(py); let mut watermark: Bound<'py, PyDict> = PyDict::new(py); @@ -83,7 +84,7 @@ pub(crate) fn resolve_cursor_input_roles<'py>( } } Err(_) => { - let cursor: Bound<'py, PyAny> = values.call_method1("get", ("cursor",))?; + let cursor: Bound<'py, PyAny> = mapping_get(&values, "cursor")?; if cursor.is_instance_of::() { for (_, name, _, _) in input_reference_rows(model)? { filter.set_item(name, &cursor)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs index a29f926377..480d6346bb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs @@ -22,6 +22,8 @@ use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::{new_record_with, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::semantic_shapes::coverage::semantic_coverage; @@ -612,8 +614,7 @@ fn model_resource<'py>( ), ( "materialized", - values - .call_method1("get", ("materialized", "view"))? + mapping_get_or(&values, "materialized", "view")? .str()? .into_any(), ), @@ -628,7 +629,7 @@ fn model_resource<'py>( )?; qualified_name(&item, model)?; for hook_key in HOOK_KEYS { - let hooks: Bound<'py, PyAny> = values.call_method1("get", (hook_key,))?; + let hooks: Bound<'py, PyAny> = mapping_get(&values, hook_key)?; if !hooks.is_none() { item.set_item( hook_key, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs index d69a1860aa..252a5a09b8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs @@ -37,6 +37,7 @@ use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; use crate::bindings::_helpers::records::registry; @@ -419,8 +420,7 @@ fn plan_tests<'py>( continue; }; let record_key: String = artifact_record_key(&test)?; - let chain: Bound<'py, PyAny> = - chains.call_method1("get", (native_field(&test, "key")?, &empty))?; + let chain: Bound<'py, PyAny> = mapping_get_or(chains, native_field(&test, "key")?, &empty)?; let identity: String = artifact_identity(&test, &chain, context)?; let reusable: Option = cached .get(&record_key) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs index c1e7130ca1..f36a2bda03 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs @@ -27,6 +27,7 @@ use crate::bindings::_helpers::project_assembly::declared_relations::{ }; use crate::bindings::_helpers::records::construct::{enum_member, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::fields::replaced; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::semantic_shapes::declarations::{declared_types, function_names}; @@ -295,26 +296,24 @@ fn record_expression_shapes<'py>( } let name: Bound<'py, PyAny> = native_field(source_input, "source_entry")?.getattr("name")?; - let declared_types: Bound<'py, PyAny> = context - .column_types - .call_method1("get", (&name, PyDict::new(py)))?; + let declared_types: Bound<'py, PyAny> = + mapping_get_or(&context.column_types, &name, PyDict::new(py))?; let declared_shape: Bound<'py, PyDict> = PyDict::new(py); for item in shape.call_method0("items")?.try_iter()? { let item: Bound<'py, PyAny> = item?; let column: Bound<'py, PyAny> = item.get_item(0)?; declared_shape.set_item( &column, - declared_types.call_method1("get", (&column, item.get_item(1)?))?, + mapping_get_or(&declared_types, &column, item.get_item(1)?)?, )?; } context.complete_schemas.set_item(&name, &declared_shape)?; context.column_types.set_item(&name, &declared_shape)?; let nullability: Bound<'py, PyDict> = PyDict::new(py); for column in declared_shape.keys() { - let known: Bound<'py, PyAny> = context - .nullability - .call_method1("get", (&name, PyDict::new(py)))?; - nullability.set_item(&column, known.call_method1("get", (&column, &unknown))?)?; + let known: Bound<'py, PyAny> = + mapping_get_or(&context.nullability, &name, PyDict::new(py))?; + nullability.set_item(&column, mapping_get_or(&known, &column, &unknown)?)?; } context.nullability.set_item(&name, nullability)?; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs index 2a5d132522..02f990d47b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs @@ -21,6 +21,7 @@ use crate::bindings::_helpers::project_assembly::syntax_validation::{ }; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::render::macro_calls::top_level_macro_call_names; @@ -80,7 +81,7 @@ fn compiled_model<'py>( &analysis_cursor_sql( py, &native_field(model_input, "query_sql")?.extract::()?, - &config_values.call_method1("get", ("cursor_type",))?, + &mapping_get(&config_values, "cursor_type")?, )?, ) .into_any(); @@ -117,7 +118,7 @@ fn compiled_model<'py>( if request.sql_validation_enabled && validates { for hook_name in HOOK_NAMES { validate_hook_sql_syntax( - config_values.call_method1("get", (hook_name,))?, + mapping_get(&config_values, hook_name)?, hook_name, location()?, syntax()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs index e4984502b7..0e03181f2e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs @@ -28,6 +28,7 @@ use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::scopes::scope_errors::report_scope_index_errors; use crate::bindings::_helpers::scopes::scope_validation::scope_index_with_compile_usages; @@ -179,7 +180,7 @@ fn effective_target_values<'py>(inputs: &Bound<'py, PyAny>) -> PyResult = if schema.is_truthy()? { schema } else { - str_or_none(&connection.call_method1("get", ("schema",))?)? + str_or_none(&mapping_get(&connection, "schema")?)? }; early_model_templates( keywords(py, &[("database", database), ("schema", schema)])?.as_any(), @@ -205,7 +206,7 @@ fn connection_database_fallback<'py>( if adapter_name.eq(host::entry(py, AdapterHost::BuiltinAdapter)?.getattr("DUCKDB")?)? { return Ok(py.None().into_bound(py)); } - str_or_none(&connection.call_method1("get", ("database",))?) + str_or_none(&mapping_get(connection, "database")?) } /// The compiled project's fields, in the order Python's assembly built them. @@ -241,11 +242,11 @@ fn project_fields<'py>( ("effective_vars", native_field(inputs, "effective_vars")?), ( "effective_target_database", - str_or_none(&target_values.call_method1("get", ("database",))?)?, + str_or_none(&mapping_get(target_values, "database")?)?, ), ( "effective_target_schema", - str_or_none(&target_values.call_method1("get", ("schema",))?)?, + str_or_none(&mapping_get(target_values, "schema")?)?, ), ( "sql_analysis_dialect", diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs index ea1bf76cb0..aa36e9c03d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::graph::python_node_graph::python_node_graph; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; const SKIPPED_UPSTREAM_CODE: &str = "P501"; @@ -289,7 +290,7 @@ fn previous_identity<'py>( native_field(identity, "node_name")?, ], )?; - previous_identities.call_method1("get", (key,)) + mapping_get(previous_identities, key) } /// `_identity_status`: whether a node's identity is unknown, new, unchanged or changed. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs index eec5b0bafe..51bfadbfb3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs @@ -13,6 +13,7 @@ use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::references::source_relations::render_source_relation; const SHARED_EXCEPTIONS_MODULE: &str = "sqlbuild.errors.contracts.exceptions"; @@ -218,7 +219,7 @@ fn planned_relation<'py>( } else { "seed_locations" })?; - let location: Bound<'py, PyAny> = locations.call_method1("get", (name,))?; + let location: Bound<'py, PyAny> = mapping_get(&locations, name)?; if location.is_none() { return Ok(location); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs index 5ed81b7d4f..f1eb35dfbc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs @@ -44,6 +44,7 @@ use crate::bindings::_helpers::contracts::spec_resolution::resolve_target_name; use crate::bindings::_helpers::discovery::guidance::setting_help; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::ErrorId; use pyo3::IntoPyObjectExt; use sqlbuild_core::constants::PROJECT_CONFIG_FILENAME; @@ -329,7 +330,7 @@ fn managed_source_namespace( &[ native_field(source_entry, "database")?, native_field(target_config, "database")?, - connection.call_method1("get", ("database",))?, + mapping_get(connection, "database")?, ], || adapter.call_method0("default_database"), )?; @@ -338,7 +339,7 @@ fn managed_source_namespace( native_field(source_entry, "schema")?, native_field(target_config, "loader_schema")?, native_field(target_config, "schema")?, - connection.call_method1("get", ("schema",))?, + mapping_get(connection, "schema")?, ], || adapter.call_method0("default_schema"), )?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs index 546dc0d42a..2aab03b0d2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs @@ -11,6 +11,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::format_command::files::write_file_atomically; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::refactor::contract_edits::edit_contract_model; @@ -74,10 +75,7 @@ pub(crate) fn write_contracts<'py>( &source, &physical_columns, write.overwrite.clone().extract::()?, - updates - .as_any() - .call_method1("get", (&path,))? - .extract::>()?, + mapping_get(updates.as_any(), &path)?.extract::>()?, ) .and_then(|value| pyo3::IntoPyObjectExt::into_bound_py_any(value, py))?; (path, edited) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs b/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs index 9f16347f26..cb3da73abc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs @@ -18,6 +18,7 @@ use crate::bindings::_helpers::contracts::effective_config::{ use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; const TARGET_GROUPS: [(&str, RecordId); 4] = [ @@ -210,12 +211,16 @@ fn scenario_local_type_overrides_for_dialect<'py>( let overrides: Bound<'py, PyDict> = PyDict::new(py); overrides.call_method1( "update", - (rules.call_method1("get", (ALL_DIALECTS, PyDict::new(py)))?,), + (mapping_get_or(&rules, ALL_DIALECTS, PyDict::new(py))?,), )?; if !sql_analysis_dialect.is_none() { overrides.call_method1( "update", - (rules.call_method1("get", (sql_analysis_dialect, PyDict::new(py)))?,), + (mapping_get_or( + &rules, + sql_analysis_dialect, + PyDict::new(py), + )?,), )?; } Ok(overrides) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs index 9bd407bbdc..b090f852da 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs @@ -23,6 +23,7 @@ use crate::bindings::_helpers::cost_telemetry::values::cost_aware; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::replaced_keywords; fn coverage(summary: &Bound<'_, PyAny>) -> PyResult { @@ -81,7 +82,7 @@ fn target_database<'py>( return Ok(database); } } - let database: Bound<'py, PyAny> = connection_config.call_method1("get", ("database",))?; + let database: Bound<'py, PyAny> = mapping_get(connection_config, "database")?; if database.is_none() { return Ok(py.None().into_bound(py)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs index ccbd1af6bc..6da921bd9b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs @@ -21,6 +21,7 @@ use crate::bindings::_helpers::cost_telemetry::values::process_object; use crate::bindings::_helpers::cursor::values::DATETIME_MODULE; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::{NativeAttr, RecordId}; use crate::bindings::_helpers::records::registry; @@ -168,7 +169,7 @@ fn record_statement(py: Python<'_>, options: Option>) -> PyRes fn ledger_entry<'py>(line: &Bound<'py, PyAny>) -> PyResult> { let py: Python<'py> = line.py(); let payload: Bound<'py, PyAny> = imported(py, "json", "loads")?.call1((line,))?; - let query_id: Bound<'py, PyAny> = payload.call_method1("get", ("query_id",))?; + let query_id: Bound<'py, PyAny> = mapping_get(&payload, "query_id")?; let field = |name: &str| -> PyResult> { Ok(payload.get_item(name)?.str()?.into_any()) }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs index 9e4c85ea6b..2e8bc71041 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs @@ -17,6 +17,8 @@ use sqlbuild_analysis::dag_artifact::models::{ use crate::bindings::_helpers::dag_artifact::selection::selected_node_ids; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; const PROJECT_NAME_KEY: &str = "project_name"; const DEFAULT_MATERIALIZATION: &str = "table"; @@ -40,15 +42,15 @@ fn listed<'py>(value: &Bound<'py, PyAny>) -> PyResult>> { fn projection_node(node: &Bound<'_, PyAny>) -> PyResult { Ok(DagProjectionNode { id: text(&node.get_item("id")?)?, - kind: text(&node.call_method1("get", ("kind",))?)?, + kind: text(&mapping_get(node, "kind")?)?, }) } fn projection_check(check: &Bound<'_, PyAny>) -> PyResult { let empty: Bound<'_, PyTuple> = PyTuple::empty(check.py()); Ok(DagProjectionCheck { - kind: text(&check.call_method1("get", ("kind",))?)?, - checked_asset_ids: listed(&check.call_method1("get", ("checked_asset_ids", empty))?)? + kind: text(&mapping_get(check, "kind")?)?, + checked_asset_ids: listed(&mapping_get_or(check, "checked_asset_ids", empty)?)? .iter() .map(text) .collect::>()?, @@ -77,7 +79,7 @@ fn artifact_graph<'py>(dag: &Bound<'py, PyAny>, with_checks: bool) -> PyResult>()? }; Ok(ArtifactGraph { - project_name: dag.call_method1("get", (PROJECT_NAME_KEY,))?, + project_name: mapping_get(dag, PROJECT_NAME_KEY)?, graph: DagProjectionGraph { nodes: nodes.iter().map(projection_node).collect::>()?, edges, @@ -131,7 +133,7 @@ fn picked<'py>(objects: &[Bound<'py, PyAny>], indexes: &[usize]) -> Vec) -> PyResult { - let value: Bound<'_, PyAny> = node.call_method1("get", ("materialization_type",))?; + let value: Bound<'_, PyAny> = mapping_get(node, "materialization_type")?; if value.is_truthy()? { text(&value) } else { @@ -206,7 +208,7 @@ fn rivers_asset_plans<'py>(dag: &Bound<'py, PyAny>) -> PyResult(check: &Bound<'py, PyAny>) -> PyResult> { - let path: Bound<'py, PyAny> = check.call_method1("get", ("path",))?; + let path: Bound<'py, PyAny> = mapping_get(check, "path")?; if path.is_none() { Ok(path) } else { @@ -263,9 +265,8 @@ fn dagster_selected_asset_nodes<'py>( ) -> PyResult> { let py: Python<'py> = dag.py(); let selected: BTreeSet = selected_node_ids(dag, (select, exclude))?; - let nodes: Vec> = - listed(&dag.call_method1("get", ("nodes", PyTuple::empty(py)))?)?; - let project_name: Bound<'py, PyAny> = dag.call_method1("get", (PROJECT_NAME_KEY,))?; + let nodes: Vec> = listed(&mapping_get_or(dag, "nodes", PyTuple::empty(py))?)?; + let project_name: Bound<'py, PyAny> = mapping_get(dag, PROJECT_NAME_KEY)?; let graph: DagProjectionGraph = DagProjectionGraph { nodes: nodes.iter().map(selection_node).collect::>()?, ..DagProjectionGraph::default() @@ -282,8 +283,8 @@ fn dagster_selected_asset_nodes<'py>( /// A node read the way selection reads it: `str(node.get("id"))` and `str(node.get("kind"))`. fn selection_node(node: &Bound<'_, PyAny>) -> PyResult { Ok(DagProjectionNode { - id: text(&node.call_method1("get", ("id",))?)?, - kind: text(&node.call_method1("get", ("kind",))?)?, + id: text(&mapping_get(node, "id")?)?, + kind: text(&mapping_get(node, "kind")?)?, }) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs index ba0b4e5305..223cc7fda1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs @@ -15,6 +15,7 @@ use sqlbuild_analysis::dag_artifact::types::DagColumnLineage; use crate::bindings::_helpers::python_values::values::python_value; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; const AUDIT_SEVERITY_MODULE: &str = "sqlbuild.compiler.auditing.types"; const DECIMAL_KIND: &str = "decimal"; @@ -191,8 +192,7 @@ fn model_schema(entry: &Bound<'_, PyAny>) -> PyResult) -> PyResult>> { - let tags: Bound<'_, PyAny> = - values.call_method1("get", ("tags", PyTuple::empty(values.py())))?; + let tags: Bound<'_, PyAny> = mapping_get_or(values, "tags", PyTuple::empty(values.py()))?; if !(tags.is_instance_of::() || tags.is_instance_of::()) { return Ok(None); } @@ -213,8 +213,7 @@ fn model(model: &Bound<'_, PyAny>) -> PyResult { authored_sql: text(model, "authored_sql")?, schema: model_schema(&attribute(model, "schema_entry")?)?, config_tags: config_tags(&values)?, - materialization: values - .call_method1("get", ("materialized", DEFAULT_MATERIALIZATION))? + materialization: mapping_get_or(&values, "materialized", DEFAULT_MATERIALIZATION)? .str()? .to_string(), inferred_columns: if inferred.is_none() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs index e03fbe078c..ddc97decfb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs @@ -20,6 +20,8 @@ use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::planner_selection::carrier::Carrier; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; const PATHLIB_MODULE: &str = "pathlib"; const JSON_MODULE: &str = "json"; @@ -32,15 +34,12 @@ fn text(value: &Bound<'_, PyAny>) -> PyResult { } fn field<'py>(mapping: &Bound<'py, PyAny>, key: &str) -> PyResult> { - mapping.call_method1("get", (key,)) + mapping_get(mapping, key) } fn items<'py>(mapping: &Bound<'py, PyAny>, key: &str) -> PyResult>> { let empty: Bound<'py, PyTuple> = PyTuple::empty(mapping.py()); - mapping - .call_method1("get", (key, empty))? - .try_iter()? - .collect() + mapping_get_or(mapping, key, empty)?.try_iter()?.collect() } fn texts(mapping: &Bound<'_, PyAny>, key: &str) -> PyResult> { @@ -181,7 +180,7 @@ fn load_sqlbuild_dag<'py>( } else { dag }; - let version: Bound<'py, PyAny> = payload.call_method1("get", ("version",))?; + let version: Bound<'py, PyAny> = mapping_get(&payload, "version")?; if version.ne(DAG_VERSION)? { return Err(raised( error_class, @@ -193,10 +192,7 @@ fn load_sqlbuild_dag<'py>( )); } for key in DAG_LIST_KEYS { - if !payload - .call_method1("get", (key,))? - .is_instance_of::() - { + if !mapping_get(&payload, key)?.is_instance_of::() { return Err(raised( error_class, format!("SQLBuild DAG artifact field '{key}' must be a list"), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs index b30bb28e28..fde9347b4c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs @@ -7,6 +7,8 @@ use pyo3::types::{PyDict, PyDictMethods, PyList, PyTuple}; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; /// An asset path as Dagster spells it. pub(crate) type AssetPath = Vec; @@ -15,7 +17,7 @@ pub(crate) type CheckKey = (AssetPath, String); /// `mapping.get(key)`. pub(crate) fn get<'py>(mapping: &Bound<'py, PyAny>, key: &str) -> PyResult> { - mapping.call_method1("get", (key,)) + mapping_get(mapping, key) } /// `mapping.get(key, default)`. @@ -24,7 +26,7 @@ pub(crate) fn value_or<'py>( key: &str, default: Bound<'py, PyAny>, ) -> PyResult> { - mapping.call_method1("get", (key, default)) + mapping_get_or(mapping, key, default) } /// `str(mapping.get(key))`. @@ -76,7 +78,7 @@ pub(crate) fn constant_contains( pub(crate) fn enabled(record: &Bound<'_, PyAny>, field_constant: ThirdPartyHost) -> PyResult { let py: Python<'_> = record.py(); let field: Bound<'_, PyAny> = constant(py, field_constant)?; - record.call_method1("get", (field, true))?.is_truthy() + mapping_get_or(record, field, true)?.is_truthy() } /// Whether a translated DAG node is owned by the SQLBuild asset definition. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs index d609740a4d..38c869c5e8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs @@ -17,6 +17,7 @@ use crate::bindings::_helpers::dagster_invocation::access::{ }; use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; const CHECK_KIND_FALLBACK: &str = "check"; const CHECK_NAME_JOIN: &str = "__"; @@ -50,7 +51,7 @@ pub(crate) fn sorted_nodes<'py>(dag: &Bound<'py, PyAny>) -> PyResult) -> PyResult { let py: Python<'_> = check.py(); let field: Bound<'_, PyAny> = constant(py, ThirdPartyHost::DagsterCheckNameField)?; - let translated: Bound<'_, PyAny> = check.call_method1("get", (field,))?; + let translated: Bound<'_, PyAny> = mapping_get(check, field)?; if !translated.is_none() { return translated.str()?.extract(); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs index c1c472ddc7..1cae5f4041 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs @@ -17,6 +17,7 @@ use sqlbuild_core::dbt_events::models::{DbtRowPosition, DbtStreamState, DbtStrea use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::dbt_events::event::dbt_event; use crate::bindings::_helpers::dbt_events::results::{native_result, python_result}; +use crate::bindings::_helpers::records::fields::mapping_get_or; const STREAM_OPTIONS: (&[&str], &[&str]) = (&["display_total", "detail_by_unique_id", "use_color"], &[]); @@ -53,7 +54,7 @@ impl DbtEventStream { if details.is_none() { return Ok(String::new()); } - details.call_method1("get", (unique_id, ""))?.extract() + mapping_get_or(details, unique_id, "")?.extract() } fn update(&self, py: Python<'_>, update: DbtStreamUpdate) -> PyResult { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs index bfec25c1c3..234250edc8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs @@ -14,6 +14,7 @@ use crate::bindings::_helpers::records::construct::{ enum_from_value, enum_member, new_record, new_record_with, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::RecordId; const BUILD_OPTIONS: (&[&str], &[&str]) = ( @@ -72,7 +73,7 @@ fn plan_text(plan: &Bound<'_, PyAny>) -> PyResult { let mut anchors: Vec<(String, Vec)> = Vec::new(); for term in native_field(&selection, "dbt_anchor_terms")?.try_iter()? { let term: Bound<'_, PyAny> = term?; - let unique_ids: Vec = strings(&anchor_ids.call_method1("get", (&term, &empty))?)?; + let unique_ids: Vec = strings(&mapping_get_or(&anchor_ids, &term, &empty)?)?; anchors.push((term.extract()?, unique_ids)); } let mut path_translations: Vec<(String, String)> = Vec::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs index 859a3859aa..405832ce4d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs @@ -28,6 +28,7 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::types::CompilerDetach; use sqlbuild_analysis::diff_selection::main::raw_query_shape::raw_query_shape; @@ -185,7 +186,7 @@ pub(crate) fn prepare_query_diff<'py>( let database: Bound<'py, PyAny> = if NAMESPACELESS_ADAPTERS.contains(&adapter_name.as_str()) { none(py) } else { - config.call_method1("get", ("database",))? + mapping_get(&config, "database")? }; let namespace: Bound<'py, PyAny> = build_effective_target_namespace( py, @@ -195,10 +196,7 @@ pub(crate) fn prepare_query_diff<'py>( ("discovered_inputs", discovered.clone()), ("selected_target", selected_target.clone()), ("connection_database", database.clone()), - ( - "connection_schema", - config.call_method1("get", ("schema",))?, - ), + ("connection_schema", mapping_get(&config, "schema")?), ( "default_database", adapter.call_method0("default_database")?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs b/crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs index 06e03d02e1..1d558d435e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs @@ -30,6 +30,7 @@ use crate::bindings::_helpers::model_config::header_columns::schema_columns; use crate::bindings::_helpers::native_host::facade::FacadeHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record, new_record_with}; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::sqltext::authored_values::map_to_python; use crate::bindings::models::{NativeDiscoverySession, NativeProjectTree}; @@ -299,15 +300,11 @@ fn audit_block<'py>(py: Python<'py>, block: &AuditBlock) -> PyResult) -> PyResult { .try_iter()? { let item: Bound<'_, PyAny> = item?; - let location: Bound<'_, PyAny> = item.call_method1("get", ("loc", py.None()))?; + let location: Bound<'_, PyAny> = mapping_get_or(&item, "loc", py.None())?; let location_text: String = if location.is_none() || !location.is_truthy()? { ROOT_LOCATION.to_owned() } else { @@ -86,9 +87,8 @@ fn validation_details(error: &Bound<'_, PyAny>) -> PyResult { .collect::>>()? .join(".") }; - let message: Bound<'_, PyAny> = item.call_method1("get", ("msg", DEFAULT_MESSAGE))?; - let error_type: Bound<'_, PyAny> = - item.call_method1("get", ("type", DEFAULT_ERROR_TYPE))?; + let message: Bound<'_, PyAny> = mapping_get_or(&item, "msg", DEFAULT_MESSAGE)?; + let error_type: Bound<'_, PyAny> = mapping_get_or(&item, "type", DEFAULT_ERROR_TYPE)?; details.push(format!( "{location_text}: {} [{}]", message.str()?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs index c8b7a81b3d..45396ddb7b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; static CURRENT_SCOPE: PyOnceLock> = PyOnceLock::new(); @@ -71,7 +72,7 @@ fn provider_arguments<'py>( let usage: Bound<'py, PyAny> = usage?; arguments.set_item( native_field(&usage, "parameter_name")?, - session.call_method1("get", (native_field(&usage, "provider_name")?,))?, + mapping_get(session, native_field(&usage, "provider_name")?)?, )?; } Ok(arguments) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs index f7525b88a7..16ba60e71c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs @@ -18,6 +18,7 @@ use crate::bindings::_helpers::freshness::observation::{ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::state_rows::freshness::{age_policy, equivalent}; use sqlbuild_core::freshness_text::main::freshness_status::freshness_status; use sqlbuild_core::freshness_text::models::{ @@ -71,8 +72,7 @@ fn previous_record<'py>( let Some(lookup) = &state.by_identity else { return Ok(None); }; - let found: Bound<'py, PyAny> = - lookup.call_method1("get", (native_field(record, "identity")?,))?; + let found: Bound<'py, PyAny> = mapping_get(lookup, native_field(record, "identity")?)?; Ok(found.is_truthy()?.then_some(found)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs index 12a825ec75..d13ee85465 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::records::construct::{ enum_from_value, enum_member, new_record, new_record_with, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::references::source_relations::render_source_relation; @@ -498,8 +499,7 @@ fn observe_adapter_batch_inner<'py>( ), )], )?; - let metadata: Bound<'py, PyAny> = - metadata_by_request.call_method1("get", (request, missing))?; + let metadata: Bound<'py, PyAny> = mapping_get_or(&metadata_by_request, request, missing)?; if let Some(unknown) = metadata_unknown(&name, &metadata)? { unknown_sources.set_item(&name, unknown)?; continue; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs index 7670aa005f..fad04155ac 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs @@ -20,6 +20,8 @@ use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::planner_identity::graph::build_downstream_model_name_closure; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::state_rows::freshness::{age_policy, equivalent}; @@ -60,9 +62,7 @@ fn previous_records<'py>( let merged: Bound<'py, PyDict> = PyDict::new(py); for schema in arguments.value("state_schemas")?.try_iter()? { let schema: Bound<'py, PyAny> = schema?; - let exists: bool = exists_by_schema - .call_method1("get", (&schema, false))? - .is_truthy()?; + let exists: bool = mapping_get_or(&exists_by_schema, &schema, false)?.is_truthy()?; let previous: Bound<'py, PyAny> = read_latest(&read, (&database, &schema), exists, source_names)?; for (identity, candidate) in native_field(&previous, "records")? @@ -212,7 +212,7 @@ pub(crate) fn build_direct_source_freshness_planning_result<'py>( let age_statuses: Bound<'py, PyDict> = PyDict::new(py); for (name, source) in observed_sources.iter() { let observation: Bound<'py, PyAny> = if freshness_strategy_is_adapter(&source)? { - let observation: Bound<'py, PyAny> = observations.call_method1("get", (&name,))?; + let observation: Bound<'py, PyAny> = mapping_get(&observations, &name)?; if observation.is_none() { continue; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs index 2b1fda2282..b411fb2370 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs @@ -9,6 +9,7 @@ use sqlbuild_core::graph_walk::main::breadth_first_reach::breadth_first_reach; use sqlbuild_core::graph_walk::main::directed_path_nodes::directed_path_nodes; use crate::bindings::_helpers::graph::node_set::PyNodeSet; +use crate::bindings::_helpers::records::fields::mapping_get_or; const BUILTINS_MODULE: &str = "builtins"; @@ -41,10 +42,7 @@ fn neighbours<'py>( current: &Bound<'py, PyAny>, none: &Bound<'py, PyTuple>, ) -> PyResult>> { - edges - .call_method1("get", (current, none))? - .try_iter()? - .collect() + mapping_get_or(edges, current, none)?.try_iter()?.collect() } /// Keys within `max_depth` edges of any start, plus the starts when requested. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs index d6c43b6c66..2ebfe2d8b7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs @@ -10,6 +10,7 @@ use crate::bindings::_helpers::analysis::explicit_references::{ use crate::bindings::_helpers::graph::keys::KeyCache; use crate::bindings::_helpers::records::construct::{enum_from_value, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; const PATHLIB_MODULE: &str = "pathlib"; @@ -97,7 +98,7 @@ pub(crate) fn model_python_hook_names<'py>( let values: Bound<'_, PyAny> = native_field(model, "config")?.getattr("values")?; let mut names: Vec = Vec::new(); for hook_key in MODEL_HOOK_KEYS { - let entries: Bound<'_, PyAny> = values.call_method1("get", (hook_key,))?; + let entries: Bound<'_, PyAny> = mapping_get(&values, hook_key)?; if entries.is_instance(&entry_type)? { names.push(native_field(&entries, "name")?.extract()?); } else if entries.is_instance_of::() || entries.is_instance_of::() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs b/crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs index c0f838f395..c950f2c2f7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs @@ -5,6 +5,7 @@ use crate::bindings::_helpers::analysis_session::outcome_objects::dynamic_contra use crate::bindings::_helpers::analysis_session::outcome_objects::session_outcome_analysis; use crate::bindings::_helpers::records::construct::{enum_from_value, enum_member, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyList, PyString, PyTuple}; @@ -156,7 +157,7 @@ fn destination<'py>(config: &Object<'py>, model_name: &Object<'py>) -> PyResult< let py: Python<'py> = config.py(); let values: Object<'py> = native_field(config, "values")?; let text = |key: &str| -> PyResult>> { - let value: Object<'py> = values.call_method1("get", (key,))?; + let value: Object<'py> = mapping_get(&values, key)?; Ok(value.is_instance_of::().then_some(value)) }; let none: Object<'py> = py.None().into_bound(py); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs index 77bdb1ac5c..39e20d4f6c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs @@ -15,6 +15,7 @@ use crate::bindings::_helpers::record_behaviours::lineage_facts::{ confidence_member, transform_kind_member, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; /// One compact model's facts and root-star flag. struct CompactModel { @@ -286,7 +287,7 @@ impl ProjectColumnLineage { builder.push_facts(classes, name, compact.columns.bind(py))?; continue; } - let model: Bound<'_, PyAny> = models.call_method1("get", (name,))?; + let model: Bound<'_, PyAny> = mapping_get(&models, name)?; if model.is_none() { continue; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs b/crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs index b76e0c358d..1447ef485b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs @@ -16,6 +16,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::load::ingestr_command::connection; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; +use crate::bindings::_helpers::records::fields::mapping_get_or; const DLT_ERROR: ThirdPartyHost = ThirdPartyHost::DltIntegrationError; @@ -50,7 +51,7 @@ fn argument<'py>( let py: Python<'py> = connection_config.py(); match value { DltValue::Text(text) => Ok(PyString::new(py, text).into_any()), - DltValue::Port { default } => connection_config.call_method1("get", ("port", *default)), + DltValue::Port { default } => mapping_get_or(connection_config, "port", *default), DltValue::Object(fields) => Ok(arguments(fields, connection_config)?.into_any()), } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs b/crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs index fac146af2d..f39befb31a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs @@ -15,6 +15,8 @@ use sqlbuild_analysis::python_values::models::PythonValue; use crate::bindings::_helpers::python_values::values::python_value; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::RecordId; const DECIMAL_KIND: &str = "decimal"; @@ -174,12 +176,12 @@ fn config_value<'py>( key: &str, default: Bound<'py, PyAny>, ) -> PyResult> { - values.call_method1("get", (key, default)) + mapping_get_or(values, key, default) } fn config(values: &Bound<'_, PyAny>) -> PyResult { let py: Python<'_> = values.py(); - let get = |key: &str| values.call_method1("get", (key,)); + let get = |key: &str| mapping_get(values, key); let materialized: Bound<'_, PyAny> = config_value( values, "materialized", diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs index b58accdc7d..200dec579f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs @@ -6,13 +6,14 @@ use pyo3::{pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::compile_driver::python_calls::{call_with, imported}; use crate::bindings::_helpers::records::construct::error_class; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::ErrorId; const DATETIME_MODULE: &str = "datetime"; /// `values.get(key)`, or `None` when the value is absent or `None`. fn authored<'py>(values: &Bound<'py, PyAny>, key: &str) -> PyResult>> { - let value: Bound<'py, PyAny> = values.call_method1("get", (key,))?; + let value: Bound<'py, PyAny> = mapping_get(values, key)?; Ok(Some(value).filter(|value| !value.is_none())) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs b/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs index ff64213160..8e23c3f973 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs @@ -17,6 +17,7 @@ use crate::bindings::_helpers::discovery::project_facts::{column_name, each, ste use crate::bindings::_helpers::model_config::authored_nodes::PyNode; use crate::bindings::_helpers::model_config::config_errors::native_config_error; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; const FILE_PATH_ATTRIBUTE: &str = "file_path"; const RETURNS_KEY: &str = "returns"; @@ -85,7 +86,7 @@ fn discovered_names(inputs: &Bound<'_, PyAny>) -> PyResult { /// Whether a SQL function's header `returns` is a mapping whose only key is `table`. fn returns_table(file: &Bound<'_, PyAny>) -> PyResult { let headers: Bound<'_, PyAny> = native_field(file, "header_values")?; - let returns: Bound<'_, PyAny> = headers.call_method1("get", (RETURNS_KEY,))?; + let returns: Bound<'_, PyAny> = mapping_get(&headers, RETURNS_KEY)?; let Ok(returns) = returns.downcast::() else { return Ok(false); }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs index e2edf0a83a..2470bf0640 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs @@ -22,6 +22,7 @@ use crate::bindings::_helpers::output_capture::values::{ freeze, json_value, object, output_error, plain_int, validation_error, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; const ENVELOPE_FIELDS: [&str; 16] = [ "record_id", @@ -308,7 +309,7 @@ pub(crate) fn invocation_context<'py>( Some(environment) if !environment.is_none() => environment, _ => imported(py, "os", "environ")?, }; - let raw = environment.call_method1("get", (INVOCATION_CONTEXT_ENV,))?; + let raw = mapping_get(&environment, INVOCATION_CONTEXT_ENV)?; if raw.is_none() { return Ok(PyDict::new(py).into_any()); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs index 282a8e1553..b7f51bc97e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs @@ -29,6 +29,7 @@ use crate::bindings::_helpers::plan_output::python_identity::{ use crate::bindings::_helpers::plan_output::values::{items, optional_text, text, texts}; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; const SKIP_ACTION: &str = "skip"; @@ -364,7 +365,7 @@ fn metadata_names(value: Option>) -> PyResult> { /// The metadata `selection_diagnostics.enabled` flag, when it is a bool. pub(crate) fn selection_diagnostics(metadata: &Bound<'_, PyAny>) -> PyResult> { - let diagnostics: Bound<'_, PyAny> = metadata.call_method1("get", ("selection_diagnostics",))?; + let diagnostics: Bound<'_, PyAny> = mapping_get(metadata, "selection_diagnostics")?; let Ok(diagnostics) = diagnostics.downcast::() else { return Ok(None); }; @@ -377,7 +378,7 @@ pub(crate) fn selection_diagnostics(metadata: &Bound<'_, PyAny>) -> PyResult) -> PyResult> { - let freshness: Bound<'_, PyAny> = metadata.call_method1("get", ("direct_source_freshness",))?; + let freshness: Bound<'_, PyAny> = mapping_get(metadata, "direct_source_freshness")?; let Ok(freshness) = freshness.downcast::() else { return Ok(None); }; @@ -396,7 +397,7 @@ fn source_freshness(metadata: &Bound<'_, PyAny>) -> PyResult) -> PyResult> { - let names: Bound<'_, PyAny> = metadata.call_method1("get", ("direct_pruned_model_names",))?; + let names: Bound<'_, PyAny> = mapping_get(metadata, "direct_pruned_model_names")?; if !names.is_instance_of::() { return Ok(Vec::new()); } @@ -486,9 +487,10 @@ fn report(arguments: &KeywordArguments<'_>) -> PyResult { .collect::>()?, warnings, source_freshness: source_freshness(&metadata)?, - remaining_stale_models: metadata_names(Some( - metadata.call_method1("get", ("direct_remaining_stale_model_names",))?, - ))?, + remaining_stale_models: metadata_names(Some(mapping_get( + &metadata, + "direct_remaining_stale_model_names", + )?))?, pruned_models: pruned_models(&metadata)?, pre_build_lines: pre_build, }) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/actions.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/actions.rs index 748e555e11..8e89db211a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/actions.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/actions.rs @@ -6,6 +6,7 @@ use pyo3::{pyfunction, wrap_pyfunction}; use crate::bindings::_helpers::records::construct::{enum_member, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; const INCREMENTAL_MATERIALIZATION: &str = "incremental"; @@ -30,7 +31,7 @@ pub(crate) fn resolve_model_actions<'py>( continue; } let name: Bound<'py, PyAny> = native_field(&key, "name")?; - let change: Bound<'py, PyAny> = model_changes.call_method1("get", (&name,))?; + let change: Bound<'py, PyAny> = mapping_get(&model_changes, &name)?; if !models_by_name.contains(&name)? || change.is_none() { continue; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs index 8cccda9fca..c87f44be17 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs @@ -45,6 +45,7 @@ use crate::bindings::_helpers::planner_identity::metadata::{ model_version_identity_metadata_json, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::type_system::equality::types_equal as native_types_equal; @@ -118,7 +119,7 @@ pub(crate) fn detect_changes<'py>( let reason: &str = if full_refresh { "full_refresh" } else { - let fingerprint: Bound<'py, PyAny> = recorded.call_method1("get", (&name,))?; + let fingerprint: Bound<'py, PyAny> = mapping_get(&recorded, &name)?; if fingerprint.is_none() { "first_run" } else if query_change_tracking @@ -279,8 +280,7 @@ pub(crate) fn scope_model_changes<'py>( if !selected.contains(&key)? || !native_field(&key, "resource_type")?.eq(&model_kind)? { continue; } - let model: Bound<'py, PyAny> = - models_by_name.call_method1("get", (native_field(&key, "name")?,))?; + let model: Bound<'py, PyAny> = mapping_get(&models_by_name, native_field(&key, "name")?)?; if model.is_none() { continue; } @@ -298,7 +298,7 @@ fn lookup(mapping: &Bound<'_, PyAny>, name: &Bound<'_, PyAny>) -> PyResult( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs index 17d88ea590..0c38f70df0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::{ }; use crate::bindings::_helpers::planner_identity::hashing::model_query_hash; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; const GENERIC_DIALECT: &str = "generic"; @@ -224,8 +225,7 @@ fn changed_referencing_query( let models_by_name: Bound<'_, PyAny> = native_field(scope, "models_by_name")?; let mut selected: Vec> = Vec::new(); for key in native_field(scope, "selected_keys")?.try_iter()? { - let model: Bound<'_, PyAny> = - models_by_name.call_method1("get", (native_field(&key?, "name")?,))?; + let model: Bound<'_, PyAny> = mapping_get(&models_by_name, native_field(&key?, "name")?)?; if !model.is_none() { selected.push(model); } @@ -236,7 +236,7 @@ fn changed_referencing_query( let dialect: Option = native_field(snapshot, "column_dialect")?.extract()?; for model in selected { let recorded: Bound<'_, PyAny> = - recorded_models.call_method1("get", (model_reads::name_object(&model)?,))?; + mapping_get(&recorded_models, model_reads::name_object(&model)?)?; if recorded.is_none() { continue; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs index daf5f0b783..5ac80284d5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs @@ -20,6 +20,7 @@ use crate::bindings::_helpers::planner_strategy::audit_entries::build_selected_a use crate::bindings::_helpers::planner_strategy::model_entries::extract_seed_columns; use crate::bindings::_helpers::planner_strategy::strategy::materialization_of; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyList, PyListMethods, PyString, PyTuple}; @@ -303,7 +304,7 @@ pub(crate) fn build_seed_command_plan<'py>( } let identity = object(py, build_seed_identity(&seed)?)?; let (version_hash, metadata_json) = (identity.get_item(0)?, identity.get_item(1)?); - let previous = existing.call_method1("get", (native_field(&seed, "name")?,))?; + let previous = mapping_get(&existing, native_field(&seed, "name")?)?; let reason = if previous.is_none() { "FIRST_RUN" } else if native_field(&previous, "version_hash")?.ne(&version_hash)? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs index 2f32727daf..9d67a16ef4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs @@ -43,6 +43,7 @@ use crate::bindings::_helpers::planner_strategy::strategy::{ use crate::bindings::_helpers::planner_strategy::values::text; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::semantic_shapes::source_bindings::source_binding_diagnostics; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; @@ -463,7 +464,7 @@ pub(crate) fn plan_entries<'py>( if !selected_keys.contains(&key)? || !models.contains(&name)? { continue; } - let model = models_by_name.call_method1("get", (&name,))?; + let model = mapping_get(&models_by_name, &name)?; let resolved = models.get_item(&name)?; if model.is_none() { continue; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs index ea11b26fed..e166cb7a9c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs @@ -16,6 +16,7 @@ use crate::bindings::_helpers::planner_strategy::fixture_context::planning_conte use crate::bindings::_helpers::planner_strategy::model_entries::extract_seed_columns; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::sql_test_glue::models::SqlTestAssembly; use crate::bindings::_helpers::sql_test_glue::plan_assembly::assemble_sql_test_plans; @@ -38,7 +39,7 @@ fn optional_get<'py>( key: &Bound<'py, PyAny>, ) -> PyResult> { if mapping.is_truthy()? { - return mapping.call_method1("get", (key,)); + return mapping_get(mapping, key); } Ok(none(mapping.py())) } @@ -279,7 +280,7 @@ fn require_intermediate_loader_targets<'py>( )?; let existing = native_field(snapshot, "existing_relations")?; for entry in source_load_entries.try_iter()? { - let source_entry = source_map.call_method1("get", (native_field(&entry?, "name")?,))?; + let source_entry = mapping_get(source_map, native_field(&entry?, "name")?)?; if source_entry.is_none() || native_field(&source_entry, "loader")?.is_none() { continue; } @@ -294,7 +295,7 @@ fn require_intermediate_loader_targets<'py>( )?; for dependency_name in dependencies.try_iter()? { let dependency_name = dependency_name?; - let dependency = source_map.call_method1("get", (&dependency_name,))?; + let dependency = mapping_get(source_map, &dependency_name)?; if dependency.is_none() || selected_names.contains(native_field(&dependency, "name")?)? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs index 338a159255..688a3d7a35 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs @@ -29,6 +29,7 @@ use crate::bindings::_helpers::planner_identity::hashing::graph_key; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; const TABLE_FN_TEST_MODE: &str = "table_fn"; @@ -357,7 +358,7 @@ pub(crate) fn check_buildability<'py>( let mut deps: HashMap> = HashMap::new(); for key in &selected { let dep_keys: Bound<'py, PyAny> = - upstream_deps.call_method1("get", (objects.object(key), PyTuple::empty(py)))?; + mapping_get_or(&upstream_deps, objects.object(key), PyTuple::empty(py))?; deps.insert(key.clone(), objects.keys(&dep_keys)?); } let available = AvailableUpstreams { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs index 3829a4699b..5963ba1b97 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs @@ -24,6 +24,7 @@ use crate::bindings::_helpers::planner_identity::metadata::{ }; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::replaced; use crate::bindings::_helpers::records::ids::RecordId; @@ -155,7 +156,7 @@ pub(crate) fn direct_model_version_identities<'py>( if order_key.kind != MODEL_RESOURCE { continue; } - let model: Bound<'py, PyAny> = models_by_name.call_method1("get", (&order_key.name,))?; + let model: Bound<'py, PyAny> = mapping_get(&models_by_name, &order_key.name)?; if model.is_none() { continue; } @@ -272,7 +273,7 @@ pub(crate) fn with_honest_model_write_hashes<'py>( local_hash: Some(seed_hash.clone()), }, ); - let fingerprint: Bound<'py, PyAny> = recorded_seeds.call_method1("get", (&name,))?; + let fingerprint: Bound<'py, PyAny> = mapping_get(&recorded_seeds, &name)?; let write_hash: String = if selected.contains(&seed_key) || fingerprint.is_none() { seed_hash } else { @@ -291,7 +292,7 @@ pub(crate) fn with_honest_model_write_hashes<'py>( key_of(MODEL_RESOURCE, &name.extract::()?), IdentityNode { upstream_keys: graph_keys(&native_field(&model, "deps")?)?, - local_hash: local_hashes.call_method1("get", (&name,))?.extract()?, + local_hash: mapping_get(&local_hashes, &name)?.extract()?, }, ); } @@ -328,12 +329,12 @@ pub(crate) fn with_honest_model_write_hashes<'py>( if order_key.kind != MODEL_RESOURCE || !selected.contains(&order_key) { continue; } - let model: Bound<'py, PyAny> = models_by_name.call_method1("get", (&order_key.name,))?; + let model: Bound<'py, PyAny> = mapping_get(&models_by_name, &order_key.name)?; if model.is_none() { continue; } let name: Bound<'py, PyAny> = model_reads::name_object(&model)?; - if local_hashes.call_method1("get", (&name,))?.is_none() { + if mapping_get(&local_hashes, &name)?.is_none() { continue; } let Some(write_hash) = @@ -373,7 +374,7 @@ pub(crate) fn merge_recomputed_model_changes<'py>( .try_iter()? { let (name, resolved): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; - let mut change: Bound<'py, PyAny> = recomputed.call_method1("get", (&name,))?; + let mut change: Bound<'py, PyAny> = mapping_get(&recomputed, &name)?; if change.is_none() { change = native_field(&resolved, "change")?; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs index 50cb22e106..57376ba7d4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs @@ -20,6 +20,7 @@ use crate::bindings::_helpers::discovery::hook_entries::hook_entries; use crate::bindings::_helpers::planner_identity::hashing::function_definition_hash; use crate::bindings::_helpers::planner_identity::json_values::{COMPACT, SPACED, sorted_dumps}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; const LOCAL_FUNCTION_HASHES_KEY: &str = "local_function_hashes"; const DATACLASSES_MODULE: &str = "dataclasses"; @@ -96,7 +97,7 @@ pub(crate) fn model_version_identity_metadata_json<'py>( continue; } let name: Bound<'py, PyAny> = native_field(&upstream_key, "name")?; - let upstream_hash: Bound<'py, PyAny> = function_hashes.call_method1("get", (&name,))?; + let upstream_hash: Bound<'py, PyAny> = mapping_get(function_hashes, &name)?; if !upstream_hash.is_none() { local_function_hashes.set_item(name, upstream_hash)?; } @@ -176,9 +177,8 @@ fn contract_output_signature<'py>( if !(columns.is_truthy()? || families.is_truthy()?) { return Ok(None); } - let enforced: bool = config_values - .call_method1("get", (CONTRACT_CONFIG_KEY,))? - .eq(ENFORCED_CONTRACT_POLICY)?; + let enforced: bool = + mapping_get(config_values, CONTRACT_CONFIG_KEY)?.eq(ENFORCED_CONTRACT_POLICY)?; if !enforced && native_field(&schema_entry, "model_schema")?.is_none() { return Ok(None); } @@ -188,7 +188,7 @@ fn contract_output_signature<'py>( let column: Bound<'py, PyAny> = column?; let entry: Bound<'py, PyDict> = column_signature(&column)?; let declaration: Bound<'py, PyAny> = - enum_columns.call_method1("get", (native_field(&column, "name")?,))?; + mapping_get(&enum_columns, native_field(&column, "name")?)?; if !declaration.is_none() { let members: Bound<'py, PyList> = PyList::empty(py); for member in native_field(&declaration, "members")?.try_iter()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs index 4e703fefba..2490654165 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs @@ -21,6 +21,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_changes::detect::{ModelPass, model_change}; use crate::bindings::_helpers::planner_identity::hashing::graph_key; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; /// Change kinds that mean the model's own identity changed. @@ -94,7 +95,7 @@ fn changed_model_names(inputs: &StalenessInputs<'_>) -> PyResult let models_by_name: Bound<'_, PyAny> = native_field(&inputs.original_scope, "models_by_name")?; for item in models_by_name.call_method0("items")?.try_iter()? { let (name, model): (String, Bound<'_, PyAny>) = item?.extract()?; - let selected_change: Bound<'_, PyAny> = models.call_method1("get", (&name,))?; + let selected_change: Bound<'_, PyAny> = mapping_get(&models, &name)?; if !selected_change.is_none() && (inputs.model_changes_complete || own_change(&selected_change)?) { @@ -110,8 +111,8 @@ fn changed_model_names(inputs: &StalenessInputs<'_>) -> PyResult &pass, &model, ( - version_hashes.call_method1("get", (&name,))?.extract()?, - metadata_jsons.call_method1("get", (&name,))?.extract()?, + mapping_get(&version_hashes, &name)?.extract()?, + mapping_get(&metadata_jsons, &name)?.extract()?, ), )?; if own_change(&change)? { @@ -133,7 +134,7 @@ fn changed_seed_names(inputs: &StalenessInputs<'_>) -> PyResult> if expected.is_none() { continue; } - let fingerprint: Bound<'_, PyAny> = recorded.call_method1("get", (&name,))?; + let fingerprint: Bound<'_, PyAny> = mapping_get(&recorded, &name)?; if fingerprint.is_none() || !native_field(&fingerprint, "version_hash")?.eq(&expected)? { changed.insert(name); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs index fd474377f4..41f26b4732 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs @@ -13,6 +13,7 @@ use crate::bindings::_helpers::planner_migrations::models::{ use crate::bindings::_helpers::planner_migrations::projections::renames_explain_change; use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; @@ -135,7 +136,7 @@ pub(super) fn cursors<'py>( let origins = PyDict::new(py); for entry in entries { let name = native_field(entry, "model_name")?; - let model = models.call_method1("get", (&name,))?; + let model = mapping_get(&models, &name)?; let cursor = if model.is_truthy()? { config(&model, "cursor")? } else { @@ -153,7 +154,7 @@ pub(super) fn cursors<'py>( } let targets = PyDict::new(py); for (name, _) in origins.iter() { - let physical = columns.physical_relations.call_method1("get", (&name,))?; + let physical = mapping_get(&columns.physical_relations, &name)?; let target = if physical.is_truthy()? { physical } else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs index 4b13d175f8..7a6b5f7765 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs @@ -9,6 +9,7 @@ use crate::bindings::_helpers::planner_migrations::models::{ }; use crate::bindings::_helpers::planner_phases::runtime::runtime_field; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PySet, PySetMethods}; use pyo3::{pyfunction, wrap_pyfunction}; @@ -106,9 +107,10 @@ pub(crate) fn plan_column_migrations<'py>( &native_field(&state, "column_events")?, &inputs, )?; - let physical = columns - .physical_relations - .call_method1("get", (model_reads::name_object(&candidate.model)?,))?; + let physical = mapping_get( + &columns.physical_relations, + model_reads::name_object(&candidate.model)?, + )?; let checked = super::column_entries::checked(&runtime, candidate, decided, &physical)?; for hint in super::column_entries::hints(candidate, &checked.entries)?.try_iter()? { hints.push(hint?); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs index bc9ed26749..8bc39a0c08 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs @@ -11,6 +11,7 @@ use crate::bindings::_helpers::planner_migrations::models::{ }; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::{ @@ -118,7 +119,7 @@ pub(super) fn automatic<'py>( } let name = native_field(item, "name")?; let event = matches.1.get_item(&name)?; - let candidate = matches.0.call_method1("get", (&name,))?; + let candidate = mapping_get(matches.0, &name)?; let origin = if let Some(event) = event { Some(( location(runtime, &native_field(&event, "origin")?, true)?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs index f322fdf91e..4c3f73f97b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs @@ -1,6 +1,7 @@ //! Physical columns of the relations a model reads, as inspected by the planner. use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyFrozenSet; use pyo3::{pyclass, pymethods}; @@ -38,7 +39,7 @@ impl KnownInputColumns { SOURCE_INPUT_FUNCTION => self.source_columns.bind(py), _ => return Ok(None), }; - let columns = inspected.call_method1("get", (name,))?; + let columns = mapping_get(inspected, name)?; if columns.is_none() || !columns.is_truthy()? { return Ok(None); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs index fb33fd20c4..138d33d354 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs @@ -6,6 +6,7 @@ use crate::bindings::_helpers::planner_migrations::models::{ FingerprintInputs, ModelMigrationRequest, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use pyo3::IntoPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; @@ -93,11 +94,7 @@ pub(super) fn migration_destination_fingerprints<'py>( for request in requests { let model = &request.model; let name = model_reads::name_object(model)?; - if inputs - .metadata_jsons - .call_method1("get", (&name,))? - .is_none() - { + if mapping_get(&inputs.metadata_jsons, &name)?.is_none() { continue; } result.set_item( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs index 8cc7381729..6e3bb3b5ba 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs @@ -16,6 +16,8 @@ use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::planner_phases::runtime::runtime_field; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::{ @@ -25,7 +27,7 @@ use pyo3::types::{ fn declared<'py>(item: &Bound<'py, PyAny>) -> PyResult>> { let py = item.py(); let values = native_field(&native_field(item, "config")?, "values")?; - let origin = values.call_method1("get", ("migrate_from",))?; + let origin = mapping_get(&values, "migrate_from")?; if !origin.is_instance_of::() { return Ok(None); } @@ -36,9 +38,7 @@ fn declared<'py>(item: &Bound<'py, PyAny>) -> PyResult( &[("missing_origin_policy", policy.clone())], )?); if decided.applies { - let destinations = discovery - .destination_fingerprints - .call_method1("get", (&name, PyTuple::empty(py)))?; + let destinations = mapping_get_or( + &discovery.destination_fingerprints, + &name, + PyTuple::empty(py), + )?; handovers.set_item( name, super::model_handover::equivalent( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs index 6e2c14a385..5565ce3709 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs @@ -21,6 +21,8 @@ use crate::bindings::_helpers::planner_migrations::constants::{ }; use crate::bindings::_helpers::planner_phases::runtime::runtime_field; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::state_rows::constants::{COLUMN_KIND, MODEL_KIND, OLD_NAME_KIND}; use crate::bindings::_helpers::state_rows::migration_io::{read_events, stored_old_name_columns}; use crate::bindings::_helpers::state_rows::migration_objects::layout; @@ -169,10 +171,7 @@ impl MigrationStateInspection { schema: &Bound<'py, PyAny>, key: &str, ) -> PyResult>> { - let known: Bound<'py, PyAny> = self - .known_fingerprints - .bind(py) - .call_method1("get", (key,))?; + let known: Bound<'py, PyAny> = mapping_get(self.known_fingerprints.bind(py), key)?; let latest: Bound<'py, PyAny> = if known.is_none() { let adapter: &Bound<'py, PyAny> = self.adapter.bind(py); let fingerprint_set: Bound<'py, PyAny> = read_latest_fingerprints(Some(&keywords( @@ -504,7 +503,7 @@ impl MigrationStateInspection { let empty: Bound<'_, PyTuple> = PyTuple::empty(py); for (key, relation) in matched { let relation_columns: Bound<'_, PyAny> = - columns.call_method1("get", (native_field(&relation, "identity")?, &empty))?; + mapping_get_or(&columns, native_field(&relation, "identity")?, &empty)?; let mut this: PyRefMut<'_, Self> = slf.borrow_mut(); this.relations.insert(key.clone(), relation.unbind()); this.columns.insert(key, relation_columns.unbind()); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs index 14fb5e8c77..53e8c181bd 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs @@ -9,6 +9,7 @@ use crate::bindings::_helpers::planner_phases::models::PlannerIdentityContext; use crate::bindings::_helpers::planner_phases::models::PlannerScopeResolution; use crate::bindings::_helpers::planner_phases::objects::{frozenset, native, replace}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::pyfunction; @@ -105,10 +106,8 @@ fn reusable_model_names( for name in native_field(execution_changes, "models")?.try_iter()? { let name = name?; let same = |field: &str| -> PyResult { - execution - .getattr(field)? - .call_method1("get", (&name,))? - .eq(native_field(&stale, field)?.call_method1("get", (&name,))?) + mapping_get(&execution.getattr(field)?, &name)? + .eq(mapping_get(&native_field(&stale, field)?, &name)?) }; if same("model_version_hashes")? && same("model_metadata_jsons")? { names.insert(name.extract()?); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs index 8001afb87b..ae5321a3ed 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs @@ -17,6 +17,7 @@ use crate::bindings::_helpers::planner_phases::objects::{ use crate::bindings::_helpers::planner_phases::runtime::runtime_field; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::IntoPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; @@ -127,7 +128,7 @@ pub(crate) fn plan_table_types<'py>( if !backed.is_truthy()? { continue; } - let relation = relations.call_method1("get", (model_reads::name_object(&model)?,))?; + let relation = mapping_get(&relations, model_reads::name_object(&model)?)?; if relation.is_none() { continue; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs index d0a1c85447..8f5ac2ff0f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs @@ -3,6 +3,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::call_with; use crate::bindings::_helpers::records::construct::{enum_from_value, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult}; use pyo3::types::PyString; @@ -45,8 +46,8 @@ fn resolve_policy<'py>( class.call0()? }; let values = native_field(&native_field(model, "config")?, "values")?; - let raw_distance = values.call_method1("get", (fields.distance_key,))?; - let raw_action = values.call_method1("get", (fields.action_key,))?; + let raw_distance = mapping_get(&values, fields.distance_key)?; + let raw_action = mapping_get(&values, fields.action_key)?; let mut distance = configured.getattr(fields.distance)?; if raw_distance.is_instance_of::() { distance = if raw_distance.eq(POLICY_DISABLED)? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs index c14d9d7bd2..1214afb4d3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::planner_resolution::sources::resolve_sources; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; @@ -344,10 +345,7 @@ pub(crate) fn model_hook_entries<'py>( let name: String = model_reads::model_name(model)?; let mut hooks: Vec> = Vec::new(); for key in ["pre_hooks", "post_hooks"] { - hooks.push(resolution.hook( - values.call_method1("get", (key,))?, - &format!("Model '{name}' {key}"), - )?); + hooks.push(resolution.hook(mapping_get(&values, key)?, &format!("Model '{name}' {key}"))?); } PyTuple::new(model.py(), hooks) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs index e8e83c03dd..d2cfdbe819 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs @@ -8,6 +8,7 @@ use crate::bindings::_helpers::planner_resolution::values::{ cursor_wrap, filtering_of, method, string, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::sqltext::code_scanner::SqlCodeScanner; use pyo3::IntoPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; @@ -61,7 +62,7 @@ pub(crate) fn resolve_refs( let mut last = 0; for span in reference_spans(&sql, kind) { output.push_str(&sql[last..span.start]); - let target = locations.call_method1("get", (&span.name,))?; + let target = mapping_get(locations, &span.name)?; if target.is_none() { output.push_str(&sql[span.start..span.end]); } else { @@ -154,7 +155,7 @@ fn resolve_function_calls( code_index = query_sql[..span.end].chars().count(); } output.push_str(query_sql.get(last..span.start).unwrap_or_default()); - let target = locations.call_method1("get", (&span.name,))?; + let target = mapping_get(locations, &span.name)?; let qualified = if target.is_none() { py.None().into_bound(py) } else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs index 75d986c8cd..292a1bd99b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs @@ -7,6 +7,7 @@ use crate::bindings::_helpers::planner_resolution::values::{ }; use crate::bindings::_helpers::planner_strategy::values::input_error; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::ErrorId; use crate::bindings::_helpers::references::source_relations::render_source_relation; use crate::bindings::_helpers::type_system::equality::types_equal; @@ -254,13 +255,13 @@ fn resolve_one( filtering: &CursorFiltering<'_>, (name, original): (&str, &str), ) -> PyResult { - let entry = source_map.call_method1("get", (name,))?; + let entry = mapping_get(source_map, name)?; if entry.is_none() { return Ok(original.to_owned()); } let adapter = adapter.clone(); let mut relation = render_source_read_relation(&adapter, &entry)?; - let columns = warehouse_columns.call_method1("get", (name,))?; + let columns = mapping_get(warehouse_columns, name)?; let expression = !native_field(&entry, "expression")?.is_none(); if columns.is_truthy()? && (!expression diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs index adba771ab2..2294eea2c1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs @@ -4,6 +4,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, use crate::bindings::_helpers::cursor::scalars::sentinel_to_token; use crate::bindings::_helpers::planner_resolution::models::CursorFiltering; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::PyString; use sqlbuild_sqltext::resolution::main::cursor_subquery::cursor_subquery; @@ -31,10 +32,7 @@ pub(super) fn cursor_wrap( if bounds.is_none() { return Ok(relation); } - let column: Option = filtering - .filter_inputs - .call_method1("get", (name,))? - .extract()?; + let column: Option = mapping_get(&filtering.filter_inputs, name)?.extract()?; let Some(column) = column else { return Ok(relation); }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs index e9c6175598..0507666d9d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs @@ -9,6 +9,7 @@ use crate::bindings::_helpers::planner_scenario::{ }; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python, pyfunction}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; @@ -82,7 +83,7 @@ pub(super) fn fixture_plans<'py>( )?); }; if kind != super::constants::DBT_REF && !overrides.is_none() { - sql = overrides.call_method1("get", ((resource, &name), sql))?; + sql = mapping_get_or(overrides, (resource, &name), sql)?; } let sql = resolve_sql(context, &sql.extract::()?, true)?; let sql = if helpers.is_empty() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs index ee1b1115ea..333ab54185 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs @@ -10,6 +10,7 @@ use crate::bindings::_helpers::planner_scenario::{ values::{error, string}, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::references::source_relations::render_source_relation; use crate::bindings::_helpers::sqltext::lexical_syntax::LexicalSyntaxInput; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python, pyfunction}; @@ -45,7 +46,7 @@ pub(super) fn resolve_sql( } let locations = context.relations.getattr(field)?; result = replace_markers(&result, kind, Some(syntax.clone().into()), |name, marker| { - let target = locations.call_method1("get", (name,))?; + let target = mapping_get(&locations, name)?; let target = if target.is_none() {target} else if kind == super::constants::SOURCE_MARKER { object(py, render_source_relation(&target, Some(&context.adapter.clone()).filter(|value| !value.is_none()))?)? } else {native_field(&target, "qualified_name")?}; @@ -70,7 +71,7 @@ pub(super) fn resolve_sql( pub(super) fn resolve_model_dbt_refs(sql: &str, relations: &Bound<'_, PyAny>) -> PyResult { let locations = native_field(relations, "dbt_ref_fixture_locations")?; replace_markers(sql, 3, None, |name, marker| { - let target = locations.call_method1("get", (name,))?; + let target = mapping_get(&locations, name)?; let qualified = if target.is_none() { target } else { @@ -105,7 +106,7 @@ pub(super) fn required_target<'py>( name: &str, kind: &str, ) -> PyResult> { - let target = native_field(relations, field)?.call_method1("get", (name,))?; + let target = mapping_get(&native_field(relations, field)?, name)?; if target.is_none() { return Err(error( relations.py(), diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs index 33b174bb4b..0f72547a56 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs @@ -23,6 +23,7 @@ use crate::bindings::_helpers::planner_strategy::constants::{ }; use crate::bindings::_helpers::planner_strategy::models::AuditPlanning; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; /// Render and validate one audit query with the supplied adapter callbacks. @@ -118,9 +119,7 @@ fn plan_audit<'py>( let target = attachment.get_item(1)?; let kind_text: String = kind.extract()?; let materialization = if kind_text == MODEL_ATTACHMENT && !target.is_none() { - request - .model_materializations - .call_method1("get", (&target,))? + mapping_get(&request.model_materializations, &target)? } else { py.None().into_bound(py) }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs index f737702e6f..3254196d1b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs @@ -22,6 +22,7 @@ use crate::bindings::_helpers::planner_strategy::models::CursorInputLookups; use crate::bindings::_helpers::planner_strategy::values::{input_error, text}; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::references::source_relations::render_source_relation; @@ -128,11 +129,9 @@ pub(crate) fn reject_unexposed_cursor_input_columns<'py>( known_columns, }; if kind == MODEL_REFERENCE { - let upstream: Bound<'py, PyAny> = models_by_name.call_method1("get", (&name,))?; + let upstream: Bound<'py, PyAny> = mapping_get(models_by_name, &name)?; if upstream.is_none() - || !model_values(&upstream)? - .call_method1("get", ("contract",))? - .eq(ENFORCED_CONTRACT)? + || !mapping_get(&model_values(&upstream)?, "contract")?.eq(ENFORCED_CONTRACT)? { continue; } @@ -148,13 +147,13 @@ pub(crate) fn reject_unexposed_cursor_input_columns<'py>( if kind != SOURCE_REFERENCE { continue; } - let source: Bound<'py, PyAny> = source_map.call_method1("get", (&name,))?; + let source: Bound<'py, PyAny> = mapping_get(source_map, &name)?; if !source.is_none() && native_field(&source, "contract")?.eq(ENFORCED_CONTRACT)? { let declared: Vec = names(&native_field(&source, "columns")?)?; check_column(check(CursorInputColumnOwner::SourceContract, declared), py)?; continue; } - let known: Bound<'py, PyAny> = warehouse_columns.call_method1("get", (&name,))?; + let known: Bound<'py, PyAny> = mapping_get(warehouse_columns, &name)?; if known.is_none() { continue; } @@ -175,16 +174,16 @@ fn input_relation<'py>( let py: Python<'py> = adapter.py(); let location: Bound<'py, PyAny> = match kind { MODEL_REFERENCE => { - let model: Bound<'py, PyAny> = lookups.model_locations.call_method1("get", (name,))?; + let model: Bound<'py, PyAny> = mapping_get(&lookups.model_locations, name)?; if model.is_none() { - lookups.seed_locations.call_method1("get", (name,))? + mapping_get(&lookups.seed_locations, name)? } else { model } } - SEED_REFERENCE => lookups.seed_locations.call_method1("get", (name,))?, + SEED_REFERENCE => mapping_get(&lookups.seed_locations, name)?, SOURCE_REFERENCE => { - let source: Bound<'py, PyAny> = lookups.source_map.call_method1("get", (name,))?; + let source: Bound<'py, PyAny> = mapping_get(&lookups.source_map, name)?; if source.is_none() { return Ok(None); } @@ -288,7 +287,7 @@ pub(crate) fn build_cursor_input_relations<'py>( continue; }; let producer: Option> = if kind == MODEL_REFERENCE { - Some(models_by_name.call_method1("get", (&name,))?).filter(|model| !model.is_none()) + Some(mapping_get(models_by_name, &name)?).filter(|model| !model.is_none()) } else { None }; @@ -346,7 +345,7 @@ pub(crate) fn runtime_cursor_producer_names<'py>( match text(&native_field(&key, "resource_type")?)?.as_str() { "model" | "seed" => names.push(name), "source" => { - let source: Bound<'py, PyAny> = source_map.call_method1("get", (&name,))?; + let source: Bound<'py, PyAny> = mapping_get(source_map, &name)?; if !source.is_none() && !native_field(&source, "loader")?.is_none() { names.push(name); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs index e6aad3b0ab..6d4752166b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs @@ -20,6 +20,7 @@ use crate::bindings::_helpers::planner_strategy::microbatches::{ }; use crate::bindings::_helpers::planner_strategy::values::{input_error, text}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::ErrorId; const MICROBATCH_MODE: &str = "microbatch"; @@ -35,7 +36,7 @@ fn mapped_references<'py>( mapping: &Bound<'py, PyAny>, name: &str, ) -> PyResult>>> { - let value: Bound<'py, PyAny> = mapping.call_method1("get", (name,))?; + let value: Bound<'py, PyAny> = mapping_get(mapping, name)?; if value.is_none() { return Ok(None); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatches.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatches.rs index 6f5a1455ed..eb708964a2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatches.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatches.rs @@ -25,6 +25,7 @@ use crate::bindings::_helpers::records::construct::{ enum_from_value, new_record_with, record_class, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; const INTEGER_CURSOR: &str = "integer"; @@ -266,7 +267,7 @@ pub(crate) fn microbatch_limit_config<'py>( values: &Bound<'py, PyAny>, ) -> PyResult<(MaybeValue<'py>, MaybeValue<'py>)> { let py: Python<'py> = values.py(); - let raw: Bound<'py, PyAny> = values.call_method1("get", ("microbatch_limit",))?; + let raw: Bound<'py, PyAny> = mapping_get(values, "microbatch_limit")?; if let Ok(raw) = raw.downcast::() { let max_batches: Option> = positive_integer(raw.get_item("max_batches")?)?; @@ -279,7 +280,7 @@ pub(crate) fn microbatch_limit_config<'py>( return Ok((Some(max_batches), Some(action))); } } - let legacy: Bound<'py, PyAny> = values.call_method1("get", ("max_microbatches",))?; + let legacy: Bound<'py, PyAny> = mapping_get(values, "max_microbatches")?; Ok((positive_integer(Some(legacy))?, None)) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs index c1013e8b9b..1b89faf1d9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs @@ -34,6 +34,7 @@ use crate::bindings::_helpers::planner_strategy::strategy::{ use crate::bindings::_helpers::planner_strategy::values::{input_error, optional_string, text}; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; /// Model config keys copied to the plan entry as optional strings, with their entry fields. @@ -121,7 +122,7 @@ fn schema_columns<'py>( /// A string or list-of-strings config value as a tuple of strings. fn string_list<'py>(values: &Bound<'py, PyAny>, key: &str) -> PyResult> { let py: Python<'py> = values.py(); - let raw: Bound<'py, PyAny> = values.call_method1("get", (key,))?; + let raw: Bound<'py, PyAny> = mapping_get(values, key)?; if raw.is_instance_of::() { return PyTuple::new(py, [raw]); } @@ -141,7 +142,7 @@ fn string_list<'py>(values: &Bound<'py, PyAny>, key: &str) -> PyResult(model: &Bound<'py, PyAny>) -> PyResult> { let py: Python<'py> = model.py(); - let raw: Bound<'py, PyAny> = model_values(model)?.call_method1("get", ("on_schema_change",))?; + let raw: Bound<'py, PyAny> = mapping_get(&model_values(model)?, "on_schema_change")?; if raw.is_none() { return Ok(raw); } @@ -290,22 +291,16 @@ fn custom_fields<'py>( let placeholders: Bound<'py, PyDict> = PyDict::new(py); let mut name: Bound<'py, PyAny> = none(py); if custom { - let raw_name: Bound<'py, PyAny> = values.call_method1("get", ("materialized",))?; + let raw_name: Bound<'py, PyAny> = mapping_get(values, "materialized")?; if raw_name.is_instance_of::() { name = raw_name; } - if let Ok(raw) = values - .call_method1("get", ("config",))? - .downcast::() - { + if let Ok(raw) = mapping_get(values, "config")?.downcast::() { for (key, value) in raw.iter() { config.set_item(key.str()?, value)?; } } - if let Ok(raw) = values - .call_method1("get", ("placeholders",))? - .downcast::() - { + if let Ok(raw) = mapping_get(values, "placeholders")?.downcast::() { for (key, value) in raw.iter() { placeholders.set_item(key.str()?, value.str()?)?; } @@ -443,9 +438,7 @@ fn contract_fields<'py>( entry.set_item("declared_columns", schema_columns(model, true)?)?; entry.set_item( "contract_enforced", - values - .call_method1("get", ("contract",))? - .eq(ENFORCED_CONTRACT)?, + mapping_get(values, "contract")?.eq(ENFORCED_CONTRACT)?, )?; entry.set_item("contract_columns", schema_columns(model, false)?)?; let schema_entry: Bound<'py, PyAny> = native_field(model, "schema_entry")?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs index 9f1cab5335..c5005d1172 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs @@ -8,6 +8,7 @@ use crate::bindings::_helpers::planner_phases::objects::{text, tuple}; use crate::bindings::_helpers::planner_warehouse::constants::ACTIVE_CATALOG; use crate::bindings::_helpers::planner_warehouse::snapshot::{columns_for, list_relations}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::pyfunction; use pyo3::types::PyDict as KeywordDict; @@ -208,7 +209,7 @@ pub(crate) fn semantic_source_columns<'py>( if columns.contains(&name)? { continue; } - let entry = source_read_map.call_method1("get", (&name,))?; + let entry = mapping_get(source_read_map, &name)?; if entry.is_none() || !native_field(&entry, "expression")?.is_none() || native_field(&entry, "contract")?.eq("enforced")? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs index 3563b6c80a..149c692a8f 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs @@ -15,6 +15,7 @@ use crate::bindings::_helpers::planner_warehouse::constants::{ }; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::pyfunction; use pyo3::types::PyDict as KeywordDict; @@ -54,7 +55,7 @@ fn hook_source_reads( let source_kind = host::entry(py, UserCodeHost::SqlResourceRefKind)?.getattr("SOURCE")?; let values = native_field(&native_field(model, "config")?, "values")?; for key in MODEL_HOOK_CONFIG_KEYS { - let value = values.call_method1("get", (key,))?; + let value = mapping_get(&values, key)?; let entries: Vec> = if value.is_instance_of::() || value.is_instance_of::() { value.try_iter()?.collect::>()? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs index bcaba41d37..1761c99d29 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs @@ -14,6 +14,7 @@ use crate::bindings::_helpers::planner_warehouse::constants::RUN_SCOPE; use crate::bindings::_helpers::planner_warehouse::snapshot::{destination_nodes, lower}; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::PyDict as KeywordDict; @@ -90,7 +91,7 @@ fn state_schemas( if schemas.is_empty() { let models = native_field(scope, "models_by_name")?; for name in model_key_names(&native_field(scope, "selected_keys")?)? { - let model = models.call_method1("get", (name,))?; + let model = mapping_get(&models, name)?; if model.is_none() { continue; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs index 864bbce797..b126d465d0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs @@ -9,6 +9,7 @@ use crate::bindings::_helpers::planner_warehouse::constants::{ MISSING_SOURCE_TABLE_CODE, RUN_BOUNDED, WILDCARD_TABLE_CHARACTER, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::references::source_relations::render_source_relation; use pyo3::IntoPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; @@ -30,10 +31,7 @@ fn selected_source_readers(scope: &Bound<'_, PyAny>) -> PyResult( continue; }; let declared = native_field(&source, "source_entry")?; - let entry = read_map.call_method1("get", (&name, &declared))?; + let entry = mapping_get_or(&read_map, &name, &declared)?; if !external_table(&declared)? || !external_table(&entry)? { continue; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs index d1607f2e4a..cbc12dd0e4 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs @@ -8,6 +8,7 @@ use crate::bindings::_helpers::planner_warehouse::constants::{ CURSOR_TYPE_INTEGER, CURSOR_TYPE_TIMESTAMP, WATERMARK_CONTRACT_CODE, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyErr, PyResult}; use pyo3::pyfunction; use pyo3::types::{PyDict, PyDictMethods}; @@ -92,7 +93,7 @@ pub(crate) fn validate_watermark_column<'py>( )); } let values = native_field(&native_field(&upstream, "config")?, "values")?; - if !values.call_method1("get", ("contract",))?.eq("enforced")? { + if !mapping_get(&values, "contract")?.eq("enforced")? { return Ok(()); } let schema = native_field(&upstream, "schema_entry")?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs index c75f0aa00b..ab1faee5ad 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs @@ -26,6 +26,7 @@ use crate::bindings::_helpers::project_assembly::models::{ }; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::ErrorId; use crate::bindings::types::CompilerDetach; @@ -135,7 +136,7 @@ fn environment_rows( environment_template_names(values) .into_iter() .map(|name| { - let value: Option = environment.call_method1("get", (&name,))?.extract()?; + let value: Option = mapping_get(&environment, &name)?.extract()?; Ok((name, value)) }) .collect() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs index d4cab8b10a..bbba79328d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs @@ -8,6 +8,7 @@ use pyo3::types::{PyDict, PyDictMethods, PySlice, PyTuple, PyTupleMethods}; use crate::bindings::_helpers::record_behaviours::call_arguments::call_argument; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::RecordId; /// `ColumnTransformKind` members by native transform code. @@ -50,7 +51,7 @@ fn resource_name<'py>( index: &Bound<'py, PyAny>, ) -> PyResult> { let names: Bound<'py, PyAny> = native_field(facts, "resource_names")?; - let name: Bound<'py, PyAny> = names.call_method1("get", (index,))?; + let name: Bound<'py, PyAny> = mapping_get(&names, index)?; if !name.is_none() { return Ok(name); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/python_nodes.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/python_nodes.rs index 27fbe35e3f..057ad3da23 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/python_nodes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/python_nodes.rs @@ -8,6 +8,8 @@ use sqlbuild_core::graph_walk::main::breadth_first_reach::breadth_first_reach; use crate::bindings::_helpers::graph::node_set::PyNodeSet; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; /// `PythonNodeGraph.selected_sql_refs(selected_names=...)`: SQL references of the selected closure. pub(crate) fn graph_selected_sql_refs( @@ -30,13 +32,12 @@ pub(crate) fn graph_selected_sql_refs( let starts: Vec> = selected.try_iter()?.collect::>()?; let mut visited: PyNodeSet<'_> = PyNodeSet(PySet::new(py, &starts)?); breadth_first_reach(starts, None, &mut visited, |name| { - upstream - .call_method1("get", (name, PyTuple::empty(py)))? + mapping_get_or(&upstream, name, PyTuple::empty(py))? .try_iter()? .collect::>>>() })?; for name in visited.0.iter() { - let node: Bound<'_, PyAny> = nodes_by_name.call_method1("get", (name,))?; + let node: Bound<'_, PyAny> = mapping_get(&nodes_by_name, name)?; if !node.is_none() { for reference in native_field(&node, "sql_deps")?.try_iter()? { refs.add(reference?)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs index f9b97a1544..0a9e6b5360 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs @@ -102,6 +102,32 @@ fn property_value( Ok(value) } +/// `mapping.get(key)`: a dict is read through the C API. +pub(crate) fn mapping_get<'py, K: pyo3::IntoPyObject<'py>>( + mapping: &Bound<'py, PyAny>, + key: K, +) -> PyResult> { + let py: Python<'py> = mapping.py(); + mapping_get_or(mapping, key, py.None()) +} + +/// `mapping.get(key, default)`: a dict is read through the C API. +pub(crate) fn mapping_get_or<'py, K: pyo3::IntoPyObject<'py>, D: pyo3::IntoPyObject<'py>>( + mapping: &Bound<'py, PyAny>, + key: K, + default: D, +) -> PyResult> { + let py: Python<'py> = mapping.py(); + let key: Bound<'py, PyAny> = key.into_bound_py_any(py)?; + if let Ok(dict) = mapping.cast_exact::() { + if let Some(found) = dict.get_item(&key)? { + return Ok(found); + } + return default.into_bound_py_any(py); + } + mapping.call_method1("get", (key, default.into_bound_py_any(py)?)) +} + /// `dataclasses.replace(value, **changes)`: a native record is rebuilt from its own values. pub(crate) fn replaced<'py>( value: &Bound<'py, PyAny>, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs b/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs index cb899e603c..54a12a4d12 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs @@ -12,6 +12,7 @@ use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::{enum_from_value, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::replaced; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::type_system::equality::types_equal as native_types_equal; @@ -501,7 +502,7 @@ pub(crate) fn compare_contracts<'py>( }; for (item, relation) in inspectable.iter().zip(&relations) { let columns: Bound<'py, PyAny> = - physical.call_method1("get", (native_field(relation, "identity")?,))?; + mapping_get(&physical, native_field(relation, "identity")?)?; evidence.push(compared(&vocabulary, (item, &columns), adapter)?); } PyTuple::new(py, evidence) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs index 0c0534206d..6db9dad189 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs @@ -14,6 +14,7 @@ use crate::bindings::_helpers::records::construct::{ enum_member, new_record, new_record_with, record_class, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::scopes::declaration_contexts::NativeDeclarationContexts; @@ -229,7 +230,7 @@ pub(crate) fn native_declaration_contexts<'py>( let identity: Bound<'py, PyAny> = identity?; let key: Bound<'py, PyAny> = identity_keys.call_method1("setdefault", (&identity, identity_keys.len()))?; - let value: Bound<'py, PyAny> = declarations.call_method1("get", (&identity,))?; + let value: Bound<'py, PyAny> = mapping_get(declarations, &identity)?; positions.push(PyTuple::new( py, [ diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs index 0ae4d7344b..d63a27e304 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs @@ -9,6 +9,7 @@ use sqlbuild_render::macro_calls::main::call_class_store_text::call_class_store_ use crate::bindings::_helpers::macro_bridge::store_keys::{context_store_token, macro_store_token}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::render::macro_expansion_facts::ResourceRef; /// `(kind, name, owner (kind, name))` of a `DeclarationIdentity`, compared by value. @@ -158,7 +159,7 @@ impl CallClassState { return Ok(found.clone()); } let py: Python<'_> = owner.py(); - let loaded: Bound<'_, PyAny> = macros.call_method1("get", (name,))?; + let loaded: Bound<'_, PyAny> = mapping_get(macros, name)?; let declarations: &Bound<'_, PyAny> = inputs.declarations; let visible: bool = !loaded.is_none() && (declarations.is_none() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs index 24ebb20da0..89df63c989 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs @@ -6,6 +6,7 @@ use pyo3::types::{PyDict, PyDictMethods, PyList}; use crate::bindings::_helpers::plan_output::safety::{future_cursor_safety, maximum_start_safety}; use crate::bindings::_helpers::plan_output::values::{any, dict, items, optional_enum_value}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::result_output::projection::{Projection, rounded}; const FAILED_STATUS: &str = "failed"; @@ -60,7 +61,7 @@ fn target<'py>( name: &Bound<'py, PyAny>, ) -> PyResult> { match targets { - Some(targets) => targets.call_method1("get", (name,)), + Some(targets) => mapping_get(targets, name), None => Ok(py.None().into_bound(py)), } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_records.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_records.rs index bda92085b5..45a7acab30 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_records.rs @@ -11,6 +11,7 @@ use sqlbuild_core::json::models::{JsonInteger, JsonValue}; use crate::bindings::_helpers::plan_output::safety::{future_cursor_safety, maximum_start_safety}; use crate::bindings::_helpers::plan_output::values::items; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::result_output::checks::{ audit_passed, measurement_evidence, measurement_thresholds, python_check_status, }; @@ -354,7 +355,7 @@ fn duration(value: &Bound<'_, PyAny>) -> PyResult { /// The envelope fields every record copies from its terminal, in record order. fn terminal_fields(terminal: &Bound<'_, PyAny>, event_sequence: usize) -> PyResult { let payload: Bound<'_, PyAny> = native_field(terminal, "payload")?; - let get = |key: &str| payload.call_method1("get", (key,)); + let get = |key: &str| mapping_get(&payload, key); let attribute = |key: &str| -> PyResult { Ok(required_json(&native_field(terminal, key)?)?.unwrap_or(JsonValue::Null)) }; @@ -404,10 +405,7 @@ fn failure_fields(terminal: &Bound<'_, PyAny>) -> PyResult { let payload: Bound<'_, PyAny> = native_field(terminal, "payload")?; let mut fields: Entries = Vec::new(); for key in ["error_code", "error_type", "skip_code", "skip_mode"] { - fields.push(( - key.to_owned(), - optional_text(&payload.call_method1("get", (key,))?)?, - )); + fields.push((key.to_owned(), optional_text(&mapping_get(&payload, key)?)?)); } Ok(fields) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs index e8efe3bb2e..0b62c7f703 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs @@ -12,6 +12,7 @@ use sqlbuild_core::terminal_events::main::claim_resource_terminal::claim_resourc use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::NativeAttr; use crate::bindings::_helpers::records::registry; use sqlbuild_core::terminal_events::main::consume_terminal_fact::consume_terminal_fact; @@ -50,7 +51,7 @@ pub(crate) struct TerminalEventClaim { /// `payload.get(key)` when it is a string. fn payload_text(payload: &Bound<'_, PyAny>, key: &str) -> PyResult> { - let value: Bound<'_, PyAny> = payload.call_method1("get", (key,))?; + let value: Bound<'_, PyAny> = mapping_get(payload, key)?; if value.is_instance_of::() { return Ok(Some(value.extract()?)); } @@ -59,7 +60,7 @@ fn payload_text(payload: &Bound<'_, PyAny>, key: &str) -> PyResult) -> PyResult> { - let value: Bound<'_, PyAny> = payload.call_method1("get", ("attempt_number",))?; + let value: Bound<'_, PyAny> = mapping_get(payload, "attempt_number")?; if !value.is_instance_of::() { return Ok(None); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs index 061a2f62ce..9e31779378 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs @@ -21,6 +21,7 @@ use sqlbuild_rules::rule_catalogue::models::{FingerprintRule, OptionText, RuleTe use crate::bindings::_helpers::boundary::panics::compiler_guard; use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::records::fields::field as record_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::rules::catalogue::{ native_rules_config, references_custom_rules, rule_catalogue, select_rules, verify_custom_rules, }; @@ -60,7 +61,7 @@ fn rule_text(rule: &Bound<'_, PyAny>, config: Option<&Bound<'_, PyAny>>) -> PyRe let name: String = text_field(&option, "name")?; let default: Bound<'_, PyAny> = record_field(&option, "default")?; let effective: Bound<'_, PyAny> = match &configured { - Some(values) => values.call_method1("get", (&name, &default))?, + Some(values) => mapping_get_or(values, &name, &default)?, None => default.clone(), }; options.push(OptionText { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_sql_bodies.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_sql_bodies.rs index c2cdc90f4d..1ee6aae410 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_sql_bodies.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/lint_sql_bodies.rs @@ -10,6 +10,7 @@ use sqlbuild_rules::lint_text::models::{ use crate::bindings::_helpers::boundary::panics::value_error; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::rules::lint_pipeline::{LintViolationRow, ViolationClasses}; use crate::bindings::types::CompilerDetach; @@ -39,7 +40,7 @@ fn relation_keys( let mut keys: Vec<(String, Vec>)> = Vec::new(); for relation in native_field(body, "dependency_relations")?.try_iter()? { let (sentinel, name): (String, Bound<'_, PyAny>) = relation?.extract()?; - let found: Bound<'_, PyAny> = declared.call_method1("get", (name,))?; + let found: Bound<'_, PyAny> = mapping_get(declared, name)?; if found.is_truthy()? { keys.push((sentinel, found.extract()?)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs index f3bece1aa5..c0486717ea 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs @@ -18,6 +18,8 @@ use crate::bindings::_helpers::analysis::model_reads::binding_validated; use crate::bindings::_helpers::boundary::panics::compiler_error; use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::semantic_checks::failures::semantic_error; use crate::bindings::_helpers::semantic_checks::inputs::{ column_names, resource_sql_diagnostics, sql_test_columns, @@ -413,19 +415,19 @@ fn text(value: &Bound<'_, PyAny>) -> PyResult> { fn metadata_model(classes: &StageClasses<'_>, model: &Bound<'_, PyAny>) -> PyResult { let values: Bound<'_, PyAny> = native_field(&native_field(model, "config")?, "values")?; - let get = |key: &str| values.call_method1("get", (key,)); + let get = |key: &str| mapping_get(&values, key); let mut references: Vec = Vec::new(); for key in METADATA_CONFIG_KEYS { references.push((key.to_owned(), column_names(&get(key)?)?)); } let custom: Bound<'_, PyAny> = get("config")?; if custom.is_instance_of::() { - let partition: Bound<'_, PyAny> = custom.call_method1("get", ("partition_column",))?; + let partition: Bound<'_, PyAny> = mapping_get(&custom, "partition_column")?; references.push(("partition_column".to_owned(), column_names(&partition)?)); } let tolerances: Bound<'_, PyAny> = get("row_diff_tolerances")?; if tolerances.is_instance_of::() { - let by_column: Bound<'_, PyAny> = tolerances.call_method1("get", ("by_column",))?; + let by_column: Bound<'_, PyAny> = mapping_get(&tolerances, "by_column")?; if by_column.is_instance_of::() { let names: Vec = by_column .try_iter()? @@ -505,7 +507,7 @@ fn metadata_audits(model: &Bound<'_, PyAny>) -> PyResult> { let mut audits: Vec = Vec::with_capacity(attached.len()); for (column, audit) in attached { let arguments: Bound<'_, PyAny> = native_field(&audit, "arguments")?; - let values: Bound<'_, PyAny> = arguments.call_method1("get", ("values",))?; + let values: Bound<'_, PyAny> = mapping_get(&arguments, "values")?; let values: Option> = if values.is_instance_of::() || values.is_instance_of::() { Some( @@ -520,13 +522,9 @@ fn metadata_audits(model: &Bound<'_, PyAny>) -> PyResult> { audits.push(MetadataAudit { column, definition: native_field(&audit, "definition_name")?.extract()?, - expression: text(&arguments.call_method1("get", ("expression",))?)?, - target: arguments - .call_method1("get", ("to", &empty))? - .str()? - .extract()?, - field: arguments - .call_method1("get", ("field", &empty))? + expression: text(&mapping_get(&arguments, "expression")?)?, + target: mapping_get_or(&arguments, "to", &empty)?.str()?.extract()?, + field: mapping_get_or(&arguments, "field", &empty)? .str()? .extract()?, values, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs index 59cb6f0514..049de01349 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::compiled_project::model_loop_host::ReferenceRow; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::models::ProjectCatalog; use crate::bindings::types::CompilerDetach; @@ -196,7 +197,7 @@ fn model_input( let values: Bound<'_, PyAny> = native_field(&native_field(model, "config")?, "values")?; let mut hooks: Vec = Vec::new(); for key in MODEL_HOOK_KEYS { - let entries: Bound<'_, PyAny> = values.call_method1("get", (key,))?; + let entries: Bound<'_, PyAny> = mapping_get(&values, key)?; if !(entries.is_instance_of::() || entries.is_instance_of::()) { continue; } @@ -253,9 +254,7 @@ fn optional_attribute<'py>(value: &Bound<'py, PyAny>, name: &str) -> PyResult) -> PyResult { - Ok(values - .call_method1("get", (SQL_ANALYSIS_CONFIG_KEY,))? - .is(PyBool::new(values.py(), false))) + Ok(mapping_get(values, SQL_ANALYSIS_CONFIG_KEY)?.is(PyBool::new(values.py(), false))) } /// `sorted(binding_relation_names(...))` of a native view's reference rows. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs index 2e99060e06..686d211f32 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs @@ -20,6 +20,7 @@ use crate::bindings::_helpers::compile_driver::stage_work::count_stage; use crate::bindings::_helpers::compiled_project::compiled_model_view::LineageInput; use crate::bindings::_helpers::compiled_project::records::with_type_recovery; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::semantic_checks::constants::SCHEMA_REVALIDATIONS; use crate::bindings::_helpers::semantic_checks::failures::{internal_error, semantic_error}; use crate::bindings::_helpers::semantic_checks::inputs::revalidation_request; @@ -207,7 +208,7 @@ fn recovery_model( let mut raw_bindings: Vec = Vec::new(); if !bindings.is_empty() { let raws: Bound<'_, PyAny> = - binding_results.call_method1("get", (&name, PyList::empty(model.py())))?; + mapping_get_or(binding_results, &name, PyList::empty(model.py()))?; for raw in raws.try_iter()? { let raw: Bound<'_, PyAny> = raw?; raw_bindings.push(RawBinding { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs index 0e45d20bc2..08bd61504e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs @@ -18,6 +18,7 @@ use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::RecordId; @@ -81,15 +82,12 @@ pub(crate) fn published_shape<'py>( let shape: Bound<'py, PyDict> = binding_shape(model, columns, inputs, profile)?; let values: Bound<'py, PyAny> = native_field(&native_field(model, "config")?, "values")?; let snapshot: Bound<'py, PyAny> = enum_member(py, RecordId::MaterializationType, "SNAPSHOT")?; - if values - .call_method1("get", ("materialized",))? - .eq(snapshot)? - { + if mapping_get(&values, "materialized")?.eq(snapshot)? { for (key, default) in [ ("valid_from_column", VALID_FROM_DEFAULT), ("valid_to_column", VALID_TO_DEFAULT), ] { - let name: Bound<'py, PyAny> = values.call_method1("get", (key,))?; + let name: Bound<'py, PyAny> = mapping_get(&values, key)?; let name: Bound<'py, PyAny> = if name.is_truthy()? { name } else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs index 4f71a89e3b..5aab83bc8d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs @@ -18,6 +18,8 @@ use crate::bindings::_helpers::planner_strategy::models::RelationFixturePlanning use crate::bindings::_helpers::planner_strategy::types::FixtureKey; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::sql_test_glue::constants::FIXTURE_PREFIXES; @@ -112,8 +114,7 @@ pub(super) fn validated_fixtures<'py>( } } else { let key = PyTuple::new(py, [kind, &key_name])?; - Some(inferred_by_fixture.call_method1("get", (key,))?) - .filter(|value| !value.is_none()) + Some(mapping_get(inferred_by_fixture, key)?).filter(|value| !value.is_none()) }; let Some(columns) = inferred else { continue; @@ -167,7 +168,7 @@ pub(super) fn validated_fixtures<'py>( let result = PyDict::new(py); for (name, sql) in fixtures.iter() { let key = PyTuple::new(py, [kind.clone(), name.clone()])?; - result.set_item(&name, fixture_sql.call_method1("get", (key, sql))?)?; + result.set_item(&name, mapping_get_or(fixture_sql, key, sql)?)?; } Ok(result) }; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_fixtures.rs b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_fixtures.rs index 8506fa10b6..f9a9d3830a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_fixtures.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_fixtures.rs @@ -5,6 +5,7 @@ use pyo3::types::{PyDict, PyDictMethods, PyTuple}; use crate::bindings::_helpers::planner_strategy::models::RelationFixturePlanningContext; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_get_or; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::sql_test_glue::authored_ctes::prefixed_ctes; use crate::bindings::_helpers::sql_test_glue::fixture_validation::validated_fixtures; @@ -45,8 +46,7 @@ pub(super) fn validated_test<'py>( let mut replacement = cte.clone(); for (index, prefix) in ["__ref__", "__source__", "__seed__"].iter().enumerate() { if let Some(name) = name.strip_prefix(prefix) { - let sql = completed[index] - .call_method1("get", (name, native_field(&cte, "sql_body")?))?; + let sql = mapping_get_or(&completed[index], name, native_field(&cte, "sql_body")?)?; let kwargs = PyDict::new(py); kwargs.set_item("sql_body", sql)?; replacement = replaced_keywords(&cte, &kwargs)?; @@ -63,7 +63,7 @@ pub(super) fn validated_test<'py>( let kwargs = PyDict::new(py); kwargs.set_item( "sql_body", - completed[3].call_method1("get", (name, native_field(&cte, "sql_body")?))?, + mapping_get_or(&completed[3], name, native_field(&cte, "sql_body")?)?, )?; expected_ctes.push(replaced_keywords(&cte, &kwargs)?); } diff --git a/fensu.toml b/fensu.toml index 606852124e..4a6252b06d 100644 --- a/fensu.toml +++ b/fensu.toml @@ -492,23 +492,22 @@ edge_paths = [ "crates/sqlbuild-python/src/bindings/_helpers/records/registry.rs", ] pending_budgets = [ - "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=20", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/nullability_rules.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/outcome_objects.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/attachments/reference_markers.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs=25", "crates/sqlbuild-python/src/bindings/_helpers/auditing/identity.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/auditing/measurement.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/auditing/render.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/auditing/schema_audits.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/authored_values/fields.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/authored_values/project_vars.rs=4", @@ -516,8 +515,8 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/boundary/config_values.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/build_command/command.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/build_command/completion.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs=21", - "crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/defer_clone.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/build_command/invocation.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs=22", "crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs=8", @@ -533,7 +532,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cache/native_store.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs=21", - "crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cli/argv.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs=19", @@ -541,7 +540,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cli/launch_state.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs=26", - "crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/cli/surrogates.rs=2", @@ -554,8 +553,8 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/invocation.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/runtime_errors.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouse_scope.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs=4", @@ -564,20 +563,20 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs=43", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs=32", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs=30", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs=48", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs=41", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/runtime_identity.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/startup_inputs.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/surrogates.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=27", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=26", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs=20", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_sql_tests.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs=24", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/compile_timings.rs=2", @@ -594,10 +593,10 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/artifacts.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/reuse.rs=1", @@ -639,17 +638,17 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compute_logs/conversion.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compute_logs/storage.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs=18", - "crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/contract_command/write.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/contracts/contract_diagnostics.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/contracts/effective_config.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/contracts/project_config.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/contracts/resource_identities.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/contracts/spec_resolution.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/contracts/sql_values.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/contracts/state_literals.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/bounds.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/command.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refresh.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/refusal.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/cost_command/sorting.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/cost_report/degradation.rs=13", @@ -659,7 +658,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/allocation.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/context.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/health.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs=14", + "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/ledger.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/snowflake.rs=22", "crates/sqlbuild-python/src/bindings/_helpers/cost_telemetry/values.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/cursor/conversion.rs=6", @@ -669,12 +668,10 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cursor/scalars.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cursor/values.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/artifact.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/projection.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs=12", - "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/access.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/translator.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs=6", @@ -682,7 +679,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init_project.rs=27", "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/support.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs=2", @@ -692,7 +689,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs=19", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_phases.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline_prologue.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/profile_coercion.rs=2", @@ -711,17 +708,17 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs=21", + "crates/sqlbuild-python/src/bindings/_helpers/diff_report/query.rs=19", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/registration.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/tolerances.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/declaration_records.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/discovery/faults.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/discovery/header_declarations.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/discovery/header_values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/discovery/hook_entries.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_providers.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_providers.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_python_nodes.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/discovery/locations.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/discovery/model_file_record.rs=1", @@ -741,7 +738,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/dispatcher.rs=27", "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/models.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/registration.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs=18", + "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/values.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/event_exporting/workers.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/execution_history/conversion.rs=19", @@ -759,9 +756,9 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/format_command/run.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/format_command/selection.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_command.rs=17", - "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/freshness/state_io.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/freshness/support.rs=2", @@ -769,15 +766,15 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/frontier/python_types.rs=29", "crates/sqlbuild-python/src/bindings/_helpers/frontier/stage_capture.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/graph/keys.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/init_command/scaffold.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_classification.rs=2", @@ -791,13 +788,13 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/validation.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_cache.rs=28", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs=13", - "crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/load/ingestr_command.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs=19", @@ -805,26 +802,26 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs=28", "crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/projection.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/model_config/authored_nodes.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_templates.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_values.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/model_config/described_models.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/model_config/errors.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/header_columns.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/header_metadata.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/model_config_builder.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/model_config/model_validator.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/template_data.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/model_config/unicode_environment.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/native_threads/exit_signal.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/output_capture/context.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/output_capture/dispatcher.rs=33", - "crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/plan_command/rules.rs=10", @@ -832,47 +829,45 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/plan_output/display.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_json.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/plan_output/python_identity.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/actions.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/metadata.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/execution_plan.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/models.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/json_values.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_candidates.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_objects.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_warnings.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/columns.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/compatibility.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_events.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/fingerprint.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_handover.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_overlay.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_warnings.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_entries.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_objects.rs=4", @@ -882,70 +877,66 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_execution.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/full_refresh.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/models.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/warehouse_state.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_records/constants.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_bounds.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_model.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_overrides.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_policies.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_ranges.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_safety.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/cursor_windows.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/refs.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/orchestration.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/sources.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/artifacts.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/cli.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/entries.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/execution.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/fixtures.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/sources.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/unit_tests.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audits.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_types.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_metadata.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_preparation.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_reads.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_sql.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_values.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/lineage.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatch_limits.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatches.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/models.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs=15", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_columns.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/watermarks.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/document.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/functions.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/style.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/terminal.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/declared_relations.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/models.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_checks.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/python_values/values.rs=5", @@ -959,17 +950,16 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/durations.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lexical.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/lineage_facts.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/macros.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/migrations.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/python_nodes.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/records/error_classes.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/records/models.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/records/registration.rs=26", - "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_edits.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/refactor/python_strings.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs=25", @@ -980,25 +970,25 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_expansion.rs=24", "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_arguments.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_memo.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_evaluation.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/result_output/aggregation.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/result_output/checks.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/result_output/event_writer.rs=20", "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_records.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_records.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/result_output/projection.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/result_output/resource_ids.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/rules/builtin_catalogue.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/rules/catalogue.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs=5", @@ -1013,13 +1003,12 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_session.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/rules/fix_verdict.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/rules/fixture_formatting.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/rules/guidance.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_expansion.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_headers.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_inputs.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_pipeline.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_preparation.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/rules/lint_sql_bodies.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/native_header_parser.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/rules/project_tree_queries.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/rules/results.rs=1", @@ -1056,23 +1045,22 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_visibility.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/completion.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/declarations.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/compiled_tests.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/constants.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_errors.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_fixtures.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_rendering.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_values.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/planning.rs=1", From c6c4537d99627872e5414b543223d5c9566d4901 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 07:32:03 +0100 Subject: [PATCH 08/19] refactor: cache stable stdlib lookups, iterate dicts natively and read macro-generated and getattr views directly --- .../_helpers/analysis/binding_catalog.rs | 8 +- .../_helpers/analysis/explicit_references.rs | 3 +- .../analysis_session/model_analyses.rs | 5 +- .../analysis_session/profile_inputs.rs | 8 +- .../analysis_session/stage_functions.rs | 6 +- .../src/bindings/_helpers/check/check_core.rs | 3 +- .../src/bindings/_helpers/cli/namespace.rs | 5 +- .../src/bindings/_helpers/cli/progress.rs | 3 +- .../_helpers/clone/clone_execution.rs | 3 +- .../compile_attachment/declaration_scope.rs | 3 +- .../compile_driver/assembly_analysis.rs | 3 +- .../_helpers/compile_driver/deferral.rs | 3 +- .../bindings/_helpers/compile_driver/diff.rs | 3 +- .../_helpers/compile_driver/python_calls.rs | 46 ++- .../compile_driver/selection_phases.rs | 4 +- .../_helpers/compile_driver/targets.rs | 3 +- .../_helpers/compiled_project/loop_classes.rs | 5 +- .../_helpers/dagster_invocation/results.rs | 5 +- .../_helpers/dbt_interop/execution.rs | 3 +- .../bindings/_helpers/dbt_interop/graph.rs | 3 +- .../_helpers/diagnostics/log_records.rs | 5 +- .../_helpers/diagnostics/redaction.rs | 3 +- .../_helpers/fingerprints/latest_rows.rs | 4 +- .../_helpers/freshness/publication.rs | 3 +- .../src/bindings/_helpers/frontier/encoder.rs | 7 +- .../src/bindings/_helpers/graph/algorithms.rs | 3 +- .../_helpers/graph/python_selection.rs | 3 +- .../src/bindings/_helpers/graph/views.rs | 9 +- .../_helpers/janitor/janitor_planning.rs | 3 +- .../_helpers/lifecycle_events/envelopes.rs | 3 +- .../_helpers/lifecycle_events/payloads.rs | 6 +- .../_helpers/lineage/column_lineage_graph.rs | 3 +- .../_helpers/lineage/lineage_index.rs | 3 +- .../_helpers/macro_bridge/module_digests.rs | 3 +- .../_helpers/macro_bridge/store_keys.rs | 3 +- .../_helpers/microbatches/statements.rs | 3 +- .../_helpers/output_capture/values.rs | 5 +- .../_helpers/planner_changes/detect.rs | 3 +- .../_helpers/planner_changes/renames.rs | 3 +- .../_helpers/planner_entries/relations.rs | 4 +- .../_helpers/planner_identity/graph.rs | 5 +- .../_helpers/planner_identity/identities.rs | 8 +- .../_helpers/planner_identity/metadata.rs | 3 +- .../_helpers/planner_identity/staleness.rs | 7 +- .../planner_migrations/discovery_models.rs | 3 +- .../planner_migrations/projections.rs | 3 +- .../planner_phases/output_assembly.rs | 3 +- .../bindings/_helpers/planner_scope/scope.rs | 4 +- .../bindings/_helpers/planner_scope/values.rs | 4 +- .../planner_strategy/cursor_inputs.rs | 8 +- .../_helpers/planner_warehouse/cursors.rs | 11 +- .../_helpers/planner_warehouse/snapshot.rs | 9 +- .../project_assembly/native_resources.rs | 6 +- .../_helpers/record_behaviours/values.rs | 3 +- .../src/bindings/_helpers/records/fields.rs | 24 +- .../src/bindings/_helpers/records/getters.rs | 371 +++++++++++++++++- .../_helpers/refactor/refactor_command.rs | 3 +- .../bindings/_helpers/references/relations.rs | 3 +- .../_helpers/render/declaration_values.rs | 6 +- .../bindings/_helpers/result_output/assets.rs | 6 +- .../result_output/integration_envelope.rs | 6 +- .../_helpers/scopes/compile_usages.rs | 3 +- .../bindings/_helpers/scopes/scope_index.rs | 3 +- .../_helpers/semantic_checks/metadata.rs | 8 +- .../_helpers/semantic_checks/resource_sql.rs | 3 +- .../_helpers/semantic_checks/type_recovery.rs | 6 +- .../_helpers/semantic_shapes/declarations.rs | 5 +- .../semantic_shapes/source_bindings.rs | 8 +- fensu.toml | 120 +++--- 69 files changed, 666 insertions(+), 190 deletions(-) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs index 2c1d7d91c5..fdec5fed18 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs @@ -15,6 +15,8 @@ use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_get_or; +use crate::bindings::_helpers::records::fields::mapping_items; +use crate::bindings::_helpers::records::fields::mapping_values; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::models::{CatalogInput, ProjectCatalog}; use crate::bindings::types::CompilerDetach; @@ -92,7 +94,7 @@ impl BindingCatalog { let additions: Bound<'_, PyDict> = PyDict::new(py); for request in requests { let schema: Bound<'_, PyAny> = native_field(request, "schema")?; - for item in schema.call_method0("items")?.try_iter()? { + for item in mapping_items(&schema)?.try_iter()? { let (name, columns): (Bound<'_, PyAny>, Bound<'_, PyAny>) = item?.extract()?; if columns.is_truthy()? && !schemas.contains(&name)? { additions.set_item(&name, &columns)?; @@ -166,7 +168,7 @@ impl BindingCatalog { ) -> PyResult<()> { let shapes: &Bound<'_, PyDict> = self.analysis_shapes.bind(py); let updates: Bound<'_, PyDict> = PyDict::new(py); - for item in nullability.call_method0("items")?.try_iter()? { + for item in mapping_items(nullability)?.try_iter()? { let (name, columns): (Bound<'_, PyAny>, Bound<'_, PyAny>) = item?.extract()?; let typed: Bound<'_, PyAny> = mapping_get_or(types, &name, PyDict::new(py))?; let shape: Bound<'_, PyTuple> = PyTuple::new(py, [typed, columns])?; @@ -223,7 +225,7 @@ impl BindingCatalog { return Ok(columns.clone()); } let mut exact_input: bool = false; - for shape in inputs.call_method0("values")?.try_iter()? { + for shape in mapping_values(inputs)?.try_iter()? { for name in shape?.try_iter()? { let name: String = name?.extract()?; exact_input |= name.contains(QUOTED_IDENTIFIER_DELIMITER); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs index 3dc00e2171..47c47892ed 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs @@ -32,6 +32,7 @@ use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::types::CompilerDetach; @@ -403,7 +404,7 @@ pub(crate) fn hard_coded_relation_remedy( ); let mut upstream_loaders: Vec<(String, String)> = Vec::new(); if let Some(loaders) = upstream_loader_by_source.filter(|loaders| !loaders.is_none()) { - for item in loaders.call_method0("items")?.try_iter()? { + for item in mapping_items(loaders)?.try_iter()? { upstream_loaders.push(item?.extract()?); } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs index a1a6677d81..04d020dd94 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs @@ -25,6 +25,7 @@ use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::semantic_shapes::shapes::{VALID_FROM_DEFAULT, VALID_TO_DEFAULT}; @@ -96,7 +97,7 @@ fn session_request<'py>( let py: Python<'py> = catalog.py(); let profile: &Bound<'py, PyAny> = &request.profile; let mut families: Vec<(String, Vec<_>)> = Vec::new(); - for item in request.dynamic_families.call_method0("items")?.try_iter()? { + for item in mapping_items(&request.dynamic_families)?.try_iter()? { let (name, declared): (String, Bound<'py, PyAny>) = item?.extract()?; families.push((name, family_rows(&declared)?)); } @@ -270,7 +271,7 @@ fn model_rows<'py>( let mut placeholders: Vec<(String, String)> = Vec::new(); let raw: Bound<'py, PyAny> = get("placeholders")?; if raw.is_instance_of::() { - for item in raw.call_method0("items")?.try_iter()? { + for item in mapping_items(&raw)?.try_iter()? { let (key, value): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; placeholders.push((key.str()?.extract()?, value.str()?.extract()?)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs index 4107fd024d..98391124cc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs @@ -11,6 +11,7 @@ use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; const GENERIC_DIALECT: &str = "generic"; @@ -61,10 +62,10 @@ pub(crate) fn nullability_rules(profile: &Bound<'_, PyAny>) -> PyResult<(Pairs, /// `{relation: {column: value}}` as ordered rows, each value as `str(value)`. pub(crate) fn shape_rows(shapes: &Bound<'_, PyAny>) -> PyResult { let mut rows: Shapes = Vec::new(); - for item in shapes.call_method0("items")?.try_iter()? { + for item in mapping_items(shapes)?.try_iter()? { let (name, shape): (String, Bound<'_, PyAny>) = item?.extract()?; let mut pairs: Pairs = Vec::new(); - for column in shape.call_method0("items")?.try_iter()? { + for column in mapping_items(&shape)?.try_iter()? { let (column, value): (String, Bound<'_, PyAny>) = column?.extract()?; pairs.push((column, value.str()?.extract()?)); } @@ -75,8 +76,7 @@ pub(crate) fn shape_rows(shapes: &Bound<'_, PyAny>) -> PyResult { /// A `{key: value}` text mapping's items in order. pub(crate) fn pairs(mapping: &Bound<'_, PyAny>) -> PyResult { - mapping - .call_method0("items")? + mapping_items(mapping)? .try_iter()? .map(|item| item?.extract()) .collect() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs index 4ded9cda1a..34104f8412 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs @@ -25,6 +25,7 @@ use crate::bindings::_helpers::compile_driver::stage_work::{ }; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::models::ProjectCatalog; @@ -216,7 +217,7 @@ pub(crate) fn dynamic_contract_proofs<'py>( let contracts: Vec = if session.is_none() { let by_table: Bound<'py, PyAny> = native_field(tables, "dynamic_families_by_table")?; let mut families: Vec<(String, Vec)> = Vec::new(); - for item in by_table.call_method0("items")?.try_iter()? { + for item in mapping_items(&by_table)?.try_iter()? { let (name, declared): (String, Bound<'py, PyAny>) = item?.extract()?; families.push((name, family_rows(&declared)?)); } @@ -325,8 +326,7 @@ pub(crate) fn query_column_rows( fn query_row(query: &Bound<'_, PyAny>) -> PyResult { let placeholders: Bound<'_, PyAny> = native_field(query, "placeholders")?; let placeholders: Pairs = if placeholders.is_truthy()? { - placeholders - .call_method0("items")? + mapping_items(&placeholders)? .try_iter()? .map(|item| item?.extract()) .collect::>()? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs b/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs index 2af4c98083..aa6932e110 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs @@ -22,6 +22,7 @@ use crate::bindings::_helpers::native_host::user_code::UserCodeHost; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_get_or; +use crate::bindings::_helpers::records::fields::mapping_items; const MISSING_RELATION_CODE: &str = "C682"; const MODEL_KIND: &str = "model"; @@ -89,7 +90,7 @@ pub(crate) fn load_results_by_loader_name<'py>( ) -> PyResult> { let py: Python<'py> = source_map.py(); let loader_by_source: Bound<'py, PyDict> = PyDict::new(py); - for item in source_map.call_method0("items")?.try_iter()? { + for item in mapping_items(source_map)?.try_iter()? { let (name, source): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; let loader: Bound<'py, PyAny> = native_field(&source, "loader")?; if !loader.is_none() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs index ef49a74deb..0434da163e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs @@ -46,7 +46,10 @@ impl CliNamespace { } /// A default not yet stored on this namespace, stored on first read. - fn __getattr__<'py>(slf: &Bound<'py, Self>, name: &str) -> PyResult> { + pub(crate) fn __getattr__<'py>( + slf: &Bound<'py, Self>, + name: &str, + ) -> PyResult> { let py: Python<'py> = slf.py(); let Some((_, default)) = cli_namespace_defaults() .iter() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs b/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs index a1b89dd647..e7d1df94fb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs @@ -22,6 +22,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_get_or; +use crate::bindings::_helpers::records::fields::mapping_items; /// The module attribute holding the `ContextVar` of the installed projector. const CONTEXT_ATTRIBUTE: &str = "_native_progress_projector_context"; @@ -253,7 +254,7 @@ impl NativeProgressProjector { #[pyo3(signature = (*, ordinals, total))] fn configure_resources(&self, ordinals: &Bound<'_, PyAny>, total: i64) -> PyResult<()> { let mut entries: Vec<(String, i64)> = Vec::new(); - for item in ordinals.call_method0("items")?.try_iter()? { + for item in mapping_items(ordinals)?.try_iter()? { entries.push(item?.extract()?); } self.locked()?.configure_resources(entries, total); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs index b0d107735f..1c0aa53e7b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs @@ -18,6 +18,7 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::{enum_member, new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::result_output::event_writer::ExecutionEventWriter; @@ -122,7 +123,7 @@ fn dependency_locations<'py>( native_field(&plan, "source_map")? }; let source_type: Bound<'py, PyAny> = enum_member(py, RecordId::CompiledResourceType, "SOURCE")?; - for pair in source_map.call_method0("items")?.try_iter()? { + for pair in mapping_items(&source_map)?.try_iter()? { let (name, source): (Bound<'py, PyAny>, Bound<'py, PyAny>) = pair?.extract()?; let table: Bound<'py, PyAny> = native_field(&source, "table")?; if table.is_none() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs index c9360aca51..1c55a14c72 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs @@ -10,6 +10,7 @@ use crate::bindings::_helpers::compile_driver::stage_work::{DECLARATION_SCOPES, use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::render::declaration_values::declaration_scope_resolver; use crate::bindings::_helpers::scopes::scope_index::open_native_scope_index; @@ -130,7 +131,7 @@ fn indexed_macro_metadata<'py>(loaded_macros: &Bound<'py, PyAny>) -> PyResult = imported(py, "types", "CodeType")?; let signature: Bound<'py, PyAny> = imported(py, "inspect", "signature")?; let mut rows: Vec> = Vec::new(); - for pair in loaded_macros.call_method0("items")?.try_iter()? { + for pair in mapping_items(loaded_macros)?.try_iter()? { let (key, loaded): (Bound<'py, PyAny>, Bound<'py, PyAny>) = pair?.extract()?; let function: Bound<'py, PyAny> = native_field(&loaded, "function")?; let code: Bound<'py, PyAny> = diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs index f36a2bda03..0dd7aef323 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs @@ -28,6 +28,7 @@ use crate::bindings::_helpers::project_assembly::declared_relations::{ use crate::bindings::_helpers::records::construct::{enum_member, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get_or; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::fields::replaced; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::semantic_shapes::declarations::{declared_types, function_names}; @@ -299,7 +300,7 @@ fn record_expression_shapes<'py>( let declared_types: Bound<'py, PyAny> = mapping_get_or(&context.column_types, &name, PyDict::new(py))?; let declared_shape: Bound<'py, PyDict> = PyDict::new(py); - for item in shape.call_method0("items")?.try_iter()? { + for item in mapping_items(&shape)?.try_iter()? { let item: Bound<'py, PyAny> = item?; let column: Bound<'py, PyAny> = item.get_item(0)?; declared_shape.set_item( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs index be68d51d2c..dc41bfd071 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs @@ -14,6 +14,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_values; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; const PRESERVE_TARGET_VALUE: &str = "preserve"; @@ -255,7 +256,7 @@ fn deferred_relations<'py>( let py: Python<'py> = adapter.py(); let mut schemas: Vec = Vec::new(); let mut database: Bound<'py, PyAny> = py.None().into_bound(py); - for location in locations.call_method0("values")?.try_iter()? { + for location in mapping_values(locations)?.try_iter()? { let location: Bound<'py, PyAny> = location?; let schema: Bound<'py, PyAny> = native_field(&location, "schema")?; if !schema.is_none() { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs index 10773d013d..c211dbd8e3 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::graph::views::project_lineage_views; use crate::bindings::_helpers::records::construct::enum_member; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::ErrorId; use crate::bindings::_helpers::records::ids::RecordId; @@ -48,7 +49,7 @@ fn adjacency<'py>( keys: &KeyIndexes<'py>, ) -> PyResult)>> { let mut rows: Vec<(usize, Vec)> = Vec::new(); - for item in edges.call_method0("items")?.try_iter()? { + for item in mapping_items(edges)?.try_iter()? { let item: Bound<'py, PyAny> = item?; rows.push(( keys.index(&item.get_item(0)?)?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs index 7d9561859a..1c9e5da343 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs @@ -1,17 +1,61 @@ //! Calling the Python stages the native driver still runs: imports, keyword calls and `with`. +use std::collections::HashMap; +use std::sync::{Mutex, PoisonError}; + use pyo3::exceptions::PyTypeError; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::sync::PyOnceLock; use pyo3::types::{PyBool, PyDict, PyDictMethods, PyString}; +/// Standard-library modules whose attributes tests and users never replace, so lookups are kept. +const STABLE_MODULES: &[&str] = &[ + "builtins", + "collections.abc", + "dataclasses", + "decimal", + "enum", + "functools", + "hashlib", + "itertools", + "json", + "math", + "operator", + "pathlib", + "re", + "uuid", +]; + +type ImportedCache = Mutex>>; + +/// `imported` attributes of `STABLE_MODULES`, looked up once. +static IMPORTED: PyOnceLock = PyOnceLock::new(); + /// `module.name`, imported. pub(crate) fn imported<'py>( py: Python<'py>, module: &str, name: &str, ) -> PyResult> { - py.import(module)?.getattr(name) + if !STABLE_MODULES.contains(&module) { + return py.import(module)?.getattr(name); + } + let cache: &ImportedCache = IMPORTED.get_or_init(py, || Mutex::new(HashMap::new())); + let key: (String, String) = (module.to_owned(), name.to_owned()); + let cached: Option> = cache + .lock() + .unwrap_or_else(PoisonError::into_inner) + .get(&key) + .map(|found| found.clone_ref(py)); + if let Some(found) = cached { + return Ok(found.into_bound(py)); + } + let found: Bound<'py, PyAny> = py.import(module)?.getattr(name)?; + let _ = cache + .lock() + .unwrap_or_else(PoisonError::into_inner) + .insert(key, found.clone().unbind()); + Ok(found) } /// Keyword arguments built from `(name, value)` pairs, in order. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs index c8ce32d6a5..be3b267a95 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::planner_phases::scopes::resolve_planner_scopes; use crate::bindings::_helpers::planner_selection::unit_tests::split_project_unit_test_selectors; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_values; use crate::bindings::_helpers::records::ids::RecordId; const DATACLASSES_MODULE: &str = "dataclasses"; @@ -127,8 +128,7 @@ pub(crate) fn resolve_configured_rule_selection<'py>( return Ok(py.None().into_bound(py)); } let models: Bound<'py, PyAny> = scoped_models(&planner_scopes(project, &selection)?)?; - let keys: Vec> = models - .call_method0("values")? + let keys: Vec> = mapping_values(&models)? .try_iter()? .map(|model| native_field(&model?, "key")) .collect::>()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs index f1eb35dfbc..8adc7fbb36 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs @@ -45,6 +45,7 @@ use crate::bindings::_helpers::discovery::guidance::setting_help; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::ErrorId; use pyo3::IntoPyObjectExt; use sqlbuild_core::constants::PROJECT_CONFIG_FILENAME; @@ -277,7 +278,7 @@ fn target_namespaces( resolved_connection.clone() }; let mut identity: Vec<(String, String)> = Vec::new(); - for item in connection.call_method0("items")?.try_iter()? { + for item in mapping_items(&connection)?.try_iter()? { let item: Bound<'_, PyAny> = item?; let key: Bound<'_, PyAny> = item.get_item(0)?; let Some(key) = text_or_none(&key)? else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs index 38343c29ec..fb9f23ff34 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs @@ -10,6 +10,7 @@ use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{enum_member, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; /// The materializations a model's storage policies are inherited for, besides none. @@ -94,7 +95,7 @@ fn named_records<'py>(resolver: &Bound<'py, PyAny>) -> PyResult>()?; let declarations: Bound<'py, PyAny> = native_field(resolver, "lookup")?.getattr("declarations")?; - for pair in declarations.call_method0("items")?.try_iter()? { + for pair in mapping_items(&declarations)?.try_iter()? { let (identity, records_of): (Bound<'py, PyAny>, Bound<'py, PyAny>) = pair?.extract()?; let kind: Bound<'py, PyAny> = native_field(&identity, "kind")?; if kinds.iter().any(|named| kind.is(named)) @@ -124,7 +125,7 @@ fn schema_enums<'py>(resolver: &Bound<'py, PyAny>) -> PyResult = record_class(py, RecordId::EnumDeclaration)?; let declarations: Bound<'py, PyAny> = native_field(resolver, "projection")?.getattr("declarations")?; - for pair in declarations.call_method0("items")?.try_iter()? { + for pair in mapping_items(&declarations)?.try_iter()? { let (identity, value): (Bound<'py, PyAny>, Bound<'py, PyAny>) = pair?.extract()?; if native_field(&identity, "kind")?.is(&enum_kind) && native_field(&identity, "owner")?.is_none() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs index 38c869c5e8..2fb97dc797 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs @@ -18,6 +18,7 @@ use crate::bindings::_helpers::dagster_invocation::access::{ use crate::bindings::_helpers::native_host::third_party::ThirdPartyHost; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; const CHECK_KIND_FALLBACK: &str = "check"; const CHECK_NAME_JOIN: &str = "__"; @@ -94,7 +95,7 @@ fn metadata_value<'py>(value: &Bound<'py, PyAny>) -> PyResult> } if value.is_instance(&imported(py, "collections.abc", "Mapping")?)? { let plain: Bound<'py, PyDict> = PyDict::new(py); - for pair in value.call_method0("items")?.try_iter()? { + for pair in mapping_items(value)?.try_iter()? { let (key, item): (Bound<'py, PyAny>, Bound<'py, PyAny>) = pair?.extract()?; plain.set_item(key.str()?, metadata_value(&item)?)?; } @@ -115,7 +116,7 @@ fn metadata_from_mapping<'py>(value: &Bound<'py, PyAny>) -> PyResult = value.py(); let excluded: Bound<'py, PyAny> = constant(py, ThirdPartyHost::CheckMetadataExcludedKeys)?; let metadata: Bound<'py, PyDict> = PyDict::new(py); - for pair in value.call_method0("items")?.try_iter()? { + for pair in mapping_items(value)?.try_iter()? { let (key, item): (Bound<'py, PyAny>, Bound<'py, PyAny>) = pair?.extract()?; if item.is_none() || excluded.contains(&key)? { continue; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs index 4d4e9d7df4..e4151638b0 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::dbt_interop::cli::option_values; use crate::bindings::_helpers::dbt_interop::graph::{DbtCombinedGraph, texts}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; const MERGED_OPTIONS: (&[&str], &[&str]) = (&["command", "options", "routed_args", "plan"], &[]); @@ -88,7 +89,7 @@ pub(crate) fn build_failed_sqlbuild_model_names<'py>( let mut dependencies: HashMap> = HashMap::new(); let lookup: Bound<'py, PyAny> = native_field(manifest, "validation_depends_on_nodes_by_unique_id")?; - for item in lookup.call_method0("items")?.try_iter()? { + for item in mapping_items(&lookup)?.try_iter()? { let (unique_id, depends_on): (String, Bound<'py, PyAny>) = item?.extract()?; dependencies.insert(unique_id, texts(&depends_on)?); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs index bbb3d39e6d..83ded1c9f5 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs @@ -27,6 +27,7 @@ use crate::bindings::_helpers::planner_selection::model_selectors::{ use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; const MODEL_RESOURCE_TYPE: &str = "model"; @@ -227,7 +228,7 @@ fn anchors(mapping: &Bound<'_, PyAny>) -> PyResult>> if mapping.is_none() { return Ok(result); } - for item in mapping.call_method0("items")?.try_iter()? { + for item in mapping_items(mapping)?.try_iter()? { let (term, unique_ids): (String, Bound<'_, PyAny>) = item?.extract()?; result.insert(term, texts(&unique_ids)?); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs index 16f4745a8d..f36f8fa2ac 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs @@ -27,6 +27,7 @@ use crate::bindings::_helpers::diagnostics::redaction::redacted_value; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; const PRIVATE_SQL_MARKER: ExecutorHost = ExecutorHost::SqlPrivateRecordMarker; @@ -41,7 +42,7 @@ fn merged<'py>( if part.is_none() { continue; } - for item in part.call_method0("items")?.try_iter()? { + for item in mapping_items(part)?.try_iter()? { let (key, value): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; if skip.is_some_and(|skipped| key.eq(skipped).unwrap_or(false)) { continue; @@ -61,7 +62,7 @@ fn identity_fields<'py>( return Ok(None); }; let fields: Bound<'py, PyDict> = PyDict::new(py); - for item in identity.call_method0("items")?.try_iter()? { + for item in mapping_items(identity)?.try_iter()? { let (key, value): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; fields.set_item(format!("{FIELD_PREFIX}{}", key.str()?.to_str()?), value)?; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs index 591f179773..3ad81fee78 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs @@ -10,6 +10,7 @@ use sqlbuild_core::redaction::main::redact_text::redact_text; use sqlbuild_core::redaction::main::secret_field_name::secret_field_name; use crate::bindings::_helpers::compile_driver::python_calls::imported; +use crate::bindings::_helpers::records::fields::mapping_items; const REDACTED: &str = "[REDACTED]"; @@ -23,7 +24,7 @@ fn redact_diagnostic_text(value: &str) -> String { fn redacted_mapping<'py>(value: &Bound<'py, PyAny>) -> PyResult> { let py: Python<'py> = value.py(); let redacted: Bound<'py, PyDict> = PyDict::new(py); - for item in value.call_method0("items")?.try_iter()? { + for item in mapping_items(value)?.try_iter()? { let (key, item): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; let name: String = key.str()?.extract()?; redacted.set_item(&name, redacted_value(&name, &item)?)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs index 993b715210..e977d6a155 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs @@ -5,6 +5,7 @@ use std::ffi::CString; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::{new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_values; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use pyo3::exceptions::{PyUnicodeDecodeError, PyValueError}; use pyo3::prelude::{ @@ -70,8 +71,7 @@ pub(crate) fn select_latest_fingerprints<'py>( } let by_identity: Bound<'py, PyAny> = native_field(fingerprint_set, "fingerprints_by_identity")?; let latest: Vec> = if by_identity.is_truthy()? { - by_identity - .call_method0("values")? + mapping_values(&by_identity)? .try_iter()? .collect::>()? } else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs b/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs index 4bb7907413..0baeb79bd9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs @@ -14,6 +14,7 @@ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::RecordId; @@ -132,7 +133,7 @@ fn eligible_records<'py>( let mut grouped: RecordsByLocation<'py> = Vec::new(); let changed: Bound<'py, PyAny> = native_field(&freshness, "propagation")?.getattr("changed_source_model_names")?; - for item in changed.call_method0("items")?.try_iter()? { + for item in mapping_items(&changed)?.try_iter()? { let (identity, affected): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; let affected: Bound<'py, PyAny> = affected.call_method1("__and__", (&selected,))?; if !affected.is_truthy()? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs b/crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs index d7dd0cabb1..3a915ef3a8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs @@ -24,6 +24,7 @@ use sqlbuild_core::json::models::{JsonInteger, JsonValue}; use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::frontier::python_types::PythonTypes; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; /// An instance's attributes, by name in first-set order. type Attributes<'py> = Vec<(String, Bound<'py, PyAny>)>; @@ -339,7 +340,7 @@ impl<'py> CaptureEncoder<'py> { )); } let mut entries: Vec<(String, JsonValue)> = Vec::new(); - for item in value.call_method0("items")?.try_iter()? { + for item in mapping_items(value)?.try_iter()? { let item: Bound<'py, PyAny> = item?; let key: String = item.get_item(0)?.str()?.to_str()?.to_owned(); let encoded: JsonValue = self.encode(&item.get_item(1)?)?; @@ -350,7 +351,7 @@ impl<'py> CaptureEncoder<'py> { fn mapping_pairs(&mut self, value: &Bound<'py, PyAny>) -> PyResult> { let mut pairs: Vec = Vec::new(); - for item in value.call_method0("items")?.try_iter()? { + for item in mapping_items(value)?.try_iter()? { let item: Bound<'py, PyAny> = item?; let key: JsonValue = self.encode(&item.get_item(0)?)?; let encoded: JsonValue = self.encode(&item.get_item(1)?)?; @@ -419,7 +420,7 @@ fn instance_attributes<'py>(value: &Bound<'py, PyAny>) -> PyResult(); let mut attributes: Vec<(String, Bound<'py, PyAny>)> = Vec::new(); if has_dict { - for item in instance_dict.call_method0("items")?.try_iter()? { + for item in mapping_items(&instance_dict)?.try_iter()? { let item: Bound<'py, PyAny> = item?; let name: String = item.get_item(0)?.str()?.to_str()?.to_owned(); attributes = with_entry(attributes, name, item.get_item(1)?); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs index b411fb2370..200e8e1105 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs @@ -10,6 +10,7 @@ use sqlbuild_core::graph_walk::main::directed_path_nodes::directed_path_nodes; use crate::bindings::_helpers::graph::node_set::PyNodeSet; use crate::bindings::_helpers::records::fields::mapping_get_or; +use crate::bindings::_helpers::records::fields::mapping_items; const BUILTINS_MODULE: &str = "builtins"; @@ -78,7 +79,7 @@ pub(crate) fn inverted<'py>(edges: &Bound<'py, PyAny>) -> PyResult, Bound<'py, PyAny>) = item?.extract()?; for target in targets.try_iter()? { let target: Bound<'py, PyAny> = target?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs index c7c34aee84..44539a45cf 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs @@ -20,6 +20,7 @@ use crate::bindings::_helpers::boundary::panics::compiler_guard; use crate::bindings::_helpers::graph::project_graph::{CompiledProjectGraph, NativeProjectGraph}; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::ErrorId; type NameRows = Vec<(String, Vec)>; @@ -55,7 +56,7 @@ fn strings(values: &Bound<'_, PyAny>) -> PyResult> { /// A `dict[str, Iterable[str]]` as rows in dict order. fn name_rows(mapping: &Bound<'_, PyAny>) -> PyResult { let mut rows: NameRows = Vec::new(); - for item in mapping.call_method0("items")?.try_iter()? { + for item in mapping_items(mapping)?.try_iter()? { let item: Bound<'_, PyAny> = item?; rows.push((item.get_item(0)?.extract()?, strings(&item.get_item(1)?)?)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs b/crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs index 9567961880..dbf1def124 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs @@ -14,6 +14,7 @@ use crate::bindings::_helpers::graph::keys::{KeyCache, native_key}; use crate::bindings::_helpers::graph::project_graph::NativeProjectGraph; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; /// The native graph's `(resource type, name)` pair for `key`. @@ -110,7 +111,7 @@ pub(crate) fn project_lineage_views<'py>( fn native_edges(mapping: &Bound<'_, PyAny>) -> PyResult)>> { let mut edges: Vec<(ObjectKey, Vec)> = Vec::new(); - for item in mapping.call_method0("items")?.try_iter()? { + for item in mapping_items(mapping)?.try_iter()? { let (key, deps): (Bound<'_, PyAny>, Bound<'_, PyAny>) = item?.extract()?; edges.push((native_key(&key)?, native_graph_keys(&deps)?)); } @@ -160,17 +161,17 @@ pub(crate) fn graph_from_view_mappings( mappings: GraphViewMappings<'_, '_>, ) -> PyResult { let mut names: Vec<(String, ObjectKey)> = Vec::new(); - for item in mappings.all_keys.call_method0("items")?.try_iter()? { + for item in mapping_items(mappings.all_keys)?.try_iter()? { let (name, key): (String, Bound<'_, PyAny>) = item?.extract()?; names.push((name, native_key(&key)?)); } let mut tags: Vec<(String, Vec)> = Vec::new(); - for item in mappings.tag_index.call_method0("items")?.try_iter()? { + for item in mapping_items(mappings.tag_index)?.try_iter()? { let (tag, keys): (String, Bound<'_, PyAny>) = item?.extract()?; tags.push((tag, native_graph_keys(&keys)?)); } let mut paths: Vec<(ObjectKey, String)> = Vec::new(); - for item in mappings.path_index.call_method0("items")?.try_iter()? { + for item in mapping_items(mappings.path_index)?.try_iter()? { let (key, folder): (Bound<'_, PyAny>, String) = item?.extract()?; paths.push((native_key(&key)?, folder)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs index e30928a701..7a45eee6b8 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs @@ -28,6 +28,7 @@ use crate::bindings::_helpers::janitor::janitor_old_names::{ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::relation_naming::fitting::shared_error; const LIFECYCLE: ExecutorHost = ExecutorHost::OperationLifecycle; @@ -310,7 +311,7 @@ fn reasons_of(value: &Bound<'_, PyAny>) -> PyResult> { return Ok(Vec::new()); } let mut reasons: Vec<(Key, String)> = Vec::new(); - for item in value.call_method0("items")?.try_iter()? { + for item in mapping_items(value)?.try_iter()? { let (key, reason): (Bound<'_, PyAny>, String) = item?.extract()?; reasons.push((Key::of(&key)?, reason)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs index be7984ec7f..26d38685c9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs @@ -24,6 +24,7 @@ use crate::bindings::_helpers::lifecycle_events::validation::{ timestamp_check, }; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; const EVENT_REQUIRED_TEXT: [&str; 5] = [ "event_id", @@ -218,7 +219,7 @@ fn validated_operation_metadata<'py>( )); } } - for item in metadata.call_method0("items")?.try_iter()? { + for item in mapping_items(metadata)?.try_iter()? { let (key, value): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; if !nonnegative_int(&value)? { return Err(validation_error( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs index 73b43f104c..0288adf8b9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs @@ -7,6 +7,7 @@ use sqlbuild_core::lifecycle_events::models::PayloadValue; use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::fields::mapping_items; /// `ObservabilityValidationError(message)`. pub(crate) fn validation_error(py: Python<'_>, message: &str) -> PyErr { @@ -74,7 +75,7 @@ pub(crate) fn frozen<'py>( } if abc_mapping(value)? { let copied: Bound<'py, PyDict> = PyDict::new(py); - for item in value.call_method0("items")?.try_iter()? { + for item in mapping_items(value)?.try_iter()? { let (key, item): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; let Ok(name) = key.downcast::() else { return Err(validation_error( @@ -146,8 +147,7 @@ pub(crate) fn payload_value(value: &Bound<'_, PyAny>) -> PyResult /// The entries of a frozen JSON object in iteration order. pub(crate) fn object_entries(value: &Bound<'_, PyAny>) -> PyResult> { - value - .call_method0("items")? + mapping_items(value)? .try_iter()? .map(|item| { let (key, item): (String, Bound<'_, PyAny>) = item?.extract()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs index 39e20d4f6c..ba0d85caeb 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs @@ -16,6 +16,7 @@ use crate::bindings::_helpers::record_behaviours::lineage_facts::{ }; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; /// One compact model's facts and root-star flag. struct CompactModel { @@ -114,7 +115,7 @@ impl ProjectColumnLineage { let _ = edge_counts.insert(name.clone(), count); } } - for item in models.call_method0("items")?.try_iter()? { + for item in mapping_items(models)?.try_iter()? { let (name, model): (String, Bound<'_, PyAny>) = item?.extract()?; let _ = edge_counts.insert(name, upstream_count(&native_field(&model, "columns")?)?); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs index eb754a9ba7..f2f7e9ec61 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs @@ -4,6 +4,7 @@ use std::collections::HashMap; use crate::bindings::_helpers::records::construct::{new_record, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PyTuple}; @@ -58,7 +59,7 @@ impl<'py> PythonKeys<'py> { fn ordered_edges(edges: &Bound<'_, PyAny>) -> PyResult)>> { let mut ordered: Vec<(LineageKey, Vec)> = Vec::new(); - for item in edges.call_method0("items")?.try_iter()? { + for item in mapping_items(edges)?.try_iter()? { let (key, targets): (Bound<'_, PyAny>, Bound<'_, PyAny>) = item?.extract()?; ordered.push((lineage_key(&key)?, lineage_keys(&targets)?)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs index 664899d77d..dd5b9d407a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs @@ -14,6 +14,7 @@ use crate::bindings::_helpers::cache::native_store::digest_files; use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::frontier::encoder::emit_error; use crate::bindings::_helpers::macro_bridge::store_keys::text; +use crate::bindings::_helpers::records::fields::mapping_items; /// The fields of one stored row: a path and its digest. const MODULE_DIGEST_ROW_FIELDS: usize = 2; @@ -52,7 +53,7 @@ fn module_digests_metadata<'py>( digests: &Bound<'py, PyAny>, ) -> PyResult> { let mut rows: Vec<(JsonValue, JsonValue)> = Vec::new(); - for item in digests.call_method0("items")?.try_iter()? { + for item in mapping_items(digests)?.try_iter()? { let item: Bound<'py, PyAny> = item?; rows.push(( text(item.get_item(0)?.downcast::()?)?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs index 6ff716cb59..af1a465080 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs @@ -18,6 +18,7 @@ use sqlbuild_core::json::models::{JsonInteger, JsonValue}; use crate::bindings::_helpers::compile_driver::python_calls::{KeywordArguments, imported}; use crate::bindings::_helpers::frontier::encoder::emit_error; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; const VALUE_RENDERER_FIELD: &str = "_value_renderer"; /// Nesting at which a value counts as too deep to key, as Python's recursion limit stops it. @@ -190,7 +191,7 @@ impl<'py> CanonicalTypes<'py> { } if value.is_instance_of::() || value.is_instance(&self.mapping_proxy)? { let mut pairs: Vec = Vec::new(); - for item in value.call_method0("items")?.try_iter()? { + for item in mapping_items(value)?.try_iter()? { let item: Bound<'py, PyAny> = item?; pairs.push(JsonValue::Array(vec![ self.canonical(&item.get_item(0)?, depth + 1)?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs b/crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs index cd90df39ac..5afe9922ae 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs @@ -21,6 +21,7 @@ use crate::bindings::_helpers::native_host::adapter::AdapterHost; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; const MISSING_SCHEMA: &str = "microbatch history requires a target schema"; const EMPTY_INSERT: &str = "bulk microbatch event insert requires at least one event"; @@ -244,7 +245,7 @@ fn create_indexes<'py>(request: Option<&Bound<'py, PyDict>>) -> PyResult)> = Vec::new(); let definitions: Bound<'_, PyAny> = host::entry(py, ExecutorHost::MicrobatchDirectIndexes)?; - for item in definitions.call_method0("items")?.try_iter()? { + for item in mapping_items(&definitions)?.try_iter()? { let (name, columns): (Bound<'_, PyAny>, Bound<'_, PyAny>) = item?.extract()?; let columns: Vec = columns .try_iter()? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs index 3060ce4e39..5a7ae85049 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs @@ -15,6 +15,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::macro_bridge::store_keys::text; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::records::fields::mapping_items; const SURROGATE_PASS: &str = "surrogatepass"; const UTF8: &str = "utf-8"; @@ -94,7 +95,7 @@ pub(crate) fn freeze<'py>(value: &Bound<'py, PyAny>, path: &str) -> PyResult = PyDict::new(py); - for item in value.call_method0("items")?.try_iter()? { + for item in mapping_items(value)?.try_iter()? { let (key, item): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; let Ok(key_text) = key.downcast::() else { return Err(validation_error( @@ -151,7 +152,7 @@ pub(crate) fn json_value(value: &Bound<'_, PyAny>) -> PyResult { return Ok(JsonValue::Array(items)); } let mut entries: Vec<(String, JsonValue)> = Vec::new(); - for item in value.call_method0("items")?.try_iter()? { + for item in mapping_items(value)?.try_iter()? { let (key, item): (String, Bound<'_, PyAny>) = item?.extract()?; entries.push((key, json_value(&item)?)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs index c87f44be17..52e3f8e2ef 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs @@ -46,6 +46,7 @@ use crate::bindings::_helpers::planner_identity::metadata::{ }; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::type_system::equality::types_equal as native_types_equal; @@ -257,7 +258,7 @@ pub(crate) fn scope_model_changes<'py>( let hook_version_hashes: Bound<'py, PyDict> = PyDict::new(py); let identities: Bound<'py, PyAny> = host::entry(py, UserCodeHost::BuildHookIdentities)? .call1((native_field(project, "hook_functions")?,))?; - for item in identities.call_method0("items")?.try_iter()? { + for item in mapping_items(&identities)?.try_iter()? { let item: Bound<'py, PyAny> = item?; hook_version_hashes.set_item( item.get_item(0)?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs index 0c38f70df0..b20359e228 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs @@ -20,6 +20,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::{ use crate::bindings::_helpers::planner_identity::hashing::model_query_hash; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; const GENERIC_DIALECT: &str = "generic"; @@ -183,7 +184,7 @@ pub(crate) fn plan_reference_renames<'py>( let target_name: Bound<'py, PyAny> = native_field(&native_field(runtime, "project")?, "effective_target_name")?; let mut renames: Vec> = Vec::new(); - for item in planned.call_method0("items")?.try_iter()? { + for item in mapping_items(&planned)?.try_iter()? { let item: Bound<'py, PyAny> = item?; let (new_name, origin_name) = (item.get_item(0)?, item.get_item(1)?); if new_name.ne(&origin_name)? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs index f362d2cafc..d784d97814 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs @@ -18,6 +18,7 @@ use crate::bindings::_helpers::planner_warehouse::source_columns::gather_source_ use crate::bindings::_helpers::planner_warehouse::source_deferral::build_source_read_map; use crate::bindings::_helpers::planner_warehouse::source_deferral::with_declared_source_reads; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_values; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyFrozenSet, PySet, PySetMethods, PyTuple}; @@ -61,8 +62,7 @@ fn source_warehouse_columns<'py>( } let entries = PyTuple::new( py, - source_read_map - .call_method0("values")? + mapping_values(source_read_map)? .try_iter()? .collect::>>()?, )?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs index 688a3d7a35..d97d516142 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs @@ -30,6 +30,7 @@ use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get_or; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; const TABLE_FN_TEST_MODE: &str = "table_fn"; @@ -262,7 +263,7 @@ fn edge_origins<'py>( if origins.is_none() { return Ok(edges); } - for item in origins.call_method0("items")?.try_iter()? { + for item in mapping_items(origins)?.try_iter()? { let ((dependent, dependency), origin): ((Bound<'py, PyAny>, Bound<'py, PyAny>), String) = item?.extract()?; edges.insert((objects.key(dependent)?, objects.key(dependency)?), origin); @@ -280,7 +281,7 @@ pub(crate) fn topologically_order_keys<'py>( let py: Python<'py> = upstream.py(); let mut objects = KeyObjects::new(); let mut edges: Vec<(GraphKey, Vec)> = Vec::new(); - for item in upstream.call_method0("items")?.try_iter()? { + for item in mapping_items(upstream)?.try_iter()? { let (key, deps): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; edges.push((objects.key(key)?, objects.keys(&deps)?)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs index 5963ba1b97..f8e834f09c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs @@ -25,6 +25,7 @@ use crate::bindings::_helpers::planner_identity::metadata::{ use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::fields::replaced; use crate::bindings::_helpers::records::ids::RecordId; @@ -40,8 +41,7 @@ fn graph_keys(keys: &Bound<'_, PyAny>) -> PyResult> { } fn string_pairs(mapping: &Bound<'_, PyAny>) -> PyResult> { - mapping - .call_method0("items")? + mapping_items(mapping)? .try_iter()? .map(|item| item?.extract::<(String, String)>()) .collect() @@ -53,7 +53,7 @@ fn hook_version_hashes<'py>(hook_functions: &Bound<'py, PyAny>) -> PyResult = PyDict::new(py); let identities: Bound<'py, PyAny> = host::entry(py, UserCodeHost::BuildHookIdentities)?.call1((hook_functions,))?; - for item in identities.call_method0("items")?.try_iter()? { + for item in mapping_items(&identities)?.try_iter()? { let (name, identity): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; hashes.set_item(name, native_field(&identity, "version_hash")?)?; } @@ -298,7 +298,7 @@ pub(crate) fn with_honest_model_write_hashes<'py>( } let recorded_models: Bound<'py, PyAny> = native_field(&native_field(&snapshot, "fingerprints")?, "models")?; - for item in recorded_models.call_method0("items")?.try_iter()? { + for item in mapping_items(&recorded_models)?.try_iter()? { let (name, fingerprint): (String, Bound<'py, PyAny>) = item?.extract()?; let version_hash: Bound<'py, PyAny> = native_field(&fingerprint, "version_hash")?; if version_hash.is_truthy()? { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs index 57376ba7d4..7a9250c696 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs @@ -21,6 +21,7 @@ use crate::bindings::_helpers::planner_identity::hashing::function_definition_ha use crate::bindings::_helpers::planner_identity::json_values::{COMPACT, SPACED, sorted_dumps}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; const LOCAL_FUNCTION_HASHES_KEY: &str = "local_function_hashes"; const DATACLASSES_MODULE: &str = "dataclasses"; @@ -136,7 +137,7 @@ fn execution_signature<'py>( } let python_hook_fields: Bound<'py, PyDict> = PyDict::new(py); if let Some(hashes) = hook_version_hashes.filter(|hashes| !hashes.is_none()) { - for item in hashes.call_method0("items")?.try_iter()? { + for item in mapping_items(hashes)?.try_iter()? { let (name, version_hash): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; let fields: Bound<'py, PyDict> = PyDict::new(py); fields.set_item("version_hash", version_hash)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs index 2490654165..fd417d7dc1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs @@ -22,6 +22,7 @@ use crate::bindings::_helpers::planner_changes::detect::{ModelPass, model_change use crate::bindings::_helpers::planner_identity::hashing::graph_key; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; /// Change kinds that mean the model's own identity changed. @@ -51,7 +52,7 @@ fn names_of_kind(keys: &Bound<'_, PyAny>, kind: &str) -> PyResult) -> PyResult>> { let mut deps: HashMap> = HashMap::new(); - for item in upstream_deps.call_method0("items")?.try_iter()? { + for item in mapping_items(upstream_deps)?.try_iter()? { let (key, upstream): (Bound<'_, PyAny>, Bound<'_, PyAny>) = item?.extract()?; let upstream_keys: Vec = upstream .try_iter()? @@ -75,7 +76,7 @@ fn changed_model_names(inputs: &StalenessInputs<'_>) -> PyResult let py: Python<'_> = inputs.snapshot.py(); let models: Bound<'_, PyAny> = native_field(&inputs.changes, "models")?; let mut changed: HashSet = HashSet::new(); - for item in models.call_method0("items")?.try_iter()? { + for item in mapping_items(&models)?.try_iter()? { let (name, change): (String, Bound<'_, PyAny>) = item?.extract()?; if own_change(&change)? { changed.insert(name); @@ -93,7 +94,7 @@ fn changed_model_names(inputs: &StalenessInputs<'_>) -> PyResult hook_version_hashes: py.None().into_bound(py), }; let models_by_name: Bound<'_, PyAny> = native_field(&inputs.original_scope, "models_by_name")?; - for item in models_by_name.call_method0("items")?.try_iter()? { + for item in mapping_items(&models_by_name)?.try_iter()? { let (name, model): (String, Bound<'_, PyAny>) = item?.extract()?; let selected_change: Bound<'_, PyAny> = mapping_get(&models, &name)?; if !selected_change.is_none() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs index 2e6597b9e7..fa88beb13e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs @@ -8,6 +8,7 @@ use crate::bindings::_helpers::planner_identity::metadata::build_model_version_i use crate::bindings::_helpers::planner_phases::objects::object; use crate::bindings::_helpers::planner_phases::runtime::runtime_field; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::{PyDict, PyDictMethods, PySet, PySetMethods}; use sqlbuild_analysis::planner_migrations::main::discovery_order::discovery_order; @@ -90,7 +91,7 @@ pub(super) fn metadata<'py>( let identities = host::entry(py, UserCodeHost::BuildHookIdentities)? .call1((native_field(&project, "hook_functions")?,))?; let hooks = PyDict::new(py); - for pair in identities.call_method0("items")?.try_iter()? { + for pair in mapping_items(&identities)?.try_iter()? { let pair = pair?; hooks.set_item( pair.get_item(0)?, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs index 45c6f43720..877ada6de2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs @@ -4,6 +4,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; use crate::bindings::_helpers::planner_migrations::errors::ProofError; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::exceptions::PyValueError; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyModule, PyModuleMethods, PyResult, Python}; @@ -109,7 +110,7 @@ pub(crate) fn explain( input_columns: &Bound<'_, PyAny>, ) -> PyResult { let mut pairs: Vec<(String, String)> = Vec::new(); - for item in renames.call_method0("items")?.try_iter()? { + for item in mapping_items(renames)?.try_iter()? { pairs.push(item?.extract::<(String, String)>()?); } proof::renames_explain_change( diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs index 422bf9f1eb..0dfe501080 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs @@ -22,6 +22,7 @@ use crate::bindings::_helpers::planner_phases::runtime::warehouse_field; use crate::bindings::_helpers::planner_warehouse::source_freshness::source_freshness_unknown_warnings; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::pyfunction; @@ -314,7 +315,7 @@ fn source_names<'py>(items: &Bound<'py, PyAny>) -> PyResult> { fn age_names<'py>(statuses: &Bound<'py, PyAny>, wanted: &str) -> PyResult> { let mut names: Vec<_> = Vec::new(); - for item in statuses.call_method0("items")?.try_iter()? { + for item in mapping_items(statuses)?.try_iter()? { let (identity, status): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; if status.eq(wanted)? { names.push(native_field(&identity, "source_name")?.extract::()?); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs index e83da0b555..5d42b34d18 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs @@ -14,6 +14,7 @@ use crate::bindings::_helpers::planner_selection::carrier::{Carrier, py_strings} use crate::bindings::_helpers::planner_selection::selectors::resolve_graph_selection; use crate::bindings::_helpers::records::construct::{new_record, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python, pyfunction}; use pyo3::types::PyDictMethods; @@ -80,8 +81,7 @@ pub(crate) fn build_planner_scope<'py>( if selected.is_none() { selected = resolve_graph_selection(lineage.borrow(), &select, &exclude)?.into_any(); } - let names: Vec<(String, (String, String))> = all_keys - .call_method0("items")? + let names: Vec<(String, (String, String))> = mapping_items(&all_keys)? .try_iter()? .map(|item| { let (name, key): (String, Bound<'py, PyAny>) = item?.extract()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/values.rs index 9180913ed7..0058a12dec 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_scope/values.rs @@ -2,6 +2,7 @@ use crate::bindings::_helpers::graph::keys::native_key; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; use pyo3::types::PyDict; use pyo3::types::PyDictMethods; @@ -16,8 +17,7 @@ pub(crate) fn keys(values: &Bound<'_, PyAny>) -> PyResult> { } pub(crate) fn edges(values: &Bound<'_, PyAny>) -> PyResult)>> { - values - .call_method0("items")? + mapping_items(values)? .try_iter()? .map(|item| { let (key, deps): (Bound<'_, PyAny>, Bound<'_, PyAny>) = item?.extract()?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs index 3254196d1b..dfb6cfb45b 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs @@ -23,6 +23,7 @@ use crate::bindings::_helpers::planner_strategy::values::{input_error, text}; use crate::bindings::_helpers::records::construct::{enum_from_value, new_record_with}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::references::source_relations::render_source_relation; @@ -108,10 +109,7 @@ pub(crate) fn reject_unexposed_cursor_input_columns<'py>( let warehouse_columns: &Bound<'py, PyAny> = &lookups.source_warehouse_columns; let model_name: String = model_reads::model_name(model)?; for role in ["filter_inputs", "watermark_inputs"] { - for item in native_field(&roles, role)? - .call_method0("items")? - .try_iter()? - { + for item in mapping_items(&native_field(&roles, role)?)?.try_iter()? { let (input_name, column): (String, String) = item?.extract()?; let reference: Bound<'py, PyAny> = resolve_lineage_reference( model, @@ -272,7 +270,7 @@ pub(crate) fn build_cursor_input_relations<'py>( let mut relations: Vec> = Vec::new(); let watermarks: Bound<'py, PyAny> = native_field(&resolve_cursor_input_roles(&model)?, "watermark_inputs")?; - for item in watermarks.call_method0("items")?.try_iter()? { + for item in mapping_items(&watermarks)?.try_iter()? { let (input_name, column): (String, Bound<'py, PyAny>) = item?.extract()?; let reference: Bound<'py, PyAny> = resolve_lineage_reference( &model, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs index 9f436db537..b5570f2f18 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs @@ -30,6 +30,7 @@ use crate::bindings::_helpers::planner_warehouse::snapshot::{ use crate::bindings::_helpers::planner_warehouse::watermarks::validate_watermark_column; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::references::source_relations::render_source_relation; use pyo3::IntoPyObject; @@ -364,11 +365,11 @@ fn collect_models<'py>( }; let watermark_inputs = native_field(&resolve_cursor_input_roles(&model)?, "watermark_inputs")?; - let watermark_inputs: Vec<(Bound<'py, PyAny>, Bound<'py, PyAny>)> = watermark_inputs - .call_method0("items")? - .try_iter()? - .map(|item| item?.extract()) - .collect::>()?; + let watermark_inputs: Vec<(Bound<'py, PyAny>, Bound<'py, PyAny>)> = + mapping_items(&watermark_inputs)? + .try_iter()? + .map(|item| item?.extract()) + .collect::>()?; if inputs.full_refresh_model_names.contains(&name_value)? { for (input_name, upstream_column) in &watermark_inputs { let reference = lineage_reference(&model, input_name, maps)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs index 8c58f504dd..c4e1e72bf1 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs @@ -21,6 +21,8 @@ use crate::bindings::_helpers::planner_warehouse::constants::{ }; use crate::bindings::_helpers::planner_warehouse::cursors::{CursorInputs, cursor_snapshots}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; +use crate::bindings::_helpers::records::fields::mapping_values; use crate::bindings::_helpers::records::ids::RecordId; use pyo3::IntoPyObject; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; @@ -209,7 +211,7 @@ fn metadata_name_filter( py, build_upstream_intermediate_source_map(project, selected)?, )?; - for entry in intermediate.call_method0("values")?.try_iter()? { + for entry in mapping_values(&intermediate)?.try_iter()? { names.insert(source_table_name(&entry?)?); } } @@ -557,8 +559,7 @@ fn gather_fingerprints<'py>( let values: Vec> = if by_identity.is_none() { Vec::new() } else { - by_identity - .call_method0("values")? + mapping_values(&by_identity)? .try_iter()? .collect::>()? }; @@ -587,7 +588,7 @@ fn gather_fingerprints<'py>( } let by_identity = native_field(&set, "fingerprints_by_identity")?; if !by_identity.is_none() { - for item in by_identity.call_method0("items")?.try_iter()? { + for item in mapping_items(&by_identity)?.try_iter()? { let (key, fingerprint): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; let node_type: String = native_field(&fingerprint, "node_type")?.extract()?; if node_type != NODE_TYPE_MODEL diff --git a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs index ab1faee5ad..267a7b8c1d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs @@ -27,6 +27,7 @@ use crate::bindings::_helpers::project_assembly::models::{ use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::ErrorId; use crate::bindings::types::CompilerDetach; @@ -103,7 +104,7 @@ fn opaque_render<'py>(value: &Bound<'py, PyAny>) -> PyResult> { fn variables<'py>(effective_vars: &Bound<'py, PyAny>) -> PyResult> { let mut rows: Vec<(String, Variable)> = Vec::new(); let mut held: Vec> = Vec::new(); - for item in effective_vars.call_method0("items")?.try_iter()? { + for item in mapping_items(effective_vars)?.try_iter()? { let (name, value): (String, Bound<'py, PyAny>) = item?.extract()?; if let Some(scalar) = plain_scalar(&value)? { rows.push((name, Variable::Scalar(scalar))); @@ -173,8 +174,7 @@ fn model_facts(model_input: &Bound<'_, PyAny>, checks: &Bound<'_, PyAny>) -> PyR for check in checks.try_iter()? { let (sql, placeholders): (String, Bound<'_, PyAny>) = check?.extract()?; let placeholders: Pairs = if placeholders.is_truthy()? { - placeholders - .call_method0("items")? + mapping_items(&placeholders)? .try_iter()? .map(|pair| pair?.extract()) .collect::>()? diff --git a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs index 29ff62861c..06e3194263 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs @@ -1,6 +1,7 @@ //! Computed attributes of the natively hosted SQL value and fingerprint records. use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_values; use pyo3::IntoPyObjectExt; use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::types::{PyDict, PyDictMethods, PyTuple}; @@ -30,7 +31,7 @@ pub(crate) fn finish_fingerprint_set( return Ok(values); } let by_identity: Bound<'_, PyDict> = PyDict::new(py); - for fingerprint in values[1].bind(py).call_method0("values")?.try_iter()? { + for fingerprint in mapping_values(values[1].bind(py))?.try_iter()? { let fingerprint: Bound<'_, PyAny> = fingerprint?; let identity: Bound<'_, PyTuple> = PyTuple::new( py, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs index 0a9e6b5360..2593d59982 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs @@ -108,7 +108,13 @@ pub(crate) fn mapping_get<'py, K: pyo3::IntoPyObject<'py>>( key: K, ) -> PyResult> { let py: Python<'py> = mapping.py(); - mapping_get_or(mapping, key, py.None()) + let key: Bound<'py, PyAny> = key.into_bound_py_any(py)?; + match mapping.cast_exact::() { + Ok(dict) => Ok(dict + .get_item(&key)? + .unwrap_or_else(|| py.None().into_bound(py))), + Err(_) => mapping.call_method1("get", (key,)), + } } /// `mapping.get(key, default)`: a dict is read through the C API. @@ -128,6 +134,22 @@ pub(crate) fn mapping_get_or<'py, K: pyo3::IntoPyObject<'py>, D: pyo3::IntoPyObj mapping.call_method1("get", (key, default.into_bound_py_any(py)?)) } +/// `mapping.items()` for iteration: a dict yields its `(key, value)` pairs through the C API. +pub(crate) fn mapping_items<'py>(mapping: &Bound<'py, PyAny>) -> PyResult> { + match mapping.cast_exact::() { + Ok(dict) => Ok(dict.items().into_any()), + Err(_) => mapping.call_method0("items"), + } +} + +/// `mapping.values()` for iteration: a dict yields its values through the C API. +pub(crate) fn mapping_values<'py>(mapping: &Bound<'py, PyAny>) -> PyResult> { + match mapping.cast_exact::() { + Ok(dict) => Ok(dict.values().into_any()), + Err(_) => mapping.call_method0("values"), + } +} + /// `dataclasses.replace(value, **changes)`: a native record is rebuilt from its own values. pub(crate) fn replaced<'py>( value: &Bound<'py, PyAny>, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs index 6ceb77c366..7b3b08b2c7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs @@ -14,7 +14,13 @@ use crate::bindings::_helpers::compile_command::reuse_recording::{ }; use crate::bindings::_helpers::compile_driver::diagnostic_collector::CollectedCompileDiagnostics; use crate::bindings::_helpers::compile_driver::input_reads::CompileInputReads; +use crate::bindings::_helpers::compiled_project::audit_views::{ + NativeAuditInput, NativeCompiledAudit, +}; use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_project::function_views::{ + NativeCompiledFunction, NativeFunctionInput, +}; use crate::bindings::_helpers::compiled_project::inputs_view::NativeInputsView; use crate::bindings::_helpers::compiled_project::model_input_view::NativeModelInput; use crate::bindings::_helpers::compiled_project::project_view::NativeProjectView; @@ -38,7 +44,9 @@ use crate::bindings::_helpers::execution_history::postgres::PostgresExecutionHis use crate::bindings::_helpers::execution_history::sqlite::SqliteExecutionHistory; use crate::bindings::_helpers::graph::project_graph::CompiledProjectGraph; use crate::bindings::_helpers::planner_migrations::state_inspection::MigrationStateInspection; -use crate::bindings::_helpers::result_output::integration_envelope::IntegrationResultEnvelope; +use crate::bindings::_helpers::result_output::integration_envelope::{ + IntegrationAssetResult, IntegrationCheckResult, IntegrationResultEnvelope, +}; use crate::bindings::_helpers::scopes::scope_index::NativeScopeIndex; use crate::bindings::models::NativeDirectorySnapshot; @@ -82,10 +90,26 @@ pub(crate) fn getter_field<'py>( py.get_type::().as_ptr() as usize, read_compile_input_reads, ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_audit_input, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_compiled_audit, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_native_compiled_model, ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_compiled_function, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_function_input, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_native_inputs_view, @@ -178,6 +202,14 @@ pub(crate) fn getter_field<'py>( py.get_type::().as_ptr() as usize, read_migration_state_inspection, ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_integration_asset_result, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_integration_check_result, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_integration_result_envelope, @@ -324,6 +356,161 @@ fn read_compile_input_reads<'py>( }) } +fn read_native_audit_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "audit_file" => this + .audit_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "audit_block" => this + .audit_block(py) + .and_then(|value| value.into_bound_py_any(py)), + "sql_body" => this + .sql_body(py) + .and_then(|value| value.into_bound_py_any(py)), + "evaluation_mode" => this + .evaluation_mode(py) + .and_then(|value| value.into_bound_py_any(py)), + "measurement_contract" => this + .measurement_contract(py) + .and_then(|value| value.into_bound_py_any(py)), + "thresholds" => this + .thresholds(py) + .and_then(|value| value.into_bound_py_any(py)), + "minimum_samples" => this + .minimum_samples(py) + .and_then(|value| value.into_bound_py_any(py)), + "measure_sql" => this + .measure_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_sql" => this + .evidence_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_limit" => this + .evidence_limit(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_kind" => this + .attached_target_kind(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_name" => this + .attached_target_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_column_name" => this + .attached_column_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "severity" => this + .severity(py) + .and_then(|value| value.into_bound_py_any(py)), + "run_scope" => this + .run_scope(py) + .and_then(|value| value.into_bound_py_any(py)), + "always_run" => this + .always_run(py) + .and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "assembly_row" => this + .assembly_row(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_compiled_audit<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "audit_file" => this + .audit_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "audit_block" => this + .audit_block(py) + .and_then(|value| value.into_bound_py_any(py)), + "sql_body" => this + .sql_body(py) + .and_then(|value| value.into_bound_py_any(py)), + "evaluation_mode" => this + .evaluation_mode(py) + .and_then(|value| value.into_bound_py_any(py)), + "measurement_contract" => this + .measurement_contract(py) + .and_then(|value| value.into_bound_py_any(py)), + "thresholds" => this + .thresholds(py) + .and_then(|value| value.into_bound_py_any(py)), + "minimum_samples" => this + .minimum_samples(py) + .and_then(|value| value.into_bound_py_any(py)), + "measure_sql" => this + .measure_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_sql" => this + .evidence_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_limit" => this + .evidence_limit(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_kind" => this + .attached_target_kind(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_name" => this + .attached_target_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_column_name" => this + .attached_column_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "severity" => this + .severity(py) + .and_then(|value| value.into_bound_py_any(py)), + "run_scope" => this + .run_scope(py) + .and_then(|value| value.into_bound_py_any(py)), + "always_run" => this + .always_run(py) + .and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "scope_deps" => this + .scope_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "definition_name" => this + .definition_name(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + fn read_native_compiled_model<'py>( value: &Bound<'py, PyAny>, name: &str, @@ -439,6 +626,149 @@ fn read_native_compiled_model<'py>( }) } +fn read_native_compiled_function<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "arguments" => this + .arguments(py) + .and_then(|value| value.into_bound_py_any(py)), + "returns" => this + .returns(py) + .and_then(|value| value.into_bound_py_any(py)), + "body_sql" => this + .body_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "return_columns" => this + .return_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "language" => this + .language(py) + .and_then(|value| value.into_bound_py_any(py)), + "runtime_version" => this + .runtime_version(py) + .and_then(|value| value.into_bound_py_any(py)), + "entry_point" => this + .entry_point(py) + .and_then(|value| value.into_bound_py_any(py)), + "packages" => this + .packages(py) + .and_then(|value| value.into_bound_py_any(py)), + "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), + "relative_path" => this + .relative_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "source_file_path" => this + .source_file_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination" => this + .destination(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_destination" => this + .fingerprint_destination(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +fn read_native_function_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "arguments" => this + .arguments(py) + .and_then(|value| value.into_bound_py_any(py)), + "returns" => this + .returns(py) + .and_then(|value| value.into_bound_py_any(py)), + "body_sql" => this + .body_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "return_columns" => this + .return_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "language" => this + .language(py) + .and_then(|value| value.into_bound_py_any(py)), + "runtime_version" => this + .runtime_version(py) + .and_then(|value| value.into_bound_py_any(py)), + "entry_point" => this + .entry_point(py) + .and_then(|value| value.into_bound_py_any(py)), + "packages" => this + .packages(py) + .and_then(|value| value.into_bound_py_any(py)), + "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "function_file" => this + .function_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "database" => this + .database(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema" => this + .schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "logical_database" => this + .logical_database(py) + .and_then(|value| value.into_bound_py_any(py)), + "logical_schema" => this + .logical_schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_database" => this + .fingerprint_database(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_schema" => this + .fingerprint_schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_logical_database" => this + .fingerprint_logical_database(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_logical_schema" => this + .fingerprint_logical_schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "assembly_row" => this + .assembly_row(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + fn read_native_inputs_view<'py>( value: &Bound<'py, PyAny>, name: &str, @@ -1098,6 +1428,40 @@ fn read_migration_state_inspection<'py>( }) } +fn read_integration_asset_result<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "as_dict" => return None, + _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), + }) +} + +fn read_integration_check_result<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "as_dict" | "decoded" | "parsed" => return None, + _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), + }) +} + fn read_integration_result_envelope<'py>( value: &Bound<'py, PyAny>, name: &str, @@ -1112,7 +1476,10 @@ fn read_integration_result_envelope<'py>( Some(match name { "asset" => this.asset(py).into_bound_py_any(py), "checks" => this.checks(py).into_bound_py_any(py), - _ => return None, + "from_json" | "from_json_without_optional_enrichment" | "register" | "to_json" => { + return None; + } + _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), }) } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs b/crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs index de3d384d87..e10f8a1198 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs @@ -38,6 +38,7 @@ use crate::bindings::_helpers::lineage::lineage_index::lineage_key; use crate::bindings::_helpers::presentation_text::terminal::stdout_supports_color; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::ErrorId; use crate::bindings::_helpers::refactor::offline_compile::{OfflineCompile, compile_for_refactor}; use crate::bindings::_helpers::refactor::refactor_facts::{ @@ -204,7 +205,7 @@ struct Verified { fn target_lookup(all_keys: &Bound<'_, PyAny>) -> PyResult> { let mut names: HashMap = HashMap::new(); - for item in all_keys.call_method0("items")?.try_iter()? { + for item in mapping_items(all_keys)?.try_iter()? { let (name, key): (String, Bound<'_, PyAny>) = item?.extract()?; names.insert(name, lineage_key(&key)?); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs b/crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs index 1c1dcbc8f8..7231c263d7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs @@ -11,6 +11,7 @@ use crate::bindings::_helpers::analysis::relation_names::{ use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; const RUNTIME_RELATION_PREFIX: &str = "SELECT 1 FROM "; @@ -111,7 +112,7 @@ fn runtime_project_relations<'py>( ) -> PyResult> { let relation_type: Bound<'py, PyAny> = host::entry(py, ExecutorHost::ProjectRelation)?; let resolved: Bound<'py, PyDict> = PyDict::new(py); - for item in relations.call_method0("items")?.try_iter()? { + for item in mapping_items(relations)?.try_iter()? { let (reference, qualified): (Bound<'py, PyAny>, String) = item?.extract()?; let sql: String = format!("{RUNTIME_RELATION_PREFIX}{qualified}"); let Some((mut names, _)) = extract_sql_relation_names(py, &sql, dialect)? else { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs index 6db9dad189..7f83991dc6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs @@ -15,6 +15,8 @@ use crate::bindings::_helpers::records::construct::{ }; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; +use crate::bindings::_helpers::records::fields::mapping_values; use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; use crate::bindings::_helpers::records::registry; use crate::bindings::_helpers::scopes::declaration_contexts::NativeDeclarationContexts; @@ -98,7 +100,7 @@ fn runtime_declarations<'py>( } } if !loaded_macros.is_none() { - for name_and_macro in loaded_macros.call_method0("values")?.try_iter()? { + for name_and_macro in mapping_values(loaded_macros)?.try_iter()? { let declared_macro: Bound<'py, PyAny> = name_and_macro?; let identity = declaration_identity( &classes, @@ -193,7 +195,7 @@ fn value_kind_code(classes: &[Bound<'_, PyAny>], value: &Bound<'_, PyAny>) -> Py /// `{owner: list(items)}` of an index position mapping. fn listed_positions<'py>(positions: &Bound<'py, PyAny>) -> PyResult> { let listed: Bound<'py, PyDict> = PyDict::new(positions.py()); - for item in positions.call_method0("items")?.try_iter()? { + for item in mapping_items(positions)?.try_iter()? { let (owner, items): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; listed.set_item( owner, diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs index 89df63c989..9ad30581f7 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs @@ -7,6 +7,7 @@ use crate::bindings::_helpers::plan_output::safety::{future_cursor_safety, maxim use crate::bindings::_helpers::plan_output::values::{any, dict, items, optional_enum_value}; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::result_output::projection::{Projection, rounded}; const FAILED_STATUS: &str = "failed"; @@ -44,10 +45,7 @@ fn targets<'py>( }; let py: Python<'py> = plan.py(); let names: Bound<'py, PyDict> = PyDict::new(py); - for item in native_field(plan, field)? - .call_method0("items")? - .try_iter()? - { + for item in mapping_items(&native_field(plan, field)?)?.try_iter()? { let (name, location): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; names.set_item(name, native_field(&location, "qualified_name")?)?; } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs index 984d750c31..fc4841cf27 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/integration_envelope.rs @@ -50,7 +50,7 @@ pub(crate) struct IntegrationResultEnvelope { #[pymethods] impl IntegrationAssetResult { - fn __getattr__(&self, py: Python<'_>, name: &str) -> PyResult> { + pub(crate) fn __getattr__(&self, py: Python<'_>, name: &str) -> PyResult> { field(&self.fields, py, name) } @@ -62,7 +62,7 @@ impl IntegrationAssetResult { #[pymethods] impl IntegrationCheckResult { - fn __getattr__(&self, py: Python<'_>, name: &str) -> PyResult> { + pub(crate) fn __getattr__(&self, py: Python<'_>, name: &str) -> PyResult> { field(&self.fields, py, name) } @@ -182,7 +182,7 @@ impl IntegrationResultEnvelope { self.checks.clone_ref(py) } - fn __getattr__(&self, py: Python<'_>, name: &str) -> PyResult> { + pub(crate) fn __getattr__(&self, py: Python<'_>, name: &str) -> PyResult> { field(&self.fields, py, name) } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs index dde2957f73..46e1d892fa 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs @@ -23,6 +23,7 @@ use crate::bindings::_helpers::compiled_project::model_loop_named::scope_path_me use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; const INACCESSIBLE_DECLARATION_CODE: &str = "S006"; @@ -99,7 +100,7 @@ pub(crate) fn model_schema_scope_usages<'py>( let mut records: Vec> = Vec::new(); let mut record_rows: Vec<(IdentityRow, RecordRow)> = Vec::new(); let declarations = native_field(&native_field(resolver, "lookup")?, "declarations")?; - for item in declarations.call_method0("items")?.try_iter()? { + for item in mapping_items(&declarations)?.try_iter()? { let (identity, found): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; if !found.is_truthy()? || !native_field(&identity, "owner")?.is_none() diff --git a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs index 81e5b98805..334bfbf364 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs @@ -22,6 +22,7 @@ use sqlbuild_scopes::scope_index::models::{ use crate::bindings::_helpers::boundary::panics::compiler_error; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_values; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::_helpers::scopes::relationship_scan::{ RelationshipScanSettings, ScenarioRow, TestFileRow, scanned_relationships, @@ -587,7 +588,7 @@ impl<'py> Walk<'py> { let key: String = normalized(py, &native_field(¯o_file, "relative_path")?)?; macro_files.insert(key, macro_file); } - for loaded in loaded_macros.call_method0("values")?.try_iter()? { + for loaded in mapping_values(loaded_macros)?.try_iter()? { let loaded: Bound<'py, PyAny> = loaded?; let key: String = normalized(py, &native_field(&loaded, "relative_path")?)?; let (line, metadata) = self.loaded_metadata(&loaded)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs index c0486717ea..02aeae8369 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs @@ -20,6 +20,7 @@ use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeComp use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; use crate::bindings::_helpers::records::fields::mapping_get_or; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::semantic_checks::failures::semantic_error; use crate::bindings::_helpers::semantic_checks::inputs::{ column_names, resource_sql_diagnostics, sql_test_columns, @@ -322,7 +323,7 @@ fn sql_test_diagnostic<'py>( /// `{name: {column: value}}` as ordered rows. pub(crate) fn shape_rows(shapes: &Bound<'_, PyAny>) -> PyResult { let mut rows: ShapeRows = Vec::new(); - for item in shapes.call_method0("items")?.try_iter()? { + for item in mapping_items(shapes)?.try_iter()? { let (name, columns): (String, Bound<'_, PyAny>) = item?.extract()?; rows.push((name, pairs(&columns)?)); } @@ -331,8 +332,7 @@ pub(crate) fn shape_rows(shapes: &Bound<'_, PyAny>) -> PyResult { /// A `{key: value}` text mapping's items in order. fn pairs(mapping: &Bound<'_, PyAny>) -> PyResult> { - mapping - .call_method0("items")? + mapping_items(mapping)? .try_iter()? .map(|item| item?.extract()) .collect() @@ -439,7 +439,7 @@ fn metadata_model(classes: &StageClasses<'_>, model: &Bound<'_, PyAny>) -> PyRes let cursor_inputs: Bound<'_, PyAny> = get("cursor_inputs")?; let mut upstreams: Vec = Vec::new(); if cursor_inputs.is_instance_of::() { - for item in cursor_inputs.call_method0("items")?.try_iter()? { + for item in mapping_items(&cursor_inputs)?.try_iter()? { let (upstream, columns): (Bound<'_, PyAny>, Bound<'_, PyAny>) = item?.extract()?; upstreams.push((upstream.str()?.extract()?, column_names(&columns)?)); } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs index 049de01349..60c4367e72 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs @@ -20,6 +20,7 @@ use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::record_class; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; use crate::bindings::models::ProjectCatalog; use crate::bindings::types::CompilerDetach; @@ -120,7 +121,7 @@ fn shape( columns: &Bound<'_, PyAny>, ) -> PyResult<(String, Vec<(String, String)>)> { let mut pairs: Vec<(String, String)> = Vec::new(); - for pair in columns.call_method0("items")?.try_iter()? { + for pair in mapping_items(columns)?.try_iter()? { pairs.push(pair?.extract()?); } Ok((name.extract()?, pairs)) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs index 686d211f32..ec5af8c9ba 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs @@ -21,6 +21,8 @@ use crate::bindings::_helpers::compiled_project::compiled_model_view::LineageInp use crate::bindings::_helpers::compiled_project::records::with_type_recovery; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get_or; +use crate::bindings::_helpers::records::fields::mapping_items; +use crate::bindings::_helpers::records::fields::mapping_values; use crate::bindings::_helpers::semantic_checks::constants::SCHEMA_REVALIDATIONS; use crate::bindings::_helpers::semantic_checks::failures::{internal_error, semantic_error}; use crate::bindings::_helpers::semantic_checks::inputs::revalidation_request; @@ -56,7 +58,7 @@ pub(crate) fn recovered_types<'py>( } let ids: Bound<'py, PyDict> = diagnostic_ids(project, &models)?; let raw_ids: Bound<'py, PyDict> = PyDict::new(py); - for rows in binding_results.call_method0("values")?.try_iter()? { + for rows in mapping_values(binding_results)?.try_iter()? { for row in rows?.try_iter()? { let row: Bound<'py, PyAny> = row?; if !raw_ids.contains(&row)? { @@ -254,7 +256,7 @@ fn revalidated<'py>( let py: Python<'py> = classes.py(); let shapes: Bound<'py, PyDict> = project_shapes(project, None)?; let unknown: Bound<'py, PyDict> = PyDict::new(py); - for item in shapes.call_method0("items")?.try_iter()? { + for item in mapping_items(&shapes)?.try_iter()? { let (name, columns): (Bound<'py, PyAny>, Bound<'py, PyAny>) = item?.extract()?; let copied: Bound<'py, PyDict> = PyDict::new(py); copied.update(columns.downcast::()?.as_mapping())?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/declarations.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/declarations.rs index 5d8cccd3ee..bb9e234d07 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/declarations.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/declarations.rs @@ -3,6 +3,7 @@ use std::collections::BTreeSet; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_values; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult}; const UNKNOWN: &str = "UNKNOWN"; @@ -25,8 +26,8 @@ pub(crate) fn declared_types( column_types: &Bound<'_, PyAny>, ) -> PyResult> { let mut types: BTreeSet = BTreeSet::new(); - for columns in column_types.call_method0("values")?.try_iter()? { - for column_type in columns?.call_method0("values")?.try_iter()? { + for columns in mapping_values(column_types)?.try_iter()? { + for column_type in mapping_values(&columns?)?.try_iter()? { types.insert(column_type?.extract()?); } } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs index 16c3bb82a2..b56bcc6b6c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs @@ -19,6 +19,7 @@ use crate::bindings::_helpers::compile_driver::python_calls::keywords; use crate::bindings::_helpers::compile_driver::stage_work::count_stage; use crate::bindings::_helpers::records::construct::{enum_from_value, enum_member, record_class}; use crate::bindings::_helpers::records::fields::field as native_field; +use crate::bindings::_helpers::records::fields::mapping_items; use crate::bindings::_helpers::records::fields::replaced_keywords; use crate::bindings::_helpers::records::ids::RecordId; use crate::bindings::_helpers::semantic_shapes::constants::SOURCE_REBINDING_ANALYSES; @@ -80,7 +81,7 @@ pub(crate) fn source_binding_diagnostics<'py>( && CASE_SENSITIVE_BINDING_DIALECTS.contains(&dialect.extract::()?.as_str()) && !ignore_case.is_truthy()?; let mut changed: HashSet = HashSet::new(); - for item in columns.call_method0("items")?.try_iter()? { + for item in mapping_items(&columns)?.try_iter()? { let (name, value): (String, Object<'py>) = item?.extract()?; if !value.is_truthy()? { continue; @@ -397,8 +398,7 @@ fn adds_physical_evidence( let Some(known) = known else { return Ok(true); }; - let known: Vec<(String, String)> = known - .call_method0("items")? + let known: Vec<(String, String)> = mapping_items(known)? .try_iter()? .map(|item| item?.extract()) .collect::>()?; @@ -435,7 +435,7 @@ fn placeholders<'py>(model: &Object<'py>) -> PyResult> { return Ok(py.None().into_bound(py)); } let placeholders: Bound<'py, PyDict> = PyDict::new(py); - for item in values.call_method0("items")?.try_iter()? { + for item in mapping_items(&values)?.try_iter()? { let (key, value): (Object<'py>, Object<'py>) = item?.extract()?; placeholders.set_item(key.str()?, value.str()?)?; } diff --git a/fensu.toml b/fensu.toml index 4a6252b06d..5abcc5e80b 100644 --- a/fensu.toml +++ b/fensu.toml @@ -492,17 +492,16 @@ edge_paths = [ "crates/sqlbuild-python/src/bindings/_helpers/records/registry.rs", ] pending_budgets = [ - "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=20", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/analysis/explicit_references.rs=19", "crates/sqlbuild-python/src/bindings/_helpers/analysis/reference_facts.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/analysis/sql_test_comparisons.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/fixture_inferences.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=12", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/nullability_rules.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/outcome_objects.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/profile_inputs.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/session.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/attachments/cursor_intrinsics.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/attachments/reference_markers.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs=25", @@ -532,7 +531,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cache/native_store.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cache/sql_test_scan_store.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs=21", - "crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/check/check_results.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/cli/argv.rs=18", "crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs=19", @@ -540,12 +539,12 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/cli/launch_state.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/cli/namespace.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs=26", - "crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_reporters.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/cli/surrogates.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_command.rs=18", - "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_execution.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_pipeline.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/clone/clone_progress.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/adapters.rs=1", @@ -555,7 +554,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouse_scope.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/cursor_roles.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/effective_config.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/sql_expansion_context.rs=2", @@ -573,7 +572,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs=20", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs=13", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_checks.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs=6", @@ -581,9 +580,9 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs=24", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/compile_timings.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/config_validation.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/deferral.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diagnostic_collector.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/diff.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/discovery.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/input_reads.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/inputs.rs=3", @@ -592,11 +591,11 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/pipeline_entries.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/plan_result.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/project.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_calls.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/relation_targets.rs=7", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/targets.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/artifacts.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/json_report.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_outputs/reuse.rs=1", @@ -609,7 +608,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_loop.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/function_views.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/inputs_view.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_input_view.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_calls.rs=4", @@ -671,7 +670,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/selection.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/arguments.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs=11", + "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/results.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/dagster_invocation/translator.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs=6", @@ -682,8 +681,8 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/cli.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/execution.rs=1", + "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/graph.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/manifest.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs=19", @@ -703,8 +702,8 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs=26", "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/console_records.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs=10", - "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/log_records.rs=8", + "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/redaction.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/command.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/diff_report/facts.rs=3", @@ -747,7 +746,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/execution_history/sqlite.rs=35", "crates/sqlbuild-python/src/bindings/_helpers/execution_history/statements.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/exported_constants/registration.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs=17", + "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/latest_rows.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/query_hashes.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_io.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/fingerprints/storage_sql.rs=1", @@ -759,21 +758,20 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/freshness/planning.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/freshness/publication.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/freshness/state_io.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/freshness/support.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/frontier/compile_frontier.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/frontier/python_types.rs=29", "crates/sqlbuild-python/src/bindings/_helpers/frontier/stage_capture.rs=14", - "crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/graph/algorithms.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/graph/execution_gates.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/graph/keys.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/project_graph.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/python_lifecycle.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/graph/views.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/graph/python_selection.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/hand_built/compiled_model.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/init_command/command.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/init_command/scaffold.rs=4", @@ -784,14 +782,14 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_phases.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_plan.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_planning.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/envelopes.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/payloads.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/lifecycle_events/validation.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=10", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/column_lineage_graph.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_cache.rs=28", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs=13", - "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_index.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_objects.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/load/dlt_destination.rs=4", @@ -799,13 +797,13 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs=17", "crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs=19", "crates/sqlbuild-python/src/bindings/_helpers/load/load_selection.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs=28", + "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/module_digests.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs=27", "crates/sqlbuild-python/src/bindings/_helpers/manifest/builder.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/conversion.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/microbatches/projection.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/microbatches/statements.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/model_config/authored_nodes.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_errors.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/model_config/config_templates.rs=4", @@ -822,7 +820,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/output_capture/context.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/output_capture/dispatcher.rs=33", "crates/sqlbuild-python/src/bindings/_helpers/output_capture/records.rs=16", - "crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs=9", + "crates/sqlbuild-python/src/bindings/_helpers/output_capture/values.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs=12", "crates/sqlbuild-python/src/bindings/_helpers/plan_command/rules.rs=10", "crates/sqlbuild-python/src/bindings/_helpers/plan_output/cursor_details.rs=5", @@ -832,9 +830,9 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/plan_output/python_identity.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/detect.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/metadata.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_changes/results.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/clone_plans.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs=4", @@ -842,14 +840,14 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/model_entries.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/models.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/relations.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_entries/values.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/graph.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/hashing.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/identities.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/json_values.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/metadata.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_identity/staleness.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_candidates.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_objects.rs=1", @@ -860,7 +858,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/compatibility.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_events.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_models.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/fingerprint.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/known_input_columns.rs=1", @@ -876,13 +874,13 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_names.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_execution.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs=6", - "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs=2", + "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/projections.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/state_inspection.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/full_refresh.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/identities.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/models.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/objects.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_phases/warehouse_state.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_records/constants.rs=2", @@ -901,15 +899,13 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/entries.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/execution.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/sql.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs=4", + "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/scope.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/sources.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/planner_scope/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/carrier.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/model_selectors.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_selection/unit_tests.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs=7", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audits.rs=8", - "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_inputs.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/cursor_types.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_metadata.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_preparation.rs=2", @@ -921,10 +917,10 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/models.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/values.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/constants.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/cursors.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/fingerprint_cache.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/semantic_sources.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/snapshot.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_columns.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_deferral.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs=6", @@ -936,7 +932,7 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/presentation_text/terminal.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/declared_relations.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/models.rs=4", - "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/native_resources.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_checks.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/project_assembly/syntax_validation.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/python_values/values.rs=5", @@ -955,22 +951,21 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/migrations.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/rule_shapes.rs=5", - "crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/records/error_classes.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/records/models.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/records/registration.rs=26", "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_compare.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/refactor/contract_edits.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/refactor/python_strings.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs=25", + "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_command.rs=24", "crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_facts.rs=11", - "crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs=3", + "crates/sqlbuild-python/src/bindings/_helpers/references/relations.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/references/source_relations.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/relation_naming/fitting.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/render/authored_sql.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_expansion.rs=24", "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_indexes.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs=15", + "crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_arguments.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_memo.rs=1", @@ -979,7 +974,6 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion_result.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/result_output/aggregation.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/result_output/checks.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/result_output/documents.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/result_output/event_writer.rs=20", @@ -1027,14 +1021,14 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs=5", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_contexts.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/scopes/declaration_resolution.rs=15", "crates/sqlbuild-python/src/bindings/_helpers/scopes/relationship_names.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_cache.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_command.rs=8", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_errors.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs=34", + "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs=33", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_loading.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_lookup.rs=9", "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs=18", @@ -1045,14 +1039,12 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_visibility.rs=5", "crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs=16", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/completion.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs=9", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=7", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/metadata.rs=6", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/resource_sql.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage_objects.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/type_recovery.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/coverage.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/declarations.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs=3", - "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs=16", + "crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs=13", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/assembly.rs=3", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/authored_ctes.rs=2", "crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/compiled_tests.rs=4", From faeadb82601c1d5271703477c39f9f0b19ba37fe Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 07:25:30 +0100 Subject: [PATCH 09/19] test: fail test runs on new native field fallbacks to Python for SQLBuild's own classes --- .../src/bindings/_helpers/records/fields.rs | 81 ++++++++++++++++++- tests/conftest.py | 7 +- tests/native_field_fallbacks.txt | 2 + 3 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 tests/native_field_fallbacks.txt diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs index 2593d59982..a80547041d 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs @@ -1,7 +1,7 @@ //! Construction, comparison and display of native record field values. -use std::collections::HashMap; -use std::sync::OnceLock; +use std::collections::{HashMap, HashSet}; +use std::sync::{Mutex, OnceLock}; use pyo3::IntoPyObjectExt; use pyo3::exceptions::{PyAttributeError, PyRuntimeError, PyTypeError}; @@ -17,8 +17,8 @@ use sqlbuild_rules::project_tree::main::pure_path_posix::pure_path_posix; use crate::bindings::_helpers::compile_driver::python_calls::imported; use crate::bindings::_helpers::native_host::host; use crate::bindings::_helpers::records::constants::{ - CACHED_PROPERTIES, CLASS_PROPERTIES, FROZEN_INSTANCE_ERROR, ORDERED_RECORDS, RECORD_FINISHERS, - RECORD_SPEC_ATTRIBUTE, RECORDS, + CACHED_PROPERTIES, CLASS_PROPERTIES, FROZEN_INSTANCE_ERROR, NATIVE_MODULE, ORDERED_RECORDS, + RECORD_FINISHERS, RECORD_SPEC_ATTRIBUTE, RECORDS, }; use crate::bindings::_helpers::records::construct::{enum_member, new_record}; use crate::bindings::_helpers::records::getters::getter_field; @@ -45,6 +45,7 @@ pub(crate) fn record_spec(cls: &Bound<'_, PyType>) -> PyResult<&'static RecordSp } /// A declared field of a native record read from its values; any other attribute, or object, by `getattr`. +#[track_caller] pub(crate) fn field<'py>(value: &Bound<'py, PyAny>, name: &str) -> PyResult> { if let Ok(cell) = value.cast::() { let record: &NativeRecord = cell.get(); @@ -64,9 +65,81 @@ pub(crate) fn field<'py>(value: &Bound<'py, PyAny>, name: &str) -> PyResult>), + Enforce(HashSet), +} + +fn strict_fields() -> Option<&'static StrictFields> { + static STRICT: OnceLock> = OnceLock::new(); + STRICT + .get_or_init(|| { + let setting: String = std::env::var(NATIVE_FIELD_STRICT_ENV_VAR).ok()?; + if let Some(path) = setting.strip_prefix("record:") { + return Some(StrictFields::Record( + path.to_owned(), + Mutex::new(HashSet::new()), + )); + } + let path: &str = setting.strip_prefix("enforce:")?; + let allowed: HashSet = std::fs::read_to_string(path) + .unwrap_or_default() + .lines() + .map(str::trim) + .filter(|line| !line.is_empty() && !line.starts_with('#')) + .map(str::to_owned) + .collect(); + Some(StrictFields::Enforce(allowed)) + }) + .as_ref() +} + +/// In strict test runs, record or reject a `getattr` fallback on one of SQLBuild's own native classes. +#[track_caller] +fn strict_fallback(value: &Bound<'_, PyAny>, name: &str) -> PyResult<()> { + let Some(strict) = strict_fields() else { + return Ok(()); + }; + let class: Bound<'_, PyType> = value.get_type(); + if class.module()?.to_cow()? != NATIVE_MODULE { + return Ok(()); + } + let caller: &std::panic::Location<'_> = std::panic::Location::caller(); + let entry: String = format!("{}\t{}.{name}", caller.file(), class.qualname()?); + match strict { + StrictFields::Enforce(allowed) if !allowed.contains(&entry) => { + Err(PyRuntimeError::new_err(format!( + "native field read fell back to Python: {}", + entry.replace('\t', " ") + ))) + } + StrictFields::Enforce(_) => Ok(()), + StrictFields::Record(path, seen) => { + let new: bool = seen + .lock() + .map(|mut held| held.insert(entry.clone())) + .unwrap_or(false); + if new + && let Ok(mut file) = std::fs::OpenOptions::new() + .create(true) + .append(true) + .open(path) + { + let _ = std::io::Write::write_all(&mut file, format!("{entry}\n").as_bytes()); + } + Ok(()) + } + } +} + /// Record properties by class and attribute name, each with its cache key when cached. type PropertyTable = HashMap<(&'static str, &'static str), (ClassProperty, Option<&'static str>)>; diff --git a/tests/conftest.py b/tests/conftest.py index 7660cdbf82..f29baaaa2d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,14 +3,19 @@ from __future__ import annotations import os +from pathlib import Path import pytest from sqlbuild._native import COMPILE_REUSE_DISABLE_ENV_VAR as REUSE_DISABLE_ENV_VAR +NATIVE_FIELD_STRICT_ENV_VAR: str = "SQLBUILD_NATIVE_FIELD_STRICT" +NATIVE_FIELD_ALLOWLIST: Path = Path(__file__).parent / "native_field_fallbacks.txt" + def pytest_configure(config: pytest.Config) -> None: - """Exercise full compiles by default; compile reuse tests opt back in explicitly.""" + """Exercise full compiles and fail on new native field fallbacks to Python by default.""" del config os.environ.setdefault(REUSE_DISABLE_ENV_VAR, "1") + os.environ.setdefault(NATIVE_FIELD_STRICT_ENV_VAR, f"enforce:{NATIVE_FIELD_ALLOWLIST}") diff --git a/tests/native_field_fallbacks.txt b/tests/native_field_fallbacks.txt new file mode 100644 index 0000000000..5e63864baa --- /dev/null +++ b/tests/native_field_fallbacks.txt @@ -0,0 +1,2 @@ +# Native field reads that still fall back to Python on SQLBuild's own classes. +# Generated by a strict record run; entries may only be removed. From a86039e77cf94a543c48aee79c9497c6bfb57679 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 07:28:58 +0100 Subject: [PATCH 10/19] test: count SQL test planning and model-chain work natively instead of spying on native functions --- .../_helpers/compile_command/target_writer.rs | 41 ++++---- .../_helpers/compile_driver/stage_work.rs | 2 + .../_helpers/planner_entries/plan_output.rs | 2 +- .../compile/test_compile_target_writer.py | 94 ++++++++++--------- 4 files changed, 76 insertions(+), 63 deletions(-) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs index 252a5a09b8..f533fd0bcc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs @@ -26,6 +26,9 @@ use crate::bindings::_helpers::compile_driver::compile_timings::record_compile_t use crate::bindings::_helpers::compile_driver::python_calls::{ KeywordArguments, call_with, imported, keywords, within, }; +use crate::bindings::_helpers::compile_driver::stage_work::{ + SQL_TEST_ARTIFACT_PLANS, SQL_TEST_MODEL_CHAINS, count_stage, +}; use crate::bindings::_helpers::compile_outputs::artifacts::{ publish_staged_artifacts, remove_stale_artifacts, }; @@ -34,12 +37,13 @@ use crate::bindings::_helpers::compile_outputs::runtime_target::{ }; use crate::bindings::_helpers::native_host::executor::ExecutorHost; use crate::bindings::_helpers::native_host::host; +use crate::bindings::_helpers::planner_entries::plan_output::sql_test_model_chain_names_by_key; use crate::bindings::_helpers::records::construct::error_class; use crate::bindings::_helpers::records::construct::new_record_with; use crate::bindings::_helpers::records::fields::field as native_field; use crate::bindings::_helpers::records::fields::mapping_get_or; -use crate::bindings::_helpers::records::ids::{ErrorId, NativeAttr, RecordId}; -use crate::bindings::_helpers::records::registry; +use crate::bindings::_helpers::records::ids::{ErrorId, RecordId}; +use crate::bindings::_helpers::sql_test_glue::plan_driver::plan_compiled_sql_test_artifacts; const COMPILED_DIR: &str = "compiled"; const MODELS_DIR: &str = "models"; @@ -362,17 +366,21 @@ fn planned_artifacts<'py>( ], )?; within(&lifecycle, |entered| { - let artifacts: Vec> = call_with( - ®istry::native(py, NativeAttr::PlanCompiledSqlTestArtifacts)?, - &[ - ("project", project.clone()), - ("tests", PyTuple::new(py, tests)?.into_any()), - ("adapter", adapter.clone()), - ( - "sql_analysis_enabled", - native_field(project, "settings")?.getattr("sql_analysis")?, - ), - ], + count_stage(py, SQL_TEST_ARTIFACT_PLANS, 1)?; + let artifacts: Vec> = plan_compiled_sql_test_artifacts( + py, + Some(keywords( + py, + &[ + ("project", project.clone()), + ("tests", PyTuple::new(py, tests)?.into_any()), + ("adapter", adapter.clone()), + ( + "sql_analysis_enabled", + native_field(&native_field(project, "settings")?, "sql_analysis")?, + ), + ], + )?), )? .try_iter()? .map(|artifact| artifact.map(Bound::unbind)) @@ -403,10 +411,9 @@ fn plan_tests<'py>( None } else { let context: IdentityContext<'py> = identity_context(project, adapter)?; - let chains: Bound<'py, PyAny> = call_with( - ®istry::native(py, NativeAttr::SqlTestModelChainNamesByKey)?, - &[("project", project.clone()), ("tests", tests.clone())], - )?; + count_stage(py, SQL_TEST_MODEL_CHAINS, 1)?; + let chains: Bound<'py, PyAny> = + sql_test_model_chain_names_by_key(project, &tests)?.into_any(); Some((context, chains)) }; let mut pending: Vec = Vec::new(); diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/stage_work.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/stage_work.rs index e57cb18e64..d9fbec14d2 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/stage_work.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/stage_work.rs @@ -23,6 +23,8 @@ pub(crate) const LINEAGE_GRAPH_BUILDS: &str = "lineage_graph_builds"; pub(crate) const PROJECT_GRAPHS: &str = "build_project_graph"; pub(crate) const FORMAT_LINT_BATCHES: &str = "format_lint_batches"; pub(crate) const FORMAT_LINT_FILES: &str = "format_lint_files"; +pub(crate) const SQL_TEST_ARTIFACT_PLANS: &str = "plan_compiled_sql_test_artifacts"; +pub(crate) const SQL_TEST_MODEL_CHAINS: &str = "sql_test_model_chain_names_by_key"; /// Compile stage runs since the last reset, by stage. #[pyclass] diff --git a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs index e166cb7a9c..2782efa869 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs @@ -741,7 +741,7 @@ pub(crate) fn plan_selected_sql_tests<'py>( /// Return model closures resolved natively in one project batch, keyed by SQL test key. #[pyfunction] #[pyo3(signature = (*, project, tests))] -fn sql_test_model_chain_names_by_key<'py>( +pub(crate) fn sql_test_model_chain_names_by_key<'py>( project: &Bound<'py, PyAny>, tests: &Bound<'py, PyAny>, ) -> PyResult> { diff --git a/tests/unit/src/sqlbuild/cli/commands/main/compile/test_compile_target_writer.py b/tests/unit/src/sqlbuild/cli/commands/main/compile/test_compile_target_writer.py index a212eaa5e2..335c170747 100644 --- a/tests/unit/src/sqlbuild/cli/commands/main/compile/test_compile_target_writer.py +++ b/tests/unit/src/sqlbuild/cli/commands/main/compile/test_compile_target_writer.py @@ -3,12 +3,10 @@ import os from dataclasses import replace from pathlib import Path -from unittest.mock import Mock import pytest import sqlbuild._native as _native -import sqlbuild._native as model_chain_module import sqlbuild._native as plan_artifacts_module from sqlbuild._native import ( ChainStep, @@ -45,6 +43,9 @@ ) from tests.unit.src.sqlbuild.compiler.manifest.helpers import build_test_project +SQL_TEST_ARTIFACT_PLANS: str = "plan_compiled_sql_test_artifacts" +SQL_TEST_MODEL_CHAINS: str = "sql_test_model_chain_names_by_key" + @pytest.mark.parametrize( "test_case", @@ -340,7 +341,6 @@ def test_given_invalid_utf8_artifact_when_writing_again_then_existing_decode_err ) def test_given_unchanged_test_artifact_when_writing_again_then_skips_test_plan_reconstruction( tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, test_case: TargetWriterCacheTestCase, ) -> None: target_dir: Path = tmp_path / "target" @@ -352,8 +352,7 @@ def test_given_unchanged_test_artifact_when_writing_again_then_skips_test_plan_r ) artifact_path: Path = next((target_dir / "compiled" / "tests").rglob("*.sql")) original_mtime_ns: int = artifact_path.stat().st_mtime_ns - planner_spy: Mock = Mock(wraps=plan_artifacts_module.plan_compiled_sql_test_artifacts) - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", planner_spy) + _ = plan_artifacts_module.compile_stage_work_info(reset=True) _ = write_static_compile_target( target_dir=target_dir, @@ -362,7 +361,10 @@ def test_given_unchanged_test_artifact_when_writing_again_then_skips_test_plan_r ) assert artifact_path.stat().st_mtime_ns == original_mtime_ns - assert planner_spy.call_count == test_case.expected_builder_calls + assert ( + plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_ARTIFACT_PLANS, 0) + == test_case.expected_builder_calls + ) @pytest.mark.parametrize( @@ -376,7 +378,6 @@ def test_given_unchanged_test_artifact_when_writing_again_then_skips_test_plan_r ) def test_given_artifact_with_moved_mtime_and_same_bytes_when_writing_then_reuses_it( tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, test_case: TargetWriterCacheTestCase, ) -> None: target_dir: Path = tmp_path / "target" @@ -389,8 +390,7 @@ def test_given_artifact_with_moved_mtime_and_same_bytes_when_writing_then_reuses artifact_path: Path = next((target_dir / "compiled" / "tests").rglob("*.sql")) moved_mtime_ns: int = artifact_path.stat().st_mtime_ns + 1_000_000_000 os.utime(artifact_path, ns=(moved_mtime_ns, moved_mtime_ns)) - planner_spy: Mock = Mock(wraps=plan_artifacts_module.plan_compiled_sql_test_artifacts) - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", planner_spy) + _ = plan_artifacts_module.compile_stage_work_info(reset=True) _ = write_static_compile_target( target_dir=target_dir, @@ -403,7 +403,10 @@ def test_given_artifact_with_moved_mtime_and_same_bytes_when_writing_then_reuses project=project, ) - assert planner_spy.call_count == test_case.expected_builder_calls + assert ( + plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_ARTIFACT_PLANS, 0) + == test_case.expected_builder_calls + ) assert artifact_path.stat().st_mtime_ns == moved_mtime_ns @@ -422,7 +425,6 @@ def test_given_artifact_with_moved_mtime_and_same_bytes_when_writing_then_reuses ) def test_given_test_with_planning_error_when_writing_twice_then_error_is_not_cached( tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, test_case: TargetWriterPlanningErrorTestCase, ) -> None: target_dir: Path = tmp_path / "target" @@ -432,8 +434,7 @@ def test_given_test_with_planning_error_when_writing_twice_then_error_is_not_cac adapter=DuckDbAdapter(), project=project, ) - planner_spy: Mock = Mock(wraps=plan_artifacts_module.plan_compiled_sql_test_artifacts) - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", planner_spy) + _ = plan_artifacts_module.compile_stage_work_info(reset=True) second: WrittenTarget = write_static_compile_target( target_dir=target_dir, @@ -441,7 +442,10 @@ def test_given_test_with_planning_error_when_writing_twice_then_error_is_not_cac project=project, ) - assert planner_spy.call_count == test_case.expected_builder_calls + assert ( + plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_ARTIFACT_PLANS, 0) + == test_case.expected_builder_calls + ) assert first.diagnostics == second.diagnostics (diagnostic,) = second.diagnostics assert diagnostic.is_error @@ -463,7 +467,6 @@ def test_given_test_with_planning_error_when_writing_twice_then_error_is_not_cac ) def test_given_changed_model_in_test_closure_when_writing_then_rebuilds_test_artifact( tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, test_case: TargetWriterCacheTestCase, ) -> None: target_dir: Path = tmp_path / "target" @@ -473,8 +476,7 @@ def test_given_changed_model_in_test_closure_when_writing_then_rebuilds_test_art adapter=DuckDbAdapter(), project=project, ) - planner_spy: Mock = Mock(wraps=plan_artifacts_module.plan_compiled_sql_test_artifacts) - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", planner_spy) + _ = plan_artifacts_module.compile_stage_work_info(reset=True) changed_project: CompiledProjectView = project_with( project=project, models=( @@ -488,7 +490,10 @@ def test_given_changed_model_in_test_closure_when_writing_then_rebuilds_test_art project=changed_project, ) - assert planner_spy.call_count == test_case.expected_builder_calls + assert ( + plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_ARTIFACT_PLANS, 0) + == test_case.expected_builder_calls + ) @pytest.mark.parametrize( @@ -498,7 +503,6 @@ def test_given_changed_model_in_test_closure_when_writing_then_rebuilds_test_art ) def test_given_changed_unrelated_model_when_writing_then_reuses_test_artifact( tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, test_case: TargetWriterCacheTestCase, ) -> None: target_dir: Path = tmp_path / "target" @@ -519,15 +523,17 @@ def test_given_changed_unrelated_model_when_writing_then_reuses_test_artifact( project=project, models=(*project.models, unrelated_model), ) - planner_spy: Mock = Mock(wraps=plan_artifacts_module.plan_compiled_sql_test_artifacts) - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", planner_spy) + _ = plan_artifacts_module.compile_stage_work_info(reset=True) _ = write_static_compile_target( target_dir=target_dir, adapter=DuckDbAdapter(), project=changed_project, ) - assert planner_spy.call_count == test_case.expected_builder_calls + assert ( + plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_ARTIFACT_PLANS, 0) + == test_case.expected_builder_calls + ) @pytest.mark.parametrize( @@ -537,7 +543,6 @@ def test_given_changed_unrelated_model_when_writing_then_reuses_test_artifact( ) def test_given_changed_test_sql_when_writing_then_rebuilds_test_artifact( tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, test_case: TargetWriterCacheTestCase, ) -> None: target_dir: Path = tmp_path / "target" @@ -547,8 +552,7 @@ def test_given_changed_test_sql_when_writing_then_rebuilds_test_artifact( adapter=DuckDbAdapter(), project=project, ) - planner_spy: Mock = Mock(wraps=plan_artifacts_module.plan_compiled_sql_test_artifacts) - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", planner_spy) + _ = plan_artifacts_module.compile_stage_work_info(reset=True) changed_test: CompiledSqlTest = replace( project.sql_tests[0], sql_body=project.sql_tests[0].sql_body + "\n-- edit" ) @@ -559,7 +563,10 @@ def test_given_changed_test_sql_when_writing_then_rebuilds_test_artifact( project=project_with(project=project, sql_tests=(changed_test,)), ) - assert planner_spy.call_count == test_case.expected_builder_calls + assert ( + plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_ARTIFACT_PLANS, 0) + == test_case.expected_builder_calls + ) @pytest.mark.parametrize( @@ -573,7 +580,6 @@ def test_given_changed_test_sql_when_writing_then_rebuilds_test_artifact( ) def test_given_changed_compile_target_when_writing_then_rebuilds_test_artifact( tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, test_case: TargetWriterCacheTestCase, ) -> None: target_dir: Path = tmp_path / "target" @@ -583,8 +589,7 @@ def test_given_changed_compile_target_when_writing_then_rebuilds_test_artifact( adapter=DuckDbAdapter(), project=project, ) - planner_spy: Mock = Mock(wraps=plan_artifacts_module.plan_compiled_sql_test_artifacts) - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", planner_spy) + _ = plan_artifacts_module.compile_stage_work_info(reset=True) _ = write_static_compile_target( target_dir=target_dir, @@ -592,7 +597,10 @@ def test_given_changed_compile_target_when_writing_then_rebuilds_test_artifact( project=project_with(project=project, effective_target_schema="changed_schema"), ) - assert planner_spy.call_count == test_case.expected_builder_calls + assert ( + plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_ARTIFACT_PLANS, 0) + == test_case.expected_builder_calls + ) @pytest.mark.parametrize( @@ -602,7 +610,6 @@ def test_given_changed_compile_target_when_writing_then_rebuilds_test_artifact( ) def test_given_compile_cache_disabled_when_writing_twice_then_rebuilds_test_artifact( tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, test_case: TargetWriterCacheTestCase, ) -> None: target_dir: Path = tmp_path / "target" @@ -610,14 +617,7 @@ def test_given_compile_cache_disabled_when_writing_twice_then_rebuilds_test_arti project=build_cached_target_writer_project(target_dir=target_dir), compile_cache_dir=None, ) - planner_spy: Mock = Mock(wraps=plan_artifacts_module.plan_compiled_sql_test_artifacts) - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", planner_spy) - closure_index_spy: Mock = Mock(wraps=model_chain_module.sql_test_model_chain_names_by_key) - monkeypatch.setattr( - model_chain_module, - "sql_test_model_chain_names_by_key", - closure_index_spy, - ) + _ = plan_artifacts_module.compile_stage_work_info(reset=True) for _ in range(2): _ = write_static_compile_target( @@ -626,8 +626,11 @@ def test_given_compile_cache_disabled_when_writing_twice_then_rebuilds_test_arti project=project, ) - assert planner_spy.call_count == test_case.expected_builder_calls - assert closure_index_spy.call_count == 0 + assert ( + plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_ARTIFACT_PLANS, 0) + == test_case.expected_builder_calls + ) + assert plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_MODEL_CHAINS, 0) == 0 assert not (target_dir / "cache" / "compiler" / "sql-test-artifacts.json").exists() @@ -638,7 +641,6 @@ def test_given_compile_cache_disabled_when_writing_twice_then_rebuilds_test_arti ) def test_given_modified_test_artifact_when_writing_then_rebuilds_expected_sql( tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, test_case: TargetWriterCacheTestCase, ) -> None: target_dir: Path = tmp_path / "target" @@ -651,8 +653,7 @@ def test_given_modified_test_artifact_when_writing_then_rebuilds_expected_sql( artifact_path: Path = next((target_dir / "compiled" / "tests").rglob("*.sql")) expected_sql: str = artifact_path.read_text(encoding="utf-8") artifact_path.write_text("SELECT 'tampered'\n", encoding="utf-8") - planner_spy: Mock = Mock(wraps=plan_artifacts_module.plan_compiled_sql_test_artifacts) - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", planner_spy) + _ = plan_artifacts_module.compile_stage_work_info(reset=True) _ = write_static_compile_target( target_dir=target_dir, @@ -660,5 +661,8 @@ def test_given_modified_test_artifact_when_writing_then_rebuilds_expected_sql( project=project, ) - assert planner_spy.call_count == test_case.expected_builder_calls + assert ( + plan_artifacts_module.compile_stage_work_info().get(SQL_TEST_ARTIFACT_PLANS, 0) + == test_case.expected_builder_calls + ) assert artifact_path.read_text(encoding="utf-8") == expected_sql From 5f721fcc240cd03c10ce552db8b1b54d5c33e034 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 07:31:06 +0100 Subject: [PATCH 11/19] test: count background SQL test planning natively and drop the planner fault-injection case --- .../compile_command/prepared_artifacts.rs | 42 +++++++++++-------- .../_helpers/compile_command/target_writer.rs | 2 +- .../_helpers/compile_driver/stage_work.rs | 1 + .../src/sqlbuild/cli/commands/main/helpers.py | 27 ------------ .../main/test_compile_prepared_artifacts.py | 22 ++++------ 5 files changed, 36 insertions(+), 58 deletions(-) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs index 02d45e76b4..16f06e3c38 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs @@ -8,16 +8,20 @@ use pyo3::types::{PyCFunction, PyDict, PyFrozenSet, PyTuple}; use pyo3::{IntoPyObjectExt, pyclass, pymethods}; use crate::bindings::_helpers::compile_command::reuse_recording::CompileArtifactWrites; +use crate::bindings::_helpers::compile_command::target_writer::{ + PlannedStaticSqlTests, plan_static_sql_tests, +}; use crate::bindings::_helpers::compile_command::target_writer::{ Prepared, planning_diagnostics, publish_staged_target, staging_changed, write_static_target, }; use crate::bindings::_helpers::compile_driver::python_calls::{ KeywordArguments, call_with, imported, keywords, }; +use crate::bindings::_helpers::compile_driver::stage_work::{ + BACKGROUND_SQL_TEST_PLANS, count_stage, +}; use crate::bindings::_helpers::compile_outputs::artifacts::staged_artifact_files; use crate::bindings::_helpers::records::fields::field as native_field; -use crate::bindings::_helpers::records::ids::NativeAttr; -use crate::bindings::_helpers::records::registry; const MIN_PREPARED_ARTIFACT_MODELS: usize = 128; const MAX_PREPARED_ARTIFACT_MODELS: usize = 5000; @@ -288,22 +292,26 @@ impl PreparedCompileArtifacts { _: Option<&Bound<'_, PyDict>>| -> PyResult> { let py: Python<'_> = arguments.py(); - Ok(call_with( - ®istry::native(py, NativeAttr::PlanStaticSqlTests)?, - &[ - ("target_dir", planned_target.bind(py).clone()), - ("adapter", planned_adapter.bind(py).clone()), - ("project", planned_project.bind(py).clone()), - ( - "artifact_writes", - recorder.as_ref().map_or_else( - || py.None().into_bound(py), - |recorder| recorder.bind(py).clone().into_any(), + count_stage(py, BACKGROUND_SQL_TEST_PLANS, 1)?; + let planned: PlannedStaticSqlTests = plan_static_sql_tests( + py, + Some(keywords( + py, + &[ + ("target_dir", planned_target.bind(py).clone()), + ("adapter", planned_adapter.bind(py).clone()), + ("project", planned_project.bind(py).clone()), + ( + "artifact_writes", + recorder.as_ref().map_or_else( + || py.None().into_bound(py), + |recorder| recorder.bind(py).clone().into_any(), + ), ), - ), - ], - )? - .unbind()) + ], + )?), + )?; + Ok(Py::new(py, planned)?.into_any()) }; let future: Bound<'py, PyAny> = submit_in_context(&executor, PyCFunction::new_closure(py, None, None, plan)?)?; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs index f533fd0bcc..230a79ca3e 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs @@ -778,7 +778,7 @@ pub(crate) fn static_sql_test_planning_diagnostics<'py>( /// Plan every SQL test whose cached artifact under `target_dir` cannot be reused. #[pyfunction] #[pyo3(signature = (**options))] -fn plan_static_sql_tests<'py>( +pub(crate) fn plan_static_sql_tests<'py>( py: Python<'py>, options: Option>, ) -> PyResult { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/stage_work.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/stage_work.rs index d9fbec14d2..074a44b231 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/stage_work.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_driver/stage_work.rs @@ -25,6 +25,7 @@ pub(crate) const FORMAT_LINT_BATCHES: &str = "format_lint_batches"; pub(crate) const FORMAT_LINT_FILES: &str = "format_lint_files"; pub(crate) const SQL_TEST_ARTIFACT_PLANS: &str = "plan_compiled_sql_test_artifacts"; pub(crate) const SQL_TEST_MODEL_CHAINS: &str = "sql_test_model_chain_names_by_key"; +pub(crate) const BACKGROUND_SQL_TEST_PLANS: &str = "background_sql_test_plans"; /// Compile stage runs since the last reset, by stage. #[pyclass] diff --git a/tests/integration/src/sqlbuild/cli/commands/main/helpers.py b/tests/integration/src/sqlbuild/cli/commands/main/helpers.py index d223da16ea..6ec216670e 100644 --- a/tests/integration/src/sqlbuild/cli/commands/main/helpers.py +++ b/tests/integration/src/sqlbuild/cli/commands/main/helpers.py @@ -15,13 +15,9 @@ import pytest import sqlbuild._native as native_module -import sqlbuild._native as plan_artifacts_module from sqlbuild._native import ( CompilerStage, CustomHostObserver, - NativeSqlTestArtifact, - NativeSqlTestPlanningError, - PlannedStaticSqlTests, PreparedCompileArtifacts, ) from sqlbuild._native import run_cli as main @@ -167,29 +163,6 @@ def keep_native_planner(monkeypatch: pytest.MonkeyPatch) -> None: """Leave the real native SQL-test planner in place.""" -def fail_native_planner(monkeypatch: pytest.MonkeyPatch) -> None: - """Make the native SQL-test planner fail as an unexpected internal error would.""" - - def fail(**kwargs: object) -> tuple[NativeSqlTestArtifact, ...]: - raise NativeSqlTestPlanningError("native SQL-test planning failed: worker stopped") - - monkeypatch.setattr(plan_artifacts_module, "plan_compiled_sql_test_artifacts", fail) - - -def record_test_planning_threads(monkeypatch: pytest.MonkeyPatch) -> list[str]: - """Record the thread-name prefix of every background SQL-test planning task.""" - - threads: list[str] = [] - plan: Callable[..., PlannedStaticSqlTests] = native_module.plan_static_sql_tests - - def recorded_plan(**kwargs: Any) -> PlannedStaticSqlTests: - threads.append(threading.current_thread().name.rpartition("_")[0]) - return plan(**kwargs) - - monkeypatch.setattr(native_module, "plan_static_sql_tests", recorded_plan) - return threads - - def use_prepared_artifacts( monkeypatch: pytest.MonkeyPatch, *, model_range: tuple[int, int] ) -> None: diff --git a/tests/integration/src/sqlbuild/cli/commands/main/test_compile_prepared_artifacts.py b/tests/integration/src/sqlbuild/cli/commands/main/test_compile_prepared_artifacts.py index d47888f705..e7f1d438b3 100644 --- a/tests/integration/src/sqlbuild/cli/commands/main/test_compile_prepared_artifacts.py +++ b/tests/integration/src/sqlbuild/cli/commands/main/test_compile_prepared_artifacts.py @@ -11,6 +11,7 @@ import pytest from filelock import FileLock +import sqlbuild._native as native_module from sqlbuild._native import run_cli as main from tests.integration.src.sqlbuild.cli.commands.main._test_types import ( AbandonedStagingCompileTestCase, @@ -26,11 +27,9 @@ compile_then_edit_one_test, compiled_files, create_owned_staging_directory, - fail_native_planner, has_second_filesystem, keep_native_planner, keep_project_unchanged, - record_test_planning_threads, skip_artifact_preparation, staging_directories, unavailable_staging_directory, @@ -41,6 +40,8 @@ write_test_planning_project, ) +BACKGROUND_SQL_TEST_PLANS: str = "background_sql_test_plans" + _SECOND_FILESYSTEM: Path = Path("/dev/shm") @@ -95,7 +96,7 @@ def test_given_compile_mode_when_preparing_artifacts_in_background_then_output_m test_case.prepare_project(project_dir=background, capsys=capsys) inline: Path = tmp_path / "inline" shutil.copytree(background, inline) - planning_threads: list[str] = record_test_planning_threads(monkeypatch) + _ = native_module.compile_stage_work_info(reset=True) background_result: tuple[int, dict[str, object]] = compile_project_json( project_dir=background, compile_args=test_case.compile_args, capsys=capsys @@ -106,7 +107,9 @@ def test_given_compile_mode_when_preparing_artifacts_in_background_then_output_m project_dir=inline, compile_args=test_case.compile_args, capsys=capsys ) - assert tuple(planning_threads) == test_case.expected_background_plans + assert native_module.compile_stage_work_info().get(BACKGROUND_SQL_TEST_PLANS, 0) == len( + test_case.expected_background_plans + ) assert background_result[0] == 0 assert background_result == inline_result assert background_result[1]["has_errors"] is False @@ -126,13 +129,6 @@ def test_given_compile_mode_when_preparing_artifacts_in_background_then_output_m keep_native_planner, "declares cursor_start or cursor_end", ), - BackgroundTestPlanningFailureTestCase( - "unexpected native planning failure without the compile cache", - ("--no-cache",), - "", - fail_native_planner, - "worker stopped", - ), ), ids=lambda case: case.description, ) @@ -152,7 +148,7 @@ def test_given_background_planning_fails_when_compiling_then_error_matches_inlin ) inline: Path = tmp_path / "inline" shutil.copytree(background, inline) - planning_threads: list[str] = record_test_planning_threads(monkeypatch) + _ = native_module.compile_stage_work_info(reset=True) background_result: tuple[int, dict[str, object]] = compile_project_json( project_dir=background, compile_args=test_case.compile_args, capsys=capsys @@ -163,7 +159,7 @@ def test_given_background_planning_fails_when_compiling_then_error_matches_inlin project_dir=inline, compile_args=test_case.compile_args, capsys=capsys ) - assert planning_threads == ["sqlbuild-tests"] + assert native_module.compile_stage_work_info().get(BACKGROUND_SQL_TEST_PLANS, 0) == 1 assert background_result[0] == 1 assert background_result == inline_result assert test_case.expected_error_fragment in json.dumps(background_result[1]) From 3dcdbacbe7777c1c305ac1da92088446f7732597 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 07:31:58 +0100 Subject: [PATCH 12/19] test: assert SQL test planning through native stage work and written artifacts in the seam test --- .../cli/commands/main/compile/_test_types.py | 1 - .../cli/commands/main/compile/helpers.py | 36 ++----------------- .../compile/test_native_analysis_seams.py | 17 ++------- 3 files changed, 6 insertions(+), 48 deletions(-) diff --git a/tests/e2e/src/sqlbuild/cli/commands/main/compile/_test_types.py b/tests/e2e/src/sqlbuild/cli/commands/main/compile/_test_types.py index a28023fb1d..f25c77f4dc 100644 --- a/tests/e2e/src/sqlbuild/cli/commands/main/compile/_test_types.py +++ b/tests/e2e/src/sqlbuild/cli/commands/main/compile/_test_types.py @@ -825,7 +825,6 @@ class NativeAnalysisSeamTestCase: """Compiling one project while the analysis stage seams are recorded.""" description: str - expected_native_returns: dict[str, list[object]] expected_stage_work: dict[str, int] diff --git a/tests/e2e/src/sqlbuild/cli/commands/main/compile/helpers.py b/tests/e2e/src/sqlbuild/cli/commands/main/compile/helpers.py index f56f722feb..489c5722af 100644 --- a/tests/e2e/src/sqlbuild/cli/commands/main/compile/helpers.py +++ b/tests/e2e/src/sqlbuild/cli/commands/main/compile/helpers.py @@ -29,7 +29,6 @@ import pytest import sqlbuild._native as native_module -import sqlbuild._native as plan_artifacts_module import sqlbuild.adapter.type_system._helpers.type_normalization as type_normalization import sqlbuild.cli.compile_reuse._helpers.provider_settings as provider_settings import sqlbuild.compiler.compile._helpers.macro_bridge.call_store as call_store_module @@ -4804,40 +4803,13 @@ def full_macro_call_runs( ) -_ANALYSIS_SEAMS: tuple[tuple[ModuleType, str], ...] = ( - (plan_artifacts_module, "plan_compiled_sql_test_artifacts"), -) - - -def record_analysis_seams(*, monkeypatch: pytest.MonkeyPatch) -> dict[str, list[object]]: - """Record what each native analysis stage seam returns, keyed by its entry name.""" - - results: dict[str, list[object]] = {} - for module, name in _ANALYSIS_SEAMS: - monkeypatch.setattr( - module, name, _recorded_seam(entry=getattr(module, name), name=name, results=results) - ) - return results - - -def _recorded_seam( - *, entry: Callable[..., object], name: str, results: dict[str, list[object]] -) -> Callable[..., object]: - def recorded(*positional: object, **arguments: object) -> object: - result: object = entry(*positional, **arguments) - results.setdefault(name, []).append(result) - return result - - return recorded - - def seam_recording_compile( *, project_dir: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], -) -> tuple[CompileReuseRun, dict[str, list[object]]]: - """Compile in this process; return the run and what each seam returned.""" +) -> CompileReuseRun: + """Compile in this process with fresh native stage counters.""" with monkeypatch.context() as patch: for name, value in { @@ -4845,10 +4817,8 @@ def seam_recording_compile( REUSE_DISABLE_ENV_VAR: "1", }.items(): patch.setenv(name, value) - seams: dict[str, list[object]] = record_analysis_seams(monkeypatch=patch) _ = native_module.compile_stage_work_info(reset=True) - run: CompileReuseRun = in_process_reuse_run(project_dir=project_dir, capsys=capsys) - return run, seams + return in_process_reuse_run(project_dir=project_dir, capsys=capsys) class NativeTypeAnswers(NamedTuple): diff --git a/tests/e2e/src/sqlbuild/cli/commands/main/compile/test_native_analysis_seams.py b/tests/e2e/src/sqlbuild/cli/commands/main/compile/test_native_analysis_seams.py index 331521fd5d..e58d1e2b7c 100644 --- a/tests/e2e/src/sqlbuild/cli/commands/main/compile/test_native_analysis_seams.py +++ b/tests/e2e/src/sqlbuild/cli/commands/main/compile/test_native_analysis_seams.py @@ -3,14 +3,10 @@ from __future__ import annotations from pathlib import Path -from unittest.mock import ANY import pytest import sqlbuild._native as native_module -from sqlbuild._native import ( - NativeSqlTestArtifact, -) from tests.e2e.src.sqlbuild.cli.commands.main.compile._test_types import ( NativeAnalysisSeamTestCase, ) @@ -25,10 +21,8 @@ [ NativeAnalysisSeamTestCase( description="models_contracts_lineage_and_sql_tests", - expected_native_returns={ - "plan_compiled_sql_test_artifacts": [ANY], - }, expected_stage_work={ + "plan_compiled_sql_test_artifacts": 1, "evaluate_model_contracts": 1, "build_project_column_lineage": 1, "infer_native_expression_source_shapes": 1, @@ -49,22 +43,17 @@ def test_given_project_when_compiling_then_native_seams_answer( ) -> None: prepared_project: Path = tmp_path / "orders" prepare_compile_reuse_project(project_dir=prepared_project) - native_run, native_seams = seam_recording_compile( + native_run = seam_recording_compile( project_dir=prepared_project, monkeypatch=monkeypatch, capsys=capsys ) assert native_run.returncode == 0, native_run.stderr assert native_run.compiled - assert native_seams == test_case.expected_native_returns stage_work: dict[str, int] = native_module.compile_stage_work_info() assert { stage: stage_work.get(stage, 0) for stage in test_case.expected_stage_work } == test_case.expected_stage_work - for seams in (native_seams,): - planned_artifacts: object = seams["plan_compiled_sql_test_artifacts"][0] - assert isinstance(planned_artifacts, tuple) - assert planned_artifacts - assert all(isinstance(artifact, NativeSqlTestArtifact) for artifact in planned_artifacts) + assert any((prepared_project / "target" / "compiled" / "tests").rglob("*.sql")) if __name__ == "__main__": From 5cf87ba92bafcc07557cfdfa10e9d37fa3a231e6 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 07:48:21 +0100 Subject: [PATCH 13/19] fix: report an unreadable native field allowlist and keep strict-mode reads explicit --- .../src/bindings/_helpers/records/fields.rs | 41 ++++++++++++------- fensu.toml | 7 ++-- .../compile/test_native_analysis_seams.py | 3 +- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs index a80547041d..f511c29605 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs @@ -25,6 +25,9 @@ use crate::bindings::_helpers::records::getters::getter_field; use crate::bindings::_helpers::records::models::{FieldDefault, NativeRecord, RecordSpec}; use crate::bindings::_helpers::records::types::ClassProperty; +/// How a test run treats `field` falling back to `getattr` on a native class: unset outside tests. +pub(crate) const NATIVE_FIELD_STRICT_ENV_VAR: &str = "SQLBUILD_NATIVE_FIELD_STRICT"; + /// Every registered record spec, in registration order. pub(crate) fn all_specs() -> impl Iterator { RECORDS.iter().flat_map(|group| group.iter()) @@ -69,20 +72,19 @@ pub(crate) fn field<'py>(value: &Bound<'py, PyAny>, name: &str) -> PyResult>), - Enforce(HashSet), + Enforce(Result, String>), } fn strict_fields() -> Option<&'static StrictFields> { static STRICT: OnceLock> = OnceLock::new(); STRICT .get_or_init(|| { - let setting: String = std::env::var(NATIVE_FIELD_STRICT_ENV_VAR).ok()?; + let setting: String = std::env::var_os(NATIVE_FIELD_STRICT_ENV_VAR)? + .to_string_lossy() + .into_owned(); if let Some(path) = setting.strip_prefix("record:") { return Some(StrictFields::Record( path.to_owned(), @@ -90,18 +92,26 @@ fn strict_fields() -> Option<&'static StrictFields> { )); } let path: &str = setting.strip_prefix("enforce:")?; - let allowed: HashSet = std::fs::read_to_string(path) - .unwrap_or_default() - .lines() - .map(str::trim) - .filter(|line| !line.is_empty() && !line.starts_with('#')) - .map(str::to_owned) - .collect(); - Some(StrictFields::Enforce(allowed)) + Some(StrictFields::Enforce( + std::fs::read_to_string(path) + .map(|listed| allowlist_entries(&listed)) + .map_err(|error| format!("cannot read native field allowlist {path}: {error}")), + )) }) .as_ref() } +/// The non-comment entries of an allowlist file. +fn allowlist_entries(listed: &str) -> HashSet { + let mut entries: HashSet = HashSet::new(); + for line in listed.lines().map(str::trim) { + if !line.is_empty() && !line.starts_with('#') { + let _ = entries.insert(line.to_owned()); + } + } + entries +} + /// In strict test runs, record or reject a `getattr` fallback on one of SQLBuild's own native classes. #[track_caller] fn strict_fallback(value: &Bound<'_, PyAny>, name: &str) -> PyResult<()> { @@ -115,13 +125,14 @@ fn strict_fallback(value: &Bound<'_, PyAny>, name: &str) -> PyResult<()> { let caller: &std::panic::Location<'_> = std::panic::Location::caller(); let entry: String = format!("{}\t{}.{name}", caller.file(), class.qualname()?); match strict { - StrictFields::Enforce(allowed) if !allowed.contains(&entry) => { + StrictFields::Enforce(Err(error)) => Err(PyRuntimeError::new_err(error.clone())), + StrictFields::Enforce(Ok(allowed)) if !allowed.contains(&entry) => { Err(PyRuntimeError::new_err(format!( "native field read fell back to Python: {}", entry.replace('\t', " ") ))) } - StrictFields::Enforce(_) => Ok(()), + StrictFields::Enforce(Ok(_)) => Ok(()), StrictFields::Record(path, seen) => { let new: bool = seen .lock() diff --git a/fensu.toml b/fensu.toml index 5abcc5e80b..220546fd6c 100644 --- a/fensu.toml +++ b/fensu.toml @@ -29,14 +29,13 @@ pending_budgets = [ "tests/e2e/src/sqlbuild/cli/commands/main/compile/helpers.py=6", "tests/integration/src/sqlbuild/adapter/type_system/test_native_type_normalization.py=1", "tests/integration/src/sqlbuild/cli/commands/main/compile_outputs/helpers.py=3", - "tests/integration/src/sqlbuild/cli/commands/main/helpers.py=6", + "tests/integration/src/sqlbuild/cli/commands/main/helpers.py=4", "tests/integration/src/sqlbuild/cli/commands/main/test_rules.py=1", "tests/integration/src/sqlbuild/compiler/contracts/helpers.py=1", "tests/integration/src/sqlbuild/compiler/model_config/helpers.py=1", "tests/integration/src/sqlbuild/compiler/pipeline/test_native_binding_catalog.py=1", "tests/integration/src/sqlbuild/compiler/project_assembly/helpers.py=1", "tests/unit/src/sqlbuild/cli/commands/main/compile/test_compile_command.py=2", - "tests/unit/src/sqlbuild/cli/commands/main/compile/test_compile_target_writer.py=10", "tests/unit/src/sqlbuild/cli/commands/main/dbt/test_dbt.py=4", "tests/unit/src/sqlbuild/cli/commands/main/init/test_run.py=2", "tests/unit/src/sqlbuild/integrations/dbt/test_execute.py=14", @@ -561,14 +560,14 @@ pending_budgets = [ "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/storage_policies.rs=1", "crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/target.rs=6", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs=1", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs=43", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs=42", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/report.rs=30", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs=48", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs=41", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/runtime_identity.rs=14", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/startup_inputs.rs=4", "crates/sqlbuild-python/src/bindings/_helpers/compile_command/surrogates.rs=2", - "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=26", + "crates/sqlbuild-python/src/bindings/_helpers/compile_command/target_writer.rs=23", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs=11", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis_cache.rs=20", "crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly.rs=3", diff --git a/tests/e2e/src/sqlbuild/cli/commands/main/compile/test_native_analysis_seams.py b/tests/e2e/src/sqlbuild/cli/commands/main/compile/test_native_analysis_seams.py index e58d1e2b7c..d0b3cb4991 100644 --- a/tests/e2e/src/sqlbuild/cli/commands/main/compile/test_native_analysis_seams.py +++ b/tests/e2e/src/sqlbuild/cli/commands/main/compile/test_native_analysis_seams.py @@ -11,6 +11,7 @@ NativeAnalysisSeamTestCase, ) from tests.e2e.src.sqlbuild.cli.commands.main.compile.helpers import ( + CompileReuseRun, prepare_compile_reuse_project, seam_recording_compile, ) @@ -43,7 +44,7 @@ def test_given_project_when_compiling_then_native_seams_answer( ) -> None: prepared_project: Path = tmp_path / "orders" prepare_compile_reuse_project(project_dir=prepared_project) - native_run = seam_recording_compile( + native_run: CompileReuseRun = seam_recording_compile( project_dir=prepared_project, monkeypatch=monkeypatch, capsys=capsys ) From a797308808d37e3fde77c64e0a2a3cee8268bd39 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 07:57:51 +0100 Subject: [PATCH 14/19] refactor: read pyo3 field getters directly and record the strict native field allowlist --- .../_helpers/analysis/binding_catalog.rs | 12 +- .../build_progress/transient_lines.rs | 2 +- .../_helpers/compile_command/models.rs | 18 +- .../bindings/_helpers/dbt_events/stream.rs | 8 +- .../bindings/_helpers/dbt_interop/runner.rs | 4 +- .../bindings/_helpers/diagnostics/trackers.rs | 12 +- .../_helpers/presentation_text/style.rs | 2 +- .../_helpers/records/getter_readers.rs | 1796 +++++++++++++++++ .../src/bindings/_helpers/records/getters.rs | 1406 ++----------- .../src/bindings/_helpers/records/mod.rs | 1 + .../_helpers/result_output/terminal_index.rs | 4 +- .../bindings/_helpers/rules/early_sql_lint.rs | 2 +- tests/native_field_fallbacks.txt | 416 ++++ 13 files changed, 2371 insertions(+), 1312 deletions(-) create mode 100644 crates/sqlbuild-python/src/bindings/_helpers/records/getter_readers.rs diff --git a/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs b/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs index fdec5fed18..0938071139 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/analysis/binding_catalog.rs @@ -39,17 +39,17 @@ const GENERIC_DIALECT: &str = "generic"; #[pyclass(module = "sqlbuild._native")] pub(crate) struct BindingCatalog { #[pyo3(get)] - schemas: Py, + pub(crate) schemas: Py, #[pyo3(get)] - dialect: String, + pub(crate) dialect: String, #[pyo3(get)] - quoted_ignore_case: bool, + pub(crate) quoted_ignore_case: bool, #[pyo3(get)] - analysis_shapes: Py, + pub(crate) analysis_shapes: Py, #[pyo3(get)] - expression_shapes: Py, + pub(crate) expression_shapes: Py, #[pyo3(get)] - native: Py, + pub(crate) native: Py, } /// A catalog's dialect, case mode, known functions and known types. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs index 72ffe392e2..c4d48bba4a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_lines.rs @@ -19,7 +19,7 @@ static SHARED_COORDINATOR: PyOnceLock> = PyOnceLock pub(crate) struct TransientLineCoordinator { /// The re-entrant lock every writer holds while it draws. #[pyo3(get)] - lock: Py, + pub(crate) lock: Py, active: Mutex>, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs index 79d636aea0..5a5a0ab866 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/compile_command/models.rs @@ -12,16 +12,16 @@ use crate::bindings::_helpers::compile_driver::python_calls::KeywordArguments; #[derive(Debug)] pub(crate) struct CompileReuseAttempt { /// `hit`, `miss` or `bypass`. - outcome: Py, - project_dir: Py, - started: Py, - check_ms: Py, - exit_code: Py, - entry_path: Py, + pub(crate) outcome: Py, + pub(crate) project_dir: Py, + pub(crate) started: Py, + pub(crate) check_ms: Py, + pub(crate) exit_code: Py, + pub(crate) entry_path: Py, /// The natively checked attempt, recorded natively after a miss. - native: Py, - selected_target: Py, - json_output: Py, + pub(crate) native: Py, + pub(crate) selected_target: Py, + pub(crate) json_output: Py, } #[pymethods] diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs index 1cae5f4041..acd8854958 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_events/stream.rs @@ -30,13 +30,13 @@ const RENDER_OPTIONS: (&[&str], &[&str]) = ( #[pyclass(module = "sqlbuild._native", frozen, get_all)] pub(crate) struct DbtEventStreamUpdate { /// The node-started progress message. - status_message: Option, + pub(crate) status_message: Option, /// The started or finished node. - result: Option>, + pub(crate) result: Option>, /// The rendered row and its messages. - row: Option, + pub(crate) row: Option, /// Whether `result` is a final result rather than a start. - finished: bool, + pub(crate) finished: bool, } /// Read dbt's JSON log lines into node progress, rows and results. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs index 25e58142b1..9f698755f9 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runner.rs @@ -35,9 +35,9 @@ const POISONED_CACHE: &str = "dbt ls cache is poisoned"; #[pyclass(module = "sqlbuild._native", frozen, subclass)] pub(crate) struct DbtRunner { #[pyo3(get)] - dbt_executable: String, + pub(crate) dbt_executable: String, #[pyo3(get)] - invoker: Option>, + pub(crate) invoker: Option>, ls_cache: Mutex, Py>>, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs index 1171a8dcb2..646afabf6c 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/diagnostics/trackers.rs @@ -57,17 +57,17 @@ pub(crate) struct BuildPhaseTimingTracker { monotonic: Py, started_at: f64, #[pyo3(get, set)] - compile_seconds: Option, + pub(crate) compile_seconds: Option, #[pyo3(get, set)] - planning_seconds: Option, + pub(crate) planning_seconds: Option, #[pyo3(get, set)] - connection_preparation_seconds: Option, + pub(crate) connection_preparation_seconds: Option, #[pyo3(get, set)] - schema_preparation_seconds: Option, + pub(crate) schema_preparation_seconds: Option, #[pyo3(get, set)] - execution_seconds: Option, + pub(crate) execution_seconds: Option, #[pyo3(get, set)] - cost_collection_seconds: Option, + pub(crate) cost_collection_seconds: Option, tokens: Mutex>>, } diff --git a/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/style.rs b/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/style.rs index a692d65322..dddb7bee3a 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/style.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/presentation_text/style.rs @@ -8,7 +8,7 @@ use sqlbuild_core::cli_text::models::CliStyle as NativeStyle; #[pyclass(name = "CliStyle", module = "sqlbuild._native", frozen)] pub(crate) struct PythonCliStyle { #[pyo3(get)] - use_color: bool, + pub(crate) use_color: bool, } impl PythonCliStyle { diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/getter_readers.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/getter_readers.rs new file mode 100644 index 0000000000..c2316a7d5e --- /dev/null +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/getter_readers.rs @@ -0,0 +1,1796 @@ +//! The per-class readers behind `getters::getter_field`, one per native pyclass. + +use pyo3::IntoPyObjectExt; +use pyo3::prelude::{Bound, PyAny, PyResult, Python}; + +use crate::bindings::_helpers::analysis::binding_catalog::BindingCatalog; +use crate::bindings::_helpers::analysis_session::session::NativeModelAnalysisSession; +use crate::bindings::_helpers::build_progress::build_callbacks::BuildProgressCallbacks; +use crate::bindings::_helpers::build_progress::transient_lines::TransientLineCoordinator; +use crate::bindings::_helpers::compile_command::models::CompileReuseAttempt; +use crate::bindings::_helpers::compile_command::prepared_artifacts::PreparedCompileArtifacts; +use crate::bindings::_helpers::compile_command::reuse_recording::{ + CompileArtifactWrites, RecordedCompileOutput, +}; +use crate::bindings::_helpers::compile_driver::diagnostic_collector::CollectedCompileDiagnostics; +use crate::bindings::_helpers::compile_driver::input_reads::CompileInputReads; +use crate::bindings::_helpers::compiled_project::audit_views::{ + NativeAuditInput, NativeCompiledAudit, +}; +use crate::bindings::_helpers::compiled_project::compiled_model_view::NativeCompiledModel; +use crate::bindings::_helpers::compiled_project::function_views::{ + NativeCompiledFunction, NativeFunctionInput, +}; +use crate::bindings::_helpers::compiled_project::inputs_view::NativeInputsView; +use crate::bindings::_helpers::compiled_project::model_input_view::NativeModelInput; +use crate::bindings::_helpers::compiled_project::project_view::NativeProjectView; +use crate::bindings::_helpers::compiled_project::seed_views::{ + NativeCompiledSeed, NativeSeedInput, +}; +use crate::bindings::_helpers::compiled_project::source_views::{ + NativeCompiledSource, NativeSourceInput, +}; +use crate::bindings::_helpers::compute_logs::storage::LocalFilesystemComputeLogStorage; +use crate::bindings::_helpers::dbt_events::stream::DbtEventStreamUpdate; +use crate::bindings::_helpers::dbt_interop::graph::DbtCombinedGraph; +use crate::bindings::_helpers::dbt_interop::reference_resolver::DbtCompileReferenceResolver; +use crate::bindings::_helpers::dbt_interop::runner::DbtRunner; +use crate::bindings::_helpers::diagnostics::trackers::BuildPhaseTimingTracker; +use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; +use crate::bindings::_helpers::event_exporting::dispatcher::EventExporterDispatcher; +use crate::bindings::_helpers::event_exporting::models::{ + BoundEventExporter, EventExportSummary, EventExporterAccounting, EventExporterCounts, + EventExporterFailure, +}; +use crate::bindings::_helpers::event_exporting::scope::EventExporterCommandScope; +use crate::bindings::_helpers::execution_history::postgres::PostgresExecutionHistory; +use crate::bindings::_helpers::execution_history::sqlite::SqliteExecutionHistory; +use crate::bindings::_helpers::graph::project_graph::CompiledProjectGraph; +use crate::bindings::_helpers::model_config::errors::NativeConfigError; +use crate::bindings::_helpers::planner_entries::models::{ + ModelPlanContext, PlanEntryBuildInputs, PlannerRelationsContext, +}; +use crate::bindings::_helpers::planner_migrations::state_inspection::MigrationStateInspection; +use crate::bindings::_helpers::planner_phases::models::{ + PlannerIdentityContext, PlannerRuntime, PlannerScopeResolution, PlannerWarehouseState, +}; +use crate::bindings::_helpers::presentation_text::style::PythonCliStyle; +use crate::bindings::_helpers::project_assembly::models::{ + NativeModelFacts, NativeProjectFacts, NativeProjectResources, NativeResourceFailure, +}; +use crate::bindings::_helpers::result_output::integration_envelope::{ + IntegrationAssetResult, IntegrationCheckResult, IntegrationResultEnvelope, +}; +use crate::bindings::_helpers::result_output::terminal_index::TerminalEventClaim; +use crate::bindings::_helpers::rules::early_sql_lint::EarlySqlLint; +use crate::bindings::_helpers::scopes::scope_index::NativeScopeIndex; +use crate::bindings::models::NativeDirectorySnapshot; + +pub(crate) fn read_binding_catalog<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "schemas" => (&this.schemas).into_bound_py_any(py), + "dialect" => (&this.dialect).into_bound_py_any(py), + "quoted_ignore_case" => (&this.quoted_ignore_case).into_bound_py_any(py), + "analysis_shapes" => (&this.analysis_shapes).into_bound_py_any(py), + "expression_shapes" => (&this.expression_shapes).into_bound_py_any(py), + "native" => (&this.native).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_model_analysis_session<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "fact_models" => this.fact_models().into_bound_py_any(py), + "cache_stats" => this.cache_stats().into_bound_py_any(py), + "sharing" => this.sharing().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_build_progress_callbacks<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "elapsed" => this.elapsed().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_transient_line_coordinator<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "lock" => (&this.lock).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_compile_reuse_attempt<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "outcome" => (&this.outcome).into_bound_py_any(py), + "project_dir" => (&this.project_dir).into_bound_py_any(py), + "started" => (&this.started).into_bound_py_any(py), + "check_ms" => (&this.check_ms).into_bound_py_any(py), + "exit_code" => (&this.exit_code).into_bound_py_any(py), + "entry_path" => (&this.entry_path).into_bound_py_any(py), + "native" => (&this.native).into_bound_py_any(py), + "selected_target" => (&this.selected_target).into_bound_py_any(py), + "json_output" => (&this.json_output).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_prepared_compile_artifacts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "enabled" => this.enabled().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_compile_artifact_writes<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "artifacts" => this + .artifacts(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_recorded_compile_output<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "stderr_lines" => this.stderr_lines(py).into_bound_py_any(py), + "stdout" => this.stdout(py).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_collected_compile_diagnostics<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "diagnostics" => this + .diagnostics(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_compile_input_reads<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "environment_names" => this + .environment_names(py) + .and_then(|value| value.into_bound_py_any(py)), + "settings_classes" => this + .settings_classes(py) + .and_then(|value| value.into_bound_py_any(py)), + "read_run_id" => this.read_run_id().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_audit_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "audit_file" => this + .audit_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "audit_block" => this + .audit_block(py) + .and_then(|value| value.into_bound_py_any(py)), + "sql_body" => this + .sql_body(py) + .and_then(|value| value.into_bound_py_any(py)), + "evaluation_mode" => this + .evaluation_mode(py) + .and_then(|value| value.into_bound_py_any(py)), + "measurement_contract" => this + .measurement_contract(py) + .and_then(|value| value.into_bound_py_any(py)), + "thresholds" => this + .thresholds(py) + .and_then(|value| value.into_bound_py_any(py)), + "minimum_samples" => this + .minimum_samples(py) + .and_then(|value| value.into_bound_py_any(py)), + "measure_sql" => this + .measure_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_sql" => this + .evidence_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_limit" => this + .evidence_limit(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_kind" => this + .attached_target_kind(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_name" => this + .attached_target_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_column_name" => this + .attached_column_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "severity" => this + .severity(py) + .and_then(|value| value.into_bound_py_any(py)), + "run_scope" => this + .run_scope(py) + .and_then(|value| value.into_bound_py_any(py)), + "always_run" => this + .always_run(py) + .and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "assembly_row" => this + .assembly_row(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_compiled_audit<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "audit_file" => this + .audit_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "audit_block" => this + .audit_block(py) + .and_then(|value| value.into_bound_py_any(py)), + "sql_body" => this + .sql_body(py) + .and_then(|value| value.into_bound_py_any(py)), + "evaluation_mode" => this + .evaluation_mode(py) + .and_then(|value| value.into_bound_py_any(py)), + "measurement_contract" => this + .measurement_contract(py) + .and_then(|value| value.into_bound_py_any(py)), + "thresholds" => this + .thresholds(py) + .and_then(|value| value.into_bound_py_any(py)), + "minimum_samples" => this + .minimum_samples(py) + .and_then(|value| value.into_bound_py_any(py)), + "measure_sql" => this + .measure_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_sql" => this + .evidence_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "evidence_limit" => this + .evidence_limit(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_kind" => this + .attached_target_kind(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_target_name" => this + .attached_target_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_column_name" => this + .attached_column_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "severity" => this + .severity(py) + .and_then(|value| value.into_bound_py_any(py)), + "run_scope" => this + .run_scope(py) + .and_then(|value| value.into_bound_py_any(py)), + "always_run" => this + .always_run(py) + .and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "scope_deps" => this + .scope_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "definition_name" => this + .definition_name(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_compiled_model<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "relative_path" => this + .relative_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "query_sql" => this + .query_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "config" => this + .config(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination" => this + .destination(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "reference_rows" => this + .reference_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "relation_key_row" => this + .relation_key_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "key_row" => this + .key_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "dep_rows" => this + .dep_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination_row" => this + .destination_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "inferred_rows" => this + .inferred_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_column_rows" => this + .schema_column_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "has_dynamic_columns" => this + .dynamic_columns_declared(py) + .and_then(|value| value.into_bound_py_any(py)), + "output_column_count" => this + .output_column_count(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "inferred_columns" => this + .inferred_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "fast_lineage_columns" => this + .fast_lineage_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "fast_lineage_has_star" => this + .fast_lineage_has_star(py) + .and_then(|value| value.into_bound_py_any(py)), + "fast_lineage_star_resolved" => this + .fast_lineage_star_resolved(py) + .and_then(|value| value.into_bound_py_any(py)), + "authored_sql" => this + .authored_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "authored_query_sql" => this + .authored_query_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "output_column_locations" => this + .output_column_locations(py) + .and_then(|value| value.into_bound_py_any(py)), + "extract_implicit_alias_columns" => this + .extract_implicit_alias_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_deps" => this + .macro_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_declarations" => this + .enum_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "constant_declarations" => this + .constant_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_columns" => this + .enum_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "binding_diagnostics" => this + .binding_diagnostics(py) + .and_then(|value| value.into_bound_py_any(py)), + "binding_validated" => this + .binding_validated(py) + .and_then(|value| value.into_bound_py_any(py)), + "dynamic_column_contract" => this + .dynamic_column_contract(py) + .and_then(|value| value.into_bound_py_any(py)), + "unchecked_output_columns" => this + .unchecked_output_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "rejected_sql_analysis_opt_out" => this + .rejected_sql_analysis_opt_out(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_compiled_function<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "arguments" => this + .arguments(py) + .and_then(|value| value.into_bound_py_any(py)), + "returns" => this + .returns(py) + .and_then(|value| value.into_bound_py_any(py)), + "body_sql" => this + .body_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "return_columns" => this + .return_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "language" => this + .language(py) + .and_then(|value| value.into_bound_py_any(py)), + "runtime_version" => this + .runtime_version(py) + .and_then(|value| value.into_bound_py_any(py)), + "entry_point" => this + .entry_point(py) + .and_then(|value| value.into_bound_py_any(py)), + "packages" => this + .packages(py) + .and_then(|value| value.into_bound_py_any(py)), + "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), + "relative_path" => this + .relative_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "source_file_path" => this + .source_file_path(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination" => this + .destination(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_destination" => this + .fingerprint_destination(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_function_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "arguments" => this + .arguments(py) + .and_then(|value| value.into_bound_py_any(py)), + "returns" => this + .returns(py) + .and_then(|value| value.into_bound_py_any(py)), + "body_sql" => this + .body_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "return_columns" => this + .return_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "language" => this + .language(py) + .and_then(|value| value.into_bound_py_any(py)), + "runtime_version" => this + .runtime_version(py) + .and_then(|value| value.into_bound_py_any(py)), + "entry_point" => this + .entry_point(py) + .and_then(|value| value.into_bound_py_any(py)), + "packages" => this + .packages(py) + .and_then(|value| value.into_bound_py_any(py)), + "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), + "description" => this + .description(py) + .and_then(|value| value.into_bound_py_any(py)), + "function_file" => this + .function_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "database" => this + .database(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema" => this + .schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "logical_database" => this + .logical_database(py) + .and_then(|value| value.into_bound_py_any(py)), + "logical_schema" => this + .logical_schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_database" => this + .fingerprint_database(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_schema" => this + .fingerprint_schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_logical_database" => this + .fingerprint_logical_database(py) + .and_then(|value| value.into_bound_py_any(py)), + "fingerprint_logical_schema" => this + .fingerprint_logical_schema(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "assembly_row" => this + .assembly_row(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_inputs_view<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "run_id" => this.run_id().into_bound_py_any(py), + "effective_target_name" => this.effective_target_name().into_bound_py_any(py), + "no_sql_validation" => this.is_sql_validation_skipped().into_bound_py_any(py), + "model_inputs" => this.model_inputs(py).into_bound_py_any(py), + "native_project" => this.native_project(py).into_bound_py_any(py), + "project_config" => this.project_config(py).into_bound_py_any(py), + "local_config" => this.local_config(py).into_bound_py_any(py), + "discovered_inputs" => this.discovered_inputs(py).into_bound_py_any(py), + "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), + "effective_target" => this.effective_target(py).into_bound_py_any(py), + "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), + "effective_connection" => this.effective_connection(py).into_bound_py_any(py), + "effective_vars" => this.effective_vars(py).into_bound_py_any(py), + "macro_context" => this.macro_context(py).into_bound_py_any(py), + "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), + "public_enums" => this.public_enums(py).into_bound_py_any(py), + "public_constants" => this.public_constants(py).into_bound_py_any(py), + "external_sql_reference_resolver" => this + .external_sql_reference_resolver(py) + .into_bound_py_any(py), + "effective_settings" => this.effective_settings(py).into_bound_py_any(py), + "seed_inputs" => this.seed_inputs(py).into_bound_py_any(py), + "source_inputs" => this.source_inputs(py).into_bound_py_any(py), + "sql_function_inputs" => this.sql_function_inputs(py).into_bound_py_any(py), + "test_inputs" => this.test_inputs(py).into_bound_py_any(py), + "scenario_inputs" => this.scenario_inputs(py).into_bound_py_any(py), + "audit_inputs" => this.audit_inputs(py).into_bound_py_any(py), + "diagnostics" => this.diagnostics(py).into_bound_py_any(py), + "scope_index" => this.scope_index(py).into_bound_py_any(py), + "declaration_scope" => this.declaration_scope(py).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_model_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "model_file" => this + .model_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "config" => this + .config(py) + .and_then(|value| value.into_bound_py_any(py)), + "query_sql" => this + .query_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_source_sql" => this + .macro_source_sql(py) + .and_then(|value| value.into_bound_py_any(py)), + "references" => this + .references(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "reference_rows" => this + .reference_rows(py) + .and_then(|value| value.into_bound_py_any(py)), + "relation_key_row" => this + .relation_key_row(py) + .and_then(|value| value.into_bound_py_any(py)), + "attached_schema_name" => this + .attached_schema_name(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_file" => this.schema_file(py).into_bound_py_any(py), + "sql_validation_enabled" => this + .sql_validation_enabled(py) + .and_then(|value| value.into_bound_py_any(py)), + "rejected_sql_analysis_opt_out" => this + .rejected_sql_analysis_opt_out(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_declarations" => this + .enum_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "constant_declarations" => this + .constant_declarations(py) + .and_then(|value| value.into_bound_py_any(py)), + "enum_columns" => this + .enum_columns(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_deps" => this + .macro_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "macro_usages" => this + .macro_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "sql_expansion" => this + .sql_expansion(py) + .and_then(|value| value.into_bound_py_any(py)), + "lint_expansion" => this + .lint_expansion(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_project_view<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "run_id" => this.run_id().into_bound_py_any(py), + "effective_target_name" => this.effective_target_name().into_bound_py_any(py), + "effective_target_database" => this.effective_target_database().into_bound_py_any(py), + "effective_target_schema" => this.effective_target_schema().into_bound_py_any(py), + "sql_analysis_dialect" => this.sql_analysis_dialect().into_bound_py_any(py), + "enforce_explicit_references" => { + this.is_explicit_reference_enforced().into_bound_py_any(py) + } + "models" => this.models(py).into_bound_py_any(py), + "native_project" => this.native_project(py).into_bound_py_any(py), + "effective_connection" => this.effective_connection(py).into_bound_py_any(py), + "effective_vars" => this.effective_vars(py).into_bound_py_any(py), + "binding_catalog" => this.binding_catalog(py).into_bound_py_any(py), + "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), + "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), + "loader_functions" => this.loader_functions(py).into_bound_py_any(py), + "hook_functions" => this.hook_functions(py).into_bound_py_any(py), + "sql_hook_files" => this.sql_hook_files(py).into_bound_py_any(py), + "materialization_files" => this.materialization_files(py).into_bound_py_any(py), + "public_enums" => this.public_enums(py).into_bound_py_any(py), + "public_constants" => this.public_constants(py).into_bound_py_any(py), + "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), + "external_sql_reference_resolver" => this + .external_sql_reference_resolver(py) + .into_bound_py_any(py), + "native_session" => this.native_session(py).into_bound_py_any(py), + "settings" => this.settings(py).into_bound_py_any(py), + "scenario" => this.scenario(py).into_bound_py_any(py), + "sources" => this.sources(py).into_bound_py_any(py), + "seeds" => this.seeds(py).into_bound_py_any(py), + "functions" => this.functions(py).into_bound_py_any(py), + "audits" => this.audits(py).into_bound_py_any(py), + "sql_tests" => this.sql_tests(py).into_bound_py_any(py), + "sql_scenarios" => this.sql_scenarios(py).into_bound_py_any(py), + "diagnostics" => this.diagnostics(py).into_bound_py_any(py), + "unmatched_literal_sql_relations" => this + .unmatched_literal_sql_relations(py) + .into_bound_py_any(py), + "scope_index" => this.scope_index(py).into_bound_py_any(py), + "sql_expansions" => this + .sql_expansions(py) + .and_then(|value| value.into_bound_py_any(py)), + "lineage_graph" => this + .lineage_graph(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_compiled_seed<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).into_bound_py_any(py), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "seed_file" => this + .seed_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_file" => this + .schema_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "destination" => this + .destination(py) + .and_then(|value| value.into_bound_py_any(py)), + "external" => this.is_external().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_seed_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "seed_file" => this + .seed_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_entry" => this + .schema_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "schema_file" => this + .schema_file(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_compiled_source<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), + "deps" => this.deps(py).into_bound_py_any(py), + "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), + "source_entry" => this + .source_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "source_file" => this + .source_file(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_source_input<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "source_entry" => this + .source_entry(py) + .and_then(|value| value.into_bound_py_any(py)), + "source_file" => this + .source_file(py) + .and_then(|value| value.into_bound_py_any(py)), + "declaration_usages" => this + .declaration_usages(py) + .and_then(|value| value.into_bound_py_any(py)), + "assembly_row" => this + .assembly_row(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_local_filesystem_compute_log_storage<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "root" => this.root(py).and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_dbt_event_stream_update<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "status_message" => (&this.status_message).into_bound_py_any(py), + "result" => (&this.result).into_bound_py_any(py), + "row" => (&this.row).into_bound_py_any(py), + "finished" => (&this.finished).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_dbt_combined_graph<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "nodes" => this.nodes(py).and_then(|value| value.into_bound_py_any(py)), + "upstream_deps" => this + .upstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "downstream_deps" => this + .downstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_dbt_compile_reference_resolver<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "_dbt_manifest" => this.dbt_manifest(py).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_dbt_runner<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "dbt_executable" => (&this.dbt_executable).into_bound_py_any(py), + "invoker" => (&this.invoker).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_build_phase_timing_tracker<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "compile_seconds" => (&this.compile_seconds).into_bound_py_any(py), + "planning_seconds" => (&this.planning_seconds).into_bound_py_any(py), + "connection_preparation_seconds" => { + (&this.connection_preparation_seconds).into_bound_py_any(py) + } + "schema_preparation_seconds" => (&this.schema_preparation_seconds).into_bound_py_any(py), + "execution_seconds" => (&this.execution_seconds).into_bound_py_any(py), + "cost_collection_seconds" => (&this.cost_collection_seconds).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_model_file<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "file_path" => this.file_path(py).into_bound_py_any(py), + "relative_path" => this.relative_path(py).into_bound_py_any(py), + "contents" => this.contents(py).into_bound_py_any(py), + "header_values" => this.header_values(py).into_bound_py_any(py), + "header_column_locations" => this + .header_column_locations(py) + .and_then(|value| value.into_bound_py_any(py)), + "output_column_locations" => this + .output_column_locations(py) + .and_then(|value| value.into_bound_py_any(py)), + "query_sql" => this.query_sql(py).into_bound_py_any(py), + "enum_declarations" => this.enum_declarations(py).into_bound_py_any(py), + "constant_declarations" => this.constant_declarations(py).into_bound_py_any(py), + "extract_implicit_alias_columns" => { + this.extract_implicit_alias_columns().into_bound_py_any(py) + } + _ => return None, + }) +} + +pub(crate) fn read_native_directory_snapshot<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project_dir" => this.project_dir(py).into_bound_py_any(py), + "memo" => this.memo(py).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_event_exporter_dispatcher<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "thread" => this.thread(py).into_bound_py_any(py), + "notification_thread" => this.notification_thread(py).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_bound_event_exporter<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "name" => this.name().into_bound_py_any(py), + "function" => this.function(py).into_bound_py_any(py), + "provider_arguments" => this.provider_arguments(py).into_bound_py_any(py), + "event_kinds" => this + .event_kinds(py) + .and_then(|value| value.into_bound_py_any(py)), + "min_severity" => this + .min_severity(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_event_export_summary<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "aggregate" => this.aggregate().into_bound_py_any(py), + "per_exporter" => this + .per_exporter(py) + .and_then(|value| value.into_bound_py_any(py)), + "queue_depth" => this.queue_depth().into_bound_py_any(py), + "queue_capacity" => this.queue_capacity().into_bound_py_any(py), + "flush_complete" => this.flush_complete().into_bound_py_any(py), + "accepted" => this.accepted().into_bound_py_any(py), + "filtered" => this.filtered().into_bound_py_any(py), + "delivered" => this.delivered().into_bound_py_any(py), + "failed" => this.failed().into_bound_py_any(py), + "dropped" => this.dropped().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_event_exporter_accounting<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "exporter_name" => this.exporter_name().into_bound_py_any(py), + "counts" => this.counts().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_event_exporter_counts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "accepted" => this.accepted().into_bound_py_any(py), + "filtered" => this.filtered().into_bound_py_any(py), + "delivered" => this.delivered().into_bound_py_any(py), + "failed" => this.failed().into_bound_py_any(py), + "dropped" => this.dropped().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_event_exporter_failure<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "exporter_name" => this.exporter_name().into_bound_py_any(py), + "error_type" => this.error_type().into_bound_py_any(py), + "event_kind" => this.event_kind().into_bound_py_any(py), + "event_severity" => this + .event_severity(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_event_exporter_command_scope<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "dispatcher" => this.dispatcher(py).into_bound_py_any(py), + "provider_session" => this + .provider_session(py) + .and_then(|value| value.into_bound_py_any(py)), + "project_dir" => this + .project_dir(py) + .and_then(|value| value.into_bound_py_any(py)), + "providers" => this + .providers(py) + .and_then(|value| value.into_bound_py_any(py)), + "event_exporters" => this + .event_exporters(py) + .and_then(|value| value.into_bound_py_any(py)), + "command_output_sinks" => this + .command_output_sinks(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_postgres_execution_history<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project_calls" => this.project_calls().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_sqlite_execution_history<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "path" => this.path(py).and_then(|value| value.into_bound_py_any(py)), + "project_calls" => this.project_calls().into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_compiled_project_graph<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project" => this.project_attribute(py).into_bound_py_any(py), + "native" => this.native_attribute(py).into_bound_py_any(py), + "lineage_views" => this + .lineage_views(py) + .and_then(|value| value.into_bound_py_any(py)), + "upstream_deps" => this + .upstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "downstream_deps" => this + .downstream_deps(py) + .and_then(|value| value.into_bound_py_any(py)), + "tag_index" => this + .tag_index(py) + .and_then(|value| value.into_bound_py_any(py)), + "path_index" => this + .path_index(py) + .and_then(|value| value.into_bound_py_any(py)), + "all_keys" => this + .all_keys(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_native_config_error<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "class_name" => (&this.class_name).into_bound_py_any(py), + "message" => (&this.message).into_bound_py_any(py), + "code" => (&this.code).into_bound_py_any(py), + "help" => (&this.help).into_bound_py_any(py), + "key" => (&this.key).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_model_plan_context<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "model_locations" => (&this.model_locations).into_bound_py_any(py), + "models_by_name" => (&this.models_by_name).into_bound_py_any(py), + "seed_locations" => (&this.seed_locations).into_bound_py_any(py), + "function_locations" => (&this.function_locations).into_bound_py_any(py), + "source_map" => (&this.source_map).into_bound_py_any(py), + "source_warehouse_columns" => (&this.source_warehouse_columns).into_bound_py_any(py), + "star_exclude_keyword" => (&this.star_exclude_keyword).into_bound_py_any(py), + "functions_by_name" => (&this.functions_by_name).into_bound_py_any(py), + "runtime_cursor_producer_names" => { + (&this.runtime_cursor_producer_names).into_bound_py_any(py) + } + "future_cursor_config" => (&this.future_cursor_config).into_bound_py_any(py), + "start_cursor_config" => (&this.start_cursor_config).into_bound_py_any(py), + "invocation_time" => (&this.invocation_time).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_plan_entry_build_inputs<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "source_freshness_blocked_model_names" => { + (&this.source_freshness_blocked_model_names).into_bound_py_any(py) + } + "external_blocked_model_names" => { + (&this.external_blocked_model_names).into_bound_py_any(py) + } + "start_cursor_override" => (&this.start_cursor_override).into_bound_py_any(py), + "end_cursor_override" => (&this.end_cursor_override).into_bound_py_any(py), + "future_cursor_config" => (&this.future_cursor_config).into_bound_py_any(py), + "start_cursor_config" => (&this.start_cursor_config).into_bound_py_any(py), + "invocation_time" => (&this.invocation_time).into_bound_py_any(py), + "max_microbatches" => (&this.max_microbatches).into_bound_py_any(py), + "max_microbatches_is_override" => { + (&this.max_microbatches_is_override).into_bound_py_any(py) + } + "microbatch_limit_action" => (&this.microbatch_limit_action).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_planner_relations_context<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "model_locations" => (&this.model_locations).into_bound_py_any(py), + "seed_locations" => (&this.seed_locations).into_bound_py_any(py), + "function_locations" => (&this.function_locations).into_bound_py_any(py), + "source_map" => (&this.source_map).into_bound_py_any(py), + "source_read_map" => (&this.source_read_map).into_bound_py_any(py), + "python_source_read_map" => (&this.python_source_read_map).into_bound_py_any(py), + "source_warehouse_columns" => (&this.source_warehouse_columns).into_bound_py_any(py), + "star_exclude_keyword" => (&this.star_exclude_keyword).into_bound_py_any(py), + "listed_source_names" => (&this.listed_source_names).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_migration_state_inspection<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "database" => this.database(py).into_bound_py_any(py), + "events" => this + .events(py) + .and_then(|value| value.into_bound_py_any(py)), + "column_events" => this + .column_events(py) + .and_then(|value| value.into_bound_py_any(py)), + "old_name_histories" => this + .old_name_histories(py) + .and_then(|value| value.into_bound_py_any(py)), + _ => return None, + }) +} + +pub(crate) fn read_planner_identity_context<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "version_identities" => (&this.version_identities).into_bound_py_any(py), + "stale_warning_identities" => (&this.stale_warning_identities).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_planner_runtime<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "project" => (&this.project).into_bound_py_any(py), + "adapter" => (&this.adapter).into_bound_py_any(py), + "connection" => (&this.connection).into_bound_py_any(py), + "project_config" => (&this.project_config).into_bound_py_any(py), + "local_config" => (&this.local_config).into_bound_py_any(py), + "on_progress" => (&this.on_progress).into_bound_py_any(py), + "invocation_time" => (&this.invocation_time).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_planner_scope_resolution<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "selected_scope" => (&this.selected_scope).into_bound_py_any(py), + "stale_warning_scope" => (&this.stale_warning_scope).into_bound_py_any(py), + "inspection_scope" => (&this.inspection_scope).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_planner_warehouse_state<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "snapshot" => (&this.snapshot).into_bound_py_any(py), + "inspection_relations" => (&this.inspection_relations).into_bound_py_any(py), + "migration_entries" => (&this.migration_entries).into_bound_py_any(py), + "migration_warnings" => (&this.migration_warnings).into_bound_py_any(py), + "column_migration_entries" => (&this.column_migration_entries).into_bound_py_any(py), + "column_rename_hints" => (&this.column_rename_hints).into_bound_py_any(py), + "old_name_view_entries" => (&this.old_name_view_entries).into_bound_py_any(py), + "old_name_views" => (&this.old_name_views).into_bound_py_any(py), + "migration_fingerprints" => (&this.migration_fingerprints).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_python_cli_style<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "use_color" => (&this.use_color).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_model_facts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "deps" => (&this.deps).into_bound_py_any(py), + "dynamic_contract" => (&this.dynamic_contract).into_bound_py_any(py), + "syntax_valid" => (&this.syntax_valid).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_project_facts<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "models" => (&this.models).into_bound_py_any(py), + "resources" => (&this.resources).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_project_resources<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "model_deps" => (&this.model_deps).into_bound_py_any(py), + "model_syntax_valid" => (&this.model_syntax_valid).into_bound_py_any(py), + "source_namespaces" => (&this.source_namespaces).into_bound_py_any(py), + "seed_namespaces" => (&this.seed_namespaces).into_bound_py_any(py), + "function_deps" => (&this.function_deps).into_bound_py_any(py), + "audit_scope_deps" => (&this.audit_scope_deps).into_bound_py_any(py), + "failure" => (&this.failure).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_resource_failure<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "slot" => (&this.slot).into_bound_py_any(py), + "index" => (&this.index).into_bound_py_any(py), + "error" => (&this.error).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_integration_asset_result<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "as_dict" => return None, + _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), + }) +} + +pub(crate) fn read_integration_check_result<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "as_dict" | "decoded" | "parsed" => return None, + _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), + }) +} + +pub(crate) fn read_integration_result_envelope<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "asset" => this.asset(py).into_bound_py_any(py), + "checks" => this.checks(py).into_bound_py_any(py), + "from_json" | "from_json_without_optional_enrichment" | "register" | "to_json" => { + return None; + } + _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), + }) +} + +pub(crate) fn read_terminal_event_claim<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "terminal" => (&this.terminal).into_bound_py_any(py), + "event_sequence" => (&this.event_sequence).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_early_sql_lint<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "enabled" => (&this.enabled).into_bound_py_any(py), + _ => return None, + }) +} + +pub(crate) fn read_native_scope_index<'py>( + value: &Bound<'py, PyAny>, + name: &str, +) -> Option>> { + let py: Python<'py> = value.py(); + let Ok(cell) = value.cast::() else { + return None; + }; + let Ok(this) = cell.try_borrow() else { + return None; + }; + Some(match name { + "index" => this.index(py).into_bound_py_any(py), + "has_scoped_relationship_declarations" => this + .has_scoped_relationship_declarations() + .into_bound_py_any(py), + _ => return None, + }) +} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs index 7b3b08b2c7..62205596c6 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/getters.rs @@ -2,12 +2,14 @@ use std::collections::HashMap; -use pyo3::IntoPyObjectExt; use pyo3::prelude::{Bound, PyAny, PyAnyMethods, PyResult, Python}; use pyo3::sync::PyOnceLock; +use crate::bindings::_helpers::analysis::binding_catalog::BindingCatalog; use crate::bindings::_helpers::analysis_session::session::NativeModelAnalysisSession; use crate::bindings::_helpers::build_progress::build_callbacks::BuildProgressCallbacks; +use crate::bindings::_helpers::build_progress::transient_lines::TransientLineCoordinator; +use crate::bindings::_helpers::compile_command::models::CompileReuseAttempt; use crate::bindings::_helpers::compile_command::prepared_artifacts::PreparedCompileArtifacts; use crate::bindings::_helpers::compile_command::reuse_recording::{ CompileArtifactWrites, RecordedCompileOutput, @@ -31,8 +33,11 @@ use crate::bindings::_helpers::compiled_project::source_views::{ NativeCompiledSource, NativeSourceInput, }; use crate::bindings::_helpers::compute_logs::storage::LocalFilesystemComputeLogStorage; +use crate::bindings::_helpers::dbt_events::stream::DbtEventStreamUpdate; use crate::bindings::_helpers::dbt_interop::graph::DbtCombinedGraph; use crate::bindings::_helpers::dbt_interop::reference_resolver::DbtCompileReferenceResolver; +use crate::bindings::_helpers::dbt_interop::runner::DbtRunner; +use crate::bindings::_helpers::diagnostics::trackers::BuildPhaseTimingTracker; use crate::bindings::_helpers::discovery::model_file_record::NativeModelFile; use crate::bindings::_helpers::event_exporting::dispatcher::EventExporterDispatcher; use crate::bindings::_helpers::event_exporting::models::{ @@ -43,10 +48,46 @@ use crate::bindings::_helpers::event_exporting::scope::EventExporterCommandScope use crate::bindings::_helpers::execution_history::postgres::PostgresExecutionHistory; use crate::bindings::_helpers::execution_history::sqlite::SqliteExecutionHistory; use crate::bindings::_helpers::graph::project_graph::CompiledProjectGraph; +use crate::bindings::_helpers::model_config::errors::NativeConfigError; +use crate::bindings::_helpers::planner_entries::models::{ + ModelPlanContext, PlanEntryBuildInputs, PlannerRelationsContext, +}; use crate::bindings::_helpers::planner_migrations::state_inspection::MigrationStateInspection; +use crate::bindings::_helpers::planner_phases::models::{ + PlannerIdentityContext, PlannerRuntime, PlannerScopeResolution, PlannerWarehouseState, +}; +use crate::bindings::_helpers::presentation_text::style::PythonCliStyle; +use crate::bindings::_helpers::project_assembly::models::{ + NativeModelFacts, NativeProjectFacts, NativeProjectResources, NativeResourceFailure, +}; +use crate::bindings::_helpers::records::getter_readers::{ + read_binding_catalog, read_bound_event_exporter, read_build_phase_timing_tracker, + read_build_progress_callbacks, read_collected_compile_diagnostics, + read_compile_artifact_writes, read_compile_input_reads, read_compile_reuse_attempt, + read_compiled_project_graph, read_dbt_combined_graph, read_dbt_compile_reference_resolver, + read_dbt_event_stream_update, read_dbt_runner, read_early_sql_lint, read_event_export_summary, + read_event_exporter_accounting, read_event_exporter_command_scope, read_event_exporter_counts, + read_event_exporter_dispatcher, read_event_exporter_failure, read_integration_asset_result, + read_integration_check_result, read_integration_result_envelope, + read_local_filesystem_compute_log_storage, read_migration_state_inspection, + read_model_plan_context, read_native_audit_input, read_native_compiled_audit, + read_native_compiled_function, read_native_compiled_model, read_native_compiled_seed, + read_native_compiled_source, read_native_config_error, read_native_directory_snapshot, + read_native_function_input, read_native_inputs_view, read_native_model_analysis_session, + read_native_model_facts, read_native_model_file, read_native_model_input, + read_native_project_facts, read_native_project_resources, read_native_project_view, + read_native_resource_failure, read_native_scope_index, read_native_seed_input, + read_native_source_input, read_plan_entry_build_inputs, read_planner_identity_context, + read_planner_relations_context, read_planner_runtime, read_planner_scope_resolution, + read_planner_warehouse_state, read_postgres_execution_history, read_prepared_compile_artifacts, + read_python_cli_style, read_recorded_compile_output, read_sqlite_execution_history, + read_terminal_event_claim, read_transient_line_coordinator, +}; use crate::bindings::_helpers::result_output::integration_envelope::{ IntegrationAssetResult, IntegrationCheckResult, IntegrationResultEnvelope, }; +use crate::bindings::_helpers::result_output::terminal_index::TerminalEventClaim; +use crate::bindings::_helpers::rules::early_sql_lint::EarlySqlLint; use crate::bindings::_helpers::scopes::scope_index::NativeScopeIndex; use crate::bindings::models::NativeDirectorySnapshot; @@ -62,6 +103,10 @@ pub(crate) fn getter_field<'py>( let py: Python<'py> = value.py(); let table: &HashMap = DISPATCH.get_or_init(py, || { let mut table: HashMap = HashMap::new(); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_binding_catalog, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_native_model_analysis_session, @@ -70,6 +115,14 @@ pub(crate) fn getter_field<'py>( py.get_type::().as_ptr() as usize, read_build_progress_callbacks, ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_transient_line_coordinator, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_compile_reuse_attempt, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_prepared_compile_artifacts, @@ -142,6 +195,10 @@ pub(crate) fn getter_field<'py>( py.get_type::().as_ptr() as usize, read_local_filesystem_compute_log_storage, ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_dbt_event_stream_update, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_dbt_combined_graph, @@ -150,6 +207,14 @@ pub(crate) fn getter_field<'py>( py.get_type::().as_ptr() as usize, read_dbt_compile_reference_resolver, ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_dbt_runner, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_build_phase_timing_tracker, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_native_model_file, @@ -198,10 +263,62 @@ pub(crate) fn getter_field<'py>( py.get_type::().as_ptr() as usize, read_compiled_project_graph, ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_config_error, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_model_plan_context, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_plan_entry_build_inputs, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_planner_relations_context, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_migration_state_inspection, ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_planner_identity_context, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_planner_runtime, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_planner_scope_resolution, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_planner_warehouse_state, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_python_cli_style, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_model_facts, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_project_facts, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_project_resources, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_native_resource_failure, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_integration_asset_result, @@ -214,6 +331,14 @@ pub(crate) fn getter_field<'py>( py.get_type::().as_ptr() as usize, read_integration_result_envelope, ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_terminal_event_claim, + ); + let _ = table.insert( + py.get_type::().as_ptr() as usize, + read_early_sql_lint, + ); let _ = table.insert( py.get_type::().as_ptr() as usize, read_native_scope_index, @@ -223,1282 +348,3 @@ pub(crate) fn getter_field<'py>( let dispatch: &Dispatch = table.get(&(value.get_type().as_ptr() as usize))?; dispatch(value, name) } - -fn read_native_model_analysis_session<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "fact_models" => this.fact_models().into_bound_py_any(py), - "cache_stats" => this.cache_stats().into_bound_py_any(py), - "sharing" => this.sharing().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_build_progress_callbacks<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "elapsed" => this.elapsed().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_prepared_compile_artifacts<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "enabled" => this.enabled().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_compile_artifact_writes<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "artifacts" => this - .artifacts(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_recorded_compile_output<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "stderr_lines" => this.stderr_lines(py).into_bound_py_any(py), - "stdout" => this.stdout(py).into_bound_py_any(py), - _ => return None, - }) -} - -fn read_collected_compile_diagnostics<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "diagnostics" => this - .diagnostics(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_compile_input_reads<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "environment_names" => this - .environment_names(py) - .and_then(|value| value.into_bound_py_any(py)), - "settings_classes" => this - .settings_classes(py) - .and_then(|value| value.into_bound_py_any(py)), - "read_run_id" => this.read_run_id().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_native_audit_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "audit_file" => this - .audit_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "audit_block" => this - .audit_block(py) - .and_then(|value| value.into_bound_py_any(py)), - "sql_body" => this - .sql_body(py) - .and_then(|value| value.into_bound_py_any(py)), - "evaluation_mode" => this - .evaluation_mode(py) - .and_then(|value| value.into_bound_py_any(py)), - "measurement_contract" => this - .measurement_contract(py) - .and_then(|value| value.into_bound_py_any(py)), - "thresholds" => this - .thresholds(py) - .and_then(|value| value.into_bound_py_any(py)), - "minimum_samples" => this - .minimum_samples(py) - .and_then(|value| value.into_bound_py_any(py)), - "measure_sql" => this - .measure_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "evidence_sql" => this - .evidence_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "evidence_limit" => this - .evidence_limit(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_target_kind" => this - .attached_target_kind(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_target_name" => this - .attached_target_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_column_name" => this - .attached_column_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "severity" => this - .severity(py) - .and_then(|value| value.into_bound_py_any(py)), - "run_scope" => this - .run_scope(py) - .and_then(|value| value.into_bound_py_any(py)), - "always_run" => this - .always_run(py) - .and_then(|value| value.into_bound_py_any(py)), - "description" => this - .description(py) - .and_then(|value| value.into_bound_py_any(py)), - "declaration_usages" => this - .declaration_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "assembly_row" => this - .assembly_row(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_native_compiled_audit<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "audit_file" => this - .audit_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "audit_block" => this - .audit_block(py) - .and_then(|value| value.into_bound_py_any(py)), - "sql_body" => this - .sql_body(py) - .and_then(|value| value.into_bound_py_any(py)), - "evaluation_mode" => this - .evaluation_mode(py) - .and_then(|value| value.into_bound_py_any(py)), - "measurement_contract" => this - .measurement_contract(py) - .and_then(|value| value.into_bound_py_any(py)), - "thresholds" => this - .thresholds(py) - .and_then(|value| value.into_bound_py_any(py)), - "minimum_samples" => this - .minimum_samples(py) - .and_then(|value| value.into_bound_py_any(py)), - "measure_sql" => this - .measure_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "evidence_sql" => this - .evidence_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "evidence_limit" => this - .evidence_limit(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_target_kind" => this - .attached_target_kind(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_target_name" => this - .attached_target_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_column_name" => this - .attached_column_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "severity" => this - .severity(py) - .and_then(|value| value.into_bound_py_any(py)), - "run_scope" => this - .run_scope(py) - .and_then(|value| value.into_bound_py_any(py)), - "always_run" => this - .always_run(py) - .and_then(|value| value.into_bound_py_any(py)), - "description" => this - .description(py) - .and_then(|value| value.into_bound_py_any(py)), - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "scope_deps" => this - .scope_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "definition_name" => this - .definition_name(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_native_compiled_model<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "relative_path" => this - .relative_path(py) - .and_then(|value| value.into_bound_py_any(py)), - "query_sql" => this - .query_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "config" => this - .config(py) - .and_then(|value| value.into_bound_py_any(py)), - "destination" => this - .destination(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "reference_rows" => this - .reference_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "relation_key_row" => this - .relation_key_row(py) - .and_then(|value| value.into_bound_py_any(py)), - "key_row" => this - .key_row(py) - .and_then(|value| value.into_bound_py_any(py)), - "dep_rows" => this - .dep_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "destination_row" => this - .destination_row(py) - .and_then(|value| value.into_bound_py_any(py)), - "inferred_rows" => this - .inferred_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_column_rows" => this - .schema_column_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "has_dynamic_columns" => this - .dynamic_columns_declared(py) - .and_then(|value| value.into_bound_py_any(py)), - "output_column_count" => this - .output_column_count(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_entry" => this - .schema_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "inferred_columns" => this - .inferred_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "fast_lineage_columns" => this - .fast_lineage_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "fast_lineage_has_star" => this - .fast_lineage_has_star(py) - .and_then(|value| value.into_bound_py_any(py)), - "fast_lineage_star_resolved" => this - .fast_lineage_star_resolved(py) - .and_then(|value| value.into_bound_py_any(py)), - "authored_sql" => this - .authored_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "authored_query_sql" => this - .authored_query_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "output_column_locations" => this - .output_column_locations(py) - .and_then(|value| value.into_bound_py_any(py)), - "extract_implicit_alias_columns" => this - .extract_implicit_alias_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "macro_deps" => this - .macro_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "enum_declarations" => this - .enum_declarations(py) - .and_then(|value| value.into_bound_py_any(py)), - "constant_declarations" => this - .constant_declarations(py) - .and_then(|value| value.into_bound_py_any(py)), - "enum_columns" => this - .enum_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "binding_diagnostics" => this - .binding_diagnostics(py) - .and_then(|value| value.into_bound_py_any(py)), - "binding_validated" => this - .binding_validated(py) - .and_then(|value| value.into_bound_py_any(py)), - "dynamic_column_contract" => this - .dynamic_column_contract(py) - .and_then(|value| value.into_bound_py_any(py)), - "unchecked_output_columns" => this - .unchecked_output_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "rejected_sql_analysis_opt_out" => this - .rejected_sql_analysis_opt_out(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_native_compiled_function<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "arguments" => this - .arguments(py) - .and_then(|value| value.into_bound_py_any(py)), - "returns" => this - .returns(py) - .and_then(|value| value.into_bound_py_any(py)), - "body_sql" => this - .body_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "return_columns" => this - .return_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "language" => this - .language(py) - .and_then(|value| value.into_bound_py_any(py)), - "runtime_version" => this - .runtime_version(py) - .and_then(|value| value.into_bound_py_any(py)), - "entry_point" => this - .entry_point(py) - .and_then(|value| value.into_bound_py_any(py)), - "packages" => this - .packages(py) - .and_then(|value| value.into_bound_py_any(py)), - "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), - "description" => this - .description(py) - .and_then(|value| value.into_bound_py_any(py)), - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "deps" => this.deps(py).and_then(|value| value.into_bound_py_any(py)), - "relative_path" => this - .relative_path(py) - .and_then(|value| value.into_bound_py_any(py)), - "source_file_path" => this - .source_file_path(py) - .and_then(|value| value.into_bound_py_any(py)), - "destination" => this - .destination(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_destination" => this - .fingerprint_destination(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_native_function_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "arguments" => this - .arguments(py) - .and_then(|value| value.into_bound_py_any(py)), - "returns" => this - .returns(py) - .and_then(|value| value.into_bound_py_any(py)), - "body_sql" => this - .body_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "return_columns" => this - .return_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "language" => this - .language(py) - .and_then(|value| value.into_bound_py_any(py)), - "runtime_version" => this - .runtime_version(py) - .and_then(|value| value.into_bound_py_any(py)), - "entry_point" => this - .entry_point(py) - .and_then(|value| value.into_bound_py_any(py)), - "packages" => this - .packages(py) - .and_then(|value| value.into_bound_py_any(py)), - "tags" => this.tags(py).and_then(|value| value.into_bound_py_any(py)), - "description" => this - .description(py) - .and_then(|value| value.into_bound_py_any(py)), - "function_file" => this - .function_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "database" => this - .database(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema" => this - .schema(py) - .and_then(|value| value.into_bound_py_any(py)), - "logical_database" => this - .logical_database(py) - .and_then(|value| value.into_bound_py_any(py)), - "logical_schema" => this - .logical_schema(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_database" => this - .fingerprint_database(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_schema" => this - .fingerprint_schema(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_logical_database" => this - .fingerprint_logical_database(py) - .and_then(|value| value.into_bound_py_any(py)), - "fingerprint_logical_schema" => this - .fingerprint_logical_schema(py) - .and_then(|value| value.into_bound_py_any(py)), - "declaration_usages" => this - .declaration_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "assembly_row" => this - .assembly_row(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_native_inputs_view<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "run_id" => this.run_id().into_bound_py_any(py), - "effective_target_name" => this.effective_target_name().into_bound_py_any(py), - "no_sql_validation" => this.is_sql_validation_skipped().into_bound_py_any(py), - "model_inputs" => this.model_inputs(py).into_bound_py_any(py), - "native_project" => this.native_project(py).into_bound_py_any(py), - "project_config" => this.project_config(py).into_bound_py_any(py), - "local_config" => this.local_config(py).into_bound_py_any(py), - "discovered_inputs" => this.discovered_inputs(py).into_bound_py_any(py), - "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), - "effective_target" => this.effective_target(py).into_bound_py_any(py), - "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), - "effective_connection" => this.effective_connection(py).into_bound_py_any(py), - "effective_vars" => this.effective_vars(py).into_bound_py_any(py), - "macro_context" => this.macro_context(py).into_bound_py_any(py), - "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), - "public_enums" => this.public_enums(py).into_bound_py_any(py), - "public_constants" => this.public_constants(py).into_bound_py_any(py), - "external_sql_reference_resolver" => this - .external_sql_reference_resolver(py) - .into_bound_py_any(py), - "effective_settings" => this.effective_settings(py).into_bound_py_any(py), - "seed_inputs" => this.seed_inputs(py).into_bound_py_any(py), - "source_inputs" => this.source_inputs(py).into_bound_py_any(py), - "sql_function_inputs" => this.sql_function_inputs(py).into_bound_py_any(py), - "test_inputs" => this.test_inputs(py).into_bound_py_any(py), - "scenario_inputs" => this.scenario_inputs(py).into_bound_py_any(py), - "audit_inputs" => this.audit_inputs(py).into_bound_py_any(py), - "diagnostics" => this.diagnostics(py).into_bound_py_any(py), - "scope_index" => this.scope_index(py).into_bound_py_any(py), - "declaration_scope" => this.declaration_scope(py).into_bound_py_any(py), - _ => return None, - }) -} - -fn read_native_model_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "model_file" => this - .model_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "config" => this - .config(py) - .and_then(|value| value.into_bound_py_any(py)), - "query_sql" => this - .query_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "macro_source_sql" => this - .macro_source_sql(py) - .and_then(|value| value.into_bound_py_any(py)), - "references" => this - .references(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_entry" => this - .schema_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "reference_rows" => this - .reference_rows(py) - .and_then(|value| value.into_bound_py_any(py)), - "relation_key_row" => this - .relation_key_row(py) - .and_then(|value| value.into_bound_py_any(py)), - "attached_schema_name" => this - .attached_schema_name(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_file" => this.schema_file(py).into_bound_py_any(py), - "sql_validation_enabled" => this - .sql_validation_enabled(py) - .and_then(|value| value.into_bound_py_any(py)), - "rejected_sql_analysis_opt_out" => this - .rejected_sql_analysis_opt_out(py) - .and_then(|value| value.into_bound_py_any(py)), - "enum_declarations" => this - .enum_declarations(py) - .and_then(|value| value.into_bound_py_any(py)), - "constant_declarations" => this - .constant_declarations(py) - .and_then(|value| value.into_bound_py_any(py)), - "enum_columns" => this - .enum_columns(py) - .and_then(|value| value.into_bound_py_any(py)), - "macro_deps" => this - .macro_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "macro_usages" => this - .macro_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "declaration_usages" => this - .declaration_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "sql_expansion" => this - .sql_expansion(py) - .and_then(|value| value.into_bound_py_any(py)), - "lint_expansion" => this - .lint_expansion(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_native_project_view<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "run_id" => this.run_id().into_bound_py_any(py), - "effective_target_name" => this.effective_target_name().into_bound_py_any(py), - "effective_target_database" => this.effective_target_database().into_bound_py_any(py), - "effective_target_schema" => this.effective_target_schema().into_bound_py_any(py), - "sql_analysis_dialect" => this.sql_analysis_dialect().into_bound_py_any(py), - "enforce_explicit_references" => { - this.is_explicit_reference_enforced().into_bound_py_any(py) - } - "models" => this.models(py).into_bound_py_any(py), - "native_project" => this.native_project(py).into_bound_py_any(py), - "effective_connection" => this.effective_connection(py).into_bound_py_any(py), - "effective_vars" => this.effective_vars(py).into_bound_py_any(py), - "binding_catalog" => this.binding_catalog(py).into_bound_py_any(py), - "sql_lexical_syntax" => this.sql_lexical_syntax(py).into_bound_py_any(py), - "compile_cache_dir" => this.compile_cache_dir(py).into_bound_py_any(py), - "loader_functions" => this.loader_functions(py).into_bound_py_any(py), - "hook_functions" => this.hook_functions(py).into_bound_py_any(py), - "sql_hook_files" => this.sql_hook_files(py).into_bound_py_any(py), - "materialization_files" => this.materialization_files(py).into_bound_py_any(py), - "public_enums" => this.public_enums(py).into_bound_py_any(py), - "public_constants" => this.public_constants(py).into_bound_py_any(py), - "loaded_macros" => this.loaded_macros(py).into_bound_py_any(py), - "external_sql_reference_resolver" => this - .external_sql_reference_resolver(py) - .into_bound_py_any(py), - "native_session" => this.native_session(py).into_bound_py_any(py), - "settings" => this.settings(py).into_bound_py_any(py), - "scenario" => this.scenario(py).into_bound_py_any(py), - "sources" => this.sources(py).into_bound_py_any(py), - "seeds" => this.seeds(py).into_bound_py_any(py), - "functions" => this.functions(py).into_bound_py_any(py), - "audits" => this.audits(py).into_bound_py_any(py), - "sql_tests" => this.sql_tests(py).into_bound_py_any(py), - "sql_scenarios" => this.sql_scenarios(py).into_bound_py_any(py), - "diagnostics" => this.diagnostics(py).into_bound_py_any(py), - "unmatched_literal_sql_relations" => this - .unmatched_literal_sql_relations(py) - .into_bound_py_any(py), - "scope_index" => this.scope_index(py).into_bound_py_any(py), - "sql_expansions" => this - .sql_expansions(py) - .and_then(|value| value.into_bound_py_any(py)), - "lineage_graph" => this - .lineage_graph(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_native_compiled_seed<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "deps" => this.deps(py).into_bound_py_any(py), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "seed_file" => this - .seed_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_entry" => this - .schema_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_file" => this - .schema_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "destination" => this - .destination(py) - .and_then(|value| value.into_bound_py_any(py)), - "external" => this.is_external().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_native_seed_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "seed_file" => this - .seed_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_entry" => this - .schema_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "schema_file" => this - .schema_file(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_native_compiled_source<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "key" => this.key(py).and_then(|value| value.into_bound_py_any(py)), - "deps" => this.deps(py).into_bound_py_any(py), - "name" => this.name(py).and_then(|value| value.into_bound_py_any(py)), - "source_entry" => this - .source_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "source_file" => this - .source_file(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_native_source_input<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "source_entry" => this - .source_entry(py) - .and_then(|value| value.into_bound_py_any(py)), - "source_file" => this - .source_file(py) - .and_then(|value| value.into_bound_py_any(py)), - "declaration_usages" => this - .declaration_usages(py) - .and_then(|value| value.into_bound_py_any(py)), - "assembly_row" => this - .assembly_row(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_local_filesystem_compute_log_storage<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "root" => this.root(py).and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_dbt_combined_graph<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "nodes" => this.nodes(py).and_then(|value| value.into_bound_py_any(py)), - "upstream_deps" => this - .upstream_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "downstream_deps" => this - .downstream_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_dbt_compile_reference_resolver<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "_dbt_manifest" => this.dbt_manifest(py).into_bound_py_any(py), - _ => return None, - }) -} - -fn read_native_model_file<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "file_path" => this.file_path(py).into_bound_py_any(py), - "relative_path" => this.relative_path(py).into_bound_py_any(py), - "contents" => this.contents(py).into_bound_py_any(py), - "header_values" => this.header_values(py).into_bound_py_any(py), - "header_column_locations" => this - .header_column_locations(py) - .and_then(|value| value.into_bound_py_any(py)), - "output_column_locations" => this - .output_column_locations(py) - .and_then(|value| value.into_bound_py_any(py)), - "query_sql" => this.query_sql(py).into_bound_py_any(py), - "enum_declarations" => this.enum_declarations(py).into_bound_py_any(py), - "constant_declarations" => this.constant_declarations(py).into_bound_py_any(py), - "extract_implicit_alias_columns" => { - this.extract_implicit_alias_columns().into_bound_py_any(py) - } - _ => return None, - }) -} - -fn read_native_directory_snapshot<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "project_dir" => this.project_dir(py).into_bound_py_any(py), - "memo" => this.memo(py).into_bound_py_any(py), - _ => return None, - }) -} - -fn read_event_exporter_dispatcher<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "thread" => this.thread(py).into_bound_py_any(py), - "notification_thread" => this.notification_thread(py).into_bound_py_any(py), - _ => return None, - }) -} - -fn read_bound_event_exporter<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "name" => this.name().into_bound_py_any(py), - "function" => this.function(py).into_bound_py_any(py), - "provider_arguments" => this.provider_arguments(py).into_bound_py_any(py), - "event_kinds" => this - .event_kinds(py) - .and_then(|value| value.into_bound_py_any(py)), - "min_severity" => this - .min_severity(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_event_export_summary<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "aggregate" => this.aggregate().into_bound_py_any(py), - "per_exporter" => this - .per_exporter(py) - .and_then(|value| value.into_bound_py_any(py)), - "queue_depth" => this.queue_depth().into_bound_py_any(py), - "queue_capacity" => this.queue_capacity().into_bound_py_any(py), - "flush_complete" => this.flush_complete().into_bound_py_any(py), - "accepted" => this.accepted().into_bound_py_any(py), - "filtered" => this.filtered().into_bound_py_any(py), - "delivered" => this.delivered().into_bound_py_any(py), - "failed" => this.failed().into_bound_py_any(py), - "dropped" => this.dropped().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_event_exporter_accounting<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "exporter_name" => this.exporter_name().into_bound_py_any(py), - "counts" => this.counts().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_event_exporter_counts<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "accepted" => this.accepted().into_bound_py_any(py), - "filtered" => this.filtered().into_bound_py_any(py), - "delivered" => this.delivered().into_bound_py_any(py), - "failed" => this.failed().into_bound_py_any(py), - "dropped" => this.dropped().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_event_exporter_failure<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "exporter_name" => this.exporter_name().into_bound_py_any(py), - "error_type" => this.error_type().into_bound_py_any(py), - "event_kind" => this.event_kind().into_bound_py_any(py), - "event_severity" => this - .event_severity(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_event_exporter_command_scope<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "dispatcher" => this.dispatcher(py).into_bound_py_any(py), - "provider_session" => this - .provider_session(py) - .and_then(|value| value.into_bound_py_any(py)), - "project_dir" => this - .project_dir(py) - .and_then(|value| value.into_bound_py_any(py)), - "providers" => this - .providers(py) - .and_then(|value| value.into_bound_py_any(py)), - "event_exporters" => this - .event_exporters(py) - .and_then(|value| value.into_bound_py_any(py)), - "command_output_sinks" => this - .command_output_sinks(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_postgres_execution_history<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "project_calls" => this.project_calls().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_sqlite_execution_history<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "path" => this.path(py).and_then(|value| value.into_bound_py_any(py)), - "project_calls" => this.project_calls().into_bound_py_any(py), - _ => return None, - }) -} - -fn read_compiled_project_graph<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "project" => this.project_attribute(py).into_bound_py_any(py), - "native" => this.native_attribute(py).into_bound_py_any(py), - "lineage_views" => this - .lineage_views(py) - .and_then(|value| value.into_bound_py_any(py)), - "upstream_deps" => this - .upstream_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "downstream_deps" => this - .downstream_deps(py) - .and_then(|value| value.into_bound_py_any(py)), - "tag_index" => this - .tag_index(py) - .and_then(|value| value.into_bound_py_any(py)), - "path_index" => this - .path_index(py) - .and_then(|value| value.into_bound_py_any(py)), - "all_keys" => this - .all_keys(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_migration_state_inspection<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "database" => this.database(py).into_bound_py_any(py), - "events" => this - .events(py) - .and_then(|value| value.into_bound_py_any(py)), - "column_events" => this - .column_events(py) - .and_then(|value| value.into_bound_py_any(py)), - "old_name_histories" => this - .old_name_histories(py) - .and_then(|value| value.into_bound_py_any(py)), - _ => return None, - }) -} - -fn read_integration_asset_result<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "as_dict" => return None, - _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), - }) -} - -fn read_integration_check_result<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "as_dict" | "decoded" | "parsed" => return None, - _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), - }) -} - -fn read_integration_result_envelope<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "asset" => this.asset(py).into_bound_py_any(py), - "checks" => this.checks(py).into_bound_py_any(py), - "from_json" | "from_json_without_optional_enrichment" | "register" | "to_json" => { - return None; - } - _ => this.__getattr__(py, name).map(|value| value.into_bound(py)), - }) -} - -fn read_native_scope_index<'py>( - value: &Bound<'py, PyAny>, - name: &str, -) -> Option>> { - let py: Python<'py> = value.py(); - let Ok(cell) = value.cast::() else { - return None; - }; - let Ok(this) = cell.try_borrow() else { - return None; - }; - Some(match name { - "index" => this.index(py).into_bound_py_any(py), - "has_scoped_relationship_declarations" => this - .has_scoped_relationship_declarations() - .into_bound_py_any(py), - _ => return None, - }) -} diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs index 0fe9d05585..ad8ff59f78 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/mod.rs @@ -2,6 +2,7 @@ pub(crate) mod constants; pub(crate) mod construct; pub(crate) mod error_classes; pub(crate) mod fields; +pub(crate) mod getter_readers; pub(crate) mod getters; pub(crate) mod ids; pub(crate) mod models; diff --git a/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs b/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs index 0b62c7f703..1981991cba 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/result_output/terminal_index.rs @@ -44,9 +44,9 @@ pub(crate) struct TerminalEventIndex { #[pyclass(module = "sqlbuild._native", frozen)] pub(crate) struct TerminalEventClaim { #[pyo3(get)] - terminal: Py, + pub(crate) terminal: Py, #[pyo3(get)] - event_sequence: usize, + pub(crate) event_sequence: usize, } /// `payload.get(key)` when it is a string. diff --git a/crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs b/crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs index 89bfd5a6f3..06568f07bc 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs @@ -285,7 +285,7 @@ pub(crate) struct ExpansionReuse { #[pyclass(module = "sqlbuild._native")] pub(crate) struct EarlySqlLint { #[pyo3(get)] - enabled: bool, + pub(crate) enabled: bool, preparation: Option>, expansion_reuse: Option, stop_requested: Arc, diff --git a/tests/native_field_fallbacks.txt b/tests/native_field_fallbacks.txt index 5e63864baa..fe3cf83d7b 100644 --- a/tests/native_field_fallbacks.txt +++ b/tests/native_field_fallbacks.txt @@ -1,2 +1,418 @@ # Native field reads that still fall back to Python on SQLBuild's own classes. # Generated by a strict record run; entries may only be removed. +crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs BindingCatalog.native +crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs BindingCatalog.prepare_analysis +crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs BindingCatalog.schemas +crates/sqlbuild-python/src/bindings/_helpers/analysis_session/model_analyses.rs .schemas +crates/sqlbuild-python/src/bindings/_helpers/analysis_session/nullability_rules.rs InferredNullability.value +crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs BindingCatalog.expression_shapes +crates/sqlbuild-python/src/bindings/_helpers/analysis_session/stage_functions.rs BindingCatalog.native +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs AuditCallbackRelay.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs AuditCallbackRelay.on_connection_error +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs AuditCallbackRelay.on_result +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs AuditProgressReporter.on_item_complete +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs AuditProgressReporter.on_item_error +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs AuditProgressReporter.on_item_physical_complete +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs AuditProgressReporter.on_item_start +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs ConnectionProgressReporter.on_connection_start +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs NativeProgressProjector.configure_resources +crates/sqlbuild-python/src/bindings/_helpers/audit_command/command.rs NativeProgressProjector.expect_resource_enrichment +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs BuildProgressCallbacks.on_node_complete +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs BuildProgressCallbacks.on_node_start +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs BuildProgressCallbacks.on_scheduler_state +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs BuildProgressCallbacks.on_statement_complete +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs BuildProgressCallbacks.on_sub_progress +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs BuildProgressCallbacks.write_execution_event +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs ConnectionProgressReporter.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs ConnectionProgressReporter.on_connection_error +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs ConnectionProgressReporter.on_connection_start +crates/sqlbuild-python/src/bindings/_helpers/build_command/execution.rs DirectPythonLifecycle.on_node_complete +crates/sqlbuild-python/src/bindings/_helpers/build_command/lifecycle.rs PythonNodeGraph.selected_sql_refs +crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs ConnectionProgressReporter.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs ConnectionProgressReporter.on_connection_error +crates/sqlbuild-python/src/bindings/_helpers/build_command/planning.rs ConnectionProgressReporter.on_connection_start +crates/sqlbuild-python/src/bindings/_helpers/build_command/policies.rs ColumnMigrationDecision.label +crates/sqlbuild-python/src/bindings/_helpers/build_progress/audit_progress.rs TransientLineCoordinator.lock +crates/sqlbuild-python/src/bindings/_helpers/build_progress/build_callbacks.rs TransientLineCoordinator.lock +crates/sqlbuild-python/src/bindings/_helpers/build_progress/nested_progress.rs TransientLineCoordinator.lock +crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs BuildProgressCallbacks._spin_until_stopped +crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs NestedCommandProgressCallbacks._spin_until_stopped +crates/sqlbuild-python/src/bindings/_helpers/build_progress/terminal.rs TransientStatusReporter._spin_until_stopped +crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs TransientLineCoordinator.lock +crates/sqlbuild-python/src/bindings/_helpers/build_progress/transient_status.rs TransientStatusReporter.close +crates/sqlbuild-python/src/bindings/_helpers/check/check_command.rs PythonNodeGraph.selected_sql_refs +crates/sqlbuild-python/src/bindings/_helpers/check/check_core.rs PythonNodeGraph.selected_sql_refs +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.command +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.contract_command +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.contract_from +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.dbt_command +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.format_diff +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.format_fix +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.format_fixtures_only +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.from_target +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.json +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.left_query +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.left_query_file +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.project_dir +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.refactor_target +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.right_query +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.right_query_file +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.scenario_command +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.scenario_local +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.scenario_refresh +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.scenario_retain +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.scenario_sync_snapshots +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.select +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.select_file +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.vars +crates/sqlbuild-python/src/bindings/_helpers/cli/dispatch.rs CliNamespace.warehouse +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs CliNamespace.json_output +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs DiffSizeGuardError.code +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs DiffSizeGuardError.help +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs DiffSizeGuardError.message +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs QueryDiffExecutionError.code +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs QueryDiffExecutionError.help +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs QueryDiffExecutionError.message +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs QueryDiffExecutionError.status +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs QueryDiffIncompleteError.code +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs QueryDiffIncompleteError.help +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs QueryDiffIncompleteError.message +crates/sqlbuild-python/src/bindings/_helpers/cli/entry.rs QueryDiffIncompleteError.status +crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs CliNamespace.command +crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs CliNamespace.debug +crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs CliNamespace.no_color +crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs EventExporterCommandScope.configure_extensions +crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs EventExporterDispatcher.enqueue +crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs InvocationOutcome.consume +crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs NativeProgressProjector.consume +crates/sqlbuild-python/src/bindings/_helpers/cli/observability.rs TerminalEventIndex.consume +crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.command +crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.dbt_args +crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.json +crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.lineage_format +crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs CliNamespace.query_format +crates/sqlbuild-python/src/bindings/_helpers/cli/progress.rs TransientLineCoordinator.lock +crates/sqlbuild-python/src/bindings/_helpers/cli/progress_text.rs VerboseInspectionWriter.write +crates/sqlbuild-python/src/bindings/_helpers/command_runtime/warehouses.rs WarehouseGroup.value +crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/declaration_scope.rs NativeScopeIndex.grant_relationships +crates/sqlbuild-python/src/bindings/_helpers/compile_attachment/model_inputs.rs DbtCompileReferenceResolver.validate_model_names +crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs PreparedCompileArtifacts.max_prepared_models +crates/sqlbuild-python/src/bindings/_helpers/compile_command/prepared_artifacts.rs PreparedCompileArtifacts.min_prepared_models +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs CompileReuseAttempt.exit_code +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs CompileReuseAttempt.json_output +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs CompileReuseAttempt.native +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs CompileReuseAttempt.outcome +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs CompileReuseAttempt.project_dir +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_attempt.rs CompileReuseAttempt.selected_target +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs CompileReuseAttempt.check_ms +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs CompileReuseAttempt.entry_path +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs CompileReuseAttempt.native +crates/sqlbuild-python/src/bindings/_helpers/compile_command/reuse_recording.rs CompileReuseAttempt.outcome +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/attachment.rs ResourceKind.value +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/loop_classes.rs DeclarationKind.value +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_macros.rs MacroArgumentError.offset +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/model_loop_named.rs ScopeKind.value +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/records.rs CollectionRendering.value +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs LayoutConfig.__dataclass_fields__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs LayoutConfig.__dict__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs PythonHookEntry.__dataclass_fields__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs PythonHookEntry.__dict__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs RuleExemption.__dataclass_fields__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs RuleExemption.__dict__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs RuleIgnore.__dataclass_fields__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs RuleIgnore.__dict__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs RulesCacheConfig.__dataclass_fields__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs RulesCacheConfig.__dict__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs RulesConfig.__dataclass_fields__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs RulesConfig.__dict__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs SqlHookEntry.__dataclass_fields__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs SqlHookEntry.__dict__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs SqlTestRulesConfig.__dataclass_fields__ +crates/sqlbuild-python/src/bindings/_helpers/compiled_project/values.rs SqlTestRulesConfig.__dict__ +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs PreparedCompileArtifacts.start +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs BindingCatalog.native +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_analysis.rs BindingCatalog.schemas +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_facts.rs NativeProjectResources.model_deps +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_facts.rs NativeProjectResources.model_syntax_valid +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs NativeModelFacts.deps +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs NativeModelFacts.dynamic_contract +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_models.rs NativeModelFacts.syntax_valid +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeProjectFacts.models +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeProjectFacts.resources +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeProjectResources.audit_scope_deps +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeProjectResources.failure +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeProjectResources.function_deps +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeProjectResources.seed_namespaces +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeProjectResources.source_namespaces +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeResourceFailure.error +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeResourceFailure.index +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/assembly_project.rs NativeResourceFailure.slot +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs CompileReuseAttempt.started +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/command.rs PreparedCompileArtifacts.remove_abandoned_staging +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs CompileInputError.code +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs CompileInputError.help +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs PreparedCompileArtifacts.publish +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs PythonNodeGraph.selected_sql_refs +crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs PlannerScopeResolution.stale_warning_scope +crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs ConnectionProgressReporter.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs DbtInitProgressReporter.complete +crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs DbtInitProgressReporter.start +crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs DbtInteropCommand.value +crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs PlanningProgressReporter.on_progress +crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs DbtInitProgressReporter.complete +crates/sqlbuild-python/src/bindings/_helpers/dbt_command/init.rs DbtInitProgressReporter.start +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs DbtEventStreamUpdate.finished +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs DbtEventStreamUpdate.result +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs DbtEventStreamUpdate.row +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs DbtEventStreamUpdate.status_message +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs DbtInteropCommand.value +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs DbtRunner.ls +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs DbtRunner.debug +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs DbtInteropSkipReason.value +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs CliStyle.use_color +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs TransientStatusReporter.complete +crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs WarehouseGroup.value +crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs CliUserError.code +crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs CliUserError.help +crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs CliUserError.message +crates/sqlbuild-python/src/bindings/_helpers/discovery/imported_modules.rs EventExporterCommandScope.cached_extensions +crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs DeclarationKind.value +crates/sqlbuild-python/src/bindings/_helpers/discovery/project_facts.rs ScopeKind.value +crates/sqlbuild-python/src/bindings/_helpers/event_exporting/scope.rs EventExporterCommandScope.cached_extensions +crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs TransientStatusReporter.complete +crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs SourceFreshnessAgeStatus.value +crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs SourceFreshnessStrategy.value +crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs SourceFreshnessValueKind.value +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BindingCatalog.analysis_shapes +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BindingCatalog.dialect +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BindingCatalog.expression_shapes +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BindingCatalog.native +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BindingCatalog.quoted_ignore_case +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BindingCatalog.schemas +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs CollectionRendering.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs ColumnContractMode.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs ColumnLineageConfidence.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs ColumnTransformKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs CompiledResourceType.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs DeclarationKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs DiagnosticPhase.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs DiagnosticSeverity.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs FutureCursorAction.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs InferredNullability.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs MicrobatchLimitAction.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs MissingMigrationOriginPolicy.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs OwnershipRootKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs ProjectCatalog.__dict__ +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs ResourceKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs RetentionDecreasePolicy.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs ScopeKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs SqlReferenceKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs SqlValueKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs TableTypeDowngradePolicy.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs TableType.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs TableTypeSource.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs UsageKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs VisibilityReason.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/stage_capture.rs CompilerStage.value +crates/sqlbuild-python/src/bindings/_helpers/graph/python_node_graph.rs SourceWriteStrategy.value +crates/sqlbuild-python/src/bindings/_helpers/janitor/janitor_old_names.rs OldNameViewHistory.status +crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs ColumnLineageMode.value +crates/sqlbuild-python/src/bindings/_helpers/lineage/lineage_command.rs PlannerInputError.code +crates/sqlbuild-python/src/bindings/_helpers/lineage/project_lineage.rs BindingCatalog.native +crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs ConnectionProgressReporter.on_connection_start +crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs LoadCallbackRelay.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs LoadCallbackRelay.on_connection_error +crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs LoadCallbackRelay.on_load_complete +crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs LoadProgressReporter.on_progress +crates/sqlbuild-python/src/bindings/_helpers/load/load_command.rs LoadProgressReporter.on_start +crates/sqlbuild-python/src/bindings/_helpers/load/load_progress.rs TransientLineCoordinator.lock +crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs CollectionRendering.value +crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs DeclarationKind.value +crates/sqlbuild-python/src/bindings/_helpers/macro_bridge/store_keys.rs SqlValueKind.value +crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs DeclarationKind.value +crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs ScopeKind.value +crates/sqlbuild-python/src/bindings/_helpers/manifest/rows.rs SourceWriteStrategy.value +crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs ConnectionProgressReporter.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs ConnectionProgressReporter.on_connection_error +crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs ConnectionProgressReporter.on_connection_start +crates/sqlbuild-python/src/bindings/_helpers/plan_command/plan.rs PlanningProgressReporter.on_progress +crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs MigrationStateInspection.inspect_migration_events +crates/sqlbuild-python/src/bindings/_helpers/planner_changes/renames.rs PlannerRuntime.project +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs MaterializationType.value +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs PlannerRelationsContext.function_locations +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs PlannerRelationsContext.model_locations +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs PlannerRelationsContext.python_source_read_map +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs PlannerRelationsContext.seed_locations +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs PlannerRelationsContext.source_map +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/command_plans.rs PlannerRelationsContext.source_read_map +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs PlannerRelationsContext.function_locations +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs PlannerRelationsContext.model_locations +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs PlannerRelationsContext.python_source_read_map +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs PlannerRelationsContext.seed_locations +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs PlannerRelationsContext.source_map +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs PlannerRelationsContext.source_read_map +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs PlannerRelationsContext.source_warehouse_columns +crates/sqlbuild-python/src/bindings/_helpers/planner_entries/plan_output.rs PlannerRelationsContext.star_exclude_keyword +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs ColumnMigrationDecision.blocks_build +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs ColumnMigrationDecision.renames +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs ColumnMigrationEvent.renamed +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs PlannerRuntime.adapter +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_entries.rs PlannerRuntime.project +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_overlay.rs ColumnMigrationDecision.renames +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/column_planning.rs MigrationStateInspection.inspect_column_events +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_events.rs MigrationStateInspection.model_fingerprint +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_events.rs PlannerRuntime.project +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs MigrationStateInspection.inspect_relations +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery_requests.rs MigrationStateInspection.orphan_fingerprints +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs MigrationStateInspection.inspect_schemas +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs MigrationStateInspection.named_fingerprint +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/discovery.rs PlannerRuntime.adapter +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/fingerprint.rs MigrationFingerprintCache.fingerprint +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/matching.rs MigrationFingerprintCache.fingerprint +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs MigrationDecision.moves_data +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs MigrationStateInspection.model_fingerprint +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_entries.rs PlannerRuntime.project +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_overlay.rs MigrationDecision.moves_data +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs MigrationStateInspection.inspect_relations +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/model_planning.rs MigrationStateInspection.inspect_schemas +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_entries.rs MigrationDecision.moves_data +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_entries.rs OldNameViewHistory.status +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_objects.rs PlannerRuntime.adapter +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_planning.rs MigrationStateInspection.inspect_old_name_views +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_planning.rs PlannerRuntime.project +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/old_name_references.rs PlannerRuntime.project +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs MigrationStateInspection.named_fingerprint +crates/sqlbuild-python/src/bindings/_helpers/planner_migrations/planning_origin.rs PlannerRuntime.adapter +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/execution_changes.rs PlannerRelationsContext.source_warehouse_columns +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/execution_changes.rs PlannerWarehouseState.inspection_relations +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs PlannerRuntime.adapter +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/output_assembly.rs SourceFreshnessUnknownReason.value +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs PlannerRuntime.adapter +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs PlannerRuntime.project +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs PlannerWarehouseState.snapshot +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs RetentionDecreasePolicy.value +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs TableTypeDowngradePolicy.value +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs TableTypeSource.value +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs TableType.value +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/retention.rs TimeTravelRetentionSource.value +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/warehouse_state.rs MigrationDecision.moves_data +crates/sqlbuild-python/src/bindings/_helpers/planner_phases/warehouse_state.rs PlannerRelationsContext.source_warehouse_columns +crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/maximum_safety.rs FutureCursorAction.value +crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs CursorOverrides.typed_as +crates/sqlbuild-python/src/bindings/_helpers/planner_resolution/values.rs DbtCompileReferenceResolver.resolve_reference +crates/sqlbuild-python/src/bindings/_helpers/planner_scenario/artifacts.rs ScenarioArtifactKind.value +crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs PlannerRelationsContext.model_locations +crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs PlannerRelationsContext.seed_locations +crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/audit_entries.rs PlannerRelationsContext.source_read_map +crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/fixture_values.rs CompiledResourceType.value +crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatch_limits.rs PlanEntryBuildInputs.max_microbatches +crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatch_limits.rs PlanEntryBuildInputs.max_microbatches_is_override +crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/microbatch_limits.rs PlanEntryBuildInputs.microbatch_limit_action +crates/sqlbuild-python/src/bindings/_helpers/planner_strategy/model_entries.rs TableType.value +crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_freshness.rs PlannerRelationsContext.source_read_map +crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs PlannerRelationsContext.listed_source_names +crates/sqlbuild-python/src/bindings/_helpers/planner_warehouse/source_tables.rs PlannerRelationsContext.source_read_map +crates/sqlbuild-python/src/bindings/_helpers/plan_output/cursor_details.rs GraphResourceKind.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs CliStyle.use_color +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs ColumnMigrationDecision.label +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs MigrationCompatibility.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs MigrationDecision.blocks_build +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs MigrationDecision.checks_compatibility +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs MigrationDecision.label +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs MigrationDiscovery.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs MigrationPromotion.label +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs RetentionDirection.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/migrations.rs RetentionPlanPhase.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_json.rs SourceWriteStrategy.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs BackfillAction.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs PlanAction.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs PlanReason.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs PythonIdentityStatus.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs PythonRunPhase.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs SchemaChangeKind.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs SourceWriteStrategy.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/plan_text.rs WarningSeverity.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs BackfillAction.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs ColumnMigrationDecision.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs FutureCursorAction.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs MaterializationType.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs MicrobatchLimitAction.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs MigrationCompatibility.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs MigrationDecision.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs MigrationDiscovery.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs MigrationPromotion.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs OldNameViewAction.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs PlanAction.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs PlanReason.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs PythonIdentityStatus.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs PythonRunPhase.value +crates/sqlbuild-python/src/bindings/_helpers/plan_output/values.rs WarningSeverity.value +crates/sqlbuild-python/src/bindings/_helpers/presentation_text/functions.rs CliStyle.use_color +crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs MacroArgumentError.detail +crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs MacroArgumentError.file_path +crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs MacroArgumentError.help +crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs MacroArgumentError.macro_name +crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs MacroArgumentError.offset +crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/error_inits.rs MacroArgumentError.relative_position +crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/planner.rs ColumnMigrationDecision.blocks_build +crates/sqlbuild-python/src/bindings/_helpers/record_behaviours/values.rs SqlValueKind.value +crates/sqlbuild-python/src/bindings/_helpers/refactor/refactor_facts.rs DeclarationKind.value +crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs CollectionRendering.value +crates/sqlbuild-python/src/bindings/_helpers/render/declaration_values.rs VisibilityReason.value +crates/sqlbuild-python/src/bindings/_helpers/render/macro_call_classes.rs DeclarationKind.value +crates/sqlbuild-python/src/bindings/_helpers/render/macro_evaluation.rs NativeMacroExpansion.render_relation +crates/sqlbuild-python/src/bindings/_helpers/render/macro_expansion.rs ResourceKind.value +crates/sqlbuild-python/src/bindings/_helpers/render/macro_generated_references.rs ResourceKind.value +crates/sqlbuild-python/src/bindings/_helpers/result_output/assets.rs PlanReason.value +crates/sqlbuild-python/src/bindings/_helpers/result_output/checks.rs SqlValueKind.value +crates/sqlbuild-python/src/bindings/_helpers/rules/custom_evaluation.rs RuleSubject.value +crates/sqlbuild-python/src/bindings/_helpers/scenario_command/capture_command.rs ScenarioProgressRelay.on_scenario_complete +crates/sqlbuild-python/src/bindings/_helpers/scenario_command/capture_command.rs ScenarioProgressRelay.on_scenario_start +crates/sqlbuild-python/src/bindings/_helpers/scenario_command/conversions.rs ScenarioArtifactKind.value +crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs ConnectionProgressReporter.on_connection_start +crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs ScenarioConnectionRelay.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/scenario_command/presentation.rs ScenarioConnectionRelay.on_connection_error +crates/sqlbuild-python/src/bindings/_helpers/scenario_command/setup.rs PlanningProgressReporter.on_progress +crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs ScenarioProgressRelay.on_scenario_complete +crates/sqlbuild-python/src/bindings/_helpers/scenario_command/snapshot_sync.rs ScenarioProgressRelay.on_scenario_start +crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs DeclarationKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/compile_usages.rs ScopeKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_errors.rs ScopeDiagnosticCode.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs CollectionRendering.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs ScopeKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_index.rs SqlValueKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_loading.rs NativeScopeIndex.grant_relationships +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs DeclarationKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs GrantKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs OwnershipRootKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs ResourceKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs ScopeDiagnosticCode.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs ScopeDiagnosticSeverity.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs ScopeKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_objects.rs UsageKind.value +crates/sqlbuild-python/src/bindings/_helpers/scopes/scope_validation.rs ScopeDiagnosticCode.value +crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs ConnectionProgressReporter.on_connection_start +crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs NativeProgressProjector.configure_resources +crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs NativeProgressProjector.consume_resource_terminal +crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs SeedCompletionRelay.on_seed_complete +crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs SeedConnectionRelay.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/seed_command/command.rs SeedConnectionRelay.on_connection_error +crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/inputs.rs BindingCatalog.native +crates/sqlbuild-python/src/bindings/_helpers/semantic_checks/stage.rs BindingCatalog.native +crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/shapes.rs BindingCatalog.inferred_schema +crates/sqlbuild-python/src/bindings/_helpers/semantic_shapes/source_bindings.rs BindingPositions.position +crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs PlanningProgressReporter.on_progress +crates/sqlbuild-python/src/bindings/_helpers/sql_test_command/test_command.rs SqlValueKind.value +crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs CursorGrain.value +crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/cursor_window.rs CursorType.value +crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/fixture_validation.rs CompiledResourceType.value +crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_driver.rs WarningSeverity.value +crates/sqlbuild-python/src/bindings/_helpers/sql_test_glue/plan_entries.rs CompiledResourceType.value +crates/sqlbuild-python/src/bindings/_helpers/state_rows/events.rs OldNameViewEventType.value +crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_io.rs ColumnMigrationDecision.records_event +crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_projections.rs OldNameViewEventType.value +crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs ColumnMigrationDecision.value +crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs MigrationDecision.value +crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs MigrationDiscovery.value +crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs OldNameViewDropReason.value +crates/sqlbuild-python/src/bindings/_helpers/state_rows/migration_rows.rs OldNameViewEventType.value From 8fd0f632607eede195133be26c1d945911612f26 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 08:52:53 +0100 Subject: [PATCH 15/19] test: allow the remaining capture-encoder and DAG row enum reads in strict native field mode --- tests/native_field_fallbacks.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/native_field_fallbacks.txt b/tests/native_field_fallbacks.txt index fe3cf83d7b..3530e8c9b3 100644 --- a/tests/native_field_fallbacks.txt +++ b/tests/native_field_fallbacks.txt @@ -155,6 +155,7 @@ crates/sqlbuild-python/src/bindings/_helpers/compile_driver/phases.rs PreparedCo crates/sqlbuild-python/src/bindings/_helpers/compile_driver/python_plan_entries.rs PythonNodeGraph.selected_sql_refs crates/sqlbuild-python/src/bindings/_helpers/compile_driver/selection_phases.rs PlannerScopeResolution.stale_warning_scope crates/sqlbuild-python/src/bindings/_helpers/contract_command/command.rs ConnectionProgressReporter.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/dag_artifact/rows.rs SqlValueKind.value crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs DbtInitProgressReporter.complete crates/sqlbuild-python/src/bindings/_helpers/dbt_command/auto_init.rs DbtInitProgressReporter.start crates/sqlbuild-python/src/bindings/_helpers/dbt_command/command.rs DbtInteropCommand.value @@ -183,6 +184,7 @@ crates/sqlbuild-python/src/bindings/_helpers/format_command/command.rs Transient crates/sqlbuild-python/src/bindings/_helpers/freshness/freshness_observe.rs SourceFreshnessAgeStatus.value crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs SourceFreshnessStrategy.value crates/sqlbuild-python/src/bindings/_helpers/freshness/observation.rs SourceFreshnessValueKind.value +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BackfillAction.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BindingCatalog.analysis_shapes crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BindingCatalog.dialect crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs BindingCatalog.expression_shapes @@ -197,15 +199,23 @@ crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs CompiledResourc crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs DeclarationKind.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs DiagnosticPhase.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs DiagnosticSeverity.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs EventExportSeverity.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs FutureCursorAction.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs GrantKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs HardCodedRelationOwnerKind.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs InferredNullability.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs LoaderConnectionMode.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs MaterializationType.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs MicrobatchLimitAction.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs MissingMigrationOriginPolicy.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs OwnershipRootKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs PlanAction.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs PlanReason.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs ProjectCatalog.__dict__ crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs ResourceKind.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs RetentionDecreasePolicy.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs ScopeKind.name +crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs SourceWriteStrategy.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs SqlReferenceKind.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs SqlValueKind.name crates/sqlbuild-python/src/bindings/_helpers/frontier/encoder.rs TableTypeDowngradePolicy.name From 5a74bd62bbf15c3acfe697d35443bfa0c1232b20 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 08:54:11 +0100 Subject: [PATCH 16/19] test: allow the dbt interop connection progress callback read in strict native field mode --- tests/native_field_fallbacks.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/native_field_fallbacks.txt b/tests/native_field_fallbacks.txt index 3530e8c9b3..a8da682f64 100644 --- a/tests/native_field_fallbacks.txt +++ b/tests/native_field_fallbacks.txt @@ -169,6 +169,7 @@ crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs DbtEven crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs DbtInteropCommand.value crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs DbtRunner.ls crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs DbtRunner.debug +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs ConnectionProgressReporter.on_connection_start crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs DbtInteropSkipReason.value crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs CliStyle.use_color crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs TransientStatusReporter.complete From 2e85f5f763c5d9537ef80fcee3089e9bc1114fe0 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 09:23:18 +0100 Subject: [PATCH 17/19] test: allow the remaining dbt interop connection progress callback reads in strict native field mode --- tests/native_field_fallbacks.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/native_field_fallbacks.txt b/tests/native_field_fallbacks.txt index a8da682f64..1e35b46986 100644 --- a/tests/native_field_fallbacks.txt +++ b/tests/native_field_fallbacks.txt @@ -169,6 +169,8 @@ crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/event_stream.rs DbtEven crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs DbtInteropCommand.value crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/orchestration.rs DbtRunner.ls crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/pipeline.rs DbtRunner.debug +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs ConnectionProgressReporter.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs ConnectionProgressReporter.on_connection_error crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs ConnectionProgressReporter.on_connection_start crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs DbtInteropSkipReason.value crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs CliStyle.use_color From 600985d7d0734e8294b5b223f58643e9515bd7c5 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 10:11:59 +0100 Subject: [PATCH 18/19] test: allow the dbt interop build progress and command reads in strict native field mode --- tests/native_field_fallbacks.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/native_field_fallbacks.txt b/tests/native_field_fallbacks.txt index 1e35b46986..b50dac1653 100644 --- a/tests/native_field_fallbacks.txt +++ b/tests/native_field_fallbacks.txt @@ -175,6 +175,13 @@ crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan_output.rs Connecti crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/plan.rs DbtInteropSkipReason.value crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs CliStyle.use_color crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/runtime_execution.rs TransientStatusReporter.complete +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs BuildProgressCallbacks.on_node_complete +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs BuildProgressCallbacks.on_node_start +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs BuildProgressCallbacks.on_sub_progress +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs ConnectionProgressReporter.on_connection_complete +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs ConnectionProgressReporter.on_connection_error +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs ConnectionProgressReporter.on_connection_start +crates/sqlbuild-python/src/bindings/_helpers/dbt_interop/sqlbuild_work.rs DbtInteropCommand.value crates/sqlbuild-python/src/bindings/_helpers/debug_command/run_debug.rs WarehouseGroup.value crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs CliUserError.code crates/sqlbuild-python/src/bindings/_helpers/diff_report/support.rs CliUserError.help From 4b93cd96c65af5862922b1dc45e1c38e61b2e541 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Sat, 17 Oct 2026 11:03:04 +0100 Subject: [PATCH 19/19] fix: let interrupts win over strict native field errors and name classes without swallowing errors --- .../sqlbuild-python/src/bindings/_helpers/records/fields.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs index f511c29605..3539a0e634 100644 --- a/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs +++ b/crates/sqlbuild-python/src/bindings/_helpers/records/fields.rs @@ -123,10 +123,12 @@ fn strict_fallback(value: &Bound<'_, PyAny>, name: &str) -> PyResult<()> { return Ok(()); } let caller: &std::panic::Location<'_> = std::panic::Location::caller(); - let entry: String = format!("{}\t{}.{name}", caller.file(), class.qualname()?); + let qualname: Bound<'_, PyString> = class.qualname()?; + let entry: String = format!("{}\t{}.{name}", caller.file(), qualname.to_cow()?); match strict { StrictFields::Enforce(Err(error)) => Err(PyRuntimeError::new_err(error.clone())), StrictFields::Enforce(Ok(allowed)) if !allowed.contains(&entry) => { + value.py().check_signals()?; Err(PyRuntimeError::new_err(format!( "native field read fell back to Python: {}", entry.replace('\t', " ")