diff -r 462470859e57 Lib/sqlite3/test/factory.py --- a/Lib/sqlite3/test/factory.py Sat Apr 26 19:01:47 2014 -0400 +++ b/Lib/sqlite3/test/factory.py Sun Apr 27 22:47:32 2014 -0700 @@ -100,6 +100,24 @@ self.assertEqual(col1, 1, "by index: wrong result for column 0") self.assertEqual(col2, 2, "by index: wrong result for column 1") + def CheckSqliteRowSlice(self): + # A sqlite.Row can be sliced like a list. + self.con.row_factory = sqlite.Row + row = self.con.execute("select 1, 2, 3, 4").fetchone() + self.assertEqual(row[0:0], ()) + self.assertEqual(row[0:1], (1,)) + self.assertEqual(row[1:3], (2, 3)) + self.assertEqual(row[3:1], ()) + # Explicit bounds are optional. + self.assertEqual(row[1:], (2, 3, 4)) + self.assertEqual(row[:3], (1, 2, 3)) + # Slices can use negative indices. + self.assertEqual(row[-2:-1], (3,)) + self.assertEqual(row[-2:], (3, 4)) + # Slicing supports steps. + self.assertEqual(row[0:4:2], (1, 3)) + self.assertEqual(row[3:0:-2], (4, 2)) + def CheckSqliteRowIter(self): """Checks if the row object is iterable""" self.con.row_factory = sqlite.Row diff -r 462470859e57 Modules/_sqlite/row.c --- a/Modules/_sqlite/row.c Sat Apr 26 19:01:47 2014 -0400 +++ b/Modules/_sqlite/row.c Sun Apr 27 22:47:32 2014 -0700 @@ -125,8 +125,34 @@ return NULL; } else if (PySlice_Check(idx)) { - PyErr_SetString(PyExc_ValueError, "slices not implemented, yet"); - return NULL; + Py_ssize_t start, stop, step, slicelength, cur, i; + PyObject* result; + PyObject* it; + PyObject **src, **dest; + if (PySlice_GetIndicesEx((PyObject *)idx, + PyTuple_GET_SIZE(self->data), + &start, &stop, &step, &slicelength) < 0) { + return NULL; + } + + if (step == 1) { + return PyTuple_GetSlice(self->data, start, stop); + } + else { + result = PyTuple_New(slicelength); + if (!result) return NULL; + + src = ((PyTupleObject *)self->data)->ob_item; + dest = ((PyTupleObject *)result)->ob_item; + for (cur = start, i = 0; i < slicelength; + cur += step, i++) { + it = src[cur]; + Py_INCREF(it); + dest[i] = it; + } + + return result; + } } else { PyErr_SetString(PyExc_IndexError, "Index must be int or string");