mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-26 02:43:43 +03:00
Give precedence to '__conform__()' over superclasses choosing adapter
Close #456
This commit is contained in:
parent
9863637f30
commit
3fbff5d848
2
NEWS
2
NEWS
|
@ -26,6 +26,8 @@ New features:
|
||||||
- Added `~psycopg2.extensions.quote_ident()` function (:ticket:`#359`).
|
- Added `~psycopg2.extensions.quote_ident()` function (:ticket:`#359`).
|
||||||
- Added `~connection.get_dsn_parameters()` connection method (:ticket:`#364`).
|
- Added `~connection.get_dsn_parameters()` connection method (:ticket:`#364`).
|
||||||
- `~cursor.callproc()` now accepts a dictionary of parameters (:ticket:`#381`).
|
- `~cursor.callproc()` now accepts a dictionary of parameters (:ticket:`#381`).
|
||||||
|
- Give precedence to `!__conform__()` over superclasses to choose an object
|
||||||
|
adapter (:ticket:`#456`).
|
||||||
- Using Python C API decoding functions and codecs caching for faster
|
- Using Python C API decoding functions and codecs caching for faster
|
||||||
unicode encoding/decoding (:ticket:`#473`).
|
unicode encoding/decoding (:ticket:`#473`).
|
||||||
- `~cursor.executemany()` slowness addressed by
|
- `~cursor.executemany()` slowness addressed by
|
||||||
|
|
|
@ -153,15 +153,6 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
return adapted;
|
return adapted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if a superclass can be adapted and use the same adapter. */
|
|
||||||
if (!(adapter = _get_superclass_adapter(obj, proto))) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (Py_None != adapter) {
|
|
||||||
adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
|
|
||||||
return adapted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* try to have the protocol adapt this object*/
|
/* try to have the protocol adapt this object*/
|
||||||
if ((meth = PyObject_GetAttrString(proto, "__adapt__"))) {
|
if ((meth = PyObject_GetAttrString(proto, "__adapt__"))) {
|
||||||
adapted = PyObject_CallFunctionObjArgs(meth, obj, NULL);
|
adapted = PyObject_CallFunctionObjArgs(meth, obj, NULL);
|
||||||
|
@ -181,7 +172,7 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and finally try to have the object adapt itself */
|
/* then try to have the object adapt itself */
|
||||||
if ((meth = PyObject_GetAttrString(obj, "__conform__"))) {
|
if ((meth = PyObject_GetAttrString(obj, "__conform__"))) {
|
||||||
adapted = PyObject_CallFunctionObjArgs(meth, proto, NULL);
|
adapted = PyObject_CallFunctionObjArgs(meth, proto, NULL);
|
||||||
Py_DECREF(meth);
|
Py_DECREF(meth);
|
||||||
|
@ -200,6 +191,15 @@ microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Finally check if a superclass can be adapted and use the same adapter. */
|
||||||
|
if (!(adapter = _get_superclass_adapter(obj, proto))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (Py_None != adapter) {
|
||||||
|
adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
|
||||||
|
return adapted;
|
||||||
|
}
|
||||||
|
|
||||||
/* else set the right exception and return NULL */
|
/* else set the right exception and return NULL */
|
||||||
PyOS_snprintf(buffer, 255, "can't adapt type '%s'",
|
PyOS_snprintf(buffer, 255, "can't adapt type '%s'",
|
||||||
Py_TYPE(obj)->tp_name);
|
Py_TYPE(obj)->tp_name);
|
||||||
|
|
|
@ -422,6 +422,19 @@ class AdaptSubclassTest(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
del psycopg2.extensions.adapters[A, psycopg2.extensions.ISQLQuote]
|
del psycopg2.extensions.adapters[A, psycopg2.extensions.ISQLQuote]
|
||||||
|
|
||||||
|
def test_conform_subclass_precedence(self):
|
||||||
|
|
||||||
|
import psycopg2.extensions as ext
|
||||||
|
|
||||||
|
class foo(tuple):
|
||||||
|
def __conform__(self, proto):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def getquoted(self):
|
||||||
|
return 'bar'
|
||||||
|
|
||||||
|
self.assertEqual(ext.adapt(foo((1, 2, 3))).getquoted(), 'bar')
|
||||||
|
|
||||||
|
|
||||||
class ByteaParserTest(unittest.TestCase):
|
class ByteaParserTest(unittest.TestCase):
|
||||||
"""Unit test for our bytea format parser."""
|
"""Unit test for our bytea format parser."""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user