dqlite-dbapi 0.2.2__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dqlite_dbapi-0.3.0/DEVELOPMENT.md +100 -0
- dqlite_dbapi-0.3.0/PKG-INFO +131 -0
- dqlite_dbapi-0.3.0/README.md +97 -0
- dqlite_dbapi-0.3.0/docs/differences-from-aiosqlite.md +42 -0
- dqlite_dbapi-0.3.0/docs/differences-from-sqlite3.md +99 -0
- dqlite_dbapi-0.3.0/docs/transactions.md +84 -0
- dqlite_dbapi-0.3.0/pyproject.toml +114 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/__init__.py +256 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/_busy_retry.py +149 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/_constants.py +37 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/_pragma_intercept.py +130 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/aio/__init__.py +373 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/aio/connection.py +1697 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/aio/cursor.py +970 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/connection.py +2574 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/cursor.py +1749 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/exceptions.py +291 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/row.py +70 -0
- dqlite_dbapi-0.3.0/src/dqlitedbapi/types.py +590 -0
- dqlite_dbapi-0.3.0/tests/aio/test_aio_version_final_annotated.py +20 -0
- dqlite_dbapi-0.3.0/tests/aio/test_async_close_underlying_close_failed_logged.py +105 -0
- dqlite_dbapi-0.3.0/tests/aio/test_async_connection_fork_guard.py +115 -0
- dqlite_dbapi-0.3.0/tests/aio/test_async_iter_protocol_invariants.py +28 -0
- dqlite_dbapi-0.3.0/tests/aio/test_async_unclosed_warning_skips_in_fork_child.py +143 -0
- dqlite_dbapi-0.3.0/tests/aio/test_close_cancel_between_cursor_cascade_and_lock.py +58 -0
- dqlite_dbapi-0.3.0/tests/aio/test_fetchmany_cancel_atomic.py +57 -0
- dqlite_dbapi-0.3.0/tests/aio/test_messages_clear_on_closed.py +49 -0
- dqlite_dbapi-0.3.0/tests/conftest.py +45 -0
- dqlite_dbapi-0.3.0/tests/integration/conftest.py +16 -0
- dqlite_dbapi-0.3.0/tests/integration/test_arraysize_zero_fetchmany.py +43 -0
- dqlite_dbapi-0.3.0/tests/integration/test_async_concurrent_executemany_serialized.py +74 -0
- dqlite_dbapi-0.3.0/tests/integration/test_async_cursor_concurrent_execute_rejected.py +57 -0
- dqlite_dbapi-0.3.0/tests/integration/test_async_cursor_edge_branches.py +61 -0
- dqlite_dbapi-0.3.0/tests/integration/test_async_executemany_param_count.py +96 -0
- dqlite_dbapi-0.3.0/tests/integration/test_async_fetchmany_cancel.py +59 -0
- dqlite_dbapi-0.3.0/tests/integration/test_async_returning_zero_rows.py +39 -0
- dqlite_dbapi-0.3.0/tests/integration/test_async_transaction_ctxmgr_rejects_stray_commit.py +52 -0
- dqlite_dbapi-0.3.0/tests/integration/test_boolean_conversion.py +62 -0
- dqlite_dbapi-0.3.0/tests/integration/test_close_implicit_rollback_pep249.py +128 -0
- dqlite_dbapi-0.3.0/tests/integration/test_concurrent_cursors_visibility.py +49 -0
- dqlite_dbapi-0.3.0/tests/integration/test_constraint_extended_codes.py +89 -0
- dqlite_dbapi-0.3.0/tests/integration/test_context_manager.py +50 -0
- dqlite_dbapi-0.3.0/tests/integration/test_cte_prefixed_dml_metadata.py +50 -0
- dqlite_dbapi-0.3.0/tests/integration/test_cursor_fetch_after_non_row_execute.py +93 -0
- dqlite_dbapi-0.3.0/tests/integration/test_cursor_misc_invariant_pins.py +72 -0
- dqlite_dbapi-0.3.0/tests/integration/test_cursor_row_index_after_fetchall.py +91 -0
- dqlite_dbapi-0.3.0/tests/integration/test_datetime_conversion.py +315 -0
- dqlite_dbapi-0.3.0/tests/integration/test_description_after_ddl_pragma.py +91 -0
- dqlite_dbapi-0.3.0/tests/integration/test_description_survives_empty_fetchall.py +113 -0
- dqlite_dbapi-0.3.0/tests/integration/test_executemany_cancel_mid_batch.py +84 -0
- dqlite_dbapi-0.3.0/tests/integration/test_executemany_completed_iterations_observability.py +61 -0
- dqlite_dbapi-0.3.0/tests/integration/test_executemany_cte_dml.py +66 -0
- dqlite_dbapi-0.3.0/tests/integration/test_executemany_failure_resets_rowcount.py +66 -0
- dqlite_dbapi-0.3.0/tests/integration/test_executemany_generator.py +47 -0
- dqlite_dbapi-0.3.0/tests/integration/test_executemany_preserves_lastrowid.py +43 -0
- dqlite_dbapi-0.3.0/tests/integration/test_executemany_returning.py +42 -0
- dqlite_dbapi-0.3.0/tests/integration/test_force_close_unblocks_run_sync.py +55 -0
- dqlite_dbapi-0.3.0/tests/integration/test_lastrowid_autoincrement.py +82 -0
- dqlite_dbapi-0.3.0/tests/integration/test_lastrowid_cursor_scoped.py +73 -0
- dqlite_dbapi-0.3.0/tests/integration/test_lastrowid_returning.py +44 -0
- dqlite_dbapi-0.3.0/tests/integration/test_lastrowid_survives_cross_cursor_rollback.py +117 -0
- dqlite_dbapi-0.3.0/tests/integration/test_leader_redirect_live.py +107 -0
- dqlite_dbapi-0.3.0/tests/integration/test_misc_coverage.py +342 -0
- dqlite_dbapi-0.3.0/tests/integration/test_multiline_returning_rows.py +69 -0
- dqlite_dbapi-0.3.0/tests/integration/test_nan_inf_float.py +50 -0
- dqlite_dbapi-0.3.0/tests/integration/test_negative_zero_and_subnormal_float.py +68 -0
- dqlite_dbapi-0.3.0/tests/integration/test_no_transaction_error_wording.py +116 -0
- dqlite_dbapi-0.3.0/tests/integration/test_null_vs_empty_text_blob_three_way.py +70 -0
- dqlite_dbapi-0.3.0/tests/integration/test_pragma_deny_list.py +85 -0
- dqlite_dbapi-0.3.0/tests/integration/test_pragma_read_rowcount_minus_one.py +46 -0
- dqlite_dbapi-0.3.0/tests/integration/test_query_detection.py +62 -0
- dqlite_dbapi-0.3.0/tests/integration/test_returning.py +83 -0
- dqlite_dbapi-0.3.0/tests/integration/test_savepoint_dbapi.py +133 -0
- dqlite_dbapi-0.3.0/tests/integration/test_savepoint_failure_responses.py +81 -0
- dqlite_dbapi-0.3.0/tests/integration/test_session_mode_read_only.py +109 -0
- dqlite_dbapi-0.3.0/tests/integration/test_sqlite_version_pin.py +55 -0
- dqlite_dbapi-0.3.0/tests/integration/test_sync_transaction_ctxmgr_rejects_stray_commit.py +107 -0
- dqlite_dbapi-0.3.0/tests/test_aconn_execute_with_parameters.py +40 -0
- dqlite_dbapi-0.3.0/tests/test_aconn_factory_getters.py +34 -0
- dqlite_dbapi-0.3.0/tests/test_aconnect_cleanup_close_shielded_against_outer_timeout.py +62 -0
- dqlite_dbapi-0.3.0/tests/test_aconnect_cleanup_on_connect_failure.py +75 -0
- dqlite_dbapi-0.3.0/tests/test_adapter_exceptions_wrapped_as_data_error.py +123 -0
- dqlite_dbapi-0.3.0/tests/test_aenter_cleanup_nulls_locks_under_concurrent_close.py +107 -0
- dqlite_dbapi-0.3.0/tests/test_aenter_cleanup_preserves_original_under_outer_cancel.py +61 -0
- dqlite_dbapi-0.3.0/tests/test_aexit_behavioural_no_close.py +64 -0
- dqlite_dbapi-0.3.0/tests/test_aexit_commit_cancel_debug_log.py +99 -0
- dqlite_dbapi-0.3.0/tests/test_aexit_commit_cancel_force_closes_transport.py +114 -0
- dqlite_dbapi-0.3.0/tests/test_aexit_rollback_cancel_body_context_pin.py +65 -0
- dqlite_dbapi-0.3.0/tests/test_aexit_rollback_debug_log.py +71 -0
- dqlite_dbapi-0.3.0/tests/test_aio_cascade_close_clears_executing_task.py +37 -0
- dqlite_dbapi-0.3.0/tests/test_aio_commit_rollback_no_tx.py +62 -0
- dqlite_dbapi-0.3.0/tests/test_aio_commit_rollback_no_tx_code_matrix.py +75 -0
- dqlite_dbapi-0.3.0/tests/test_aio_commit_rollback_wrapping.py +125 -0
- dqlite_dbapi-0.3.0/tests/test_aio_connection_finalizer_detached_on_close.py +44 -0
- dqlite_dbapi-0.3.0/tests/test_aio_cursor_drain_rows.py +69 -0
- dqlite_dbapi-0.3.0/tests/test_aio_cursor_row_factory_typeerror_wrap.py +80 -0
- dqlite_dbapi-0.3.0/tests/test_aio_description_tuple_exported.py +16 -0
- dqlite_dbapi-0.3.0/tests/test_aio_execute_unlocked_silent_drop_scrubs_state.py +102 -0
- dqlite_dbapi-0.3.0/tests/test_aio_executemany_cursor_close_cascade.py +23 -0
- dqlite_dbapi-0.3.0/tests/test_aio_force_close_foreign_thread_cursor_closed_pre_cascade.py +91 -0
- dqlite_dbapi-0.3.0/tests/test_aio_force_close_transport_cursor_cascade.py +78 -0
- dqlite_dbapi-0.3.0/tests/test_aio_init_reexports_diagnostic_prefixes.py +31 -0
- dqlite_dbapi-0.3.0/tests/test_aio_loop_affinity_exc_class.py +54 -0
- dqlite_dbapi-0.3.0/tests/test_aio_module_attributes.py +79 -0
- dqlite_dbapi-0.3.0/tests/test_aio_register_adapter_export.py +35 -0
- dqlite_dbapi-0.3.0/tests/test_aio_register_converter_stubs.py +28 -0
- dqlite_dbapi-0.3.0/tests/test_aio_row_factory_setter_loop_binding.py +76 -0
- dqlite_dbapi-0.3.0/tests/test_aio_setters_clear_messages_pep249.py +37 -0
- dqlite_dbapi-0.3.0/tests/test_aio_transaction_recheck_after_ensure_connection.py +79 -0
- dqlite_dbapi-0.3.0/tests/test_arraysize_validation.py +107 -0
- dqlite_dbapi-0.3.0/tests/test_async_backup_not_async_def.py +24 -0
- dqlite_dbapi-0.3.0/tests/test_async_check_loop_only_pid_before_loop.py +55 -0
- dqlite_dbapi-0.3.0/tests/test_async_close_cancel_arm_cancels_inner_pending_drain.py +101 -0
- dqlite_dbapi-0.3.0/tests/test_async_close_ensure_locks_guard.py +34 -0
- dqlite_dbapi-0.3.0/tests/test_async_close_finally_propagates_cancel.py +127 -0
- dqlite_dbapi-0.3.0/tests/test_async_close_op_lock_bounded.py +128 -0
- dqlite_dbapi-0.3.0/tests/test_async_close_outer_cancel_force_closes_transport.py +89 -0
- dqlite_dbapi-0.3.0/tests/test_async_close_race.py +106 -0
- dqlite_dbapi-0.3.0/tests/test_async_commit_rollback_force_close_on_outer_cancel.py +101 -0
- dqlite_dbapi-0.3.0/tests/test_async_commit_rollback_in_transaction_under_lock.py +77 -0
- dqlite_dbapi-0.3.0/tests/test_async_commit_rollback_loop_binding_first.py +69 -0
- dqlite_dbapi-0.3.0/tests/test_async_commit_rollback_messages_under_lock.py +69 -0
- dqlite_dbapi-0.3.0/tests/test_async_commit_rollback_op_lock_bounded.py +54 -0
- dqlite_dbapi-0.3.0/tests/test_async_commit_rollback_phase_budget.py +92 -0
- dqlite_dbapi-0.3.0/tests/test_async_commit_rollback_retry_after_invalidate.py +111 -0
- dqlite_dbapi-0.3.0/tests/test_async_commit_rollback_timeout_outer_scope_hint.py +105 -0
- dqlite_dbapi-0.3.0/tests/test_async_commit_rollback_timeout_phase_aware.py +100 -0
- dqlite_dbapi-0.3.0/tests/test_async_connect_cross_loop_diagnostic_on_fast_path.py +47 -0
- dqlite_dbapi-0.3.0/tests/test_async_connection.py +75 -0
- dqlite_dbapi-0.3.0/tests/test_async_connection_close_during_connect.py +51 -0
- dqlite_dbapi-0.3.0/tests/test_async_connection_cursor_fork_guard.py +63 -0
- dqlite_dbapi-0.3.0/tests/test_async_connection_ensure_connection_post_yield_close_shielded.py +139 -0
- dqlite_dbapi-0.3.0/tests/test_async_connection_race.py +40 -0
- dqlite_dbapi-0.3.0/tests/test_async_connection_setters_loop_binding.py +60 -0
- dqlite_dbapi-0.3.0/tests/test_async_connection_transaction.py +48 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor.py +248 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_aclose_alias.py +72 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_add_races_cascade_clear.py +94 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_aenter_cross_task_executing_guard.py +57 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_aenter_gc_parent_pep249.py +23 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_aiter_aenter_pep249_pins.py +59 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_aiter_cross_loop_fail_fast.py +50 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_anext_cooperative_yield.py +116 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_arraysize_row_factory_loop_binding.py +68 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_callproc_nextset_scroll_loop_binding.py +78 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_close_clears_executing_task.py +59 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_close_is_sync_and_race_safe.py +90 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_close_lock_free.py +52 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_closed_state_pep249.py +92 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_execute_executing_task_inside_try_frame.py +47 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_execute_messages_clear.py +59 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_executemany_validation_clears_executing_task.py +94 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_fetch_loop_binding.py +125 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_finally_clear_executing_task_unconditional.py +41 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_late_add_proxy_swap.py +34 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_loop_binding.py +47 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_repr_with_gced_parent_connection.py +29 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_rownumber_closed_cross_loop.py +55 -0
- dqlite_dbapi-0.3.0/tests/test_async_cursor_setinputsizes_loop_binding.py +46 -0
- dqlite_dbapi-0.3.0/tests/test_async_execute_busy_retry_releases_op_lock_between_attempts.py +55 -0
- dqlite_dbapi-0.3.0/tests/test_async_executemany_atomic.py +58 -0
- dqlite_dbapi-0.3.0/tests/test_async_executemany_close_race.py +56 -0
- dqlite_dbapi-0.3.0/tests/test_async_executescript_stub_raises_on_call.py +51 -0
- dqlite_dbapi-0.3.0/tests/test_async_fetch_does_not_lazy_bind_loop.py +41 -0
- dqlite_dbapi-0.3.0/tests/test_async_fetchall_row_factory_cooperative_yield.py +166 -0
- dqlite_dbapi-0.3.0/tests/test_async_fetchall_row_factory_happy_path.py +46 -0
- dqlite_dbapi-0.3.0/tests/test_async_fetchmany_row_factory_cooperative_yield.py +153 -0
- dqlite_dbapi-0.3.0/tests/test_async_force_close_transport.py +153 -0
- dqlite_dbapi-0.3.0/tests/test_async_in_transaction_closed_foreign_loop.py +58 -0
- dqlite_dbapi-0.3.0/tests/test_async_in_transaction_loop_binding.py +61 -0
- dqlite_dbapi-0.3.0/tests/test_async_invalidated_property.py +48 -0
- dqlite_dbapi-0.3.0/tests/test_async_lock_binding.py +111 -0
- dqlite_dbapi-0.3.0/tests/test_async_resource_warning_gate.py +109 -0
- dqlite_dbapi-0.3.0/tests/test_async_resource_warning_sanitize_parity.py +47 -0
- dqlite_dbapi-0.3.0/tests/test_async_secondary_methods_clear_messages_before_guards.py +117 -0
- dqlite_dbapi-0.3.0/tests/test_async_transaction_owner_set_inside_try_frame.py +78 -0
- dqlite_dbapi-0.3.0/tests/test_async_unclosed_warning_shutdown_safety.py +135 -0
- dqlite_dbapi-0.3.0/tests/test_audit_2026_05_coverage_gaps.py +256 -0
- dqlite_dbapi-0.3.0/tests/test_audit_2026_05_dbapi_coverage.py +332 -0
- dqlite_dbapi-0.3.0/tests/test_autocommit_doc_no_round_trip.py +36 -0
- dqlite_dbapi-0.3.0/tests/test_autocommit_legacy_transaction_control.py +57 -0
- dqlite_dbapi-0.3.0/tests/test_autocommit_property.py +64 -0
- dqlite_dbapi-0.3.0/tests/test_autocommit_setter_exact_int_gate.py +101 -0
- dqlite_dbapi-0.3.0/tests/test_begin_rewrite_session_mode.py +179 -0
- dqlite_dbapi-0.3.0/tests/test_binary_typeerror_stdlib_parity.py +45 -0
- dqlite_dbapi-0.3.0/tests/test_bind_typeerror_as_dataerror.py +36 -0
- dqlite_dbapi-0.3.0/tests/test_build_and_connect_base_exception_group_wrap.py +105 -0
- dqlite_dbapi-0.3.0/tests/test_build_and_connect_pragma_shield_observer.py +58 -0
- dqlite_dbapi-0.3.0/tests/test_build_and_connect_resolve_leader_oserror_wrap.py +57 -0
- dqlite_dbapi-0.3.0/tests/test_build_and_connect_wire_encode_error_translation.py +76 -0
- dqlite_dbapi-0.3.0/tests/test_busy_retry_async_wiring.py +138 -0
- dqlite_dbapi-0.3.0/tests/test_busy_retry_classifier.py +69 -0
- dqlite_dbapi-0.3.0/tests/test_busy_retry_curve.py +81 -0
- dqlite_dbapi-0.3.0/tests/test_busy_retry_sync_wiring.py +129 -0
- dqlite_dbapi-0.3.0/tests/test_call_client_base_exception_group_wrap.py +71 -0
- dqlite_dbapi-0.3.0/tests/test_call_client_baseexceptiongroup_cancel_split.py +80 -0
- dqlite_dbapi-0.3.0/tests/test_call_client_mapping.py +105 -0
- dqlite_dbapi-0.3.0/tests/test_call_client_typeerror_message_does_not_blame_bind.py +32 -0
- dqlite_dbapi-0.3.0/tests/test_call_client_wire_encode_error.py +30 -0
- dqlite_dbapi-0.3.0/tests/test_callproc_scroll_clear_messages.py +78 -0
- dqlite_dbapi-0.3.0/tests/test_cascade_cursors_clears_messages.py +79 -0
- dqlite_dbapi-0.3.0/tests/test_check_same_thread_kwarg.py +180 -0
- dqlite_dbapi-0.3.0/tests/test_classify_caller_sql.py +84 -0
- dqlite_dbapi-0.3.0/tests/test_classify_caller_sql_hardening.py +101 -0
- dqlite_dbapi-0.3.0/tests/test_classify_caller_sql_structural_reject_precedence.py +70 -0
- dqlite_dbapi-0.3.0/tests/test_classify_operational_code_zero.py +20 -0
- dqlite_dbapi-0.3.0/tests/test_cleanup_loop_thread_disarms_inner_and_reaps_drain.py +296 -0
- dqlite_dbapi-0.3.0/tests/test_cleanup_loop_thread_finalizer_fork_safe.py +150 -0
- dqlite_dbapi-0.3.0/tests/test_cleanup_loop_thread_foreign_loop_short_floor.py +160 -0
- dqlite_dbapi-0.3.0/tests/test_close_bypass_path_releases_latched_op_lock.py +59 -0
- dqlite_dbapi-0.3.0/tests/test_close_resource_leak.py +31 -0
- dqlite_dbapi-0.3.0/tests/test_close_signal_handler_reentry.py +125 -0
- dqlite_dbapi-0.3.0/tests/test_close_surfaces_op_lock_contention.py +52 -0
- dqlite_dbapi-0.3.0/tests/test_close_thread_join_uses_close_timeout.py +157 -0
- dqlite_dbapi-0.3.0/tests/test_close_timeout_floor_enforcement.py +47 -0
- dqlite_dbapi-0.3.0/tests/test_close_timeout_plumbing.py +101 -0
- dqlite_dbapi-0.3.0/tests/test_closed_property.py +96 -0
- dqlite_dbapi-0.3.0/tests/test_cluster_policy_rejection_prefix_constant.py +53 -0
- dqlite_dbapi-0.3.0/tests/test_code_to_exception_wire_ssot.py +35 -0
- dqlite_dbapi-0.3.0/tests/test_collated_coverage_gaps.py +151 -0
- dqlite_dbapi-0.3.0/tests/test_commit_after_external_close.py +67 -0
- dqlite_dbapi-0.3.0/tests/test_commit_leader_flip_ambiguous_commit_error.py +241 -0
- dqlite_dbapi-0.3.0/tests/test_commit_leader_flip_propagates.py +114 -0
- dqlite_dbapi-0.3.0/tests/test_commit_no_spurious_connect.py +27 -0
- dqlite_dbapi-0.3.0/tests/test_commit_rollback_shortcircuit_uses_in_transaction.py +130 -0
- dqlite_dbapi-0.3.0/tests/test_conform_adapter_non_primitive_rejected_at_dbapi_layer.py +70 -0
- dqlite_dbapi-0.3.0/tests/test_conftest_adapter_registry_isolation.py +28 -0
- dqlite_dbapi-0.3.0/tests/test_connect_baseexceptiongroup_cancel_split.py +86 -0
- dqlite_dbapi-0.3.0/tests/test_connect_busy_timeout_kwarg.py +86 -0
- dqlite_dbapi-0.3.0/tests/test_connect_clears_messages.py +41 -0
- dqlite_dbapi-0.3.0/tests/test_connect_closed_precedes_thread_affinity.py +69 -0
- dqlite_dbapi-0.3.0/tests/test_connect_iso_autocommit_round_trip.py +97 -0
- dqlite_dbapi-0.3.0/tests/test_connect_isolation_level_autocommit_kwargs_symmetric.py +108 -0
- dqlite_dbapi-0.3.0/tests/test_connect_preserves_code.py +69 -0
- dqlite_dbapi-0.3.0/tests/test_connection.py +38 -0
- dqlite_dbapi-0.3.0/tests/test_connection_after_fork_raises.py +125 -0
- dqlite_dbapi-0.3.0/tests/test_connection_autocommit_isolation_level_closed_state.py +66 -0
- dqlite_dbapi-0.3.0/tests/test_connection_close_cascades_cursors.py +67 -0
- dqlite_dbapi-0.3.0/tests/test_connection_close_cursor_cascade_atomicity.py +62 -0
- dqlite_dbapi-0.3.0/tests/test_connection_close_idempotent_cross_thread.py +55 -0
- dqlite_dbapi-0.3.0/tests/test_connection_closed_checks.py +205 -0
- dqlite_dbapi-0.3.0/tests/test_connection_cursor_class_attribute.py +38 -0
- dqlite_dbapi-0.3.0/tests/test_connection_cursor_closed_state_precedes_unknown_kwarg.py +35 -0
- dqlite_dbapi-0.3.0/tests/test_connection_database_empty_string_rejected.py +45 -0
- dqlite_dbapi-0.3.0/tests/test_connection_database_kwarg_isinstance.py +38 -0
- dqlite_dbapi-0.3.0/tests/test_connection_eager_address_validation.py +48 -0
- dqlite_dbapi-0.3.0/tests/test_connection_enter_eager.py +30 -0
- dqlite_dbapi-0.3.0/tests/test_connection_executemany_outer_shape_check.py +192 -0
- dqlite_dbapi-0.3.0/tests/test_connection_exit_commit_ki_breadcrumb.py +79 -0
- dqlite_dbapi-0.3.0/tests/test_connection_exit_short_circuits_on_closed.py +70 -0
- dqlite_dbapi-0.3.0/tests/test_connection_messages_cleared_by_cursor_methods.py +53 -0
- dqlite_dbapi-0.3.0/tests/test_connection_row_factory_setter_closed_check.py +50 -0
- dqlite_dbapi-0.3.0/tests/test_context_manager_exit.py +79 -0
- dqlite_dbapi-0.3.0/tests/test_convert_bind_param_conform_exception_propagates.py +50 -0
- dqlite_dbapi-0.3.0/tests/test_convert_bind_param_unsupported_vs_bad_adapter_message.py +37 -0
- dqlite_dbapi-0.3.0/tests/test_convert_params_async_cooperative_yield.py +121 -0
- dqlite_dbapi-0.3.0/tests/test_convert_params_conform_raise_propagates_unwrapped.py +51 -0
- dqlite_dbapi-0.3.0/tests/test_convert_rows_async_cooperative_yield.py +106 -0
- dqlite_dbapi-0.3.0/tests/test_convert_rows_async_probe_does_not_walk_all_row_types_up_front.py +85 -0
- dqlite_dbapi-0.3.0/tests/test_convert_rows_converter_free_fast_path.py +109 -0
- dqlite_dbapi-0.3.0/tests/test_cte_prefix_stripper_edges.py +71 -0
- dqlite_dbapi-0.3.0/tests/test_cursor.py +215 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_after_external_close.py +57 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_arraysize_row_factory_setter_thread.py +115 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_close_clears_messages.py +32 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_close_cross_thread.py +43 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_close_preserves_body_exception_on_messages_strip.py +56 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_close_releases_connection_pin.py +46 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_closed_after_connection_gc_pep249.py +90 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_closed_state_pep249.py +74 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_completed_iterations_resets_on_single_execute.py +73 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_connection_partial_init_attributeerror.py +42 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_connection_property_after_gc_pep249.py +45 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_execute_non_str_operation.py +36 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_execute_state_reset_on_failure.py +366 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_executemany_non_str_operation.py +68 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_executemany_outer_shape_check.py +72 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_factory_kwarg_rejected.py +49 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_force_close_race.py +66 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_iter_clears_messages_pep249.py +71 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_iterator_reset.py +91 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_kwargs_rejection_precedence.py +61 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_next_row_factory_raise_replays_row.py +104 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_per_row_types.py +153 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_post_close_property_reads.py +100 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_protocol_check.py +50 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_rejects_generator_params.py +38 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_repr_with_gced_parent_connection.py +53 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_row_factory_rejecting_setter.py +97 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_row_factory_subclass_inheritance.py +68 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_row_index_reset.py +76 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_rowcount_after_ddl_stdlib_parity.py +195 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_rownumber_affinity.py +54 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_rownumber_post_close.py +64 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_scroll_mode_validation.py +126 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_secondary_methods_positional_only.py +116 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_setinputsizes_affinity_precedes_shape.py +151 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_setinputsizes_setoutputsize_closed_state_precedes_validation.py +90 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_setters_clear_messages_pep249.py +48 -0
- dqlite_dbapi-0.3.0/tests/test_cursor_stop_iteration_contract.py +82 -0
- dqlite_dbapi-0.3.0/tests/test_cursors_weakset_state_lock.py +104 -0
- dqlite_dbapi-0.3.0/tests/test_date_widens_to_datetime.py +25 -0
- dqlite_dbapi-0.3.0/tests/test_datetime_time_round_trip.py +47 -0
- dqlite_dbapi-0.3.0/tests/test_dbapi_commit_deferred_fk.py +31 -0
- dqlite_dbapi-0.3.0/tests/test_dbapi_default_timeouts_use_client_constants.py +43 -0
- dqlite_dbapi-0.3.0/tests/test_dbapi_exception_message_arg_cap.py +87 -0
- dqlite_dbapi-0.3.0/tests/test_dbapi_exception_raw_message_cap.py +67 -0
- dqlite_dbapi-0.3.0/tests/test_dbapi_fork_guard_cluster.py +204 -0
- dqlite_dbapi-0.3.0/tests/test_dbapi_type_hash_consistency.py +72 -0
- dqlite_dbapi-0.3.0/tests/test_description_null_first_row_resolves.py +136 -0
- dqlite_dbapi-0.3.0/tests/test_description_null_rescue_scan_yields_cooperatively.py +144 -0
- dqlite_dbapi-0.3.0/tests/test_description_null_type_code_to_none.py +90 -0
- dqlite_dbapi-0.3.0/tests/test_description_strict_type_codes.py +53 -0
- dqlite_dbapi-0.3.0/tests/test_description_tuple_public_alias.py +32 -0
- dqlite_dbapi-0.3.0/tests/test_description_type_code_unknown_sentinel.py +42 -0
- dqlite_dbapi-0.3.0/tests/test_diagnostic_messages.py +131 -0
- dqlite_dbapi-0.3.0/tests/test_dial_attempt_timeout_propagation.py +96 -0
- dqlite_dbapi-0.3.0/tests/test_dial_func_propagation.py +67 -0
- dqlite_dbapi-0.3.0/tests/test_dial_func_propagation_to_leader_resolve.py +152 -0
- dqlite_dbapi-0.3.0/tests/test_dqlite_namespace_error_classification.py +37 -0
- dqlite_dbapi-0.3.0/tests/test_ensure_loop_fast_path_snapshot_dcl_defence.py +79 -0
- dqlite_dbapi-0.3.0/tests/test_ensure_loop_post_fork_pid_guard.py +108 -0
- dqlite_dbapi-0.3.0/tests/test_ensure_loop_signal_teardown.py +125 -0
- dqlite_dbapi-0.3.0/tests/test_error_code_mapping.py +91 -0
- dqlite_dbapi-0.3.0/tests/test_error_pickle_cause_either_or.py +41 -0
- dqlite_dbapi-0.3.0/tests/test_error_pickle_preserves_raw_message.py +74 -0
- dqlite_dbapi-0.3.0/tests/test_exception_coded_mixin.py +90 -0
- dqlite_dbapi-0.3.0/tests/test_exception_mapping.py +65 -0
- dqlite_dbapi-0.3.0/tests/test_exception_repr_code.py +46 -0
- dqlite_dbapi-0.3.0/tests/test_exception_wrapping.py +102 -0
- dqlite_dbapi-0.3.0/tests/test_exceptions.py +38 -0
- dqlite_dbapi-0.3.0/tests/test_exceptions_all_symmetry.py +34 -0
- dqlite_dbapi-0.3.0/tests/test_execute_caller_param_shape_preserves_prior_state.py +89 -0
- dqlite_dbapi-0.3.0/tests/test_execute_executemany_positional_only.py +69 -0
- dqlite_dbapi-0.3.0/tests/test_execute_multi_statement_rejection.py +87 -0
- dqlite_dbapi-0.3.0/tests/test_execute_reject_scrubs_prior_result_state.py +156 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_accumulator_semantics.py +87 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_basecaught_state_reset.py +172 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_cancel_restores_pre_batch_lastrowid.py +132 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_cancellederror_restores_pre_batch_lastrowid.py +101 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_classifier_resets_state_first.py +89 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_completed_iterations_snapshot_conditional_restore.py +128 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_dict_subclass_accepted.py +64 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_empty.py +92 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_empty_batch_preserves_lastrowid.py +52 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_lastrowid_restored_pre_batch_on_raise.py +145 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_none_seq_rejected.py +59 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_per_iter_structural_rejects.py +77 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_pragma_with_leading_comment.py +62 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_push_skips_cascade_zeroed_cursor.py +64 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_reject_scrubs_prior_result_state.py +231 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_rejects_pure_queries.py +93 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_rejects_transaction_verbs.py +235 -0
- dqlite_dbapi-0.3.0/tests/test_executemany_returning_cap.py +61 -0
- dqlite_dbapi-0.3.0/tests/test_exit_logs_rollback_failure.py +76 -0
- dqlite_dbapi-0.3.0/tests/test_fetchall_row_factory_raise_replay.py +125 -0
- dqlite_dbapi-0.3.0/tests/test_fetchmany_edges.py +63 -0
- dqlite_dbapi-0.3.0/tests/test_fetchmany_negative_size_rejected.py +78 -0
- dqlite_dbapi-0.3.0/tests/test_fetchmany_non_int_validation.py +66 -0
- dqlite_dbapi-0.3.0/tests/test_fetchmany_one_clear_per_call_pep249.py +42 -0
- dqlite_dbapi-0.3.0/tests/test_fetchmany_row_factory_raise_replay.py +111 -0
- dqlite_dbapi-0.3.0/tests/test_finalizer_strict_warnings.py +38 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_cancel_and_observe_narrow_suppress.py +19 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_observe_callback_coverage.py +49 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_transport_cleanup_tail_unconditional.py +88 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_transport_clears_messages.py +87 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_transport_cross_thread_cancel_threadsafe.py +101 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_transport_cursor_cascade_threadsafe.py +135 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_transport_defensive_arms.py +83 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_transport_disarms_inner_finalizer.py +68 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_transport_nulls_lock_and_loop_slots.py +74 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_transport_pending_drain_resnapshot.py +115 -0
- dqlite_dbapi-0.3.0/tests/test_force_close_transport_writer_cross_thread.py +114 -0
- dqlite_dbapi-0.3.0/tests/test_fork_diagnostic_includes_pids.py +41 -0
- dqlite_dbapi-0.3.0/tests/test_format_utc_offset_non_timedelta_guard.py +50 -0
- dqlite_dbapi-0.3.0/tests/test_fromticks_tz_policy.py +35 -0
- dqlite_dbapi-0.3.0/tests/test_gc_cleanup.py +43 -0
- dqlite_dbapi-0.3.0/tests/test_get_async_connection_force_close_race.py +101 -0
- dqlite_dbapi-0.3.0/tests/test_get_resolve_leader_cluster_no_loop_raises_runtime_error.py +24 -0
- dqlite_dbapi-0.3.0/tests/test_in_transaction_after_close.py +95 -0
- dqlite_dbapi-0.3.0/tests/test_in_transaction_closed_divergence_doc.py +13 -0
- dqlite_dbapi-0.3.0/tests/test_in_transaction_closed_foreign_thread.py +85 -0
- dqlite_dbapi-0.3.0/tests/test_in_transaction_property.py +35 -0
- dqlite_dbapi-0.3.0/tests/test_in_transaction_property_under_check_same_thread.py +101 -0
- dqlite_dbapi-0.3.0/tests/test_is_multi_statement_walker.py +40 -0
- dqlite_dbapi-0.3.0/tests/test_is_no_transaction_error.py +113 -0
- dqlite_dbapi-0.3.0/tests/test_is_row_returning_multiline_whitespace.py +88 -0
- dqlite_dbapi-0.3.0/tests/test_is_row_returning_sql_noise.py +70 -0
- dqlite_dbapi-0.3.0/tests/test_iso8601_aware_microseconds_round_trip.py +61 -0
- dqlite_dbapi-0.3.0/tests/test_iso8601_decoder_leap_seconds_rejected.py +28 -0
- dqlite_dbapi-0.3.0/tests/test_iso8601_decoder_subsecond_truncation.py +45 -0
- dqlite_dbapi-0.3.0/tests/test_iso8601_encoder.py +369 -0
- dqlite_dbapi-0.3.0/tests/test_iso8601_encoder_fold.py +48 -0
- dqlite_dbapi-0.3.0/tests/test_iso8601_encoder_utcoffset_exception_wrap.py +110 -0
- dqlite_dbapi-0.3.0/tests/test_iso8601_parse_error_truncation.py +53 -0
- dqlite_dbapi-0.3.0/tests/test_iso8601_tzinfo_exception_classes_wrapped.py +70 -0
- dqlite_dbapi-0.3.0/tests/test_isolation_level_stdlib_accept_set.py +75 -0
- dqlite_dbapi-0.3.0/tests/test_iterdump_stub_signature_3_13_filter_kwarg.py +52 -0
- dqlite_dbapi-0.3.0/tests/test_join_budget_helper_shutdown_safety.py +70 -0
- dqlite_dbapi-0.3.0/tests/test_lastrowid_docstring_stdlib_parity_claim.py +20 -0
- dqlite_dbapi-0.3.0/tests/test_lastrowid_insert_only.py +68 -0
- dqlite_dbapi-0.3.0/tests/test_lastrowid_signed_int64_cast.py +51 -0
- dqlite_dbapi-0.3.0/tests/test_leader_error_codes_identity.py +26 -0
- dqlite_dbapi-0.3.0/tests/test_leader_redirect_on_connect.py +207 -0
- dqlite_dbapi-0.3.0/tests/test_legacy_transaction_control_constant.py +36 -0
- dqlite_dbapi-0.3.0/tests/test_max_continuation_frames_upper_bound.py +53 -0
- dqlite_dbapi-0.3.0/tests/test_max_message_size_round_trip.py +51 -0
- dqlite_dbapi-0.3.0/tests/test_max_total_rows_plumbing.py +63 -0
- dqlite_dbapi-0.3.0/tests/test_max_total_rows_validation.py +47 -0
- dqlite_dbapi-0.3.0/tests/test_messages_attribute.py +33 -0
- dqlite_dbapi-0.3.0/tests/test_messages_clear_on_ctxmgr_entry.py +67 -0
- dqlite_dbapi-0.3.0/tests/test_module_attributes.py +223 -0
- dqlite_dbapi-0.3.0/tests/test_module_level_stubs.py +88 -0
- dqlite_dbapi-0.3.0/tests/test_multi_statement_classifier_allows_trigger_bodies.py +66 -0
- dqlite_dbapi-0.3.0/tests/test_no_transaction_substrings_source_of_truth.py +22 -0
- dqlite_dbapi-0.3.0/tests/test_no_tx_primary_codes_invariant.py +41 -0
- dqlite_dbapi-0.3.0/tests/test_no_workflow_references_in_source.py +38 -0
- dqlite_dbapi-0.3.0/tests/test_number_includes_boolean_documented.py +10 -0
- dqlite_dbapi-0.3.0/tests/test_op_lock_bounded_acquire.py +69 -0
- dqlite_dbapi-0.3.0/tests/test_operational_error_classification.py +64 -0
- dqlite_dbapi-0.3.0/tests/test_operational_error_raw_message.py +62 -0
- dqlite_dbapi-0.3.0/tests/test_param_conversion.py +59 -0
- dqlite_dbapi-0.3.0/tests/test_param_validation.py +42 -0
- dqlite_dbapi-0.3.0/tests/test_paramstyle_qmark_only_pin.py +52 -0
- dqlite_dbapi-0.3.0/tests/test_parse_decltypes_colnames_constants.py +58 -0
- dqlite_dbapi-0.3.0/tests/test_pep249_database_error_routing.py +41 -0
- dqlite_dbapi-0.3.0/tests/test_pep249_exception_aliases.py +68 -0
- dqlite_dbapi-0.3.0/tests/test_pep249_messages_clearing.py +233 -0
- dqlite_dbapi-0.3.0/tests/test_pep249_messages_independence.py +73 -0
- dqlite_dbapi-0.3.0/tests/test_pep249_misc_pins.py +124 -0
- dqlite_dbapi-0.3.0/tests/test_pep249_stub_hasattr_divergence.py +79 -0
- dqlite_dbapi-0.3.0/tests/test_pep249_type_constructors_vs_singletons.py +60 -0
- dqlite_dbapi-0.3.0/tests/test_pep249_type_constructors_wrap_valueerror.py +39 -0
- dqlite_dbapi-0.3.0/tests/test_pep249_type_objects_final_annotated.py +28 -0
- dqlite_dbapi-0.3.0/tests/test_pickle_guard.py +64 -0
- dqlite_dbapi-0.3.0/tests/test_pragma_busy_timeout_intercept.py +208 -0
- dqlite_dbapi-0.3.0/tests/test_pragma_write_description_none.py +48 -0
- dqlite_dbapi-0.3.0/tests/test_prepare_protocol_in_types_all.py +24 -0
- dqlite_dbapi-0.3.0/tests/test_property_round_trip_and_fork_guard.py +223 -0
- dqlite_dbapi-0.3.0/tests/test_property_setters_do_not_mirror_to_inner_async_conn.py +44 -0
- dqlite_dbapi-0.3.0/tests/test_protocol_serialization.py +79 -0
- dqlite_dbapi-0.3.0/tests/test_pyproject_dependency_graph.py +40 -0
- dqlite_dbapi-0.3.0/tests/test_readme_truthfulness_pins.py +52 -0
- dqlite_dbapi-0.3.0/tests/test_register_adapter_conform_fallback.py +126 -0
- dqlite_dbapi-0.3.0/tests/test_register_adapter_global_sync_aio_symmetry.py +49 -0
- dqlite_dbapi-0.3.0/tests/test_register_adapter_positional_only_signature.py +33 -0
- dqlite_dbapi-0.3.0/tests/test_repr.py +62 -0
- dqlite_dbapi-0.3.0/tests/test_repr_sanitizes_address.py +131 -0
- dqlite_dbapi-0.3.0/tests/test_resolve_leader_cache_dial_func_id_recycle.py +130 -0
- dqlite_dbapi-0.3.0/tests/test_resolve_leader_cache_lock_atfork_hook.py +25 -0
- dqlite_dbapi-0.3.0/tests/test_resolve_leader_cluster_cache.py +93 -0
- dqlite_dbapi-0.3.0/tests/test_resolve_leader_cluster_constructs_outside_lock.py +87 -0
- dqlite_dbapi-0.3.0/tests/test_resolve_leader_cross_loop_isolation.py +187 -0
- dqlite_dbapi-0.3.0/tests/test_rollback_busy_retry.py +81 -0
- dqlite_dbapi-0.3.0/tests/test_row_factory_annotation.py +49 -0
- dqlite_dbapi-0.3.0/tests/test_row_factory_sqlite3_equivalent.py +188 -0
- dqlite_dbapi-0.3.0/tests/test_row_factory_sqlite3_row_surfaces_dataerror.py +53 -0
- dqlite_dbapi-0.3.0/tests/test_row_hash_eq_empty.py +36 -0
- dqlite_dbapi-0.3.0/tests/test_rowid_number_overlap_documented.py +25 -0
- dqlite_dbapi-0.3.0/tests/test_rownumber_closed_cursor_returns_none_documented.py +60 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_ensure_loop_raise_closes_coroutine.py +59 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_finally_suppresses_double_release.py +83 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_keyboard_interrupt.py +287 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_keyboard_interrupt_cleanup_paths.py +133 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_ki_post_schedule_pre_await.py +71 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_ki_race_recovery.py +164 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_loop_closed_during_schedule.py +93 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_other_runtimeerror_propagates.py +88 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_owner_stamp_window.py +82 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_timeout.py +352 -0
- dqlite_dbapi-0.3.0/tests/test_run_sync_timeout_recovery_preserves_conn.py +85 -0
- dqlite_dbapi-0.3.0/tests/test_secondary_methods_clear_messages_before_thread_check.py +75 -0
- dqlite_dbapi-0.3.0/tests/test_setinputsizes_accepts_none.py +55 -0
- dqlite_dbapi-0.3.0/tests/test_setinputsizes_clears_messages_per_pep249.py +45 -0
- dqlite_dbapi-0.3.0/tests/test_setinputsizes_non_sequence_iterable.py +60 -0
- dqlite_dbapi-0.3.0/tests/test_setinputsizes_sequence_acceptance.py +66 -0
- dqlite_dbapi-0.3.0/tests/test_setinputsizes_short_circuit_on_closed_connection.py +83 -0
- dqlite_dbapi-0.3.0/tests/test_setoutputsize_accepts_none.py +56 -0
- dqlite_dbapi-0.3.0/tests/test_setter_closed_state_precedes_thread.py +63 -0
- dqlite_dbapi-0.3.0/tests/test_sqlite_errorname_property.py +99 -0
- dqlite_dbapi-0.3.0/tests/test_sqlite_version_not_public_attribute.py +37 -0
- dqlite_dbapi-0.3.0/tests/test_strip_leading_comments_bom.py +52 -0
- dqlite_dbapi-0.3.0/tests/test_strip_leading_comments_parity.py +62 -0
- dqlite_dbapi-0.3.0/tests/test_strip_sql_noise_backtick_identifier.py +43 -0
- dqlite_dbapi-0.3.0/tests/test_stub_signatures_normalize_to_dbapi_error.py +135 -0
- dqlite_dbapi-0.3.0/tests/test_submodule_all.py +32 -0
- dqlite_dbapi-0.3.0/tests/test_sync_close_op_lock_owner_aware_probe.py +78 -0
- dqlite_dbapi-0.3.0/tests/test_sync_commit_rollback_closed_precedes_thread.py +38 -0
- dqlite_dbapi-0.3.0/tests/test_sync_commit_rollback_inside_ctxmgr_guard.py +87 -0
- dqlite_dbapi-0.3.0/tests/test_sync_commit_rollback_messages_under_lock.py +64 -0
- dqlite_dbapi-0.3.0/tests/test_sync_commit_rollback_protocol_recheck.py +37 -0
- dqlite_dbapi-0.3.0/tests/test_sync_commit_rollback_retry_after_invalidate.py +68 -0
- dqlite_dbapi-0.3.0/tests/test_sync_connection_execute_shortcut.py +55 -0
- dqlite_dbapi-0.3.0/tests/test_sync_connection_executemany_shortcut.py +32 -0
- dqlite_dbapi-0.3.0/tests/test_sync_cursor_post_add_closed_recheck.py +102 -0
- dqlite_dbapi-0.3.0/tests/test_sync_cursor_rownumber_closed_cross_thread.py +50 -0
- dqlite_dbapi-0.3.0/tests/test_sync_execute_async_pre_wire_close_recheck.py +65 -0
- dqlite_dbapi-0.3.0/tests/test_sync_execute_async_silent_drop_scrubs_state.py +94 -0
- dqlite_dbapi-0.3.0/tests/test_sync_executemany_close_race.py +56 -0
- dqlite_dbapi-0.3.0/tests/test_sync_exit_signal_mid_rollback.py +66 -0
- dqlite_dbapi-0.3.0/tests/test_sync_fetchmany_cancel_atomic.py +60 -0
- dqlite_dbapi-0.3.0/tests/test_sync_force_close_transport.py +147 -0
- dqlite_dbapi-0.3.0/tests/test_sync_force_close_transport_pending_drain_reap.py +145 -0
- dqlite_dbapi-0.3.0/tests/test_sync_invalidated_property.py +47 -0
- dqlite_dbapi-0.3.0/tests/test_sync_run_sync_multiphase_timeout.py +87 -0
- dqlite_dbapi-0.3.0/tests/test_sync_transaction_ctxmgr_owner_slot_busy_sentinel.py +14 -0
- dqlite_dbapi-0.3.0/tests/test_sync_transaction_owner_token_bookkeeping.py +110 -0
- dqlite_dbapi-0.3.0/tests/test_sync_transaction_signal_in_restore_reaps_owner.py +67 -0
- dqlite_dbapi-0.3.0/tests/test_text_bind_nul_byte_rejected_with_blob_hint.py +61 -0
- dqlite_dbapi-0.3.0/tests/test_thread_safety_enforcement.py +327 -0
- dqlite_dbapi-0.3.0/tests/test_timeout_validation.py +62 -0
- dqlite_dbapi-0.3.0/tests/test_total_changes_hasattr_safe.py +44 -0
- dqlite_dbapi-0.3.0/tests/test_transaction_ctxmgr_state_lock.py +129 -0
- dqlite_dbapi-0.3.0/tests/test_transitive_wire_import.py +46 -0
- dqlite_dbapi-0.3.0/tests/test_type_coercion_documented_asymmetries.py +138 -0
- dqlite_dbapi-0.3.0/tests/test_types_dbapi_compare.py +191 -0
- dqlite_dbapi-0.3.0/tests/test_types_validator_branches.py +84 -0
- dqlite_dbapi-0.3.0/tests/test_unregister_adapter.py +74 -0
- dqlite_dbapi-0.3.0/tests/test_unregister_adapter_rejects_built_in_datetime_types.py +65 -0
- dqlite_dbapi-0.3.0/tests/test_unsupported_method_stubs.py +352 -0
- dqlite_dbapi-0.3.0/tests/test_validate_positive_int_pep249_wrap.py +87 -0
- dqlite_dbapi-0.3.0/tests/test_validate_ticks.py +76 -0
- dqlite_dbapi-0.3.0/tests/test_validate_ticks_and_unixtime_reject_bool_and_non_numeric.py +74 -0
- dqlite_dbapi-0.3.0/uv.lock +360 -0
- dqlite_dbapi-0.2.2/DEVELOPMENT.md +0 -75
- dqlite_dbapi-0.2.2/PKG-INFO +0 -377
- dqlite_dbapi-0.2.2/README.md +0 -343
- dqlite_dbapi-0.2.2/pyproject.toml +0 -114
- dqlite_dbapi-0.2.2/src/dqlitedbapi/__init__.py +0 -514
- dqlite_dbapi-0.2.2/src/dqlitedbapi/_busy_retry.py +0 -297
- dqlite_dbapi-0.2.2/src/dqlitedbapi/_constants.py +0 -88
- dqlite_dbapi-0.2.2/src/dqlitedbapi/_pragma_intercept.py +0 -264
- dqlite_dbapi-0.2.2/src/dqlitedbapi/aio/__init__.py +0 -602
- dqlite_dbapi-0.2.2/src/dqlitedbapi/aio/connection.py +0 -2974
- dqlite_dbapi-0.2.2/src/dqlitedbapi/aio/cursor.py +0 -1647
- dqlite_dbapi-0.2.2/src/dqlitedbapi/connection.py +0 -4432
- dqlite_dbapi-0.2.2/src/dqlitedbapi/cursor.py +0 -2934
- dqlite_dbapi-0.2.2/src/dqlitedbapi/exceptions.py +0 -460
- dqlite_dbapi-0.2.2/src/dqlitedbapi/row.py +0 -93
- dqlite_dbapi-0.2.2/src/dqlitedbapi/types.py +0 -1157
- dqlite_dbapi-0.2.2/tests/aio/test_aio_version_final_annotated.py +0 -26
- dqlite_dbapi-0.2.2/tests/aio/test_async_close_underlying_close_failed_logged.py +0 -144
- dqlite_dbapi-0.2.2/tests/aio/test_async_connection_fork_guard.py +0 -136
- dqlite_dbapi-0.2.2/tests/aio/test_async_iter_protocol_invariants.py +0 -41
- dqlite_dbapi-0.2.2/tests/aio/test_async_unclosed_warning_skips_in_fork_child.py +0 -181
- dqlite_dbapi-0.2.2/tests/aio/test_close_cancel_between_cursor_cascade_and_lock.py +0 -71
- dqlite_dbapi-0.2.2/tests/aio/test_fetchmany_cancel_atomic.py +0 -87
- dqlite_dbapi-0.2.2/tests/aio/test_messages_clear_on_closed.py +0 -56
- dqlite_dbapi-0.2.2/tests/conftest.py +0 -60
- dqlite_dbapi-0.2.2/tests/integration/conftest.py +0 -17
- dqlite_dbapi-0.2.2/tests/integration/test_async_concurrent_executemany_serialized.py +0 -95
- dqlite_dbapi-0.2.2/tests/integration/test_async_cursor_concurrent_execute_rejected.py +0 -74
- dqlite_dbapi-0.2.2/tests/integration/test_async_cursor_edge_branches.py +0 -81
- dqlite_dbapi-0.2.2/tests/integration/test_async_fetchmany_cancel.py +0 -87
- dqlite_dbapi-0.2.2/tests/integration/test_async_returning_zero_rows.py +0 -43
- dqlite_dbapi-0.2.2/tests/integration/test_async_transaction_ctxmgr_rejects_stray_commit.py +0 -71
- dqlite_dbapi-0.2.2/tests/integration/test_close_implicit_rollback_pep249.py +0 -148
- dqlite_dbapi-0.2.2/tests/integration/test_concurrent_cursors_visibility.py +0 -52
- dqlite_dbapi-0.2.2/tests/integration/test_constraint_extended_codes.py +0 -104
- dqlite_dbapi-0.2.2/tests/integration/test_context_manager.py +0 -56
- dqlite_dbapi-0.2.2/tests/integration/test_cursor_fetch_after_non_row_execute.py +0 -113
- dqlite_dbapi-0.2.2/tests/integration/test_cursor_misc_invariant_pins.py +0 -90
- dqlite_dbapi-0.2.2/tests/integration/test_cursor_row_index_after_fetchall.py +0 -110
- dqlite_dbapi-0.2.2/tests/integration/test_datetime_conversion.py +0 -300
- dqlite_dbapi-0.2.2/tests/integration/test_description_after_ddl_pragma.py +0 -107
- dqlite_dbapi-0.2.2/tests/integration/test_description_survives_empty_fetchall.py +0 -126
- dqlite_dbapi-0.2.2/tests/integration/test_executemany_cancel_mid_batch.py +0 -115
- dqlite_dbapi-0.2.2/tests/integration/test_executemany_completed_iterations_observability.py +0 -69
- dqlite_dbapi-0.2.2/tests/integration/test_executemany_cte_dml.py +0 -74
- dqlite_dbapi-0.2.2/tests/integration/test_executemany_failure_resets_rowcount.py +0 -78
- dqlite_dbapi-0.2.2/tests/integration/test_executemany_generator.py +0 -51
- dqlite_dbapi-0.2.2/tests/integration/test_executemany_returning.py +0 -43
- dqlite_dbapi-0.2.2/tests/integration/test_lastrowid_autoincrement.py +0 -91
- dqlite_dbapi-0.2.2/tests/integration/test_lastrowid_cursor_scoped.py +0 -89
- dqlite_dbapi-0.2.2/tests/integration/test_lastrowid_returning.py +0 -65
- dqlite_dbapi-0.2.2/tests/integration/test_lastrowid_survives_cross_cursor_rollback.py +0 -129
- dqlite_dbapi-0.2.2/tests/integration/test_leader_redirect_live.py +0 -142
- dqlite_dbapi-0.2.2/tests/integration/test_misc_coverage.py +0 -409
- dqlite_dbapi-0.2.2/tests/integration/test_multiline_returning_rows.py +0 -73
- dqlite_dbapi-0.2.2/tests/integration/test_nan_inf_float.py +0 -69
- dqlite_dbapi-0.2.2/tests/integration/test_negative_zero_and_subnormal_float.py +0 -97
- dqlite_dbapi-0.2.2/tests/integration/test_no_transaction_error_wording.py +0 -127
- dqlite_dbapi-0.2.2/tests/integration/test_null_vs_empty_text_blob_three_way.py +0 -91
- dqlite_dbapi-0.2.2/tests/integration/test_pragma_deny_list.py +0 -122
- dqlite_dbapi-0.2.2/tests/integration/test_query_detection.py +0 -66
- dqlite_dbapi-0.2.2/tests/integration/test_returning.py +0 -98
- dqlite_dbapi-0.2.2/tests/integration/test_savepoint_dbapi.py +0 -155
- dqlite_dbapi-0.2.2/tests/integration/test_savepoint_failure_responses.py +0 -95
- dqlite_dbapi-0.2.2/tests/integration/test_session_mode_read_only.py +0 -128
- dqlite_dbapi-0.2.2/tests/integration/test_sqlite_version_pin.py +0 -73
- dqlite_dbapi-0.2.2/tests/integration/test_sync_transaction_ctxmgr_rejects_stray_commit.py +0 -120
- dqlite_dbapi-0.2.2/tests/test_aconn_execute_with_parameters.py +0 -59
- dqlite_dbapi-0.2.2/tests/test_aconn_factory_getters.py +0 -54
- dqlite_dbapi-0.2.2/tests/test_aconnect_cleanup_close_shielded_against_outer_timeout.py +0 -91
- dqlite_dbapi-0.2.2/tests/test_aconnect_cleanup_on_connect_failure.py +0 -91
- dqlite_dbapi-0.2.2/tests/test_adapter_exceptions_wrapped_as_data_error.py +0 -175
- dqlite_dbapi-0.2.2/tests/test_aenter_cleanup_nulls_locks_under_concurrent_close.py +0 -136
- dqlite_dbapi-0.2.2/tests/test_aenter_cleanup_preserves_original_under_outer_cancel.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_aexit_behavioural_no_close.py +0 -90
- dqlite_dbapi-0.2.2/tests/test_aexit_commit_cancel_debug_log.py +0 -120
- dqlite_dbapi-0.2.2/tests/test_aexit_commit_cancel_force_closes_transport.py +0 -137
- dqlite_dbapi-0.2.2/tests/test_aexit_rollback_cancel_body_context_pin.py +0 -97
- dqlite_dbapi-0.2.2/tests/test_aexit_rollback_debug_log.py +0 -79
- dqlite_dbapi-0.2.2/tests/test_aio_commit_rollback_no_tx.py +0 -76
- dqlite_dbapi-0.2.2/tests/test_aio_commit_rollback_no_tx_code_matrix.py +0 -101
- dqlite_dbapi-0.2.2/tests/test_aio_commit_rollback_wrapping.py +0 -149
- dqlite_dbapi-0.2.2/tests/test_aio_connection_finalizer_detached_on_cancel_close.py +0 -75
- dqlite_dbapi-0.2.2/tests/test_aio_connection_finalizer_detached_on_close.py +0 -79
- dqlite_dbapi-0.2.2/tests/test_aio_cursor_drain_rows.py +0 -91
- dqlite_dbapi-0.2.2/tests/test_aio_cursor_row_factory_typeerror_wrap.py +0 -113
- dqlite_dbapi-0.2.2/tests/test_aio_description_tuple_exported.py +0 -23
- dqlite_dbapi-0.2.2/tests/test_aio_execute_unlocked_silent_drop_scrubs_state.py +0 -126
- dqlite_dbapi-0.2.2/tests/test_aio_executemany_cursor_close_cascade.py +0 -36
- dqlite_dbapi-0.2.2/tests/test_aio_force_close_foreign_thread_cursor_closed_pre_cascade.py +0 -123
- dqlite_dbapi-0.2.2/tests/test_aio_force_close_transport_cursor_cascade.py +0 -102
- dqlite_dbapi-0.2.2/tests/test_aio_init_reexports_diagnostic_prefixes.py +0 -40
- dqlite_dbapi-0.2.2/tests/test_aio_loop_affinity_exc_class.py +0 -70
- dqlite_dbapi-0.2.2/tests/test_aio_module_attributes.py +0 -83
- dqlite_dbapi-0.2.2/tests/test_aio_register_adapter_export.py +0 -47
- dqlite_dbapi-0.2.2/tests/test_aio_register_converter_stubs.py +0 -36
- dqlite_dbapi-0.2.2/tests/test_aio_row_factory_setter_loop_binding.py +0 -109
- dqlite_dbapi-0.2.2/tests/test_aio_setters_clear_messages_pep249.py +0 -45
- dqlite_dbapi-0.2.2/tests/test_aio_transaction_recheck_after_ensure_connection.py +0 -96
- dqlite_dbapi-0.2.2/tests/test_arraysize_validation.py +0 -109
- dqlite_dbapi-0.2.2/tests/test_async_backup_not_async_def.py +0 -34
- dqlite_dbapi-0.2.2/tests/test_async_check_loop_only_pid_before_loop.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_async_close_cancel_arm_cancels_inner_pending_drain.py +0 -121
- dqlite_dbapi-0.2.2/tests/test_async_close_ensure_locks_guard.py +0 -45
- dqlite_dbapi-0.2.2/tests/test_async_close_finally_propagates_cancel.py +0 -163
- dqlite_dbapi-0.2.2/tests/test_async_close_op_lock_bounded.py +0 -147
- dqlite_dbapi-0.2.2/tests/test_async_close_outer_cancel_force_closes_transport.py +0 -119
- dqlite_dbapi-0.2.2/tests/test_async_close_race.py +0 -120
- dqlite_dbapi-0.2.2/tests/test_async_commit_rollback_force_close_on_outer_cancel.py +0 -125
- dqlite_dbapi-0.2.2/tests/test_async_commit_rollback_in_transaction_under_lock.py +0 -102
- dqlite_dbapi-0.2.2/tests/test_async_commit_rollback_loop_binding_first.py +0 -88
- dqlite_dbapi-0.2.2/tests/test_async_commit_rollback_messages_under_lock.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_async_commit_rollback_op_lock_bounded.py +0 -67
- dqlite_dbapi-0.2.2/tests/test_async_commit_rollback_phase_budget.py +0 -109
- dqlite_dbapi-0.2.2/tests/test_async_commit_rollback_retry_after_invalidate.py +0 -143
- dqlite_dbapi-0.2.2/tests/test_async_commit_rollback_timeout_outer_scope_hint.py +0 -131
- dqlite_dbapi-0.2.2/tests/test_async_commit_rollback_timeout_phase_aware.py +0 -118
- dqlite_dbapi-0.2.2/tests/test_async_connect_cross_loop_diagnostic_on_fast_path.py +0 -65
- dqlite_dbapi-0.2.2/tests/test_async_connection.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_async_connection_close_during_connect.py +0 -72
- dqlite_dbapi-0.2.2/tests/test_async_connection_cursor_fork_guard.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_async_connection_ensure_connection_post_yield_close_shielded.py +0 -188
- dqlite_dbapi-0.2.2/tests/test_async_connection_race.py +0 -44
- dqlite_dbapi-0.2.2/tests/test_async_connection_setters_loop_binding.py +0 -68
- dqlite_dbapi-0.2.2/tests/test_async_connection_transaction.py +0 -59
- dqlite_dbapi-0.2.2/tests/test_async_cursor.py +0 -270
- dqlite_dbapi-0.2.2/tests/test_async_cursor_aclose_alias.py +0 -98
- dqlite_dbapi-0.2.2/tests/test_async_cursor_add_races_cascade_clear.py +0 -151
- dqlite_dbapi-0.2.2/tests/test_async_cursor_aenter_cross_task_executing_guard.py +0 -80
- dqlite_dbapi-0.2.2/tests/test_async_cursor_aenter_gc_parent_pep249.py +0 -32
- dqlite_dbapi-0.2.2/tests/test_async_cursor_aiter_aenter_pep249_pins.py +0 -98
- dqlite_dbapi-0.2.2/tests/test_async_cursor_aiter_cross_loop_fail_fast.py +0 -68
- dqlite_dbapi-0.2.2/tests/test_async_cursor_arraysize_row_factory_loop_binding.py +0 -79
- dqlite_dbapi-0.2.2/tests/test_async_cursor_callproc_nextset_scroll_loop_binding.py +0 -91
- dqlite_dbapi-0.2.2/tests/test_async_cursor_close_clears_executing_task.py +0 -80
- dqlite_dbapi-0.2.2/tests/test_async_cursor_close_is_sync_and_race_safe.py +0 -137
- dqlite_dbapi-0.2.2/tests/test_async_cursor_close_lock_free.py +0 -75
- dqlite_dbapi-0.2.2/tests/test_async_cursor_closed_state_pep249.py +0 -110
- dqlite_dbapi-0.2.2/tests/test_async_cursor_execute_executing_task_inside_try_frame.py +0 -63
- dqlite_dbapi-0.2.2/tests/test_async_cursor_execute_messages_clear.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_async_cursor_executemany_validation_clears_executing_task.py +0 -118
- dqlite_dbapi-0.2.2/tests/test_async_cursor_fetch_loop_binding.py +0 -146
- dqlite_dbapi-0.2.2/tests/test_async_cursor_finally_clear_executing_task_unconditional.py +0 -48
- dqlite_dbapi-0.2.2/tests/test_async_cursor_late_add_proxy_swap.py +0 -52
- dqlite_dbapi-0.2.2/tests/test_async_cursor_loop_binding.py +0 -61
- dqlite_dbapi-0.2.2/tests/test_async_cursor_rownumber_closed_cross_loop.py +0 -68
- dqlite_dbapi-0.2.2/tests/test_async_cursor_setinputsizes_loop_binding.py +0 -54
- dqlite_dbapi-0.2.2/tests/test_async_executemany_atomic.py +0 -63
- dqlite_dbapi-0.2.2/tests/test_async_executemany_close_race.py +0 -72
- dqlite_dbapi-0.2.2/tests/test_async_executescript_stub_raises_on_call.py +0 -61
- dqlite_dbapi-0.2.2/tests/test_async_fetch_does_not_lazy_bind_loop.py +0 -89
- dqlite_dbapi-0.2.2/tests/test_async_fetchall_row_factory_happy_path.py +0 -65
- dqlite_dbapi-0.2.2/tests/test_async_force_close_transport.py +0 -200
- dqlite_dbapi-0.2.2/tests/test_async_in_transaction_closed_foreign_loop.py +0 -75
- dqlite_dbapi-0.2.2/tests/test_async_in_transaction_loop_binding.py +0 -80
- dqlite_dbapi-0.2.2/tests/test_async_invalidated_property.py +0 -58
- dqlite_dbapi-0.2.2/tests/test_async_lock_binding.py +0 -143
- dqlite_dbapi-0.2.2/tests/test_async_resource_warning_gate.py +0 -144
- dqlite_dbapi-0.2.2/tests/test_async_resource_warning_sanitize_parity.py +0 -83
- dqlite_dbapi-0.2.2/tests/test_async_secondary_methods_clear_messages_before_guards.py +0 -144
- dqlite_dbapi-0.2.2/tests/test_async_transaction_owner_set_inside_try_frame.py +0 -185
- dqlite_dbapi-0.2.2/tests/test_async_with_exit_does_not_close.py +0 -83
- dqlite_dbapi-0.2.2/tests/test_audit_2026_05_coverage_gaps.py +0 -302
- dqlite_dbapi-0.2.2/tests/test_audit_2026_05_dbapi_coverage.py +0 -421
- dqlite_dbapi-0.2.2/tests/test_autocommit_doc_no_round_trip.py +0 -69
- dqlite_dbapi-0.2.2/tests/test_autocommit_legacy_transaction_control.py +0 -68
- dqlite_dbapi-0.2.2/tests/test_autocommit_property.py +0 -83
- dqlite_dbapi-0.2.2/tests/test_autocommit_setter_exact_int_gate.py +0 -114
- dqlite_dbapi-0.2.2/tests/test_begin_rewrite_session_mode.py +0 -210
- dqlite_dbapi-0.2.2/tests/test_binary_typeerror_stdlib_parity.py +0 -53
- dqlite_dbapi-0.2.2/tests/test_bind_typeerror_as_dataerror.py +0 -53
- dqlite_dbapi-0.2.2/tests/test_build_and_connect_base_exception_group_wrap.py +0 -123
- dqlite_dbapi-0.2.2/tests/test_build_and_connect_resolve_leader_oserror_wrap.py +0 -84
- dqlite_dbapi-0.2.2/tests/test_build_and_connect_wire_encode_error_translation.py +0 -100
- dqlite_dbapi-0.2.2/tests/test_busy_retry_async_wiring.py +0 -159
- dqlite_dbapi-0.2.2/tests/test_busy_retry_classifier.py +0 -97
- dqlite_dbapi-0.2.2/tests/test_busy_retry_curve.py +0 -149
- dqlite_dbapi-0.2.2/tests/test_busy_retry_docstring_pins_cross_thread_caveat.py +0 -61
- dqlite_dbapi-0.2.2/tests/test_busy_retry_sync_wiring.py +0 -140
- dqlite_dbapi-0.2.2/tests/test_call_client_base_exception_group_wrap.py +0 -91
- dqlite_dbapi-0.2.2/tests/test_call_client_baseexceptiongroup_cancel_split.py +0 -110
- dqlite_dbapi-0.2.2/tests/test_call_client_docstring_mapping_table.py +0 -77
- dqlite_dbapi-0.2.2/tests/test_call_client_mapping.py +0 -155
- dqlite_dbapi-0.2.2/tests/test_call_client_typeerror_message_does_not_blame_bind.py +0 -43
- dqlite_dbapi-0.2.2/tests/test_call_client_wire_encode_error.py +0 -36
- dqlite_dbapi-0.2.2/tests/test_callproc_noreturn_annotation.py +0 -44
- dqlite_dbapi-0.2.2/tests/test_callproc_scroll_clear_messages.py +0 -88
- dqlite_dbapi-0.2.2/tests/test_cascade_cursors_clears_messages.py +0 -98
- dqlite_dbapi-0.2.2/tests/test_check_same_thread_kwarg.py +0 -264
- dqlite_dbapi-0.2.2/tests/test_classify_caller_sql.py +0 -99
- dqlite_dbapi-0.2.2/tests/test_classify_caller_sql_hardening.py +0 -142
- dqlite_dbapi-0.2.2/tests/test_classify_caller_sql_structural_reject_precedence.py +0 -100
- dqlite_dbapi-0.2.2/tests/test_classify_operational_code_zero.py +0 -29
- dqlite_dbapi-0.2.2/tests/test_cleanup_loop_thread_disarms_inner_and_reaps_drain.py +0 -304
- dqlite_dbapi-0.2.2/tests/test_cleanup_loop_thread_finalizer_fork_safe.py +0 -191
- dqlite_dbapi-0.2.2/tests/test_close_bypass_path_releases_latched_op_lock.py +0 -76
- dqlite_dbapi-0.2.2/tests/test_close_resource_leak.py +0 -35
- dqlite_dbapi-0.2.2/tests/test_close_signal_handler_reentry.py +0 -182
- dqlite_dbapi-0.2.2/tests/test_close_surfaces_op_lock_contention.py +0 -96
- dqlite_dbapi-0.2.2/tests/test_close_thread_join_uses_close_timeout.py +0 -186
- dqlite_dbapi-0.2.2/tests/test_close_timeout_floor_enforcement.py +0 -59
- dqlite_dbapi-0.2.2/tests/test_close_timeout_plumbing.py +0 -113
- dqlite_dbapi-0.2.2/tests/test_closed_property.py +0 -104
- dqlite_dbapi-0.2.2/tests/test_cluster_policy_rejection_prefix_constant.py +0 -67
- dqlite_dbapi-0.2.2/tests/test_code_to_exception_wire_ssot.py +0 -58
- dqlite_dbapi-0.2.2/tests/test_collated_coverage_gaps.py +0 -193
- dqlite_dbapi-0.2.2/tests/test_commit_after_external_close.py +0 -83
- dqlite_dbapi-0.2.2/tests/test_commit_leader_flip_ambiguous_commit_error.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_commit_leader_flip_propagates.py +0 -136
- dqlite_dbapi-0.2.2/tests/test_commit_no_spurious_connect.py +0 -72
- dqlite_dbapi-0.2.2/tests/test_commit_rollback_shortcircuit_uses_in_transaction.py +0 -182
- dqlite_dbapi-0.2.2/tests/test_conform_adapter_non_primitive_rejected_at_dbapi_layer.py +0 -83
- dqlite_dbapi-0.2.2/tests/test_conftest_adapter_registry_isolation.py +0 -31
- dqlite_dbapi-0.2.2/tests/test_connect_baseexceptiongroup_cancel_split.py +0 -108
- dqlite_dbapi-0.2.2/tests/test_connect_busy_timeout_kwarg.py +0 -125
- dqlite_dbapi-0.2.2/tests/test_connect_clears_messages.py +0 -46
- dqlite_dbapi-0.2.2/tests/test_connect_closed_precedes_thread_affinity.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_connect_docstring_parity.py +0 -36
- dqlite_dbapi-0.2.2/tests/test_connect_iso_autocommit_round_trip.py +0 -115
- dqlite_dbapi-0.2.2/tests/test_connect_isolation_level_autocommit_kwargs_symmetric.py +0 -141
- dqlite_dbapi-0.2.2/tests/test_connect_preserves_code.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_connection.py +0 -44
- dqlite_dbapi-0.2.2/tests/test_connection_after_fork_raises.py +0 -157
- dqlite_dbapi-0.2.2/tests/test_connection_autocommit_isolation_level_closed_state.py +0 -95
- dqlite_dbapi-0.2.2/tests/test_connection_close_cascades_cursors.py +0 -76
- dqlite_dbapi-0.2.2/tests/test_connection_close_cursor_cascade_atomicity.py +0 -74
- dqlite_dbapi-0.2.2/tests/test_connection_close_idempotent_cross_thread.py +0 -72
- dqlite_dbapi-0.2.2/tests/test_connection_closed_checks.py +0 -293
- dqlite_dbapi-0.2.2/tests/test_connection_cursor_class_attribute.py +0 -61
- dqlite_dbapi-0.2.2/tests/test_connection_cursor_closed_state_precedes_unknown_kwarg.py +0 -43
- dqlite_dbapi-0.2.2/tests/test_connection_database_empty_string_rejected.py +0 -56
- dqlite_dbapi-0.2.2/tests/test_connection_database_kwarg_isinstance.py +0 -45
- dqlite_dbapi-0.2.2/tests/test_connection_docstring_pins_check_same_thread_contract.py +0 -106
- dqlite_dbapi-0.2.2/tests/test_connection_eager_address_validation.py +0 -52
- dqlite_dbapi-0.2.2/tests/test_connection_enter_eager.py +0 -44
- dqlite_dbapi-0.2.2/tests/test_connection_executemany_outer_shape_check.py +0 -214
- dqlite_dbapi-0.2.2/tests/test_connection_exit_commit_ki_breadcrumb.py +0 -103
- dqlite_dbapi-0.2.2/tests/test_connection_exit_short_circuits_on_closed.py +0 -104
- dqlite_dbapi-0.2.2/tests/test_connection_messages_cleared_by_cursor_methods.py +0 -65
- dqlite_dbapi-0.2.2/tests/test_connection_row_factory_setter_closed_check.py +0 -57
- dqlite_dbapi-0.2.2/tests/test_context_manager_exit.py +0 -103
- dqlite_dbapi-0.2.2/tests/test_convert_bind_param_conform_exception_propagates.py +0 -77
- dqlite_dbapi-0.2.2/tests/test_convert_params_conform_raise_propagates_unwrapped.py +0 -81
- dqlite_dbapi-0.2.2/tests/test_cte_prefix_stripper_edges.py +0 -117
- dqlite_dbapi-0.2.2/tests/test_cursor.py +0 -234
- dqlite_dbapi-0.2.2/tests/test_cursor_after_external_close.py +0 -63
- dqlite_dbapi-0.2.2/tests/test_cursor_arraysize_row_factory_setter_thread.py +0 -129
- dqlite_dbapi-0.2.2/tests/test_cursor_close_clears_messages.py +0 -38
- dqlite_dbapi-0.2.2/tests/test_cursor_close_cross_thread.py +0 -48
- dqlite_dbapi-0.2.2/tests/test_cursor_close_preserves_body_exception_on_messages_strip.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_cursor_close_releases_connection_pin.py +0 -64
- dqlite_dbapi-0.2.2/tests/test_cursor_closed_after_connection_gc_pep249.py +0 -116
- dqlite_dbapi-0.2.2/tests/test_cursor_closed_state_pep249.py +0 -79
- dqlite_dbapi-0.2.2/tests/test_cursor_completed_iterations_resets_on_single_execute.py +0 -100
- dqlite_dbapi-0.2.2/tests/test_cursor_connection_partial_init_attributeerror.py +0 -52
- dqlite_dbapi-0.2.2/tests/test_cursor_connection_property_after_gc_pep249.py +0 -60
- dqlite_dbapi-0.2.2/tests/test_cursor_execute_non_str_operation.py +0 -45
- dqlite_dbapi-0.2.2/tests/test_cursor_execute_state_reset_on_failure.py +0 -411
- dqlite_dbapi-0.2.2/tests/test_cursor_executemany_non_str_operation.py +0 -80
- dqlite_dbapi-0.2.2/tests/test_cursor_executemany_outer_shape_check.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_cursor_factory_kwarg_rejected.py +0 -56
- dqlite_dbapi-0.2.2/tests/test_cursor_force_close_race.py +0 -127
- dqlite_dbapi-0.2.2/tests/test_cursor_iter_clears_messages_pep249.py +0 -96
- dqlite_dbapi-0.2.2/tests/test_cursor_iterator_reset.py +0 -104
- dqlite_dbapi-0.2.2/tests/test_cursor_kwargs_rejection_precedence.py +0 -76
- dqlite_dbapi-0.2.2/tests/test_cursor_next_row_factory_raise_replays_row.py +0 -142
- dqlite_dbapi-0.2.2/tests/test_cursor_per_row_types.py +0 -177
- dqlite_dbapi-0.2.2/tests/test_cursor_post_close_property_reads.py +0 -121
- dqlite_dbapi-0.2.2/tests/test_cursor_protocol_check.py +0 -53
- dqlite_dbapi-0.2.2/tests/test_cursor_rejects_generator_params.py +0 -53
- dqlite_dbapi-0.2.2/tests/test_cursor_repr_with_gced_parent_connection.py +0 -85
- dqlite_dbapi-0.2.2/tests/test_cursor_row_factory_rejecting_setter.py +0 -104
- dqlite_dbapi-0.2.2/tests/test_cursor_row_factory_subclass_inheritance.py +0 -90
- dqlite_dbapi-0.2.2/tests/test_cursor_row_index_reset.py +0 -89
- dqlite_dbapi-0.2.2/tests/test_cursor_rowcount_after_ddl_stdlib_parity.py +0 -269
- dqlite_dbapi-0.2.2/tests/test_cursor_rownumber_affinity.py +0 -63
- dqlite_dbapi-0.2.2/tests/test_cursor_rownumber_post_close.py +0 -80
- dqlite_dbapi-0.2.2/tests/test_cursor_scroll_mode_validation.py +0 -157
- dqlite_dbapi-0.2.2/tests/test_cursor_secondary_methods_positional_only.py +0 -140
- dqlite_dbapi-0.2.2/tests/test_cursor_setinputsizes_affinity_precedes_shape.py +0 -168
- dqlite_dbapi-0.2.2/tests/test_cursor_setinputsizes_setoutputsize_closed_state_precedes_validation.py +0 -104
- dqlite_dbapi-0.2.2/tests/test_cursor_setters_clear_messages_pep249.py +0 -56
- dqlite_dbapi-0.2.2/tests/test_cursor_stop_iteration_contract.py +0 -90
- dqlite_dbapi-0.2.2/tests/test_cursor_uses_run_protocol.py +0 -63
- dqlite_dbapi-0.2.2/tests/test_cursors_weakset_state_lock.py +0 -142
- dqlite_dbapi-0.2.2/tests/test_date_widens_to_datetime.py +0 -34
- dqlite_dbapi-0.2.2/tests/test_datetime_from_iso8601_docstring_two_step_fallback.py +0 -47
- dqlite_dbapi-0.2.2/tests/test_datetime_time_round_trip.py +0 -54
- dqlite_dbapi-0.2.2/tests/test_dbapi_commit_deferred_fk.py +0 -39
- dqlite_dbapi-0.2.2/tests/test_dbapi_default_timeouts_use_client_constants.py +0 -57
- dqlite_dbapi-0.2.2/tests/test_dbapi_exception_message_arg_cap.py +0 -115
- dqlite_dbapi-0.2.2/tests/test_dbapi_exception_raw_message_cap.py +0 -77
- dqlite_dbapi-0.2.2/tests/test_dbapi_fork_guard_cluster.py +0 -246
- dqlite_dbapi-0.2.2/tests/test_dbapi_type_hash_consistency.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_description_null_first_row_resolves.py +0 -131
- dqlite_dbapi-0.2.2/tests/test_description_null_type_code_to_none.py +0 -110
- dqlite_dbapi-0.2.2/tests/test_description_strict_type_codes.py +0 -59
- dqlite_dbapi-0.2.2/tests/test_description_tuple_public_alias.py +0 -44
- dqlite_dbapi-0.2.2/tests/test_description_type_code_unknown_sentinel.py +0 -69
- dqlite_dbapi-0.2.2/tests/test_diagnostic_messages.py +0 -140
- dqlite_dbapi-0.2.2/tests/test_dial_attempt_timeout_propagation.py +0 -117
- dqlite_dbapi-0.2.2/tests/test_dial_func_propagation.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_dial_func_propagation_to_leader_resolve.py +0 -180
- dqlite_dbapi-0.2.2/tests/test_doc_class_and_description_drift.py +0 -68
- dqlite_dbapi-0.2.2/tests/test_dqlite_namespace_error_classification.py +0 -52
- dqlite_dbapi-0.2.2/tests/test_ensure_loop_fast_path_snapshot_dcl_defence.py +0 -100
- dqlite_dbapi-0.2.2/tests/test_ensure_loop_post_fork_pid_guard.py +0 -133
- dqlite_dbapi-0.2.2/tests/test_error_code_mapping.py +0 -120
- dqlite_dbapi-0.2.2/tests/test_error_pickle_cause_either_or.py +0 -50
- dqlite_dbapi-0.2.2/tests/test_error_pickle_preserves_raw_message.py +0 -78
- dqlite_dbapi-0.2.2/tests/test_exception_coded_mixin.py +0 -112
- dqlite_dbapi-0.2.2/tests/test_exception_mapping.py +0 -79
- dqlite_dbapi-0.2.2/tests/test_exception_repr_code.py +0 -55
- dqlite_dbapi-0.2.2/tests/test_exception_wrapping.py +0 -131
- dqlite_dbapi-0.2.2/tests/test_exceptions.py +0 -40
- dqlite_dbapi-0.2.2/tests/test_exceptions_all_symmetry.py +0 -43
- dqlite_dbapi-0.2.2/tests/test_execute_caller_param_shape_preserves_prior_state.py +0 -111
- dqlite_dbapi-0.2.2/tests/test_execute_executemany_positional_only.py +0 -77
- dqlite_dbapi-0.2.2/tests/test_execute_multi_statement_rejection.py +0 -114
- dqlite_dbapi-0.2.2/tests/test_execute_reject_scrubs_prior_result_state.py +0 -212
- dqlite_dbapi-0.2.2/tests/test_executemany_accumulator_semantics.py +0 -110
- dqlite_dbapi-0.2.2/tests/test_executemany_basecaught_state_reset.py +0 -230
- dqlite_dbapi-0.2.2/tests/test_executemany_cancel_restores_pre_batch_lastrowid.py +0 -167
- dqlite_dbapi-0.2.2/tests/test_executemany_cancellederror_restores_pre_batch_lastrowid.py +0 -105
- dqlite_dbapi-0.2.2/tests/test_executemany_classifier_resets_state_first.py +0 -120
- dqlite_dbapi-0.2.2/tests/test_executemany_classify_caller_sql_hoisted.py +0 -61
- dqlite_dbapi-0.2.2/tests/test_executemany_completed_iterations_snapshot_conditional_restore.py +0 -160
- dqlite_dbapi-0.2.2/tests/test_executemany_dict_subclass_accepted.py +0 -80
- dqlite_dbapi-0.2.2/tests/test_executemany_empty.py +0 -112
- dqlite_dbapi-0.2.2/tests/test_executemany_empty_batch_preserves_lastrowid.py +0 -65
- dqlite_dbapi-0.2.2/tests/test_executemany_lastrowid_docstring_modern_stdlib.py +0 -41
- dqlite_dbapi-0.2.2/tests/test_executemany_lastrowid_mid_batch_preserves_in_batch.py +0 -167
- dqlite_dbapi-0.2.2/tests/test_executemany_none_seq_rejected.py +0 -78
- dqlite_dbapi-0.2.2/tests/test_executemany_per_iter_structural_rejects.py +0 -122
- dqlite_dbapi-0.2.2/tests/test_executemany_pragma_with_leading_comment.py +0 -75
- dqlite_dbapi-0.2.2/tests/test_executemany_push_skips_cascade_zeroed_cursor.py +0 -77
- dqlite_dbapi-0.2.2/tests/test_executemany_reject_scrubs_prior_result_state.py +0 -265
- dqlite_dbapi-0.2.2/tests/test_executemany_rejects_pure_queries.py +0 -103
- dqlite_dbapi-0.2.2/tests/test_executemany_rejects_transaction_verbs.py +0 -288
- dqlite_dbapi-0.2.2/tests/test_executemany_returning_cap.py +0 -69
- dqlite_dbapi-0.2.2/tests/test_exit_logs_rollback_failure.py +0 -102
- dqlite_dbapi-0.2.2/tests/test_fetchall_row_factory_raise_replay.py +0 -147
- dqlite_dbapi-0.2.2/tests/test_fetchmany_edges.py +0 -73
- dqlite_dbapi-0.2.2/tests/test_fetchmany_negative_size_rejected.py +0 -91
- dqlite_dbapi-0.2.2/tests/test_fetchmany_non_int_validation.py +0 -78
- dqlite_dbapi-0.2.2/tests/test_fetchmany_one_clear_per_call_pep249.py +0 -111
- dqlite_dbapi-0.2.2/tests/test_fetchmany_row_factory_raise_replay.py +0 -128
- dqlite_dbapi-0.2.2/tests/test_fetchmany_zero_docstring_stdlib_divergence.py +0 -60
- dqlite_dbapi-0.2.2/tests/test_finalizer_strict_warnings.py +0 -53
- dqlite_dbapi-0.2.2/tests/test_force_close_cancel_and_observe_narrow_suppress.py +0 -35
- dqlite_dbapi-0.2.2/tests/test_force_close_observe_ast_pin.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_force_close_observe_callback_coverage.py +0 -71
- dqlite_dbapi-0.2.2/tests/test_force_close_transport_cleanup_tail_unconditional.py +0 -103
- dqlite_dbapi-0.2.2/tests/test_force_close_transport_clears_messages.py +0 -95
- dqlite_dbapi-0.2.2/tests/test_force_close_transport_cross_thread_cancel_threadsafe.py +0 -129
- dqlite_dbapi-0.2.2/tests/test_force_close_transport_cursor_cascade_threadsafe.py +0 -161
- dqlite_dbapi-0.2.2/tests/test_force_close_transport_defensive_arms.py +0 -123
- dqlite_dbapi-0.2.2/tests/test_force_close_transport_disarms_inner_finalizer.py +0 -85
- dqlite_dbapi-0.2.2/tests/test_force_close_transport_pending_drain_resnapshot.py +0 -143
- dqlite_dbapi-0.2.2/tests/test_force_close_transport_writer_cross_thread.py +0 -130
- dqlite_dbapi-0.2.2/tests/test_fork_diagnostic_includes_pids.py +0 -48
- dqlite_dbapi-0.2.2/tests/test_format_utc_offset_non_timedelta_guard.py +0 -62
- dqlite_dbapi-0.2.2/tests/test_fromticks_tz_policy.py +0 -44
- dqlite_dbapi-0.2.2/tests/test_gc_cleanup.py +0 -55
- dqlite_dbapi-0.2.2/tests/test_get_async_connection_force_close_race.py +0 -148
- dqlite_dbapi-0.2.2/tests/test_get_resolve_leader_cluster_no_loop_raises_runtime_error.py +0 -37
- dqlite_dbapi-0.2.2/tests/test_in_transaction_after_close.py +0 -113
- dqlite_dbapi-0.2.2/tests/test_in_transaction_closed_divergence_doc.py +0 -55
- dqlite_dbapi-0.2.2/tests/test_in_transaction_closed_foreign_thread.py +0 -107
- dqlite_dbapi-0.2.2/tests/test_in_transaction_property.py +0 -39
- dqlite_dbapi-0.2.2/tests/test_in_transaction_property_under_check_same_thread.py +0 -141
- dqlite_dbapi-0.2.2/tests/test_init_docstring_fromticks_three_impls.py +0 -64
- dqlite_dbapi-0.2.2/tests/test_is_multi_statement_walker.py +0 -61
- dqlite_dbapi-0.2.2/tests/test_is_no_transaction_error.py +0 -162
- dqlite_dbapi-0.2.2/tests/test_is_row_returning_multiline_whitespace.py +0 -112
- dqlite_dbapi-0.2.2/tests/test_is_row_returning_sql_noise.py +0 -76
- dqlite_dbapi-0.2.2/tests/test_iso8601_aware_microseconds_round_trip.py +0 -72
- dqlite_dbapi-0.2.2/tests/test_iso8601_decoder_leap_seconds_rejected.py +0 -39
- dqlite_dbapi-0.2.2/tests/test_iso8601_decoder_subsecond_truncation.py +0 -92
- dqlite_dbapi-0.2.2/tests/test_iso8601_encoder.py +0 -471
- dqlite_dbapi-0.2.2/tests/test_iso8601_encoder_fold.py +0 -73
- dqlite_dbapi-0.2.2/tests/test_iso8601_encoder_utcoffset_exception_wrap.py +0 -133
- dqlite_dbapi-0.2.2/tests/test_iso8601_parse_error_truncation.py +0 -67
- dqlite_dbapi-0.2.2/tests/test_iso8601_tzinfo_exception_classes_wrapped.py +0 -83
- dqlite_dbapi-0.2.2/tests/test_isolation_level_stdlib_accept_set.py +0 -83
- dqlite_dbapi-0.2.2/tests/test_iterdump_stub_signature_3_13_filter_kwarg.py +0 -69
- dqlite_dbapi-0.2.2/tests/test_lastrowid_docstring_stdlib_parity_claim.py +0 -66
- dqlite_dbapi-0.2.2/tests/test_lastrowid_insert_only.py +0 -72
- dqlite_dbapi-0.2.2/tests/test_lastrowid_signed_int64_cast.py +0 -59
- dqlite_dbapi-0.2.2/tests/test_leader_error_codes_identity.py +0 -45
- dqlite_dbapi-0.2.2/tests/test_leader_redirect_on_connect.py +0 -279
- dqlite_dbapi-0.2.2/tests/test_legacy_transaction_control_constant.py +0 -44
- dqlite_dbapi-0.2.2/tests/test_max_continuation_frames_upper_bound.py +0 -65
- dqlite_dbapi-0.2.2/tests/test_max_message_size_round_trip.py +0 -82
- dqlite_dbapi-0.2.2/tests/test_max_total_rows_plumbing.py +0 -70
- dqlite_dbapi-0.2.2/tests/test_max_total_rows_validation.py +0 -56
- dqlite_dbapi-0.2.2/tests/test_messages_attribute.py +0 -34
- dqlite_dbapi-0.2.2/tests/test_messages_clear_on_ctxmgr_entry.py +0 -84
- dqlite_dbapi-0.2.2/tests/test_module_attributes.py +0 -258
- dqlite_dbapi-0.2.2/tests/test_module_level_stubs.py +0 -126
- dqlite_dbapi-0.2.2/tests/test_nextset_noreturn_annotation.py +0 -43
- dqlite_dbapi-0.2.2/tests/test_no_transaction_substrings_source_of_truth.py +0 -31
- dqlite_dbapi-0.2.2/tests/test_no_tx_primary_codes_invariant.py +0 -65
- dqlite_dbapi-0.2.2/tests/test_number_includes_boolean_documented.py +0 -34
- dqlite_dbapi-0.2.2/tests/test_op_lock_bounded_acquire.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_operational_error_classification.py +0 -76
- dqlite_dbapi-0.2.2/tests/test_operational_error_raw_message.py +0 -81
- dqlite_dbapi-0.2.2/tests/test_param_conversion.py +0 -71
- dqlite_dbapi-0.2.2/tests/test_param_validation.py +0 -48
- dqlite_dbapi-0.2.2/tests/test_paramstyle_qmark_only_pin.py +0 -75
- dqlite_dbapi-0.2.2/tests/test_parse_decltypes_colnames_constants.py +0 -65
- dqlite_dbapi-0.2.2/tests/test_pep249_database_error_routing.py +0 -55
- dqlite_dbapi-0.2.2/tests/test_pep249_exception_aliases.py +0 -80
- dqlite_dbapi-0.2.2/tests/test_pep249_messages_clearing.py +0 -256
- dqlite_dbapi-0.2.2/tests/test_pep249_messages_independence.py +0 -88
- dqlite_dbapi-0.2.2/tests/test_pep249_misc_pins.py +0 -181
- dqlite_dbapi-0.2.2/tests/test_pep249_stub_hasattr_divergence.py +0 -103
- dqlite_dbapi-0.2.2/tests/test_pep249_type_constructors_vs_singletons.py +0 -81
- dqlite_dbapi-0.2.2/tests/test_pep249_type_constructors_wrap_valueerror.py +0 -49
- dqlite_dbapi-0.2.2/tests/test_pep249_type_objects_final_annotated.py +0 -42
- dqlite_dbapi-0.2.2/tests/test_pickle_guard.py +0 -80
- dqlite_dbapi-0.2.2/tests/test_pragma_busy_timeout_intercept.py +0 -201
- dqlite_dbapi-0.2.2/tests/test_pragma_write_description_none.py +0 -60
- dqlite_dbapi-0.2.2/tests/test_prepare_protocol_in_types_all.py +0 -38
- dqlite_dbapi-0.2.2/tests/test_property_round_trip_and_fork_guard.py +0 -255
- dqlite_dbapi-0.2.2/tests/test_property_setters_do_not_mirror_to_inner_async_conn.py +0 -107
- dqlite_dbapi-0.2.2/tests/test_protocol_serialization.py +0 -99
- dqlite_dbapi-0.2.2/tests/test_pyproject_dependency_graph.py +0 -52
- dqlite_dbapi-0.2.2/tests/test_readme_truthfulness_pins.py +0 -73
- dqlite_dbapi-0.2.2/tests/test_register_adapter_conform_fallback.py +0 -162
- dqlite_dbapi-0.2.2/tests/test_register_adapter_global_sync_aio_symmetry.py +0 -73
- dqlite_dbapi-0.2.2/tests/test_register_adapter_positional_only_signature.py +0 -38
- dqlite_dbapi-0.2.2/tests/test_repr.py +0 -66
- dqlite_dbapi-0.2.2/tests/test_repr_sanitizes_address.py +0 -162
- dqlite_dbapi-0.2.2/tests/test_resolve_leader_cache_dial_func_id_recycle.py +0 -178
- dqlite_dbapi-0.2.2/tests/test_resolve_leader_cache_lock_atfork_hook.py +0 -73
- dqlite_dbapi-0.2.2/tests/test_resolve_leader_cluster_cache.py +0 -124
- dqlite_dbapi-0.2.2/tests/test_resolve_leader_cross_loop_isolation.py +0 -233
- dqlite_dbapi-0.2.2/tests/test_row_factory_annotation.py +0 -67
- dqlite_dbapi-0.2.2/tests/test_row_factory_sqlite3_equivalent.py +0 -110
- dqlite_dbapi-0.2.2/tests/test_row_factory_sqlite3_row_surfaces_dataerror.py +0 -94
- dqlite_dbapi-0.2.2/tests/test_rowcount_select_divergence_documented.py +0 -47
- dqlite_dbapi-0.2.2/tests/test_rowid_number_overlap_documented.py +0 -43
- dqlite_dbapi-0.2.2/tests/test_rownumber_closed_cursor_returns_none_documented.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_run_sync_ensure_loop_raise_closes_coroutine.py +0 -105
- dqlite_dbapi-0.2.2/tests/test_run_sync_keyboard_interrupt.py +0 -373
- dqlite_dbapi-0.2.2/tests/test_run_sync_keyboard_interrupt_cleanup_paths.py +0 -162
- dqlite_dbapi-0.2.2/tests/test_run_sync_ki_post_schedule_pre_await.py +0 -122
- dqlite_dbapi-0.2.2/tests/test_run_sync_ki_race_recovery.py +0 -198
- dqlite_dbapi-0.2.2/tests/test_run_sync_loop_closed_during_schedule.py +0 -143
- dqlite_dbapi-0.2.2/tests/test_run_sync_other_runtimeerror_propagates.py +0 -113
- dqlite_dbapi-0.2.2/tests/test_run_sync_timeout.py +0 -412
- dqlite_dbapi-0.2.2/tests/test_run_sync_timeout_recovery_preserves_conn.py +0 -111
- dqlite_dbapi-0.2.2/tests/test_secondary_methods_clear_messages_before_thread_check.py +0 -99
- dqlite_dbapi-0.2.2/tests/test_setinputsizes_accepts_none.py +0 -60
- dqlite_dbapi-0.2.2/tests/test_setinputsizes_clears_messages_per_pep249.py +0 -55
- dqlite_dbapi-0.2.2/tests/test_setinputsizes_non_sequence_iterable.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_setinputsizes_sequence_acceptance.py +0 -80
- dqlite_dbapi-0.2.2/tests/test_setinputsizes_short_circuit_on_closed_connection.py +0 -112
- dqlite_dbapi-0.2.2/tests/test_setoutputsize_accepts_none.py +0 -61
- dqlite_dbapi-0.2.2/tests/test_setter_closed_state_precedes_thread.py +0 -78
- dqlite_dbapi-0.2.2/tests/test_sqlite_errorname_property.py +0 -96
- dqlite_dbapi-0.2.2/tests/test_sqlite_version_not_public_attribute.py +0 -52
- dqlite_dbapi-0.2.2/tests/test_strip_leading_comments_bom.py +0 -70
- dqlite_dbapi-0.2.2/tests/test_strip_leading_comments_parity.py +0 -96
- dqlite_dbapi-0.2.2/tests/test_strip_sql_noise_backtick_identifier.py +0 -73
- dqlite_dbapi-0.2.2/tests/test_stub_signatures_normalize_to_dbapi_error.py +0 -161
- dqlite_dbapi-0.2.2/tests/test_submodule_all.py +0 -39
- dqlite_dbapi-0.2.2/tests/test_sync_close_op_lock_owner_aware_probe.py +0 -100
- dqlite_dbapi-0.2.2/tests/test_sync_commit_rollback_closed_precedes_thread.py +0 -47
- dqlite_dbapi-0.2.2/tests/test_sync_commit_rollback_inside_ctxmgr_guard.py +0 -125
- dqlite_dbapi-0.2.2/tests/test_sync_commit_rollback_messages_under_lock.py +0 -78
- dqlite_dbapi-0.2.2/tests/test_sync_commit_rollback_retry_after_invalidate.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_sync_commit_rollback_snapshot_inner_for_tier2.py +0 -53
- dqlite_dbapi-0.2.2/tests/test_sync_connection_execute_shortcut.py +0 -67
- dqlite_dbapi-0.2.2/tests/test_sync_connection_executemany_shortcut.py +0 -43
- dqlite_dbapi-0.2.2/tests/test_sync_cursor_post_add_closed_recheck.py +0 -151
- dqlite_dbapi-0.2.2/tests/test_sync_exit_signal_mid_rollback.py +0 -75
- dqlite_dbapi-0.2.2/tests/test_sync_fetchmany_cancel_atomic.py +0 -84
- dqlite_dbapi-0.2.2/tests/test_sync_force_close_transport.py +0 -192
- dqlite_dbapi-0.2.2/tests/test_sync_force_close_transport_pending_drain_reap.py +0 -185
- dqlite_dbapi-0.2.2/tests/test_sync_invalidated_property.py +0 -59
- dqlite_dbapi-0.2.2/tests/test_sync_run_sync_multiphase_timeout.py +0 -127
- dqlite_dbapi-0.2.2/tests/test_sync_transaction_ctxmgr_owner_slot_busy_sentinel.py +0 -55
- dqlite_dbapi-0.2.2/tests/test_sync_transaction_owner_token_bookkeeping.py +0 -189
- dqlite_dbapi-0.2.2/tests/test_text_bind_nul_byte_rejected_with_blob_hint.py +0 -92
- dqlite_dbapi-0.2.2/tests/test_thread_safety_enforcement.py +0 -370
- dqlite_dbapi-0.2.2/tests/test_timeout_validation.py +0 -74
- dqlite_dbapi-0.2.2/tests/test_total_changes_hasattr_safe.py +0 -62
- dqlite_dbapi-0.2.2/tests/test_transaction_ctxmgr_state_lock.py +0 -235
- dqlite_dbapi-0.2.2/tests/test_transitive_wire_import.py +0 -52
- dqlite_dbapi-0.2.2/tests/test_type_coercion_documented_asymmetries.py +0 -183
- dqlite_dbapi-0.2.2/tests/test_types_dbapi_compare.py +0 -264
- dqlite_dbapi-0.2.2/tests/test_types_validator_branches.py +0 -125
- dqlite_dbapi-0.2.2/tests/test_unregister_adapter.py +0 -93
- dqlite_dbapi-0.2.2/tests/test_unregister_adapter_rejects_built_in_datetime_types.py +0 -87
- dqlite_dbapi-0.2.2/tests/test_unsupported_method_stubs.py +0 -403
- dqlite_dbapi-0.2.2/tests/test_validate_positive_int_pep249_wrap.py +0 -103
- dqlite_dbapi-0.2.2/tests/test_validate_ticks.py +0 -86
- dqlite_dbapi-0.2.2/tests/test_validate_ticks_and_unixtime_reject_bool_and_non_numeric.py +0 -107
- dqlite_dbapi-0.2.2/uv.lock +0 -360
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/.github/workflows/publish-to-pypi.yml +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/.gitignore +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/LICENSE.md +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/src/dqlitedbapi/py.typed +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/tests/__init__.py +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/tests/integration/__init__.py +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/tests/integration/test_integrity_error.py +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/tests/test_dbapi_hardening.py +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/tests/test_top_level_logger_has_null_handler.py +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/tests/test_version.py +0 -0
- {dqlite_dbapi-0.2.2 → dqlite_dbapi-0.3.0}/tests/test_version_export.py +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- Python 3.13+
|
|
6
|
+
- [uv](https://github.com/astral-sh/uv) - Fast Python package manager
|
|
7
|
+
- Docker (for integration tests)
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
Clone [dqlite-wire](https://github.com/letsdiscodev/python-dqlite-wire) and [dqlite-client](https://github.com/letsdiscodev/python-dqlite-client) alongside this checkout; `[tool.uv.sources]` in `pyproject.toml` points the sibling packages at `../python-dqlite-wire` and `../python-dqlite-client`, so `uv sync` picks up in-tree changes automatically.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Install uv (if not already installed)
|
|
15
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
16
|
+
|
|
17
|
+
# Create virtual environment and install dependencies
|
|
18
|
+
uv sync --extra dev
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Development Tools
|
|
22
|
+
|
|
23
|
+
| Tool | Purpose | Command |
|
|
24
|
+
|------|---------|---------|
|
|
25
|
+
| **pytest** | Testing framework | `pytest` |
|
|
26
|
+
| **ruff** | Linter (replaces flake8, isort, etc.) | `ruff check` |
|
|
27
|
+
| **ruff format** | Code formatter (replaces black) | `ruff format` |
|
|
28
|
+
| **mypy** | Static type checker | `mypy src` |
|
|
29
|
+
|
|
30
|
+
## Running Tests
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Run unit tests only
|
|
34
|
+
.venv/bin/pytest tests/ --ignore=tests/integration
|
|
35
|
+
|
|
36
|
+
# Run all tests (requires Docker cluster)
|
|
37
|
+
cd ../dqlite-test-cluster && docker compose up -d
|
|
38
|
+
.venv/bin/pytest tests/
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Linting & Formatting
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Lint
|
|
45
|
+
.venv/bin/ruff check src tests
|
|
46
|
+
|
|
47
|
+
# Auto-fix lint issues
|
|
48
|
+
.venv/bin/ruff check --fix src tests
|
|
49
|
+
|
|
50
|
+
# Format
|
|
51
|
+
.venv/bin/ruff format src tests
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Type Checking
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
.venv/bin/mypy src
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Comments and docstrings
|
|
61
|
+
|
|
62
|
+
Keep comments and docstrings to a minimum — the code should be clear
|
|
63
|
+
enough to stand on its own. Prefer renaming a function or variable over
|
|
64
|
+
writing a comment to explain an unclear one.
|
|
65
|
+
|
|
66
|
+
- Write a comment only when it captures something genuinely non-obvious
|
|
67
|
+
that the code cannot: a subtle invariant, a security caveat, a
|
|
68
|
+
workaround for an upstream bug, or a "why" a reader would otherwise
|
|
69
|
+
get wrong. Delete comments that merely restate what the code does.
|
|
70
|
+
- Most functions need no docstring. Add a one-line docstring only when
|
|
71
|
+
it tells a reader something the name and signature do not. Avoid
|
|
72
|
+
multi-paragraph essays, param-by-param prose, and "Notes/Divergence"
|
|
73
|
+
sections.
|
|
74
|
+
- Do not record rationale, history, or decision logs in comments — that
|
|
75
|
+
context belongs in the commit message and git history (`git blame`,
|
|
76
|
+
`git log -p`), where it stays attached to the change instead of aging
|
|
77
|
+
in the source.
|
|
78
|
+
- Tooling directives (`# type:`, `# noqa`, `# pragma:`) are exempt —
|
|
79
|
+
keep them.
|
|
80
|
+
|
|
81
|
+
When in doubt, leave it out: a missing explanation is a `git blame`
|
|
82
|
+
away; a redundant or stale comment is noise every future reader pays
|
|
83
|
+
for.
|
|
84
|
+
|
|
85
|
+
## Pre-commit Workflow
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
.venv/bin/ruff format src tests
|
|
89
|
+
.venv/bin/ruff check --fix src tests
|
|
90
|
+
.venv/bin/mypy src
|
|
91
|
+
.venv/bin/pytest tests/ --ignore=tests/integration
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## PEP 249 Compliance
|
|
95
|
+
|
|
96
|
+
This package implements the DB-API 2.0 specification (PEP 249):
|
|
97
|
+
|
|
98
|
+
- `apilevel = "2.0"`
|
|
99
|
+
- `threadsafety = 2` (threads may share module and connections, not cursors)
|
|
100
|
+
- `paramstyle = "qmark"` (question mark placeholders)
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dqlite-dbapi
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: PEP 249 (DB-API 2.0) compliant interface for dqlite
|
|
5
|
+
Project-URL: Homepage, https://github.com/letsdiscodev/python-dqlite-dbapi
|
|
6
|
+
Project-URL: Repository, https://github.com/letsdiscodev/python-dqlite-dbapi
|
|
7
|
+
Project-URL: Issues, https://github.com/letsdiscodev/python-dqlite-dbapi/issues
|
|
8
|
+
Author-email: Antoine Leclair <antoineleclair@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE.md
|
|
11
|
+
Keywords: database,dbapi,distributed,dqlite,pep249,sqlite
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Framework :: AsyncIO
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Database
|
|
21
|
+
Classifier: Topic :: Database :: Database Engines/Servers
|
|
22
|
+
Classifier: Topic :: Database :: Front-Ends
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.13
|
|
25
|
+
Requires-Dist: dqlite-client<0.4.0,>=0.3.0
|
|
26
|
+
Requires-Dist: dqlite-wire<0.4.0,>=0.3.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: mypy>=1.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# dqlite-dbapi
|
|
36
|
+
|
|
37
|
+
A [PEP 249](https://peps.python.org/pep-0249/) (DB-API 2.0) driver for
|
|
38
|
+
[dqlite](https://dqlite.io/), Canonical's distributed SQLite. If you have
|
|
39
|
+
used Python's standard `sqlite3` module, this will feel familiar — same
|
|
40
|
+
`connect()` / `cursor()` / `execute()` / `fetchone()` shape — but it talks
|
|
41
|
+
to a replicated dqlite cluster over the network instead of a local file.
|
|
42
|
+
|
|
43
|
+
It comes in two flavors from one package: a **synchronous** API
|
|
44
|
+
(`dqlitedbapi`) and an **async** API (`dqlitedbapi.aio`).
|
|
45
|
+
|
|
46
|
+
## Is this the package you want?
|
|
47
|
+
|
|
48
|
+
Yes, if you want a drop-in-style database driver for dqlite — directly,
|
|
49
|
+
or under a tool that expects a DB-API 2.0 driver. For SQLAlchemy
|
|
50
|
+
specifically, use [sqlalchemy-dqlite](https://github.com/letsdiscodev/sqlalchemy-dqlite)
|
|
51
|
+
(it builds on this package).
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install dqlite-dbapi
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Requires Python 3.13+.
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
### Sync
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
import dqlitedbapi
|
|
67
|
+
|
|
68
|
+
conn = dqlitedbapi.connect("localhost:9001")
|
|
69
|
+
cur = conn.cursor()
|
|
70
|
+
cur.execute("SELECT 1")
|
|
71
|
+
print(cur.fetchone())
|
|
72
|
+
conn.close()
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Async
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
import asyncio
|
|
79
|
+
from dqlitedbapi.aio import aconnect
|
|
80
|
+
|
|
81
|
+
async def main():
|
|
82
|
+
conn = await aconnect("localhost:9001")
|
|
83
|
+
cur = conn.cursor()
|
|
84
|
+
await cur.execute("SELECT 1")
|
|
85
|
+
print(await cur.fetchone())
|
|
86
|
+
await conn.close()
|
|
87
|
+
|
|
88
|
+
asyncio.run(main())
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Key facts
|
|
92
|
+
|
|
93
|
+
- `apilevel = "2.0"`, `paramstyle = "qmark"` (`?` placeholders),
|
|
94
|
+
`threadsafety = 2`.
|
|
95
|
+
- **Autocommit by default.** Unlike stdlib `sqlite3`, the driver does not
|
|
96
|
+
auto-`BEGIN` before a statement — wrap writes in an explicit transaction
|
|
97
|
+
when you need atomic multi-statement semantics. See
|
|
98
|
+
[Transactions](docs/transactions.md).
|
|
99
|
+
- **Isolation is always SERIALIZABLE** — every write goes through Raft
|
|
100
|
+
consensus, every read is serializable.
|
|
101
|
+
|
|
102
|
+
## The dqlite Python stack
|
|
103
|
+
|
|
104
|
+
This is one of four layered packages. Each builds on the one below:
|
|
105
|
+
|
|
106
|
+
| Package | Role |
|
|
107
|
+
| --- | --- |
|
|
108
|
+
| [sqlalchemy-dqlite](https://github.com/letsdiscodev/sqlalchemy-dqlite) | SQLAlchemy 2.0 dialect |
|
|
109
|
+
| **dqlite-dbapi** — this package | PEP 249 (DB-API 2.0) driver — sync & async |
|
|
110
|
+
| [dqlite-client](https://github.com/letsdiscodev/python-dqlite-client) | Async wire client — pooling, leader discovery |
|
|
111
|
+
| [dqlite-wire](https://github.com/letsdiscodev/python-dqlite-wire) | Wire-protocol codec |
|
|
112
|
+
|
|
113
|
+
Using SQLAlchemy or an ORM? Prefer
|
|
114
|
+
[sqlalchemy-dqlite](https://github.com/letsdiscodev/sqlalchemy-dqlite).
|
|
115
|
+
|
|
116
|
+
## Documentation
|
|
117
|
+
|
|
118
|
+
- [Transactions](docs/transactions.md) — the autocommit-by-default model and how to group statements.
|
|
119
|
+
- [Differences from `sqlite3`](docs/differences-from-sqlite3.md) — what to
|
|
120
|
+
expect when porting from the stdlib module (and a server-version NULL
|
|
121
|
+
gotcha).
|
|
122
|
+
- [Differences from `aiosqlite`](docs/differences-from-aiosqlite.md) — for
|
|
123
|
+
the async surface.
|
|
124
|
+
|
|
125
|
+
## Development
|
|
126
|
+
|
|
127
|
+
See [DEVELOPMENT.md](DEVELOPMENT.md) for setup and contribution guidelines.
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
MIT
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# dqlite-dbapi
|
|
2
|
+
|
|
3
|
+
A [PEP 249](https://peps.python.org/pep-0249/) (DB-API 2.0) driver for
|
|
4
|
+
[dqlite](https://dqlite.io/), Canonical's distributed SQLite. If you have
|
|
5
|
+
used Python's standard `sqlite3` module, this will feel familiar — same
|
|
6
|
+
`connect()` / `cursor()` / `execute()` / `fetchone()` shape — but it talks
|
|
7
|
+
to a replicated dqlite cluster over the network instead of a local file.
|
|
8
|
+
|
|
9
|
+
It comes in two flavors from one package: a **synchronous** API
|
|
10
|
+
(`dqlitedbapi`) and an **async** API (`dqlitedbapi.aio`).
|
|
11
|
+
|
|
12
|
+
## Is this the package you want?
|
|
13
|
+
|
|
14
|
+
Yes, if you want a drop-in-style database driver for dqlite — directly,
|
|
15
|
+
or under a tool that expects a DB-API 2.0 driver. For SQLAlchemy
|
|
16
|
+
specifically, use [sqlalchemy-dqlite](https://github.com/letsdiscodev/sqlalchemy-dqlite)
|
|
17
|
+
(it builds on this package).
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install dqlite-dbapi
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Requires Python 3.13+.
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Sync
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
import dqlitedbapi
|
|
33
|
+
|
|
34
|
+
conn = dqlitedbapi.connect("localhost:9001")
|
|
35
|
+
cur = conn.cursor()
|
|
36
|
+
cur.execute("SELECT 1")
|
|
37
|
+
print(cur.fetchone())
|
|
38
|
+
conn.close()
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Async
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
import asyncio
|
|
45
|
+
from dqlitedbapi.aio import aconnect
|
|
46
|
+
|
|
47
|
+
async def main():
|
|
48
|
+
conn = await aconnect("localhost:9001")
|
|
49
|
+
cur = conn.cursor()
|
|
50
|
+
await cur.execute("SELECT 1")
|
|
51
|
+
print(await cur.fetchone())
|
|
52
|
+
await conn.close()
|
|
53
|
+
|
|
54
|
+
asyncio.run(main())
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Key facts
|
|
58
|
+
|
|
59
|
+
- `apilevel = "2.0"`, `paramstyle = "qmark"` (`?` placeholders),
|
|
60
|
+
`threadsafety = 2`.
|
|
61
|
+
- **Autocommit by default.** Unlike stdlib `sqlite3`, the driver does not
|
|
62
|
+
auto-`BEGIN` before a statement — wrap writes in an explicit transaction
|
|
63
|
+
when you need atomic multi-statement semantics. See
|
|
64
|
+
[Transactions](docs/transactions.md).
|
|
65
|
+
- **Isolation is always SERIALIZABLE** — every write goes through Raft
|
|
66
|
+
consensus, every read is serializable.
|
|
67
|
+
|
|
68
|
+
## The dqlite Python stack
|
|
69
|
+
|
|
70
|
+
This is one of four layered packages. Each builds on the one below:
|
|
71
|
+
|
|
72
|
+
| Package | Role |
|
|
73
|
+
| --- | --- |
|
|
74
|
+
| [sqlalchemy-dqlite](https://github.com/letsdiscodev/sqlalchemy-dqlite) | SQLAlchemy 2.0 dialect |
|
|
75
|
+
| **dqlite-dbapi** — this package | PEP 249 (DB-API 2.0) driver — sync & async |
|
|
76
|
+
| [dqlite-client](https://github.com/letsdiscodev/python-dqlite-client) | Async wire client — pooling, leader discovery |
|
|
77
|
+
| [dqlite-wire](https://github.com/letsdiscodev/python-dqlite-wire) | Wire-protocol codec |
|
|
78
|
+
|
|
79
|
+
Using SQLAlchemy or an ORM? Prefer
|
|
80
|
+
[sqlalchemy-dqlite](https://github.com/letsdiscodev/sqlalchemy-dqlite).
|
|
81
|
+
|
|
82
|
+
## Documentation
|
|
83
|
+
|
|
84
|
+
- [Transactions](docs/transactions.md) — the autocommit-by-default model and how to group statements.
|
|
85
|
+
- [Differences from `sqlite3`](docs/differences-from-sqlite3.md) — what to
|
|
86
|
+
expect when porting from the stdlib module (and a server-version NULL
|
|
87
|
+
gotcha).
|
|
88
|
+
- [Differences from `aiosqlite`](docs/differences-from-aiosqlite.md) — for
|
|
89
|
+
the async surface.
|
|
90
|
+
|
|
91
|
+
## Development
|
|
92
|
+
|
|
93
|
+
See [DEVELOPMENT.md](DEVELOPMENT.md) for setup and contribution guidelines.
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Differences from `aiosqlite`
|
|
2
|
+
|
|
3
|
+
The async surface lives under `dqlitedbapi.aio` and mirrors the sync
|
|
4
|
+
`dqlitedbapi` surface, plus async-specific `aconnect` / `AsyncConnection` /
|
|
5
|
+
`AsyncCursor`.
|
|
6
|
+
|
|
7
|
+
For easy porting from [aiosqlite](https://github.com/omnilib/aiosqlite), the
|
|
8
|
+
full PEP 249 module surface is re-exported under `dqlitedbapi.aio` from one
|
|
9
|
+
namespace: the module attributes (`apilevel`, `threadsafety`, `paramstyle`,
|
|
10
|
+
`sqlite_version`, `sqlite_version_info`), the exception hierarchy (`Warning`,
|
|
11
|
+
`Error`, `InterfaceError`, `DatabaseError`, `DataError`, `OperationalError`,
|
|
12
|
+
`IntegrityError`, `InternalError`, `ProgrammingError`, `NotSupportedError`),
|
|
13
|
+
the type constructors (`Date`, `Time`, `Timestamp`, `DateFromTicks`,
|
|
14
|
+
`TimeFromTicks`, `TimestampFromTicks`, `Binary`), the type sentinels
|
|
15
|
+
(`STRING`, `BINARY`, `NUMBER`, `DATETIME`, `ROWID`, `UNKNOWN`), the `Row`
|
|
16
|
+
factory and `DescriptionTuple`, `register_adapter` / `unregister_adapter`, and
|
|
17
|
+
the `NotSupportedError` stubs for stdlib-only APIs.
|
|
18
|
+
|
|
19
|
+
## The one difference to watch
|
|
20
|
+
|
|
21
|
+
**`AsyncConnection.__aexit__` does not close the connection.** It commits or
|
|
22
|
+
rolls back per the block outcome and leaves the connection reusable — matching
|
|
23
|
+
stdlib `sqlite3.Connection.__exit__` and PEP 249 §7. `aiosqlite`'s
|
|
24
|
+
`__aexit__` *does* close (it tears down its proxy thread and sqlite3
|
|
25
|
+
connection).
|
|
26
|
+
|
|
27
|
+
So when porting from aiosqlite, add an explicit `await conn.close()` (or use a
|
|
28
|
+
pool) where you relied on close-on-exit:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
# aiosqlite — closes on aexit:
|
|
32
|
+
async with aiosqlite.connect(":memory:") as conn:
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
# dqlitedbapi.aio — does NOT close on aexit (matches stdlib sqlite3):
|
|
36
|
+
async with await dqlitedbapi.aio.aconnect(...) as conn:
|
|
37
|
+
...
|
|
38
|
+
await conn.close() # explicit
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Everything else under [Differences from `sqlite3`](differences-from-sqlite3.md)
|
|
42
|
+
applies to the async surface too.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Differences from `sqlite3`
|
|
2
|
+
|
|
3
|
+
`dqlite-dbapi` is shaped like the stdlib `sqlite3` module, but it talks to a
|
|
4
|
+
replicated cluster over the network rather than a local file. This page
|
|
5
|
+
covers the differences you are most likely to notice when porting code.
|
|
6
|
+
|
|
7
|
+
## Things you'll likely notice
|
|
8
|
+
|
|
9
|
+
- **Autocommit by default.** No implicit `BEGIN` before DML — the opposite
|
|
10
|
+
of stdlib's implicit-transaction model. See
|
|
11
|
+
[Transactions](transactions.md).
|
|
12
|
+
- **One statement per `execute()`.** `cursor.execute("SELECT 1; SELECT 2;")`
|
|
13
|
+
raises `ProgrammingError` (client-side, before any network round-trip).
|
|
14
|
+
Split into separate calls. There is no `executescript()` — it raises
|
|
15
|
+
`NotSupportedError`.
|
|
16
|
+
- **`qmark` parameters only.** Use `?` placeholders. Stdlib also accepts
|
|
17
|
+
`:name`; this driver advertises only `qmark` and rejects mappings with
|
|
18
|
+
`ProgrammingError`.
|
|
19
|
+
- **Foreign keys are enforced by default.** dqlite defaults every fresh
|
|
20
|
+
connection to `PRAGMA foreign_keys = ON` — the opposite of stdlib/pysqlite,
|
|
21
|
+
which default `OFF`. Issue `PRAGMA foreign_keys = OFF` per connection for
|
|
22
|
+
SQLite's legacy unenforced behavior.
|
|
23
|
+
- **SERIALIZABLE isolation only.** Every statement is ordered by Raft;
|
|
24
|
+
weaker isolation levels are not exposed.
|
|
25
|
+
- **`connect()` timeouts differ from stdlib.** stdlib's `timeout` is the
|
|
26
|
+
busy (lock-wait) budget; here `timeout` is a per-RPC-phase deadline and
|
|
27
|
+
the busy budget is the separate `busy_timeout` argument. `connect()` also
|
|
28
|
+
exposes safety caps — `max_message_size`, `max_continuation_frames`,
|
|
29
|
+
`max_total_rows` — and `trust_server_heartbeat`.
|
|
30
|
+
- **Result sets are fully materialized at `execute()` time.** Stdlib streams
|
|
31
|
+
rows lazily from the C engine; dqlite drains every continuation frame into
|
|
32
|
+
the cursor's in-memory buffer before `execute()` returns, and `fetchone()`
|
|
33
|
+
/ `fetchmany()` / `fetchall()` iterate that buffer. For large queries, cap
|
|
34
|
+
memory with `max_total_rows` (forwarded from `connect()`) or shape queries
|
|
35
|
+
with an explicit `LIMIT`.
|
|
36
|
+
- **No SQLite extension APIs.** `create_function`, `create_aggregate`,
|
|
37
|
+
`create_window_function`, `iterdump`, `backup`, `set_authorizer`,
|
|
38
|
+
`serialize`, `blobopen`, `executescript`, and `register_converter` have no
|
|
39
|
+
server-side counterpart in dqlite; their stubs raise `NotSupportedError`.
|
|
40
|
+
- **`rowcount` after SELECT is `len(rows)`.** Stdlib returns `-1` for queries.
|
|
41
|
+
dqlite knows the full result at execute time, so it reports the count.
|
|
42
|
+
`rowcount` stays `-1` for non-result paths, for all PRAGMA statements (read
|
|
43
|
+
or write — matching stdlib), and for a never-executed cursor.
|
|
44
|
+
|
|
45
|
+
## NULL in BOOLEAN/DATETIME columns depends on the server version
|
|
46
|
+
|
|
47
|
+
A 2026 dqlite server change (upstream commit `f30fc99`) changed how a NULL
|
|
48
|
+
cell is encoded in columns declared `BOOLEAN`, `DATE`, `DATETIME`, or
|
|
49
|
+
`TIMESTAMP`:
|
|
50
|
+
|
|
51
|
+
- **Before**: a NULL came back as `False` (for `BOOLEAN`) or `""` (for
|
|
52
|
+
datetime types) — indistinguishable from a real value.
|
|
53
|
+
- **After**: a NULL comes back as `None`.
|
|
54
|
+
|
|
55
|
+
There is no handshake that distinguishes the two server versions, and the
|
|
56
|
+
driver decodes faithfully whatever the server sends. Code like
|
|
57
|
+
`if row[0] is None:` will silently miss rows on an old cluster and start
|
|
58
|
+
matching after an upgrade. Check your dqlite cluster version before relying
|
|
59
|
+
on `is None` for these columns.
|
|
60
|
+
|
|
61
|
+
## Minor / edge-case differences
|
|
62
|
+
|
|
63
|
+
You can usually ignore these, but they are here so nothing surprises you:
|
|
64
|
+
|
|
65
|
+
- **`lastrowid` is `None` (not `0`) before the first INSERT.** After the
|
|
66
|
+
first INSERT both drivers agree and keep the value sticky across
|
|
67
|
+
UPDATE/DELETE/DDL.
|
|
68
|
+
- **`fetchmany(0)` returns `[]`** (PEP 249 read literally). Pass `None` or
|
|
69
|
+
omit the argument to default to `arraysize`. `fetchmany(negative)` raises
|
|
70
|
+
`ProgrammingError`.
|
|
71
|
+
- **`execute("")` raises `ProgrammingError`** (empty/whitespace/comment-only
|
|
72
|
+
SQL). Stdlib treats it as a no-op.
|
|
73
|
+
- **Empty result sets report the `UNKNOWN` type code** in
|
|
74
|
+
`description[i][1]` (importable from `dqlitedbapi`). Test it with
|
|
75
|
+
`type_code == UNKNOWN`; for column types on an empty result, query
|
|
76
|
+
`PRAGMA table_info(...)`.
|
|
77
|
+
- **CTE-prefixed DML** (`WITH ... INSERT/UPDATE/DELETE`) sets `lastrowid` and
|
|
78
|
+
reports `rowcount` as the affected-row count. That `rowcount` is a dqlite
|
|
79
|
+
extra: stdlib sqlite3 returns `-1` for CTE-prefixed DML (it counts only
|
|
80
|
+
non-CTE DML). `WITH ... SELECT` and `WITH ... RETURNING` return rows as usual.
|
|
81
|
+
|
|
82
|
+
### Type-code sentinels: compare with `==`, not `in {}`
|
|
83
|
+
|
|
84
|
+
The PEP 249 type sentinels (`STRING`, `BINARY`, `NUMBER`, `DATETIME`,
|
|
85
|
+
`ROWID`) match a `description` type code through `__eq__`, and each wraps
|
|
86
|
+
several wire types (`NUMBER` covers INTEGER+FLOAT+BOOLEAN; `DATETIME` covers
|
|
87
|
+
DATE+TIMESTAMP+ISO8601). A bare wire-int type code does not *hash* equal to a
|
|
88
|
+
sentinel, so set/dict membership silently returns `False`:
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
type_code = cur.description[i][1]
|
|
92
|
+
if type_code == STRING or type_code == NUMBER: # correct
|
|
93
|
+
...
|
|
94
|
+
if type_code in {STRING, NUMBER}: # WRONG: silently False
|
|
95
|
+
...
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Stdlib `sqlite3` doesn't export these sentinels at all, so the
|
|
99
|
+
chained-equality form is also the cross-driver-portable idiom.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Transactions
|
|
2
|
+
|
|
3
|
+
## Autocommit by default
|
|
4
|
+
|
|
5
|
+
`dqlite-dbapi` does **not** issue an implicit `BEGIN` before your DML. Each
|
|
6
|
+
statement runs in the dqlite engine's autocommit mode unless you have
|
|
7
|
+
explicitly opened a transaction.
|
|
8
|
+
|
|
9
|
+
This differs from stdlib `sqlite3` and `psycopg`, which auto-`BEGIN` on the
|
|
10
|
+
first DML. It matches the dqlite C and Go reference clients, which have the
|
|
11
|
+
same opt-in contract. If you are porting code that relied on implicit
|
|
12
|
+
transactions, add explicit `BEGIN` calls to recover atomic multi-statement
|
|
13
|
+
semantics.
|
|
14
|
+
|
|
15
|
+
Note that **isolation is always SERIALIZABLE** regardless — every write
|
|
16
|
+
goes through Raft consensus and every read is serializable. Only the
|
|
17
|
+
*grouping* of statements into one transaction is opt-in.
|
|
18
|
+
|
|
19
|
+
## Grouping statements into a transaction
|
|
20
|
+
|
|
21
|
+
Issue an explicit `BEGIN` through a cursor, then `commit()` / `rollback()`
|
|
22
|
+
on the connection:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
cur = conn.cursor()
|
|
26
|
+
cur.execute("BEGIN")
|
|
27
|
+
cur.execute("INSERT INTO t VALUES (?)", (1,))
|
|
28
|
+
cur.execute("INSERT INTO t VALUES (?)", (2,))
|
|
29
|
+
conn.commit() # or conn.rollback()
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Under the default session mode (`immediate`) a bare `BEGIN` / `BEGIN
|
|
33
|
+
TRANSACTION` is rewritten to `BEGIN IMMEDIATE`, so the deferred-to-write
|
|
34
|
+
upgrade can't fail later with `SQLITE_BUSY_SNAPSHOT`; an explicit `DEFERRED`
|
|
35
|
+
/ `IMMEDIATE` / `EXCLUSIVE` qualifier is passed through unchanged. dqlite's
|
|
36
|
+
Raft FSM serializes the transaction across the cluster regardless of the
|
|
37
|
+
qualifier, so the qualifier changes only lock-acquisition timing on the
|
|
38
|
+
leader, never isolation.
|
|
39
|
+
|
|
40
|
+
The session mode is selected with the `session_mode` connect argument (or the
|
|
41
|
+
`DQLITE_SESSION_MODE` environment variable): `immediate` (default; rewrites a
|
|
42
|
+
bare `BEGIN`), `deferred` / `exclusive` (no rewrite), or `read_only` (issues
|
|
43
|
+
`PRAGMA query_only = 1`).
|
|
44
|
+
|
|
45
|
+
The connection also works as a context manager (matching stdlib `sqlite3`):
|
|
46
|
+
the `with conn:` block commits on clean exit and rolls back on exception.
|
|
47
|
+
It does **not** close the connection — the connection stays reusable.
|
|
48
|
+
|
|
49
|
+
## `commit()` / `rollback()` details
|
|
50
|
+
|
|
51
|
+
- Calling `commit()` / `rollback()` before any query has run is a silent
|
|
52
|
+
no-op (the driver won't open a TCP connection just to send a COMMIT).
|
|
53
|
+
- Calling them with no active transaction (e.g. right after DDL) is also a
|
|
54
|
+
silent success, matching stdlib `sqlite3`.
|
|
55
|
+
- **Commit failures propagate.** Silent swallowing would risk hiding data
|
|
56
|
+
loss, so a failing commit raises.
|
|
57
|
+
|
|
58
|
+
## `isolation_level`
|
|
59
|
+
|
|
60
|
+
The `Connection.isolation_level` attribute exists for pre-3.12 stdlib
|
|
61
|
+
parity. The setter accepts `None` and the legacy qualifier values (`""`,
|
|
62
|
+
`"DEFERRED"`, `"IMMEDIATE"`, `"EXCLUSIVE"`, case-insensitive) as no-ops; the
|
|
63
|
+
getter returns the last value set (default `None`). Any other value —
|
|
64
|
+
including `"SERIALIZABLE"` and `"AUTOCOMMIT"` — raises `ProgrammingError`,
|
|
65
|
+
because the qualifier cannot change dqlite's single serialized isolation
|
|
66
|
+
level.
|
|
67
|
+
|
|
68
|
+
## Leader flips during COMMIT
|
|
69
|
+
|
|
70
|
+
If the leader loses leadership *after* the COMMIT entry was submitted, the
|
|
71
|
+
write is in doubt — Raft may already have replicated it — and the driver
|
|
72
|
+
raises `AmbiguousCommitError` (an `OperationalError` subclass, so
|
|
73
|
+
`except OperationalError` still catches it). Use idempotent DML (`INSERT OR
|
|
74
|
+
REPLACE`, `UPDATE` on a unique key) or an out-of-band state check before
|
|
75
|
+
retrying. A plain not-leader rejection *before* the entry was submitted is a
|
|
76
|
+
clean failure (the write definitely did not apply) and raises a plain
|
|
77
|
+
`OperationalError`.
|
|
78
|
+
|
|
79
|
+
## With SQLAlchemy
|
|
80
|
+
|
|
81
|
+
If you use [sqlalchemy-dqlite](https://github.com/letsdiscodev/sqlalchemy-dqlite),
|
|
82
|
+
the dialect emits `BEGIN` for every `engine.begin()` / `connection.begin()`
|
|
83
|
+
block — you don't manage `BEGIN` yourself. The autocommit-by-default
|
|
84
|
+
behavior above applies only to direct dbapi users.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.26"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "dqlite-dbapi"
|
|
7
|
+
version = "0.3.0"
|
|
8
|
+
description = "PEP 249 (DB-API 2.0) compliant interface for dqlite"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.13"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{ name = "Antoine Leclair", email = "antoineleclair@gmail.com" }]
|
|
13
|
+
keywords = ["dqlite", "sqlite", "distributed", "database", "dbapi", "pep249"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Framework :: AsyncIO",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Topic :: Database",
|
|
24
|
+
"Topic :: Database :: Database Engines/Servers",
|
|
25
|
+
"Topic :: Database :: Front-Ends",
|
|
26
|
+
"Typing :: Typed",
|
|
27
|
+
]
|
|
28
|
+
dependencies = [
|
|
29
|
+
"dqlite-client>=0.3.0,<0.4.0",
|
|
30
|
+
"dqlite-wire>=0.3.0,<0.4.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[tool.uv.sources]
|
|
34
|
+
dqlite-client = { path = "../python-dqlite-client", editable = true }
|
|
35
|
+
dqlite-wire = { path = "../python-dqlite-wire", editable = true }
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://github.com/letsdiscodev/python-dqlite-dbapi"
|
|
39
|
+
Repository = "https://github.com/letsdiscodev/python-dqlite-dbapi"
|
|
40
|
+
Issues = "https://github.com/letsdiscodev/python-dqlite-dbapi/issues"
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
dev = ["pytest>=8.0", "pytest-cov>=4.0", "pytest-asyncio>=0.23", "mypy>=1.0", "ruff>=0.4"]
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.wheel]
|
|
46
|
+
packages = ["src/dqlitedbapi"]
|
|
47
|
+
|
|
48
|
+
# Hatchling's default file-selection would already ship ``py.typed`` via
|
|
49
|
+
# ``packages``, but declaring it explicitly is the documented PEP 561
|
|
50
|
+
# pattern and makes the intent obvious to anyone auditing the wheel.
|
|
51
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
52
|
+
"src/dqlitedbapi/py.typed" = "dqlitedbapi/py.typed"
|
|
53
|
+
|
|
54
|
+
[tool.pytest.ini_options]
|
|
55
|
+
testpaths = ["tests"]
|
|
56
|
+
pythonpath = ["src"]
|
|
57
|
+
asyncio_mode = "auto"
|
|
58
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
59
|
+
filterwarnings = [
|
|
60
|
+
# Promote deprecations to errors so the suite catches stdlib
|
|
61
|
+
# deprecation surface under the CPython version the workspace
|
|
62
|
+
# already runs CI on (3.13/3.14). Whitelist genuine third-party
|
|
63
|
+
# noise with explicit ``ignore:<pattern>:DeprecationWarning:<module>``
|
|
64
|
+
# entries below, with a comment explaining the upstream tracker.
|
|
65
|
+
"error::DeprecationWarning",
|
|
66
|
+
"error::PendingDeprecationWarning",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[tool.mypy]
|
|
70
|
+
strict = true
|
|
71
|
+
python_version = "3.13"
|
|
72
|
+
# Tests live under ``tests/`` with no ``__init__.py``; mypy needs
|
|
73
|
+
# ``explicit_package_bases`` (or namespace packages) to avoid the
|
|
74
|
+
# duplicate-conftest module-name collision when scanning sibling
|
|
75
|
+
# integration/ subdirectories. ``mypy_path`` mirrors the
|
|
76
|
+
# ``pythonpath = ["src"]`` declared for pytest so the source files
|
|
77
|
+
# resolve under the package name (``dqlitedbapi``), not the layout
|
|
78
|
+
# path (``src.dqlitedbapi``).
|
|
79
|
+
explicit_package_bases = true
|
|
80
|
+
mypy_path = "src"
|
|
81
|
+
|
|
82
|
+
# Tests use a few patterns that mypy's strict mode flags but are
|
|
83
|
+
# correct at runtime. Disabling these codes only inside ``tests.*``
|
|
84
|
+
# keeps strict typing on production code while letting the test suite
|
|
85
|
+
# use idiomatic patterns without per-line ``# type: ignore`` noise:
|
|
86
|
+
#
|
|
87
|
+
# * ``method-assign`` — monkey-patching bound methods
|
|
88
|
+
# (``conn.execute = fake_execute``) is the standard way to inject a
|
|
89
|
+
# fake without subclassing.
|
|
90
|
+
# * ``no-untyped-def`` / ``no-untyped-call`` — pytest fixtures and
|
|
91
|
+
# small helpers are conventionally written without type annotations.
|
|
92
|
+
# * ``comparison-overlap`` — ``assert SomeIntEnum.FOO == 0`` is the
|
|
93
|
+
# canonical "this enum matches its int value" pin against a
|
|
94
|
+
# reference table; mypy's literal-type narrowing incorrectly flags
|
|
95
|
+
# it as non-overlapping even though IntEnum's ``__eq__`` works.
|
|
96
|
+
[[tool.mypy.overrides]]
|
|
97
|
+
module = "tests.*"
|
|
98
|
+
disable_error_code = ["method-assign", "no-untyped-def", "no-untyped-call", "comparison-overlap"]
|
|
99
|
+
|
|
100
|
+
[tool.ruff]
|
|
101
|
+
target-version = "py313"
|
|
102
|
+
line-length = 100
|
|
103
|
+
src = ["src", "tests"]
|
|
104
|
+
|
|
105
|
+
[tool.ruff.lint]
|
|
106
|
+
select = ["E", "F", "I", "UP", "B", "SIM"]
|
|
107
|
+
|
|
108
|
+
[tool.ruff.lint.isort]
|
|
109
|
+
known-first-party = ["dqlitedbapi", "dqliteclient", "dqlitewire"]
|
|
110
|
+
|
|
111
|
+
[tool.ruff.format]
|
|
112
|
+
quote-style = "double"
|
|
113
|
+
indent-style = "space"
|
|
114
|
+
docstring-code-format = true
|