From f4ba16b31ea282d0787a40be3f37b951584143a1 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Tue, 10 May 2016 13:19:26 +0200 Subject: python: Rename bindings. -- Signed-off-by: Justus Winter --- lang/python/gpgme.i | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 lang/python/gpgme.i (limited to 'lang/python/gpgme.i') diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i new file mode 100644 index 00000000..0115caf3 --- /dev/null +++ b/lang/python/gpgme.i @@ -0,0 +1,267 @@ +/* +# $Id$ +# Copyright (C) 2004,2008 Igor Belyi +# Copyright (C) 2002 John Goerzen +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +%module pygpgme +%include "cpointer.i" +%include "cstring.i" + +// Generate doc strings for all methods. +%feature("autodoc", "0"); + +// Allow use of None for strings. + +%typemap(in) const char * { + if ($input == Py_None) + $1 = NULL; + else if (PyBytes_Check($input)) + $1 = PyBytes_AsString($input); + else { + PyErr_Format(PyExc_TypeError, + "arg %d: expected string or None, got %s", + $argnum, $input->ob_type->tp_name); + return NULL; + } +} +%typemap(freearg) const char * ""; + +// Release returned buffers as necessary. +%typemap(newfree) char * "free($1);"; +%newobject gpgme_data_release_and_get_mem; + +%{ +/* Convert object to a pointer to gpgme type */ +PyObject* object_to_gpgme_t(PyObject* input, const char* objtype, int argnum) { + PyObject *pyname = NULL, *pypointer = NULL; + pyname = PyObject_CallMethod(input, "_getctype", NULL); + if (pyname == NULL) { + PyErr_Format(PyExc_TypeError, + "arg %d: Expected an instance of type %s, but got %s", + argnum, objtype, + input == Py_None ? "None" : input->ob_type->tp_name); + return NULL; + } + if (strcmp(PyBytes_AsString(pyname), objtype) != 0) { + PyErr_Format(PyExc_TypeError, + "arg %d: Expected value of type %s, but got %s", + argnum, objtype, PyBytes_AsString(pyname)); + Py_DECREF(pyname); + return NULL; + } + Py_DECREF(pyname); + pypointer = PyObject_GetAttrString(input, "wrapped"); + if (pypointer == NULL) { + PyErr_Format(PyExc_TypeError, + "arg %d: Use of uninitialized Python object %s", + argnum, objtype); + return NULL; + } + return pypointer; +} +%} + +%typemap(arginit) gpgme_key_t [] { + $1 = NULL; +} + +%typemap(in) gpgme_key_t [] { + int i, numb = 0; + if (!PySequence_Check($input)) { + PyErr_Format(PyExc_ValueError, "arg %d: Expected a list of gpgme_key_t", + $argnum); + return NULL; + } + if((numb = PySequence_Length($input)) != 0) { + $1 = (gpgme_key_t*)malloc((numb+1)*sizeof(gpgme_key_t)); + for(i=0; inext) { + size++; + } + $result = PyList_New(size); + for (i=0,curr=$1; inext) { + PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr(curr), $1_descriptor, %newpointer_flags); + PyList_SetItem($result, i, o); + } +} + +// Include mapper for edit callbacks +%typemap(in) (gpgme_edit_cb_t fnc, void *fnc_value) { + $1 = (gpgme_edit_cb_t) pyEditCb; + if ($input == Py_None) + $2 = NULL; + else + $2 = $input; +} + +// Include the header file both for cc (first) and for swig (second) +// Include for swig locally since we need to fix 'class' usage there. +%{ +#include +%} +%include "gpgme.h" + +%constant long EOF = GPG_ERR_EOF; + +// Generating and handling pointers-to-pointers. + +%pointer_functions(gpgme_ctx_t, gpgme_ctx_t_p); +%pointer_functions(gpgme_data_t, gpgme_data_t_p); +%pointer_functions(gpgme_key_t, gpgme_key_t_p); +%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. + +%{ +#include +%} +FILE *fdopen(int fildes, const char *mode); + +%{ +#include "helpers.h" +%} +%include "helpers.h" + +%{ +gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status, + const char *args, int fd) { + PyObject *func = NULL, *dataarg = NULL, *pyargs = NULL, *retval = NULL; + PyObject *pyopaque = (PyObject *) opaque; + gpgme_error_t err_status = 0; + + pygpgme_exception_init(); + + if (PyTuple_Check(pyopaque)) { + func = PyTuple_GetItem(pyopaque, 0); + dataarg = PyTuple_GetItem(pyopaque, 1); + pyargs = PyTuple_New(3); + } else { + func = pyopaque; + pyargs = PyTuple_New(2); + } + + PyTuple_SetItem(pyargs, 0, PyLong_FromLong((long) status)); + PyTuple_SetItem(pyargs, 1, PyBytes_FromString(args)); + if (dataarg) { + Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */ + PyTuple_SetItem(pyargs, 2, dataarg); + } + + retval = PyObject_CallObject(func, pyargs); + Py_DECREF(pyargs); + if (PyErr_Occurred()) { + err_status = pygpgme_exception2code(); + } else { + if (fd>=0 && retval) { + write(fd, PyBytes_AsString(retval), PyBytes_Size(retval)); + write(fd, "\n", 1); + } + } + + Py_XDECREF(retval); + return err_status; +} +%} + -- cgit v1.2.3 From aade53a12b9716997684b872bc2ac87229f73fb3 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Tue, 10 May 2016 13:30:30 +0200 Subject: python: Delete trailing whitespace. -- Signed-off-by: Justus Winter --- lang/python/gpgme.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lang/python/gpgme.i') diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index 0115caf3..87efce73 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -241,14 +241,14 @@ gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status, func = pyopaque; pyargs = PyTuple_New(2); } - + PyTuple_SetItem(pyargs, 0, PyLong_FromLong((long) status)); PyTuple_SetItem(pyargs, 1, PyBytes_FromString(args)); if (dataarg) { Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */ PyTuple_SetItem(pyargs, 2, dataarg); } - + retval = PyObject_CallObject(func, pyargs); Py_DECREF(pyargs); if (PyErr_Occurred()) { -- cgit v1.2.3 From d60deb8a127fb35c01acc729f33b014840af0e7b Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 12 May 2016 11:21:58 +0200 Subject: python: Fix type translation. * lang/python/gpgme.i: Adjust to Python3's string type being 'Unicode', not 'bytes'. Fix type checking. * lang/python/core.py (Data.write): Add docstring mentioning the expected type of parameter 'buffer'. (Data.read): Adjust read loop. Also, use a saner chunk size, and join all chunks at the end instead of adding them. * lang/python/examples/simple.py: Adjust example. Signed-off-by: Justus Winter --- lang/python/gpgme.i | 51 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'lang/python/gpgme.i') diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index 87efce73..7c11943c 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -24,16 +24,18 @@ // Generate doc strings for all methods. %feature("autodoc", "0"); -// Allow use of None for strings. +/* Allow use of Unicode objects, bytes, and None for strings. */ %typemap(in) const char * { if ($input == Py_None) $1 = NULL; + else if (PyUnicode_Check($input)) + $1 = PyUnicode_AsUTF8($input); else if (PyBytes_Check($input)) $1 = PyBytes_AsString($input); else { PyErr_Format(PyExc_TypeError, - "arg %d: expected string or None, got %s", + "arg %d: expected str, bytes, or None, got %s", $argnum, $input->ob_type->tp_name); return NULL; } @@ -49,20 +51,27 @@ PyObject* object_to_gpgme_t(PyObject* input, const char* objtype, int argnum) { PyObject *pyname = NULL, *pypointer = NULL; pyname = PyObject_CallMethod(input, "_getctype", NULL); - if (pyname == NULL) { - PyErr_Format(PyExc_TypeError, - "arg %d: Expected an instance of type %s, but got %s", - argnum, objtype, - input == Py_None ? "None" : input->ob_type->tp_name); - return NULL; - } - if (strcmp(PyBytes_AsString(pyname), objtype) != 0) { - PyErr_Format(PyExc_TypeError, - "arg %d: Expected value of type %s, but got %s", - argnum, objtype, PyBytes_AsString(pyname)); - Py_DECREF(pyname); - return NULL; - } + if (pyname && PyUnicode_Check(pyname)) + { + if (strcmp(PyUnicode_AsUTF8(pyname), objtype) != 0) + { + PyErr_Format(PyExc_TypeError, + "arg %d: Expected value of type %s, but got %s", + argnum, objtype, PyUnicode_AsUTF8(pyname)); + Py_DECREF(pyname); + return NULL; + } + } + else + { + PyErr_Format(PyExc_TypeError, + "Protocol violation: Expected an instance of type str " + "from _getctype, but got %s", + pyname == NULL ? "NULL" + : (pyname == Py_None ? "None" : pyname->ob_type->tp_name)); + return NULL; + } + Py_DECREF(pyname); pypointer = PyObject_GetAttrString(input, "wrapped"); if (pypointer == NULL) { @@ -243,7 +252,7 @@ gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status, } PyTuple_SetItem(pyargs, 0, PyLong_FromLong((long) status)); - PyTuple_SetItem(pyargs, 1, PyBytes_FromString(args)); + PyTuple_SetItem(pyargs, 1, PyUnicode_FromString(args)); if (dataarg) { Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */ PyTuple_SetItem(pyargs, 2, dataarg); @@ -254,8 +263,12 @@ gpgme_error_t pyEditCb(void *opaque, gpgme_status_code_t status, if (PyErr_Occurred()) { err_status = pygpgme_exception2code(); } else { - if (fd>=0 && retval) { - write(fd, PyBytes_AsString(retval), PyBytes_Size(retval)); + if (fd>=0 && retval && PyUnicode_Check(retval)) { + const char *buffer; + Py_ssize_t size; + + buffer = PyUnicode_AsUTF8AndSize(retval, &size); + write(fd, buffer, size); write(fd, "\n", 1); } } -- cgit v1.2.3 From f7094d8358e933f3ce074eade7a40b2a7d291180 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 12 May 2016 17:44:54 +0200 Subject: python: Fix writing to data buffers. * lang/python/gpgme.i: Add typemap for buffers. * lang/python/pyme/core.py (Data.write): Fix function. * lang/python/tests/Makefile.am: Add new test. * lang/python/tests/t-data.py: New file. Signed-off-by: Justus Winter --- lang/python/gpgme.i | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'lang/python/gpgme.i') diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i index 7c11943c..c5b5bc97 100644 --- a/lang/python/gpgme.i +++ b/lang/python/gpgme.i @@ -173,6 +173,23 @@ PyObject* object_to_gpgme_t(PyObject* input, const char* objtype, int argnum) { free($1); } +/* For gpgme_data_write, but should be universal. */ +%typemap(in) (const void *buffer, size_t size) { + if ($input == Py_None) + $1 = NULL, $2 = 0; + else if (PyUnicode_Check($input)) + $1 = PyUnicode_AsUTF8AndSize($input, (size_t *) &$2); + else if (PyBytes_Check($input)) + PyBytes_AsStringAndSize($input, (char **) &$1, (size_t *) &$2); + else { + PyErr_Format(PyExc_TypeError, + "arg %d: expected str, bytes, or None, got %s", + $argnum, $input->ob_type->tp_name); + return NULL; + } +} +%typemap(freearg) (const void *buffer, size_t size) ""; + // Make types containing 'next' field to be lists %ignore next; %typemap(out) gpgme_sig_notation_t, gpgme_engine_info_t, gpgme_subkey_t, gpgme_key_sig_t, -- cgit v1.2.3