[Pkg-gnupg-commit] [gpgme] 129/412: python: Improve support for edit callbacks.

Daniel Kahn Gillmor dkg at fifthhorseman.net
Thu Sep 22 21:26:31 UTC 2016


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch master
in repository gpgme.

commit 09803c4a81b9431fd4c8f30abb1c60c4c735f0cb
Author: Justus Winter <justus at gnupg.org>
Date:   Tue May 24 12:29:32 2016 +0200

    python: Improve support for edit callbacks.
    
    * lang/python/helpers.c (pyEditCb): Stash exceptions.
    * lang/python/pyme/core.py (Context.op_edit): Hand in 'self'.
    * lang/python/tests/Makefile.am (py_tests): Add new test.
    * lang/python/tests/t-callbacks.py: Test edit callbacks.
    * lang/python/tests/t-edit.py: New file.
    
    Signed-off-by: Justus Winter <justus at gnupg.org>
---
 lang/python/helpers.c            | 12 +++++---
 lang/python/pyme/core.py         | 11 +++++--
 lang/python/tests/Makefile.am    |  3 +-
 lang/python/tests/t-callbacks.py | 33 +++++++++++++++++++++
 lang/python/tests/t-edit.py      | 62 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 114 insertions(+), 7 deletions(-)

diff --git a/lang/python/helpers.c b/lang/python/helpers.c
index 0ee24a3..d0c1f3b 100644
--- a/lang/python/helpers.c
+++ b/lang/python/helpers.c
@@ -280,15 +280,18 @@ gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status,
   PyObject *func = NULL, *dataarg = NULL, *pyargs = NULL, *retval = NULL;
   PyObject *pyopaque = (PyObject *) opaque;
   gpgme_error_t err_status = 0;
+  PyObject *self = NULL;
 
   pygpgme_exception_init();
 
-  if (PyTuple_Check(pyopaque)) {
-    func = PyTuple_GetItem(pyopaque, 0);
-    dataarg = PyTuple_GetItem(pyopaque, 1);
+  assert (PyTuple_Check(pyopaque));
+  assert (PyTuple_Size(pyopaque) == 2 || PyTuple_Size(pyopaque) == 3);
+  self = PyTuple_GetItem(pyopaque, 0);
+  func = PyTuple_GetItem(pyopaque, 1);
+  if (PyTuple_Size(pyopaque) == 3) {
+    dataarg = PyTuple_GetItem(pyopaque, 2);
     pyargs = PyTuple_New(3);
   } else {
-    func = pyopaque;
     pyargs = PyTuple_New(2);
   }
 
@@ -303,6 +306,7 @@ gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status,
   Py_DECREF(pyargs);
   if (PyErr_Occurred()) {
     err_status = pygpgme_exception2code();
+    pygpgme_stash_callback_exception(self);
   } else {
     if (fd>=0 && retval && PyUnicode_Check(retval)) {
       const char *buffer;
diff --git a/lang/python/pyme/core.py b/lang/python/pyme/core.py
index 9e7faf7..1b4e6ae 100644
--- a/lang/python/pyme/core.py
+++ b/lang/python/pyme/core.py
@@ -225,8 +225,15 @@ class Context(GpgmeWrapper):
         """Start key editing using supplied callback function"""
         if key == None:
             raise ValueError("op_edit: First argument cannot be None")
-        opaquedata = (func, fnc_value)
-        errorcheck(pygpgme.gpgme_op_edit(self.wrapped, key, opaquedata, out))
+        if fnc_value:
+            opaquedata = (self, func, fnc_value)
+        else:
+            opaquedata = (self, func)
+
+        result = pygpgme.gpgme_op_edit(self.wrapped, key, opaquedata, out)
+        if self._callback_excinfo:
+            pygpgme.pygpgme_raise_callback_exception(self)
+        errorcheck(result)
 
 class Data(GpgmeWrapper):
     """From the GPGME C manual:
diff --git a/lang/python/tests/Makefile.am b/lang/python/tests/Makefile.am
index 32dc432..236354f 100644
--- a/lang/python/tests/Makefile.am
+++ b/lang/python/tests/Makefile.am
@@ -38,7 +38,8 @@ py_tests = t-wrapper.py \
 	t-sign.py \
 	t-signers.py \
 	t-decrypt.py \
-	t-export.py
+	t-export.py \
+	t-edit.py
 
 TESTS = $(top_srcdir)/tests/gpg/initial.test \
 	$(py_tests) \
diff --git a/lang/python/tests/t-callbacks.py b/lang/python/tests/t-callbacks.py
index 70f641d..d962dc4 100755
--- a/lang/python/tests/t-callbacks.py
+++ b/lang/python/tests/t-callbacks.py
@@ -113,3 +113,36 @@ except Exception as e:
     assert e == myException
 else:
     assert False, "Expected an error, got none"
+
+
+# Test the edit callback.
+c = core.Context()
+c.set_pinentry_mode(constants.PINENTRY_MODE_LOOPBACK)
+c.set_passphrase_cb(lambda *args: "abc")
+sink = core.Data()
+alpha = c.get_key("A0FF4590BB6122EDEF6E3C542D727CC768697734", False)
+
+cookie = object()
+edit_cb_called = False
+def edit_cb(status, args, hook):
+    global edit_cb_called
+    edit_cb_called = True
+    assert hook == cookie
+    return "quit" if args == "keyedit.prompt" else None
+c.op_edit(alpha, edit_cb, cookie, sink)
+assert edit_cb_called
+
+# Test exceptions.
+c = core.Context()
+c.set_pinentry_mode(constants.PINENTRY_MODE_LOOPBACK)
+c.set_passphrase_cb(lambda *args: "abc")
+sink = core.Data()
+
+def edit_cb(status, args):
+    raise myException
+try:
+    c.op_edit(alpha, edit_cb, None, sink)
+except Exception as e:
+    assert e == myException
+else:
+    assert False, "Expected an error, got none"
diff --git a/lang/python/tests/t-edit.py b/lang/python/tests/t-edit.py
new file mode 100755
index 0000000..64255c9
--- /dev/null
+++ b/lang/python/tests/t-edit.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2005 Igor Belyi <belyi at users.sourceforge.net>
+# Copyright (C) 2016 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os
+from pyme import core, constants
+import support
+
+class KeyEditor(object):
+    def __init__(self):
+        self.steps = ["fpr", "expire", "1", "primary", "quit"]
+        self.step = 0
+        self.done = False
+        self.verbose = int(os.environ.get('verbose', 0)) > 1
+
+    def edit_fnc(self, status, args, out):
+        if args == "keyedit.prompt":
+            result = self.steps[self.step]
+            self.step += 1
+        elif args == "keyedit.save.okay":
+            result = "Y"
+            self.done = self.step == len(self.steps)
+        elif args == "keygen.valid":
+            result = "0"
+        else:
+            result = None
+
+        if self.verbose:
+            sys.stderr.write("Code: {}, args: {!r}, Returning: {!r}\n"
+                             .format(status, args, result))
+
+        return result
+
+support.init_gpgme(constants.PROTOCOL_OpenPGP)
+
+c = core.Context()
+c.set_pinentry_mode(constants.PINENTRY_MODE_LOOPBACK)
+c.set_passphrase_cb(lambda *args: "abc")
+c.set_armor(True)
+sink = core.Data()
+
+editor = KeyEditor()
+c.op_edit(c.get_key("A0FF4590BB6122EDEF6E3C542D727CC768697734", False),
+          editor.edit_fnc, sink, sink)
+assert editor.done

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gpgme.git



More information about the Pkg-gnupg-commit mailing list