From 47a981337a8f3898482a1c0c51ad2d91c7a6bc2f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 28 May 2014 12:58:34 +0300 Subject: Issue #10203: sqlite3.Row now truly supports sequence protocol. In particulr it supports reverse() and negative indices. Original patch by Claudiu Popa. --- Lib/sqlite3/dbapi2.py | 2 ++ Lib/sqlite3/test/factory.py | 26 +++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'Lib/sqlite3') diff --git a/Lib/sqlite3/dbapi2.py b/Lib/sqlite3/dbapi2.py index 9a0b76645e..991682ce9e 100644 --- a/Lib/sqlite3/dbapi2.py +++ b/Lib/sqlite3/dbapi2.py @@ -22,6 +22,7 @@ import datetime import time +import collections.abc from _sqlite3 import * @@ -50,6 +51,7 @@ version_info = tuple([int(x) for x in version.split(".")]) sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")]) Binary = memoryview +collections.abc.Sequence.register(Row) def register_adapters_and_converters(): def adapt_date(val): diff --git a/Lib/sqlite3/test/factory.py b/Lib/sqlite3/test/factory.py index 1013755b9c..98dcae5d6c 100644 --- a/Lib/sqlite3/test/factory.py +++ b/Lib/sqlite3/test/factory.py @@ -23,6 +23,7 @@ import unittest import sqlite3 as sqlite +from collections.abc import Sequence class MyConnection(sqlite.Connection): def __init__(self, *args, **kwargs): @@ -96,9 +97,19 @@ class RowFactoryTests(unittest.TestCase): self.assertEqual(col1, 1, "by name: wrong result for column 'A'") self.assertEqual(col2, 2, "by name: wrong result for column 'B'") - col1, col2 = row[0], row[1] - self.assertEqual(col1, 1, "by index: wrong result for column 0") - self.assertEqual(col2, 2, "by index: wrong result for column 1") + self.assertEqual(row[0], 1, "by index: wrong result for column 0") + self.assertEqual(row[1], 2, "by index: wrong result for column 1") + self.assertEqual(row[-1], 2, "by index: wrong result for column -1") + self.assertEqual(row[-2], 1, "by index: wrong result for column -2") + + with self.assertRaises(IndexError): + row['c'] + with self.assertRaises(IndexError): + row[2] + with self.assertRaises(IndexError): + row[-3] + with self.assertRaises(IndexError): + row[2**1000] def CheckSqliteRowIter(self): """Checks if the row object is iterable""" @@ -142,6 +153,15 @@ class RowFactoryTests(unittest.TestCase): 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 """ + self.con.row_factory = sqlite.Row + row = self.con.execute("select 1 as a, 2 as b").fetchone() + + as_tuple = tuple(row) + self.assertEqual(list(reversed(row)), list(reversed(as_tuple))) + self.assertIsInstance(row, Sequence) + def tearDown(self): self.con.close() -- cgit v1.2.1