From a2a5461c2819b9be8d0eb15d80b75dd813ba12e6 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sun, 8 Feb 2015 11:27:10 +0000 Subject: [PATCH] Make Column picklable on Python >= 3.3 Also expose the type from the extensions module, not from the main module. --- lib/__init__.py | 1 - lib/extensions.py | 2 +- psycopg/psycopgmodule.c | 22 +++++++++++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/__init__.py b/lib/__init__.py index a67c0930..cf8c06ae 100644 --- a/lib/__init__.py +++ b/lib/__init__.py @@ -55,7 +55,6 @@ from psycopg2._psycopg import DateFromTicks, TimeFromTicks, TimestampFromTicks from psycopg2._psycopg import Error, Warning, DataError, DatabaseError, ProgrammingError from psycopg2._psycopg import IntegrityError, InterfaceError, InternalError from psycopg2._psycopg import NotSupportedError, OperationalError -from psycopg2._psycopg import Column from psycopg2._psycopg import _connect, apilevel, threadsafety, paramstyle from psycopg2._psycopg import __version__ diff --git a/lib/extensions.py b/lib/extensions.py index 71a92b93..216d8ad2 100644 --- a/lib/extensions.py +++ b/lib/extensions.py @@ -58,7 +58,7 @@ except ImportError: from psycopg2._psycopg import adapt, adapters, encodings, connection, cursor, lobject, Xid from psycopg2._psycopg import string_types, binary_types, new_type, new_array_type, register_type -from psycopg2._psycopg import ISQLQuote, Notify, Diagnostics +from psycopg2._psycopg import ISQLQuote, Notify, Diagnostics, Column from psycopg2._psycopg import QueryCanceledError, TransactionRollbackError diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c index daeff09f..c9daf69c 100644 --- a/psycopg/psycopgmodule.c +++ b/psycopg/psycopgmodule.c @@ -625,8 +625,10 @@ psyco_GetDecimalType(void) static PyObject * psyco_make_description_type(void) { - PyObject *nt = NULL; PyObject *coll = NULL; + PyObject *nt = NULL; + PyTypeObject *t = NULL; + PyObject *s = NULL; PyObject *rv = NULL; /* Try to import collections.namedtuple */ @@ -640,12 +642,26 @@ psyco_make_description_type(void) } /* Build the namedtuple */ - rv = PyObject_CallFunction(nt, "ss", "Column", - "name type_code display_size internal_size precision scale null_ok"); + if(!(t = (PyTypeObject *)PyObject_CallFunction(nt, "ss", "Column", + "name type_code display_size internal_size precision scale null_ok"))) { + goto exit; + } + + /* Export the tuple on the extensions module + * Required to guarantee picklability on Py > 3.3 (see Python issue 21374) + * for previous Py version the module is psycopg2 anyway but for consistency + * we'd rather expose it from the extensions module. */ + if (!(s = Text_FromUTF8("psycopg2.extensions"))) { goto exit; } + if (0 > PyDict_SetItemString(t->tp_dict, "__module__", s)) { goto exit; } + + rv = (PyObject *)t; + t = NULL; exit: Py_XDECREF(coll); Py_XDECREF(nt); + Py_XDECREF((PyObject *)t); + Py_XDECREF(s); return rv;