Repository navigation
PERF: Reduce Python Row indexing overhead - #822
Merged
Merged
Azure Pipelines / MSSQL-Python-PR-Validation
succeeded
Sep 28, 2026 in 14m 27s
Build #pr-validation-pipeline had test failures
Details
- Failed: 1 (0.00%)
- Passed: 94,705 (97.75%)
- Other: 2,177 (2.25%)
- Total: 96,883
- 9376 of 11059 lines covered (84.78%)
Annotations
Check failure on line 1 in test_native_destructor_rolls_back_pending_dml[True-False]
azure-pipelines / MSSQL-Python-PR-Validation
test_native_destructor_rolls_back_pending_dml[True-False]
Failed: Subprocess test body failed
--- stdout ---
--- stderr ---
Traceback (most recent call last):
File "<string>", line 66, in <module>
assert time.monotonic() < deadline, "Native session survived destruction"
^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Native session survived destruction
Raw output
conn_str = 'Database=TestDB;PWD=***;Server=localhost;TrustServerCertificate=yes;UID=testuser'
use_pool = False, autocommit = True
@pytest.mark.parametrize("use_pool", [False, True])
@pytest.mark.parametrize("autocommit", [False, True])
def test_native_destructor_rolls_back_pending_dml(conn_str, use_pool, autocommit):
"""Native destruction must release transactions, locks, and the server session."""
> _run_in_subprocess(
f"use_pool = {use_pool!r}\nautocommit = {autocommit!r}\n" + textwrap.dedent("""
import gc
import os
import sys
import time
import uuid
from mssql_python import connect, ddbc_bindings as ddbc, pooling
conn_str = os.environ["DB_CONNECTION_STRING"]
pool_key = "pytest_native_cleanup_" + uuid.uuid4().hex
table = pool_key
pooling(max_size=1, idle_timeout=30)
observer = connect(conn_str, autocommit=True)
native = ddbc.Connection(conn_str, use_pool, {}, pool_key, None)
statement = native.alloc_statement_handle()
try:
assert ddbc.DDBCSQLExecDirect(statement, "SELECT @@SPID") in (0, 1)
row = []
assert ddbc.DDBCSQLFetchOne(statement, row) in (0, 1)
session_id = row[0]
statement.free()
cursor = observer.cursor()
try:
cursor.execute(
"SELECT session_id FROM sys.dm_exec_sessions WHERE session_id = ?",
[session_id],
)
except Exception as exc:
if "permission" in str(exc).lower():
print("Observer cannot inspect the native session", file=sys.stderr)
sys.exit(77)
raise
if cursor.fetchone() is None:
print("Observer cannot inspect the native session", file=sys.stderr)
sys.exit(77)
cursor.execute("SET LOCK_TIMEOUT 1000")
cursor.execute(f"CREATE TABLE {table} (id INT)")
try:
native.set_autocommit(autocommit)
statement = native.alloc_statement_handle()
sql = f"INSERT INTO {table} VALUES (1)"
if autocommit:
sql = "BEGIN TRANSACTION; " + sql
assert ddbc.DDBCSQLExecDirect(statement, sql) in (0, 1)
statement.free()
statement = None
native = None
gc.collect()
cursor.execute(f"SELECT COUNT(*) FROM {table} WITH (READCOMMITTEDLOCK)")
assert cursor.fetchone()[0] == 0, "Destructor committed abandoned work"
deadline = time.monotonic() + 5
while True:
cursor.execute(
"SELECT session_id FROM sys.dm_exec_sessions WHERE session_id = ?",
[session_id],
)
if cursor.fetchone() is None:
break
assert time.monotonic() < deadline, "Native session survived destruction"
time.sleep(0.05)
replacement = ddbc.Connection(conn_str, use_pool, {}, pool_key, None)
replacement_statement = replacement.alloc_stat
... [The stack trace has been truncated as it exceeded the maximum allowed size. Please refer to the complete log available in the Test Run attachments for full details.]
Loading