Skip to content

Commit 8a7952f

Browse files
authored
sqlite3: add Cursor.row_factory pygetset and fix Connection.cursor() propagation (RustPython#7278)
Add #[pygetset] getter/setter for Cursor.row_factory so that Python-level attribute access reads/writes the Rust struct field instead of the instance dict. Fix Connection.cursor() to only propagate the connection's row_factory to the cursor when the connection's row_factory is not None, matching CPython behavior. Previously it unconditionally overwrote the cursor's row_factory, discarding any factory set by a cursor subclass __init__.
1 parent 757ff94 commit 8a7952f

2 files changed

Lines changed: 14 additions & 3 deletions

File tree

Lib/test/test_sqlite3/test_factory.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ def test_invalid_factory(self):
112112

113113
class RowFactoryTestsBackwardsCompat(MemoryDatabaseMixin, unittest.TestCase):
114114

115-
@unittest.expectedFailure # TODO: RUSTPYTHON
116115
def test_is_produced_by_factory(self):
117116
cur = self.con.cursor(factory=MyCursor)
118117
cur.execute("select 4+5 as foo")

crates/stdlib/src/_sqlite3.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,8 +1043,10 @@ mod _sqlite3 {
10431043
)));
10441044
}
10451045

1046-
if let Some(cursor_ref) = cursor.downcast_ref::<Cursor>() {
1047-
let _ = unsafe { cursor_ref.row_factory.swap(zelf.row_factory.to_owned()) };
1046+
if let Some(cursor_ref) = cursor.downcast_ref::<Cursor>()
1047+
&& let Some(factory) = zelf.row_factory.to_owned()
1048+
{
1049+
let _ = unsafe { cursor_ref.row_factory.swap(Some(factory)) };
10481050
}
10491051

10501052
Ok(cursor)
@@ -1977,6 +1979,16 @@ mod _sqlite3 {
19771979
Ok(())
19781980
}
19791981

1982+
#[pygetset]
1983+
fn row_factory(&self) -> Option<PyObjectRef> {
1984+
self.row_factory.to_owned()
1985+
}
1986+
1987+
#[pygetset(setter)]
1988+
fn set_row_factory(&self, val: Option<PyObjectRef>) {
1989+
let _ = unsafe { self.row_factory.swap(val) };
1990+
}
1991+
19801992
fn build_row_cast_map(
19811993
&self,
19821994
st: &SqliteStatementRaw,

0 commit comments

Comments
 (0)