Column objects can be sliced

Close #1034.
This commit is contained in:
Daniele Varrazzo 2020-03-11 10:50:56 +13:00
parent 5d96b0c024
commit 054123254e
3 changed files with 34 additions and 1 deletions

2
NEWS
View File

@ -8,6 +8,8 @@ What's new in psycopg 2.8.5
(:ticket:`#1019`). (:ticket:`#1019`).
- Added support for `~logging.LoggerAdapter` in - Added support for `~logging.LoggerAdapter` in
`~psycopg2.extras.LoggingConnection` (:ticket:`#1026`). `~psycopg2.extras.LoggingConnection` (:ticket:`#1026`).
- `~psycopg2.extensions.Column` objects in `cursor.description` can be sliced
(:ticket:`#1034`).
What's new in psycopg 2.8.4 What's new in psycopg 2.8.4

View File

@ -233,6 +233,32 @@ column_getitem(columnObject *self, Py_ssize_t item)
} }
static PyObject*
column_subscript(columnObject* self, PyObject* item)
{
PyObject *t = NULL;
PyObject *rv = NULL;
/* t = tuple(self) */
if (!(t = PyObject_CallFunctionObjArgs(
(PyObject *)&PyTuple_Type, (PyObject *)self, NULL))) {
goto exit;
}
/* rv = t[item] */
rv = PyObject_GetItem(t, item);
exit:
Py_XDECREF(t);
return rv;
}
static PyMappingMethods column_mapping = {
(lenfunc)column_len, /* mp_length */
(binaryfunc)column_subscript, /* mp_subscript */
0 /* mp_ass_subscript */
};
static PySequenceMethods column_sequence = { static PySequenceMethods column_sequence = {
(lenfunc)column_len, /* sq_length */ (lenfunc)column_len, /* sq_length */
0, /* sq_concat */ 0, /* sq_concat */
@ -346,7 +372,7 @@ PyTypeObject columnType = {
(reprfunc)column_repr, /*tp_repr*/ (reprfunc)column_repr, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
&column_sequence, /*tp_as_sequence*/ &column_sequence, /*tp_as_sequence*/
0, /*tp_as_mapping*/ &column_mapping, /*tp_as_mapping*/
0, /*tp_hash */ 0, /*tp_hash */
0, /*tp_call*/ 0, /*tp_call*/
0, /*tp_str*/ 0, /*tp_str*/

View File

@ -433,6 +433,11 @@ class CursorTests(ConnectingTestCase):
self.assertEqual(curs.description[2].table_oid, None) self.assertEqual(curs.description[2].table_oid, None)
self.assertEqual(curs.description[2].table_column, None) self.assertEqual(curs.description[2].table_column, None)
def test_description_slice(self):
curs = self.conn.cursor()
curs.execute("select 1::int as a")
self.assertEqual(curs.description[0][0:2], ('a', 23))
def test_pickle_description(self): def test_pickle_description(self):
curs = self.conn.cursor() curs = self.conn.cursor()
curs.execute('SELECT 1 AS foo') curs.execute('SELECT 1 AS foo')