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.  */ | 
