From 407ba437cd283f27a00b6c1a41cbcc0d5d16c83f Mon Sep 17 00:00:00 2001 From: Jiseok CHOI Date: Sun, 13 Sep 2026 00:51:06 +0900 Subject: [PATCH] sqlite3: fix row_factory deletion error (#8693) Match CPython 3.14 by distinguishing row_factory assignment from deletion and raising AttributeError with the compatible message. Unmark the passing row_factory deletion test. Assisted-by: GitHub Copilot:GPT-5.6 Luna (high) --- Lib/test/test_sqlite3/test_factory.py | 1 - crates/stdlib/src/_sqlite3.rs | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py index 4345df7ae..299b514cf 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -159,7 +159,6 @@ class RowFactoryTests(MemoryDatabaseMixin, unittest.TestCase): with self.assertRaises(IndexError): row[complex()] # index must be int or string - @unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: can't delete attribute def test_delete_connection_row_factory(self): # gh-149738: deleting row_factory should raise an exception with self.assertRaises(AttributeError): diff --git a/crates/stdlib/src/_sqlite3.rs b/crates/stdlib/src/_sqlite3.rs index 02d408450..25b7e0032 100644 --- a/crates/stdlib/src/_sqlite3.rs +++ b/crates/stdlib/src/_sqlite3.rs @@ -1661,8 +1661,20 @@ mod _sqlite3 { self.row_factory.to_owned() } #[pygetset(setter)] - fn set_row_factory(&self, val: Option) { - let _ = unsafe { self.row_factory.swap(val) }; + fn set_row_factory( + &self, + val: PySetterValue>, + vm: &VirtualMachine, + ) -> PyResult<()> { + match val { + PySetterValue::Assign(val) => { + let _ = unsafe { self.row_factory.swap(val) }; + Ok(()) + } + PySetterValue::Delete => { + Err(vm.new_attribute_error("cannot delete row_factory attribute")) + } + } } fn check_thread(&self, vm: &VirtualMachine) -> PyResult<()> {