From 0d4e95621e05d50cd454049a424bb9ee098a5db6 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 19 May 2016 15:53:19 +0200 Subject: [PATCH] python: Improve progress callbacks. * lang/python/helpers.c (pyProgressCb): Stash python errors, convert 'what' to Unicode object. * lang/python/pyme/core.py (Context.set_progress_cb): Hand in 'self'. * lang/python/tests/t-callbacks.py: Test progress callbacks. Signed-off-by: Justus Winter --- lang/python/helpers.c | 18 +++++++++++---- lang/python/pyme/core.py | 4 ++-- lang/python/tests/t-callbacks.py | 38 ++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/lang/python/helpers.c b/lang/python/helpers.c index c3cf3b38..7ced04a4 100644 --- a/lang/python/helpers.c +++ b/lang/python/helpers.c @@ -229,17 +229,25 @@ static void pyProgressCb(void *hook, const char *what, int type, int current, int total) { PyObject *func = NULL, *dataarg = NULL, *args = NULL, *retval = NULL; PyObject *pyhook = (PyObject *) hook; + PyObject *self = NULL; - if (PyTuple_Check(pyhook)) { - func = PyTuple_GetItem(pyhook, 0); + assert (PyTuple_Check(pyhook)); + self = PyTuple_GetItem(pyhook, 0); + func = PyTuple_GetItem(pyhook, 1); + if (PyTuple_Size(pyhook) == 3) { dataarg = PyTuple_GetItem(pyhook, 1); args = PyTuple_New(5); } else { - func = pyhook; args = PyTuple_New(4); } - PyTuple_SetItem(args, 0, PyBytes_FromString(what)); + PyTuple_SetItem(args, 0, PyUnicode_DecodeUTF8(what, strlen (what), + "strict")); + if (PyErr_Occurred()) { + pygpgme_stash_callback_exception(self); + Py_DECREF(args); + return; + } PyTuple_SetItem(args, 1, PyLong_FromLong((long) type)); PyTuple_SetItem(args, 2, PyLong_FromLong((long) current)); PyTuple_SetItem(args, 3, PyLong_FromLong((long) total)); @@ -249,6 +257,8 @@ static void pyProgressCb(void *hook, const char *what, int type, int current, } retval = PyObject_CallObject(func, args); + if (PyErr_Occurred()) + pygpgme_stash_callback_exception(self); Py_DECREF(args); Py_XDECREF(retval); } diff --git a/lang/python/pyme/core.py b/lang/python/pyme/core.py index 8a4c197e..9e7faf77 100644 --- a/lang/python/pyme/core.py +++ b/lang/python/pyme/core.py @@ -185,9 +185,9 @@ class Context(GpgmeWrapper): else: self.last_progresscb = pygpgme.new_PyObject_p_p() if hook == None: - hookdata = func + hookdata = (self, func) else: - hookdata = (func, hook) + hookdata = (self, func, hook) pygpgme.pygpgme_set_progress_cb(self.wrapped, hookdata, self.last_progresscb) def get_engine_info(self): diff --git a/lang/python/tests/t-callbacks.py b/lang/python/tests/t-callbacks.py index e89fcb8d..bd88d861 100755 --- a/lang/python/tests/t-callbacks.py +++ b/lang/python/tests/t-callbacks.py @@ -75,3 +75,41 @@ except Exception as e: assert type(e) == TypeError else: assert False, "Expected an error, got none" + + + +# Test the progress callback. +parms = """ +Key-Type: RSA +Key-Length: 1024 +Name-Real: Joe Tester +Name-Comment: with stupid passphrase +Name-Email: joe+pyme@example.org +Passphrase: Crypt0R0cks +Expire-Date: 2020-12-31 + +""" + +messages = [] +def progress_cb(what, typ, current, total, hook=None): + messages.append( + "PROGRESS UPDATE: what = {}, type = {}, current = {}, total = {}" + .format(what, typ, current, total)) + +c = core.Context() +c.set_progress_cb(progress_cb, None) +c.op_genkey(parms, None, None) +assert len(messages) > 0 + +# Test exception handling. +def progress_cb(what, typ, current, total, hook=None): + raise myException + +c = core.Context() +c.set_progress_cb(progress_cb, None) +try: + c.op_genkey(parms, None, None) +except Exception as e: + assert e == myException +else: + assert False, "Expected an error, got none"