[git] GPGME - branch, master, updated. gpgme-1.6.0-216-g007382c

by Justus Winter cvs at cvs.gnupg.org
Mon Jul 11 18:18:23 CEST 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".

The branch, master has been updated
       via  007382ce94a6318557370c440f7d609a030a119e (commit)
       via  98cba522c906115efcba1f8cc0bec7e5edb51ecd (commit)
       via  c53f87c5f9ca63119152f41dcebfb175d4df2cef (commit)
      from  bfa8ac7e02c16790ee5bd3b42c26699f4821d72e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 007382ce94a6318557370c440f7d609a030a119e
Author: Justus Winter <justus at g10code.com>
Date:   Mon Jul 11 16:38:37 2016 +0200

    python: Enable out-of-tree build of pyme bindings.
    
    * lang/python/MANIFEST.in: Update manifest template.
    * lang/python/Makefile.am: Copy more files, move generation of files
    to Python build script, add 'sdist' target to build a Python source
    distribution.
    * lang/python/gpgme-h-clean.py: Add code to build 'errors.i'.
    * lang/python/setup.py.in: Generate files, enable out-of-tree builds.
    
    Signed-off-by: Justus Winter <justus at g10code.com>

diff --git a/lang/python/MANIFEST.in b/lang/python/MANIFEST.in
index f079538..abdc08f 100644
--- a/lang/python/MANIFEST.in
+++ b/lang/python/MANIFEST.in
@@ -1,5 +1,4 @@
-recursive-include examples *.py *.glade *.gladep
+recursive-include examples *.py
 include gpgme-h-clean.py gpgme.i
 include helpers.c helpers.h
-include Makefile
 recursive-include pyme *.py
diff --git a/lang/python/Makefile.am b/lang/python/Makefile.am
index 527212a..89b1c28 100644
--- a/lang/python/Makefile.am
+++ b/lang/python/Makefile.am
@@ -26,34 +26,30 @@ EXTRA_DIST = \
 SUBDIRS = tests
 
 COPY_FILES = \
+	$(srcdir)/gpgme.i \
 	$(srcdir)/README \
+	$(srcdir)/MANIFEST.in \
+	$(srcdir)/gpgme-h-clean.py \
 	$(srcdir)/pyme \
+	$(srcdir)/examples \
 	$(srcdir)/helpers.c $(srcdir)/helpers.h
 
-# Cleanup gpgme.h from deprecated functions and typedefs.
-gpgme.h: ../../src/gpgme.h $(srcdir)/gpgme-h-clean.py
-	$(PYTHON) $(srcdir)/gpgme-h-clean.py $< >$@
-
 # For VPATH builds we need to copy some files because Python's
 # distutils are not VPATH-aware.
 copystamp: $(COPY_FILES)
 	if test "$(srcdir)" != "$(builddir)" ; then cp -r $^ . ; fi
 	touch $@
 
-errors.i:
-	sed -n -e \
-	  '/GPG_ERR_[^ ]* =/s/ *\(.*\) = .*/%constant long \1 = \1;/p' \
-	  `$(GPG_ERROR_CONFIG) --prefix`/include/gpg-error.h >$@
-
-gpgme_wrap.c pyme/pygpgme.py: gpgme.i errors.i gpgme.h copystamp
-	$(SWIG) -python -py3 -builtin $(SWIGOPT) \
-	  -o $(builddir)/gpgme_wrap.c -outdir $(builddir)/pyme \
-	  $<
-
-all-local: gpgme_wrap.c pyme/pygpgme.py copystamp
+all-local: copystamp
 	CFLAGS="$(CFLAGS) -I$(top_srcdir)" \
 	  $(PYTHON) setup.py build --verbose
 
+dist/pyme3-$(VERSION).tar.gz: copystamp
+	CFLAGS="$(CFLAGS) -I$(top_srcdir)" \
+	  $(PYTHON) setup.py sdist --verbose
+
+sdist: dist/pyme3-$(VERSION).tar.gz
+
 CLEANFILES = gpgme.h errors.i gpgme_wrap.c pyme/pygpgme.py \
 	  copystamp
 
@@ -65,7 +61,7 @@ clean-local:
 	rm -rf -- build
 	if test "$(srcdir)" != "$(builddir)" ; then \
 	  find . -type d ! -perm -200 -exec chmod u+w {} ';' ; \
-	  rm -rf README pyme helpers.c helpers.h ; \
+	  for F in $(COPY_FILES); do rm -rf -- `basename $$F` ; done ; \
 	fi
 
 install-exec-local:
diff --git a/lang/python/gpgme-h-clean.py b/lang/python/gpgme-h-clean.py
index b7052ff..b29b2e1 100755
--- a/lang/python/gpgme-h-clean.py
+++ b/lang/python/gpgme-h-clean.py
@@ -19,8 +19,8 @@
 
 import sys, re
 
-if len(sys.argv) < 2:
-    sys.stderr.write("Usage: %s gpgme.h\n" % sys.argv[0])
+if len(sys.argv) != 2:
+    sys.stderr.write("Usage: %s path/to/[gpgme|gpg-error].h\n" % sys.argv[0])
     sys.exit(1)
 
 deprec_func = re.compile(r'^(.*typedef.*|.*\(.*\)|[^#]+\s+.+)'
@@ -28,7 +28,7 @@ deprec_func = re.compile(r'^(.*typedef.*|.*\(.*\)|[^#]+\s+.+)'
                          re.S)
 line_break = re.compile(';|\\$|\\x0c|^\s*#|{');
 
-try:
+if 'gpgme.h' in sys.argv[1]:
     gpgme = open(sys.argv[1])
     tmp = gpgme.readline()
     text = ''
@@ -41,6 +41,10 @@ try:
         tmp = gpgme.readline()
     sys.stdout.write(text)
     gpgme.close()
-except IOError as errmsg:
-    sys.stderr.write("%s: %s\n" % (sys.argv[0], errmsg))
-    sys.exit(1)
+else:
+    filter_re = re.compile(r'GPG_ERR_[^ ]* =')
+    rewrite_re = re.compile(r' *(.*) = .*')
+    for line in open(sys.argv[1]):
+        if not filter_re.search(line):
+            continue
+        print(rewrite_re.sub(r'%constant long \1 = \1;', line.strip()))
diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in
index 9e6e008..4667a9d 100755
--- a/lang/python/setup.py.in
+++ b/lang/python/setup.py.in
@@ -20,16 +20,71 @@
 
 from distutils.core import setup, Extension
 import os, os.path, sys
+import glob
 import subprocess
 
-def getconfig(what):
-    confdata = subprocess.Popen(["../../src/gpgme-config", "--%s" % what],
+# Out-of-tree build of the pyme3 bindings.
+gpg_error_config = "gpg-error-config"
+gpgme_config = "gpgme-config"
+gpgme_h = ""
+library_dirs = []
+extra_swig_opts = []
+
+if os.path.exists("../../src/gpgme-config"):
+    # In-tree build.
+    in_tree = True
+    gpgme_config = "../../src/gpgme-config"
+    gpgme_h = "../../src/gpgme.h"
+    library_dirs = ["../../src/.libs"] # XXX uses libtool internals
+    extra_swig_opts = ["-DHAVE_DATA_H=1"]
+
+try:
+    subprocess.check_call([gpg_error_config, '--version'],
+                          stdout=subprocess.DEVNULL)
+except:
+    sys.exit("Could not find gpg-error-config.  " +
+             "Please install the libgpg-error development package.")
+
+try:
+    subprocess.check_call([gpgme_config, '--version'],
+                          stdout=subprocess.DEVNULL)
+except:
+    sys.exit("Could not find gpgme-config.  " +
+             "Please install the libgpgme development package.")
+
+def getconfig(what, config=gpgme_config):
+    confdata = subprocess.Popen([config, "--%s" % what],
                                 stdout=subprocess.PIPE).communicate()[0]
     return [x for x in confdata.decode('utf-8').split() if x != '']
 
+version = version_raw = getconfig("version")[0]
+if '-' in version:
+    version = version.split('-')[0]
+major, minor, patch = map(int, version.split('.'))
+
+if not (major > 1 or (major == 1 and minor >= 6)):
+    sys.exit('Need at least GPGME version 1.6, found {}.'.format(version_raw))
+
+if not gpgme_h:
+    gpgme_h = os.path.join(getconfig("prefix")[0], "include", "gpgme.h")
+
+gpg_error_prefix = getconfig("prefix", config=gpg_error_config)[0]
+gpg_error_h = os.path.join(gpg_error_prefix, "include", "gpg-error.h")
+if not os.path.exists(gpg_error_h):
+    gpg_error_h = \
+        glob.glob(os.path.join(gpg_error_prefix, "include",
+                               "*", "gpg-error.h"))[0]
+
+print("Building pyme3 using {} and {}.".format(gpgme_h, gpg_error_h))
+
+# Cleanup gpgme.h from deprecated functions and typedefs.
+subprocess.check_call(["python3", "gpgme-h-clean.py", gpgme_h],
+                      stdout=open("gpgme.h", "w"))
+subprocess.check_call(["python3", "gpgme-h-clean.py", gpg_error_h],
+                      stdout=open("errors.i", "w"))
+
 include_dirs = [os.getcwd()]
 define_macros = []
-library_dirs = ["../../src/.libs"] # XXX uses libtool internals
 libs = getconfig('libs')
 
 for item in getconfig('cflags'):
@@ -67,13 +122,29 @@ if uname_s.startswith("MINGW32"):
                library_dirs.append(os.path.join(tgt, item))
                break
 
-swige = Extension("pyme._pygpgme", ["gpgme_wrap.c", "helpers.c"],
+# We build an Extension using SWIG, which generates a Python module.
+# By default, the 'build_py' step is run before 'build_ext', and
+# therefore the generated Python module is not copied into the build
+# directory.
+# Bug: http://bugs.python.org/issue1016626
+# Workaround:
+# http://stackoverflow.com/questions/12491328/python-distutils-not-include-the-swig-generated-module
+from distutils.command.build import build
+class BuildExtFirstHack(build):
+    def run(self):
+        self.run_command('build_ext')
+        build.run(self)
+
+swige = Extension("pyme._pygpgme", ["gpgme.i", "helpers.c"],
+                  swig_opts = ['-py3', '-builtin',
+                               '-outdir', 'pyme'] + extra_swig_opts,
                   include_dirs = include_dirs,
                   define_macros = define_macros,
                   library_dirs = library_dirs,
                   extra_link_args = libs)
 
-setup(name = "pyme",
+setup(name="pyme3",
+      cmdclass={'build': BuildExtFirstHack},
       version="@VERSION@",
       description='Python bindings for GPGME GnuPG cryptography library',
       author='The GnuPG hackers',

commit 98cba522c906115efcba1f8cc0bec7e5edb51ecd
Author: Justus Winter <justus at g10code.com>
Date:   Mon Jul 11 16:34:15 2016 +0200

    python: Do not depend on access to internal data structures.
    
    * lang/python/gpgme.i (gpgme_data_t): Rework so that it works without
    access to the definition of 'struct gpgme_data'.
    * lang/python/helpers.c (object_to_gpgme_data_t): Add assertion.
    
    Signed-off-by: Justus Winter <justus at g10code.com>

diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i
index 8dbb0c2..c1e0074 100644
--- a/lang/python/gpgme.i
+++ b/lang/python/gpgme.i
@@ -125,7 +125,8 @@
 
 // Special handling for references to our objects.
 %typemap(in) gpgme_data_t DATAIN (gpgme_data_t wrapper = NULL,
-                                  PyObject *bytesio = NULL, Py_buffer view) {
+                                  PyObject *bytesio = NULL,
+                                  Py_buffer view, int have_view = 0) {
   /* If we create a temporary wrapper object, we will store it in
      wrapperN, where N is $argnum.  Here in this fragment, SWIG will
      automatically append $argnum.  */
@@ -138,6 +139,7 @@
                                        &bytesio, &view);
     if (pypointer == NULL)
       return NULL;
+    have_view = !! view.obj;
 
     /* input = $input, 1 = $1, 1_descriptor = $1_descriptor */
 
@@ -152,79 +154,108 @@
   }
 }
 
+#if HAVE_DATA_H
+/* If we are doing an in-tree build, we can use the internal
+   representation of struct gpgme_data for an very efficient check if
+   the buffer has been modified.  */
+%{
+#include "src/data.h"	/* For struct gpgme_data.  */
+%}
+#endif
+
 %typemap(freearg) gpgme_data_t DATAIN {
   /* See whether we need to update the Python buffer.  */
-  if (resultobj && wrapper$argnum && view$argnum.buf
-      && wrapper$argnum->data.mem.buffer != NULL)
+  if (resultobj && wrapper$argnum && view$argnum.buf)
     {
-      /* The buffer is dirty.  */
-      if (view$argnum.readonly)
+      int dirty;
+      char *new_data = NULL;
+      size_t new_size;
+
+#if HAVE_DATA_H
+      new_data = wrapper$argnum->data.mem.buffer;
+      new_size = wrapper$argnum->data.mem.length;
+      dirty = new_data != NULL;
+#else
+      new_data = gpgme_data_release_and_get_mem (wrapper$argnum, &new_size);
+      wrapper$argnum = NULL;
+      dirty = new_size != view$argnum.len
+        || memcmp (new_data, view$argnum.buf, view$argnum.len);
+#endif
+
+      if (dirty)
         {
-          Py_XDECREF(resultobj);
-          resultobj = NULL;
-          PyErr_SetString(PyExc_ValueError, "cannot update read-only buffer");
-        }
-
-      /* See if we need to truncate the buffer.  */
-      if (resultobj && view$argnum.len != wrapper$argnum->data.mem.length)
-        {
-          if (bytesio$argnum == NULL)
+          /* The buffer is dirty.  */
+          if (view$argnum.readonly)
             {
               Py_XDECREF(resultobj);
               resultobj = NULL;
-              PyErr_SetString(PyExc_ValueError, "cannot resize buffer");
+              PyErr_SetString(PyExc_ValueError,
+                              "cannot update read-only buffer");
             }
-          else
+
+          /* See if we need to truncate the buffer.  */
+          if (resultobj && view$argnum.len != new_size)
             {
-              PyObject *retval;
-              PyBuffer_Release(&view$argnum);
-              retval = PyObject_CallMethod(bytesio$argnum, "truncate", "l",
-                                           (long)
-                                           wrapper$argnum->data.mem.length);
-              if (retval == NULL)
+              if (bytesio$argnum == NULL)
                 {
                   Py_XDECREF(resultobj);
                   resultobj = NULL;
+                  PyErr_SetString(PyExc_ValueError, "cannot resize buffer");
                 }
               else
                 {
-                  Py_DECREF(retval);
-
-                  retval = PyObject_CallMethod(bytesio$argnum, "getbuffer", NULL);
-                  if (retval == NULL
-                      || PyObject_GetBuffer(retval, &view$argnum,
-                                            PyBUF_SIMPLE|PyBUF_WRITABLE) < 0)
+                  PyObject *retval;
+                  PyBuffer_Release(&view$argnum);
+                  assert(view$argnum.obj == NULL);
+                  retval = PyObject_CallMethod(bytesio$argnum, "truncate",
+                                               "l", (long) new_size);
+                  if (retval == NULL)
                     {
                       Py_XDECREF(resultobj);
                       resultobj = NULL;
                     }
-
-                  Py_XDECREF(retval);
-
-                  if (resultobj && view$argnum.len
-                      != wrapper$argnum->data.mem.length)
+                  else
                     {
-                      Py_XDECREF(resultobj);
-                      resultobj = NULL;
-                      PyErr_Format(PyExc_ValueError,
-                                   "Expected buffer of length %zu, got %zi",
-                                   wrapper$argnum->data.mem.length,
-                                   view$argnum.len);
+                      Py_DECREF(retval);
+
+                      retval = PyObject_CallMethod(bytesio$argnum,
+                                                   "getbuffer", NULL);
+                      if (retval == NULL
+                          || PyObject_GetBuffer(retval, &view$argnum,
+                                           PyBUF_SIMPLE|PyBUF_WRITABLE) < 0)
+                        {
+                          Py_XDECREF(resultobj);
+                          resultobj = NULL;
+                        }
+
+                      Py_XDECREF(retval);
+
+                      if (resultobj && view$argnum.len
+                          != new_size)
+                        {
+                          Py_XDECREF(resultobj);
+                          resultobj = NULL;
+                          PyErr_Format(PyExc_ValueError,
+                                       "Expected buffer of length %zu, got %zi",
+                                       new_size,
+                                       view$argnum.len);
+                        }
                     }
                 }
             }
+          if (resultobj)
+            memcpy(view$argnum.buf, new_data, new_size);
         }
-
-      if (resultobj)
-        memcpy(view$argnum.buf, wrapper$argnum->data.mem.buffer,
-               wrapper$argnum->data.mem.length);
+#if ! HAVE_DATA_H
+      free (new_data);
+#endif
     }
 
   /* Free the temporary wrapper, if any.  */
   if (wrapper$argnum)
     gpgme_data_release(wrapper$argnum);
   Py_XDECREF (bytesio$argnum);
-  if (wrapper$argnum && view$argnum.buf)
+  if (have_view$argnum && view$argnum.buf)
     PyBuffer_Release(&view$argnum);
 }
 
@@ -398,7 +429,6 @@
    SWIG.  */
 %{
 #include <gpgme.h>
-#include "src/data.h"	/* For struct gpgme_data.  */
 %}
 
 /* This is for notations, where we want to hide the length fields, and
diff --git a/lang/python/helpers.c b/lang/python/helpers.c
index 43a55d0..d6cbb88 100644
--- a/lang/python/helpers.c
+++ b/lang/python/helpers.c
@@ -254,6 +254,7 @@ object_to_gpgme_data_t(PyObject *input, int argnum, gpgme_data_t *wrapper,
       if (data != input)
         Py_DECREF(data);
 
+      assert (view->obj);
       assert (view->ndim == 1);
       assert (view->shape == NULL);
       assert (view->strides == NULL);

commit c53f87c5f9ca63119152f41dcebfb175d4df2cef
Author: Justus Winter <justus at g10code.com>
Date:   Mon Jul 11 12:29:17 2016 +0200

    python: Make result wrapping backwards compatible.
    
    * lang/python/pyme/results.py (Result.__init__): Skip missing fields.
    
    Signed-off-by: Justus Winter <justus at g10code.com>

diff --git a/lang/python/pyme/results.py b/lang/python/pyme/results.py
index e6e8968..aa9b38e 100644
--- a/lang/python/pyme/results.py
+++ b/lang/python/pyme/results.py
@@ -46,13 +46,12 @@ class Result(object):
     }
     def __init__(self, fragile):
         for key, func in self._type.items():
-            setattr(self, key, func(getattr(fragile, key)))
+            if hasattr(fragile, key):
+                setattr(self, key, func(getattr(fragile, key)))
 
         for key, func in self._map.items():
-            setattr(self, key, list(map(func, getattr(fragile, key))))
-
-        for key, func in self._map.items():
-            setattr(self, key, list(map(func, getattr(fragile, key))))
+            if hasattr(fragile, key):
+                setattr(self, key, list(map(func, getattr(fragile, key))))
 
         for key in dir(fragile):
             if key.startswith('_') or key in self._blacklist:

-----------------------------------------------------------------------

Summary of changes:
 lang/python/MANIFEST.in      |   3 +-
 lang/python/Makefile.am      |  28 +++++-----
 lang/python/gpgme-h-clean.py |  16 +++---
 lang/python/gpgme.i          | 120 +++++++++++++++++++++++++++----------------
 lang/python/helpers.c        |   1 +
 lang/python/pyme/results.py  |   9 ++--
 lang/python/setup.py.in      |  81 +++++++++++++++++++++++++++--
 7 files changed, 179 insertions(+), 79 deletions(-)


hooks/post-receive
-- 
GnuPG Made Easy
http://git.gnupg.org




More information about the Gnupg-commits mailing list