mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-09-21 11:18:49 +03:00
Added comparison between Notify objects and Notify or tuple.
Explicit comparison with the tuple is required if we want to make Notify() == (pid, channel) work: item access is not enough (and a test in the suite fails if we get this wrong).
This commit is contained in:
parent
6cb949d371
commit
9c58c01e0f
|
@ -125,6 +125,57 @@ notify_del(PyObject *self)
|
||||||
PyObject_GC_Del(self);
|
PyObject_GC_Del(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a notify into a 3-items tuple.
|
||||||
|
* This is done for help hashing and comparison, *not* for comparison
|
||||||
|
* against other tuples, where the payload is discarded.
|
||||||
|
*/
|
||||||
|
static PyObject *
|
||||||
|
notify_astuple(NotifyObject *self)
|
||||||
|
{
|
||||||
|
PyObject *tself;
|
||||||
|
if (!(tself = PyTuple_New(3))) { return NULL; }
|
||||||
|
|
||||||
|
Py_INCREF(self->pid);
|
||||||
|
PyTuple_SET_ITEM(tself, 0, self->pid);
|
||||||
|
Py_INCREF(self->channel);
|
||||||
|
PyTuple_SET_ITEM(tself, 1, self->channel);
|
||||||
|
Py_INCREF(self->payload);
|
||||||
|
PyTuple_SET_ITEM(tself, 2, self->payload);
|
||||||
|
|
||||||
|
return tself;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
notify_richcompare(NotifyObject *self, PyObject *other, int op)
|
||||||
|
{
|
||||||
|
PyObject *rv = NULL;
|
||||||
|
PyObject *tself = NULL;
|
||||||
|
PyObject *tother = NULL;
|
||||||
|
|
||||||
|
if (Py_TYPE(other) == &NotifyType) {
|
||||||
|
if (!(tself = notify_astuple(self))) { goto exit; }
|
||||||
|
if (!(tother = notify_astuple((NotifyObject *)other))) { goto exit; }
|
||||||
|
rv = PyObject_RichCompare(tself, tother, op);
|
||||||
|
}
|
||||||
|
else if (PyTuple_Check(other)) {
|
||||||
|
if (!(tself = PyTuple_New(2))) { goto exit; };
|
||||||
|
Py_INCREF(self->pid);
|
||||||
|
PyTuple_SET_ITEM(tself, 0, self->pid);
|
||||||
|
Py_INCREF(self->channel);
|
||||||
|
PyTuple_SET_ITEM(tself, 1, self->channel);
|
||||||
|
rv = PyObject_RichCompare(tself, other, op);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Py_INCREF(Py_False);
|
||||||
|
rv = Py_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
Py_XDECREF(tself);
|
||||||
|
Py_XDECREF(tother);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
notify_repr(NotifyObject *self)
|
notify_repr(NotifyObject *self)
|
||||||
{
|
{
|
||||||
|
@ -227,7 +278,7 @@ PyTypeObject NotifyType = {
|
||||||
(traverseproc)notify_traverse, /*tp_traverse*/
|
(traverseproc)notify_traverse, /*tp_traverse*/
|
||||||
0, /*tp_clear*/
|
0, /*tp_clear*/
|
||||||
|
|
||||||
0, /*tp_richcompare*/
|
(richcmpfunc)notify_richcompare, /*tp_richcompare*/
|
||||||
0, /*tp_weaklistoffset*/
|
0, /*tp_weaklistoffset*/
|
||||||
|
|
||||||
0, /*tp_iter*/
|
0, /*tp_iter*/
|
||||||
|
|
|
@ -154,6 +154,22 @@ conn.close()
|
||||||
(pid, channel) = n
|
(pid, channel) = n
|
||||||
self.assertEqual((pid, channel), (42, 'bar'))
|
self.assertEqual((pid, channel), (42, 'bar'))
|
||||||
|
|
||||||
|
def test_compare(self):
|
||||||
|
data = [(10, 'foo'), (20, 'foo'), (10, 'foo', 'bar'), (10, 'foo', 'baz')]
|
||||||
|
for d1 in data:
|
||||||
|
for d2 in data:
|
||||||
|
n1 = psycopg2.extensions.Notify(*d1)
|
||||||
|
n2 = psycopg2.extensions.Notify(*d2)
|
||||||
|
self.assertEqual((n1 == n2), (d1 == d2))
|
||||||
|
self.assertEqual((n1 != n2), (d1 != d2))
|
||||||
|
|
||||||
|
def test_compare_tuple(self):
|
||||||
|
from psycopg2.extensions import Notify
|
||||||
|
self.assertEqual((10, 'foo'), Notify(10, 'foo'))
|
||||||
|
self.assertEqual((10, 'foo'), Notify(10, 'foo', 'bar'))
|
||||||
|
self.assertNotEqual((10, 'foo'), Notify(20, 'foo'))
|
||||||
|
self.assertNotEqual((10, 'foo'), Notify(10, 'bar'))
|
||||||
|
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user