Skip to content

segfault after deleting row_factory attr of sqlite3 cursor #152817

Description

@stestagg

Crash report

What happened?

gh-149754 / gh-149738 prevent calling del connection.row_factory on a sqlite3 connection, and document that this is not allowed both for connections and for cursor objects, but the code does not prevent del cursor.row_factory which causes a segfault when the cursor tries to construct a row.

This code currently segfaults (or debug abort on calling null pointer)

import sqlite3

cur = sqlite3.connect(":memory:").cursor()
del cur.row_factory
cur.execute("select 1").fetchone()

this is due to cursor.row_factory becoming NULL and then the cursor iterator doing this:

if (!Py_IsNone(self->row_factory)) {
PyObject *factory = self->row_factory;
PyObject *args[] = { op, row, };
PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL);

The IsNone check does not check for NULL values, so the flow falls through to the PyObject_Vectorcall

The fix seems to be the same as was made for the connection, just guarding against deletion of the row_factory attribute.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.16.0a0 (heads/del-rowcursor:df2538adfdc, Jul 1 2026, 19:02:00) [Clang 21.0.0 (clang-2100.3.20.102)]

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-crashA hard crash of the interpreter, possibly with a core dump
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions