From f194f8435e87e08422436e3601f04ba2df56534f Mon Sep 17 00:00:00 2001 From: EddInSverige Date: Tue, 29 Aug 2023 12:58:01 +0200 Subject: [PATCH 1/4] Add a couple tests --- Lib/test/test_sqlite3/test_factory.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py index 48d35b54a2e239..ad4dade2adf4e0 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -251,6 +251,24 @@ def test_sqlite_row_keys(self): row = self.con.execute("select 1 as a, 2 as b").fetchone() self.assertEqual(row.keys(), ['a', 'b']) + # Test exception raised on an empty sql query result + with self.assertRaises(AttributeError): + row = self.con.execute("select 1 as a where a == 'THISDOESNOTEXIST'").fetchone() + row.keys() + + # docs.python.org: "Immediately after a query, it is + # the first member of each tuple in Cursor.description." + cur = self.con.cursor(factory=MyCursor) + cur.execute("select 1 as a") + row = cur.fetchone() + self.assertEqual(cur.description[0][0], row.keys()[0]) + + # Two Row objects compare equal if they have identical column names + # and values. Assert the keys values are the same too. + 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() + self.assertEqual(row_1.keys(), row_2.keys()) + def test_fake_cursor_class(self): # Issue #24257: Incorrect use of PyObject_IsInstance() caused # segmentation fault. From 0bce0d7688f735de7316da8fc067582f75e422c6 Mon Sep 17 00:00:00 2001 From: EddInSverige Date: Tue, 29 Aug 2023 13:02:47 +0200 Subject: [PATCH 2/4] Add additional assertion that row objects are the same --- Lib/test/test_sqlite3/test_factory.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py index ad4dade2adf4e0..a7110498c41501 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -267,6 +267,7 @@ def test_sqlite_row_keys(self): # and values. Assert the keys values are the same too. 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() + self.assertEqual(row_1, row_2) self.assertEqual(row_1.keys(), row_2.keys()) def test_fake_cursor_class(self): From fd7c46e04c6a530281cf78d355c468db66fda7b6 Mon Sep 17 00:00:00 2001 From: EddInSverige Date: Tue, 29 Aug 2023 13:06:03 +0200 Subject: [PATCH 3/4] Appease the linting overlords --- Lib/test/test_sqlite3/test_factory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py index a7110498c41501..e56231aa784781 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -256,7 +256,7 @@ def test_sqlite_row_keys(self): row = self.con.execute("select 1 as a where a == 'THISDOESNOTEXIST'").fetchone() row.keys() - # docs.python.org: "Immediately after a query, it is + # docs.python.org: "Immediately after a query, it is # the first member of each tuple in Cursor.description." cur = self.con.cursor(factory=MyCursor) cur.execute("select 1 as a") From f07edbdbc3458479600c357a3eae24a67a5fee76 Mon Sep 17 00:00:00 2001 From: EddInSverige Date: Tue, 29 Aug 2023 13:37:58 +0200 Subject: [PATCH 4/4] Refactor test into multiple tests --- Lib/test/test_sqlite3/test_factory.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py index e56231aa784781..11a4c59bc729ae 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -246,16 +246,18 @@ def test_sqlite_row_as_sequence(self): self.assertEqual(list(reversed(row)), list(reversed(as_tuple))) self.assertIsInstance(row, Sequence) - def test_sqlite_row_keys(self): + def test_sqlite_row_keys_return_columns_as_strings(self): # Checks if the row object can return a list of columns as strings. row = self.con.execute("select 1 as a, 2 as b").fetchone() self.assertEqual(row.keys(), ['a', 'b']) + def test_sqlite_row_keys_raises_exception_on_empty_sql_query(self): # Test exception raised on an empty sql query result with self.assertRaises(AttributeError): row = self.con.execute("select 1 as a where a == 'THISDOESNOTEXIST'").fetchone() row.keys() + def test_sqlite_row_keys_returns_first_value_from_cursor_description(self): # docs.python.org: "Immediately after a query, it is # the first member of each tuple in Cursor.description." cur = self.con.cursor(factory=MyCursor) @@ -263,6 +265,7 @@ def test_sqlite_row_keys(self): row = cur.fetchone() self.assertEqual(cur.description[0][0], row.keys()[0]) + def test_sqlite_row_keys_are_equal_if_rows_are_equal(self): # Two Row objects compare equal if they have identical column names # and values. Assert the keys values are the same too. row_1 = self.con.execute("select 1 as a, 2 as b").fetchone()