diff options
author | Justus Winter <[email protected]> | 2016-06-06 11:11:15 +0000 |
---|---|---|
committer | Justus Winter <[email protected]> | 2016-06-06 12:16:04 +0000 |
commit | 8196edf9ca5c8f2f02553e7f22d9c79dbd229882 (patch) | |
tree | d3bacbbbe7f72ba90bbe2715b5a87acac6871445 /lang/python/helpers.c | |
parent | python: Move helper function. (diff) | |
download | gpgme-8196edf9ca5c8f2f02553e7f22d9c79dbd229882.tar.gz gpgme-8196edf9ca5c8f2f02553e7f22d9c79dbd229882.zip |
python: Wrap file-like objects on demand.
* lang/python/gpgme.i (gpgme_data_t): Use new function to create
wrapper objects if necessary, and deallocate them after the function
call.
* lang/python/helpers.c (object_to_gpgme_data_t): New function.
* lang/python/helpers.h (object_to_gpgme_data_t): New prototype.
* lang/python/tests/Makefile.am (pytests): Add new test.
* lang/python/tests/t-idiomatic.py: New file.
Signed-off-by: Justus Winter <[email protected]>
Diffstat (limited to 'lang/python/helpers.c')
-rw-r--r-- | lang/python/helpers.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/lang/python/helpers.c b/lang/python/helpers.c index 3ecbacc7..7e1c1c34 100644 --- a/lang/python/helpers.c +++ b/lang/python/helpers.c @@ -180,6 +180,71 @@ object_to_gpgme_t(PyObject *input, const char *objtype, int argnum) return pypointer; } +/* Convert object to a pointer to gpgme type, version for data + objects. Constructs a wrapper Python on the fly e.g. for file-like + objects with a fileno method, returning it in WRAPPER. This object + must be de-referenced when no longer needed. */ +PyObject * +object_to_gpgme_data_t(PyObject *input, int argnum, PyObject **wrapper) +{ + static PyObject *Data = NULL; + PyObject *data = input; + PyObject *fd; + PyObject *result; + *wrapper = NULL; + + if (Data == NULL) { + PyObject *core; + PyObject *from_list = PyList_New(0); + core = PyImport_ImportModuleLevel("core", PyEval_GetGlobals(), + PyEval_GetLocals(), from_list, 1); + Py_XDECREF(from_list); + if (core) { + Data = PyDict_GetItemString(PyModule_GetDict(core), "Data"); + Py_XINCREF(Data); + } + else + return NULL; + } + + fd = PyObject_CallMethod(input, "fileno", NULL); + if (fd) { + /* File-like object with file number. */ + PyObject *args = NULL; + PyObject *kw = NULL; + + /* We don't need the fd, as we have no constructor accepting file + descriptors directly. */ + Py_DECREF(fd); + + args = PyTuple_New(0); + kw = PyDict_New(); + if (args == NULL || kw == NULL) + { + fail: + Py_XDECREF(args); + Py_XDECREF(kw); + return NULL; + } + + if (PyDict_SetItemString(kw, "file", input) < 0) + goto fail; + + *wrapper = PyObject_Call(Data, args, kw); + if (*wrapper == NULL) + goto fail; + + Py_DECREF(args); + Py_DECREF(kw); + data = *wrapper; + } + else + PyErr_Clear(); + + result = object_to_gpgme_t(data, "gpgme_data_t", argnum); + return result; +} + /* Callback support. */ |