diff options
| -rw-r--r-- | lang/python/gpgme.i | 25 | ||||
| -rw-r--r-- | lang/python/helpers.c | 156 | ||||
| -rw-r--r-- | lang/python/helpers.h | 15 | ||||
| -rw-r--r-- | lang/python/pyme/core.py | 64 | 
4 files changed, 171 insertions, 89 deletions
| diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index 1e4c9ff6..65cd2352 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -302,11 +302,14 @@  // Include mapper for edit callbacks  %typemap(in) (gpgme_edit_cb_t fnc, void *fnc_value) { +  if (! PyTuple_Check($input)) +    return PyErr_Format(PyExc_TypeError, "edit callback must be a tuple"); +  if (PyTuple_Size($input) != 2 && PyTuple_Size($input) != 3) +    return PyErr_Format(PyExc_TypeError, +                        "edit callback must be a tuple of size 2 or 3"); +    $1 = (gpgme_edit_cb_t) pyEditCb; -  if ($input == Py_None) -    $2 = NULL; -  else -    $2 = $input; +  $2 = $input;  }  /* Include the unmodified <gpgme.h> for cc, and the cleaned-up local @@ -355,8 +358,6 @@ struct _gpgme_sig_notation  %pointer_functions(gpgme_error_t, gpgme_error_t_p);  %pointer_functions(gpgme_trust_item_t, gpgme_trust_item_t_p);  %pointer_functions(gpgme_engine_info_t, gpgme_engine_info_t_p); -%pointer_functions(PyObject *, PyObject_p_p); -%pointer_functions(void *, void_p_p);  // Helper functions. @@ -374,6 +375,18 @@ pygpgme_wrap_gpgme_data_t(gpgme_data_t data)  {    return SWIG_NewPointerObj(data, SWIGTYPE_p_gpgme_data, 0);  } + +gpgme_ctx_t +pygpgme_unwrap_gpgme_ctx_t(PyObject *wrapped) +{ +  gpgme_ctx_t result; +  if (SWIG_ConvertPtr(wrapped, +                      (void **) &result, +                      SWIGTYPE_p_gpgme_context, +                      SWIG_POINTER_EXCEPTION) == -1) +    return NULL; +  return result; +}  %}  %include "helpers.h" diff --git a/lang/python/helpers.c b/lang/python/helpers.c index ad33d07b..5380ff26 100644 --- a/lang/python/helpers.c +++ b/lang/python/helpers.c @@ -76,10 +76,6 @@ gpgme_error_t pygpgme_exception2code(void) {    return err_status;  } -void pygpgme_clear_generic_cb(PyObject **cb) { -  Py_DECREF(*cb); -} -  /* Exception support for callbacks.  */  #define EXCINFO	"_callback_excinfo" @@ -293,6 +289,7 @@ static gpgme_error_t pyPassphraseCb(void *hook,    pygpgme_exception_init();    assert (PyTuple_Check(pyhook)); +  assert (PyTuple_Size(pyhook) == 2 || PyTuple_Size(pyhook) == 3);    self = PyTuple_GetItem(pyhook, 0);    func = PyTuple_GetItem(pyhook, 1);    if (PyTuple_Size(pyhook) == 3) { @@ -374,15 +371,47 @@ static gpgme_error_t pyPassphraseCb(void *hook,    return err_status;  } -void pygpgme_set_passphrase_cb(gpgme_ctx_t ctx, PyObject *cb, -			       PyObject **freelater) { +PyObject * +pygpgme_set_passphrase_cb(PyObject *self, PyObject *cb) { +  PyObject *wrapped; +  gpgme_ctx_t ctx; + +  wrapped = PyObject_GetAttrString(self, "wrapped"); +  if (wrapped == NULL) +    { +      assert (PyErr_Occurred ()); +      return NULL; +    } + +  ctx = pygpgme_unwrap_gpgme_ctx_t(wrapped); +  Py_DECREF(wrapped); +  if (ctx == NULL) +    { +      if (cb == Py_None) +        goto out; +      else +        return PyErr_Format(PyExc_RuntimeError, "wrapped is NULL"); +    } +    if (cb == Py_None) {      gpgme_set_passphrase_cb(ctx, NULL, NULL); -    return; +    PyObject_SetAttrString(self, "_passphrase_cb", Py_None); +    goto out;    } -  Py_INCREF(cb); -  *freelater = cb; -  gpgme_set_passphrase_cb(ctx, (gpgme_passphrase_cb_t)pyPassphraseCb, (void *) cb); + +  if (! PyTuple_Check(cb)) +    return PyErr_Format(PyExc_TypeError, "cb must be a tuple"); +  if (PyTuple_Size(cb) != 2 && PyTuple_Size(cb) != 3) +    return PyErr_Format(PyExc_TypeError, +                        "cb must be a tuple of size 2 or 3"); + +  gpgme_set_passphrase_cb(ctx, (gpgme_passphrase_cb_t) pyPassphraseCb, +                          (void *) cb); +  PyObject_SetAttrString(self, "_passphrase_cb", cb); + + out: +  Py_INCREF(Py_None); +  return Py_None;  }  static void pyProgressCb(void *hook, const char *what, int type, int current, @@ -392,6 +421,7 @@ static void pyProgressCb(void *hook, const char *what, int type, int current,    PyObject *self = NULL;    assert (PyTuple_Check(pyhook)); +  assert (PyTuple_Size(pyhook) == 2 || PyTuple_Size(pyhook) == 3);    self = PyTuple_GetItem(pyhook, 0);    func = PyTuple_GetItem(pyhook, 1);    if (PyTuple_Size(pyhook) == 3) { @@ -423,14 +453,46 @@ static void pyProgressCb(void *hook, const char *what, int type, int current,    Py_XDECREF(retval);  } -void pygpgme_set_progress_cb(gpgme_ctx_t ctx, PyObject *cb, PyObject **freelater){ +PyObject * +pygpgme_set_progress_cb(PyObject *self, PyObject *cb) { +  PyObject *wrapped; +  gpgme_ctx_t ctx; + +  wrapped = PyObject_GetAttrString(self, "wrapped"); +  if (wrapped == NULL) +    { +      assert (PyErr_Occurred ()); +      return NULL; +    } + +  ctx = pygpgme_unwrap_gpgme_ctx_t(wrapped); +  Py_DECREF(wrapped); +  if (ctx == NULL) +    { +      if (cb == Py_None) +        goto out; +      else +        return PyErr_Format(PyExc_RuntimeError, "wrapped is NULL"); +    } +    if (cb == Py_None) {      gpgme_set_progress_cb(ctx, NULL, NULL); -    return; +    PyObject_SetAttrString(self, "_progress_cb", Py_None); +    goto out;    } -  Py_INCREF(cb); -  *freelater = cb; + +  if (! PyTuple_Check(cb)) +    return PyErr_Format(PyExc_TypeError, "cb must be a tuple"); +  if (PyTuple_Size(cb) != 2 && PyTuple_Size(cb) != 3) +    return PyErr_Format(PyExc_TypeError, +                        "cb must be a tuple of size 2 or 3"); +    gpgme_set_progress_cb(ctx, (gpgme_progress_cb_t) pyProgressCb, (void *) cb); +  PyObject_SetAttrString(self, "_progress_cb", cb); + + out: +  Py_INCREF(Py_None); +  return Py_None;  }  /* Status callbacks.  */ @@ -488,15 +550,46 @@ static gpgme_error_t pyStatusCb(void *hook, const char *keyword,    return err;  } -void pygpgme_set_status_cb(gpgme_ctx_t ctx, PyObject *cb, -                           PyObject **freelater) { +PyObject * +pygpgme_set_status_cb(PyObject *self, PyObject *cb) { +  PyObject *wrapped; +  gpgme_ctx_t ctx; + +  wrapped = PyObject_GetAttrString(self, "wrapped"); +  if (wrapped == NULL) +    { +      assert (PyErr_Occurred ()); +      return NULL; +    } + +  ctx = pygpgme_unwrap_gpgme_ctx_t(wrapped); +  Py_DECREF(wrapped); +  if (ctx == NULL) +    { +      if (cb == Py_None) +        goto out; +      else +        return PyErr_Format(PyExc_RuntimeError, "wrapped is NULL"); +    } +    if (cb == Py_None) {      gpgme_set_status_cb(ctx, NULL, NULL); -    return; +    PyObject_SetAttrString(self, "_status_cb", Py_None); +    goto out;    } -  Py_INCREF(cb); -  *freelater = cb; + +  if (! PyTuple_Check(cb)) +    return PyErr_Format(PyExc_TypeError, "cb must be a tuple"); +  if (PyTuple_Size(cb) != 2 && PyTuple_Size(cb) != 3) +    return PyErr_Format(PyExc_TypeError, +                        "cb must be a tuple of size 2 or 3"); +    gpgme_set_status_cb(ctx, (gpgme_status_cb_t) pyStatusCb, (void *) cb); +  PyObject_SetAttrString(self, "_status_cb", cb); + + out: +  Py_INCREF(Py_None); +  return Py_None;  }  /* Edit callbacks.  */ @@ -775,9 +868,10 @@ static void pyDataReleaseCb(void *hook)      pygpgme_stash_callback_exception(self);  } -gpgme_error_t pygpgme_data_new_from_cbs(gpgme_data_t *r_data, -                                        PyObject *pycbs, -                                        PyObject **freelater) +PyObject * +pygpgme_data_new_from_cbs(PyObject *self, +                          PyObject *pycbs, +                          gpgme_data_t *r_data)  {    static struct gpgme_data_cbs cbs = {      pyDataReadCb, @@ -785,12 +879,20 @@ gpgme_error_t pygpgme_data_new_from_cbs(gpgme_data_t *r_data,      pyDataSeekCb,      pyDataReleaseCb,    }; +  gpgme_error_t err; + +  if (! PyTuple_Check(pycbs)) +    return PyErr_Format(PyExc_TypeError, "pycbs must be a tuple"); +  if (PyTuple_Size(pycbs) != 5 && PyTuple_Size(pycbs) != 6) +    return PyErr_Format(PyExc_TypeError, +                        "pycbs must be a tuple of size 5 or 6"); -  assert (PyTuple_Check(pycbs)); -  assert (PyTuple_Size(pycbs) == 5 || PyTuple_Size(pycbs) == 6); +  err = gpgme_data_new_from_cbs(r_data, &cbs, (void *) pycbs); +  if (err) +    return pygpgme_raise_exception(err); -  Py_INCREF(pycbs); -  *freelater = pycbs; +  PyObject_SetAttrString(self, "_data_cbs", pycbs); -  return gpgme_data_new_from_cbs(r_data, &cbs, (void *) pycbs); +  Py_INCREF(Py_None); +  return Py_None;  } diff --git a/lang/python/helpers.h b/lang/python/helpers.h index 37362aee..15642903 100644 --- a/lang/python/helpers.h +++ b/lang/python/helpers.h @@ -34,21 +34,18 @@ PyObject *object_to_gpgme_data_t(PyObject *input, int argnum,  				 gpgme_data_t *wrapper,  				 PyObject **bytesio, Py_buffer *view); -void pygpgme_clear_generic_cb(PyObject **cb);  PyObject *pygpgme_raise_callback_exception(PyObject *self); -void pygpgme_set_passphrase_cb(gpgme_ctx_t ctx, PyObject *cb, -			       PyObject **freelater); -void pygpgme_set_progress_cb(gpgme_ctx_t ctx, PyObject *cb, PyObject **freelater); -void pygpgme_set_status_cb(gpgme_ctx_t ctx, PyObject *cb, -                           PyObject **freelater); +PyObject *pygpgme_set_passphrase_cb(PyObject *self, PyObject *cb); +PyObject *pygpgme_set_progress_cb(PyObject *self, PyObject *cb); +PyObject *pygpgme_set_status_cb(PyObject *self, PyObject *cb);  gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status,  		       const char *args, int fd); -gpgme_error_t pygpgme_data_new_from_cbs(gpgme_data_t *r_data, -                                        PyObject *pycbs, -                                        PyObject **freelater); +PyObject *pygpgme_data_new_from_cbs(PyObject *self, PyObject *pycbs, +				    gpgme_data_t *r_data);  /* SWIG support for helpers.c  */  PyObject *pygpgme_wrap_gpgme_data_t(gpgme_data_t data); +gpgme_ctx_t pygpgme_unwrap_gpgme_ctx_t(PyObject *wrapped); diff --git a/lang/python/pyme/core.py b/lang/python/pyme/core.py index 64dc7878..e5a50617 100644 --- a/lang/python/pyme/core.py +++ b/lang/python/pyme/core.py @@ -220,9 +220,6 @@ class Context(GpgmeWrapper):              pygpgme.delete_gpgme_ctx_t_p(tmp)              self.own = True          super().__init__(wrapped) -        self.last_passcb = None -        self.last_progresscb = None -        self.last_statuscb = None          self.armor = armor          self.textmode = textmode          self.offline = offline @@ -247,30 +244,6 @@ class Context(GpgmeWrapper):      def __exit__(self, type, value, tb):          self.__del__() -    def _free_passcb(self): -        if self.last_passcb != None: -            if pygpgme.pygpgme_clear_generic_cb: -                pygpgme.pygpgme_clear_generic_cb(self.last_passcb) -            if pygpgme.delete_PyObject_p_p: -                pygpgme.delete_PyObject_p_p(self.last_passcb) -            self.last_passcb = None - -    def _free_progresscb(self): -        if self.last_progresscb != None: -            if pygpgme.pygpgme_clear_generic_cb: -                pygpgme.pygpgme_clear_generic_cb(self.last_progresscb) -            if pygpgme.delete_PyObject_p_p: -                pygpgme.delete_PyObject_p_p(self.last_progresscb) -            self.last_progresscb = None - -    def _free_statuscb(self): -        if self.last_statuscb != None: -            if pygpgme.pygpgme_clear_generic_cb: -                pygpgme.pygpgme_clear_generic_cb(self.last_statuscb) -            if pygpgme.delete_PyObject_p_p: -                pygpgme.delete_PyObject_p_p(self.last_statuscb) -            self.last_statuscb = None -      def op_keylist_all(self, *args, **kwargs):          self.op_keylist_start(*args, **kwargs)          key = self.op_keylist_next() @@ -341,16 +314,18 @@ class Context(GpgmeWrapper):          Please see the GPGME manual for more information.          """ -        self._free_passcb()          if func == None:              hookdata = None          else: -            self.last_passcb = pygpgme.new_PyObject_p_p()              if hook == None:                  hookdata = (weakref.ref(self), func)              else:                  hookdata = (weakref.ref(self), func, hook) -        pygpgme.pygpgme_set_passphrase_cb(self.wrapped, hookdata, self.last_passcb) +        pygpgme.pygpgme_set_passphrase_cb(self, hookdata) + +    def _free_passcb(self): +        if pygpgme.pygpgme_set_passphrase_cb: +            self.set_passphrase_cb(None)      def set_progress_cb(self, func, hook=None):          """Sets the progress meter callback to the function specified by FUNC. @@ -364,16 +339,18 @@ class Context(GpgmeWrapper):          Please see the GPGME manual for more information.          """ -        self._free_progresscb()          if func == None:              hookdata = None          else: -            self.last_progresscb = pygpgme.new_PyObject_p_p()              if hook == None:                  hookdata = (weakref.ref(self), func)              else:                  hookdata = (weakref.ref(self), func, hook) -        pygpgme.pygpgme_set_progress_cb(self.wrapped, hookdata, self.last_progresscb) +        pygpgme.pygpgme_set_progress_cb(self, hookdata) + +    def _free_progresscb(self): +        if pygpgme.pygpgme_set_progress_cb: +            self.set_progress_cb(None)      def set_status_cb(self, func, hook=None):          """Sets the status callback to the function specified by FUNC.  If @@ -386,17 +363,18 @@ class Context(GpgmeWrapper):          Please see the GPGME manual for more information.          """ -        self._free_statuscb()          if func == None:              hookdata = None          else: -            self.last_statuscb = pygpgme.new_PyObject_p_p()              if hook == None:                  hookdata = (weakref.ref(self), func)              else:                  hookdata = (weakref.ref(self), func, hook) -        pygpgme.pygpgme_set_status_cb(self.wrapped, hookdata, -                                      self.last_statuscb) +        pygpgme.pygpgme_set_status_cb(self, hookdata) + +    def _free_statuscb(self): +        if pygpgme.pygpgme_set_status_cb: +            self.set_status_cb(None)      def get_engine_info(self):          """Returns this context specific engine info""" @@ -547,12 +525,7 @@ class Data(GpgmeWrapper):          self.__del__()      def _free_datacbs(self): -        if self.data_cbs != None: -            if pygpgme.pygpgme_clear_generic_cb: -                pygpgme.pygpgme_clear_generic_cb(self.data_cbs) -            if pygpgme.delete_PyObject_p_p: -                pygpgme.delete_PyObject_p_p(self.data_cbs) -            self.data_cbs = None +        self._data_cbs = None      def new(self):          tmp = pygpgme.new_gpgme_data_t_p() @@ -579,8 +552,6 @@ class Data(GpgmeWrapper):          pygpgme.delete_gpgme_data_t_p(tmp)      def new_from_cbs(self, read_cb, write_cb, seek_cb, release_cb, hook=None): -        assert self.data_cbs == None -        self.data_cbs = pygpgme.new_PyObject_p_p()          tmp = pygpgme.new_gpgme_data_t_p()          if hook != None:              hookdata = (weakref.ref(self), @@ -588,8 +559,7 @@ class Data(GpgmeWrapper):          else:              hookdata = (weakref.ref(self),                          read_cb, write_cb, seek_cb, release_cb) -        errorcheck( -            pygpgme.pygpgme_data_new_from_cbs(tmp, hookdata, self.data_cbs)) +        pygpgme.pygpgme_data_new_from_cbs(self, hookdata, tmp)          self.wrapped = pygpgme.gpgme_data_t_p_value(tmp)          pygpgme.delete_gpgme_data_t_p(tmp) | 
