Skip to content

Commit

Permalink
[2.7] bpo-38175: Fix a memory leak in comparison of sqlite3.Row objec…
Browse files Browse the repository at this point in the history
…ts. (GH-16155). (GH-16215)

(cherry picked from commit 8debfa5)
  • Loading branch information
serhiy-storchaka committed Sep 17, 2019
1 parent 5d55d52 commit be257bc
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 12 deletions.
19 changes: 12 additions & 7 deletions Lib/sqlite3/test/factory.py
Expand Up @@ -159,19 +159,24 @@ def CheckSqliteRowHashCmp(self):
row_1 = self.con.execute("select 1 as a, 2 as b").fetchone()
row_2 = self.con.execute("select 1 as a, 2 as b").fetchone()
row_3 = self.con.execute("select 1 as a, 3 as b").fetchone()
row_4 = self.con.execute("select 1 as b, 2 as a").fetchone()
row_5 = self.con.execute("select 2 as b, 1 as a").fetchone()

self.assertEqual(row_1, row_1)
self.assertEqual(row_1, row_2)
self.assertTrue(row_2 != row_3)
self.assertTrue(row_1 == row_1)
self.assertTrue(row_1 == row_2)
self.assertFalse(row_1 == row_3)
self.assertFalse(row_1 == row_4)
self.assertFalse(row_1 == row_5)
self.assertFalse(row_1 == object())

self.assertFalse(row_1 != row_1)
self.assertFalse(row_1 != row_2)
self.assertFalse(row_2 == row_3)
self.assertTrue(row_1 != row_3)
self.assertTrue(row_1 != row_4)
self.assertTrue(row_1 != row_5)
self.assertTrue(row_1 != object())

self.assertEqual(row_1, row_2)
self.assertEqual(hash(row_1), hash(row_2))
self.assertNotEqual(row_1, row_3)
self.assertNotEqual(hash(row_1), hash(row_3))

def CheckSqliteRowAsSequence(self):
""" Checks if the row object can act like a sequence """
Expand Down
@@ -0,0 +1 @@
Fix a memory leak in comparison of :class:`sqlite3.Row` objects.
12 changes: 7 additions & 5 deletions Modules/_sqlite/row.c
Expand Up @@ -199,14 +199,16 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other,
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
if (PyType_IsSubtype(Py_TYPE(_other), &pysqlite_RowType)) {
if (PyObject_TypeCheck(_other, &pysqlite_RowType)) {
pysqlite_Row *other = (pysqlite_Row *)_other;
PyObject *res = PyObject_RichCompare(self->description, other->description, opid);
if ((opid == Py_EQ && res == Py_True)
|| (opid == Py_NE && res == Py_False)) {
Py_DECREF(res);
int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ);
if (eq < 0) {
return NULL;
}
if (eq) {
return PyObject_RichCompare(self->data, other->data, opid);
}
return PyBool_FromLong(opid != Py_EQ);
}
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
Expand Down

0 comments on commit be257bc

Please sign in to comment.