Author: cito
Date: Mon Feb 1 00:56:27 2016
New Revision: 805
Log:
Backport minor fixes from trunk to 4.x
Fixed one reference counting issue with setting the notice receiver,
also support unmounting the notice receiver callback.
Replaced some overly complicated or unofficial ways of calling
Python functions with cleaner code.
Modified:
branches/4.x/pgmodule.c
branches/4.x/tests/test_classic_connection.py
Modified: branches/4.x/pgmodule.c
==============================================================================
--- branches/4.x/pgmodule.c Sun Jan 31 17:57:22 2016 (r804)
+++ branches/4.x/pgmodule.c Mon Feb 1 00:56:27 2016 (r805)
@@ -1787,10 +1787,11 @@
PyGILState_STATE gstate = PyGILState_Ensure();
pgobject *self = (pgobject*) arg;
PyObject *proc = self->notice_receiver;
+
if (proc && PyCallable_Check(proc))
{
pgnoticeobject *notice = PyObject_NEW(pgnoticeobject,
&PgNoticeType);
- PyObject *args, *ret;
+ PyObject *ret;
if (notice)
{
notice->pgcnx = arg;
@@ -1801,10 +1802,8 @@
Py_INCREF(Py_None);
notice = (pgnoticeobject *)(void *)Py_None;
}
- args = Py_BuildValue("(O)", notice);
- ret = PyObject_CallObject(proc, args);
+ ret = PyObject_CallFunction(proc, "(O)", notice);
Py_XDECREF(ret);
- Py_DECREF(args);
}
PyGILState_Release(gstate);
}
@@ -1963,9 +1962,15 @@
if (PyArg_ParseTuple(args, "O", &proc))
{
- if (PyCallable_Check(proc))
+ if (proc == Py_None)
+ {
+ Py_XDECREF(self->notice_receiver);
+ self->notice_receiver = NULL;
+ Py_INCREF(Py_None); ret = Py_None;
+ }
+ else if (PyCallable_Check(proc))
{
- Py_XINCREF(proc);
+ Py_XINCREF(proc); Py_XDECREF(self->notice_receiver);
self->notice_receiver = proc;
PQsetNoticeReceiver(self->cnx, notice_receiver, self);
Py_INCREF(Py_None); ret = Py_None;
@@ -2202,15 +2207,14 @@
case PYGRES_DECIMAL:
if (decimal)
{
- tmp_obj =
Py_BuildValue("(s)", s);
- val =
PyEval_CallObject(decimal, tmp_obj);
+ val =
PyObject_CallFunction(decimal, "(s)", s);
}
else
{
tmp_obj =
PyString_FromString(s);
val =
PyFloat_FromString(tmp_obj, NULL);
+ Py_DECREF(tmp_obj);
}
- Py_DECREF(tmp_obj);
break;
case PYGRES_BOOL:
@@ -2343,15 +2347,14 @@
case PYGRES_DECIMAL:
if (decimal)
{
- tmp_obj =
Py_BuildValue("(s)", s);
- val =
PyEval_CallObject(decimal, tmp_obj);
+ val =
PyObject_CallFunction(decimal, "(s)", s);
}
else
{
tmp_obj =
PyString_FromString(s);
val =
PyFloat_FromString(tmp_obj, NULL);
+ Py_DECREF(tmp_obj);
}
- Py_DECREF(tmp_obj);
break;
case PYGRES_BOOL:
@@ -2401,8 +2404,7 @@
static PyObject *
pgquery_namedresult(pgqueryobject *self, PyObject *args)
{
- PyObject *arglist,
- *ret;
+ PyObject *ret;
/* checks args (args == NULL for an internal call) */
if (args && !PyArg_ParseTuple(args, ""))
@@ -2419,9 +2421,7 @@
return NULL;
}
- arglist = Py_BuildValue("(O)", self);
- ret = PyObject_CallObject(namedresult, arglist);
- Py_DECREF(arglist);
+ ret = PyObject_CallFunction(namedresult, "(O)", self);
if (ret == NULL)
return NULL;
Modified: branches/4.x/tests/test_classic_connection.py
==============================================================================
--- branches/4.x/tests/test_classic_connection.py Sun Jan 31 17:57:22
2016 (r804)
+++ branches/4.x/tests/test_classic_connection.py Mon Feb 1 00:56:27
2016 (r805)
@@ -903,14 +903,17 @@
self.assertIsNone(self.c.get_notice_receiver())
def testSetNoticeReceiver(self):
- self.assertRaises(TypeError, self.c.set_notice_receiver, None)
self.assertRaises(TypeError, self.c.set_notice_receiver, 42)
+ self.assertRaises(TypeError, self.c.set_notice_receiver, 'invalid')
self.assertIsNone(self.c.set_notice_receiver(lambda notice: None))
+ self.assertIsNone(self.c.set_notice_receiver(None))
def testSetAndGetNoticeReceiver(self):
r = lambda notice: None
self.assertIsNone(self.c.set_notice_receiver(r))
self.assertIs(self.c.get_notice_receiver(), r)
+ self.assertIsNone(self.c.set_notice_receiver(None))
+ self.assertIsNone(self.c.get_notice_receiver())
def testNoticeReceiver(self):
self.c.query('''create function bilbo_notice() returns void AS $$
_______________________________________________
PyGreSQL mailing list
[email protected]
https://mail.vex.net/mailman/listinfo.cgi/pygresql