Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-python-gnupg for 
openSUSE:Factory checked in at 2025-08-15 21:51:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-gnupg (Old)
 and      /work/SRC/openSUSE:Factory/.python-python-gnupg.new.1085 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-python-gnupg"

Fri Aug 15 21:51:51 2025 rev:19 rq:1299387 version:0.5.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-python-gnupg/python-python-gnupg.changes  
2025-02-17 20:55:02.653770064 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-python-gnupg.new.1085/python-python-gnupg.changes
        2025-08-15 21:52:47.633949827 +0200
@@ -1,0 +2,8 @@
+Thu Aug 14 09:54:33 UTC 2025 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 0.5.5
+  * Fix #249: Handle fetching GPG version when not the first item in the 
configuration.
+  * Fix #250: Capture uid info in a uid_map attribute of ScanKeys/ListKeys.
+  * Fix #255: Improve handling of exceptions raised in background threads.
+
+-------------------------------------------------------------------

Old:
----
  python-gnupg-0.5.4.tar.gz

New:
----
  python-gnupg-0.5.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-python-gnupg.spec ++++++
--- /var/tmp/diff_new_pack.EVSsrt/_old  2025-08-15 21:52:48.225974444 +0200
+++ /var/tmp/diff_new_pack.EVSsrt/_new  2025-08-15 21:52:48.225974444 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-python-gnupg
-Version:        0.5.4
+Version:        0.5.5
 Release:        0
 Summary:        A wrapper for the GNU Privacy Guard (GPG or GnuPG)
 License:        BSD-3-Clause

++++++ python-gnupg-0.5.4.tar.gz -> python-gnupg-0.5.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.5.4/PKG-INFO 
new/python-gnupg-0.5.5/PKG-INFO
--- old/python-gnupg-0.5.4/PKG-INFO     2025-01-07 12:57:56.000000000 +0100
+++ new/python-gnupg-0.5.5/PKG-INFO     2025-08-04 21:16:46.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: python-gnupg
-Version: 0.5.4
+Version: 0.5.5
 Summary: A wrapper for the Gnu Privacy Guard (GPG or GnuPG)
 Home-page: https://github.com/vsajip/python-gnupg
 Author: Vinay Sajip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.5.4/README.rst 
new/python-gnupg-0.5.5/README.rst
--- old/python-gnupg-0.5.4/README.rst   2024-10-25 15:49:15.000000000 +0200
+++ new/python-gnupg-0.5.5/README.rst   2025-08-04 20:48:16.000000000 +0200
@@ -72,13 +72,32 @@
 .. note:: GCnn refers to an issue nn on Google Code.
 
 
-0.5.4 (future)
+0.5.6 (future)
 --------------
 
 Released: Not yet
 
+
+0.5.5
+-----
+
+Released: 2025-08-04
+
+* Fix #249: Handle fetching GPG version when not the first item in the 
configuration.
+
+* Fix #250: Capture uid info in a uid_map attribute of ScanKeys/ListKeys.
+
+* Fix #255: Improve handling of exceptions raised in background threads.
+
+
+0.5.4
+-----
+
+Released: 2025-01-07
+
 * Fix #242: Handle exceptions in ``on_data`` callable.
 
+
 0.5.3
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.5.4/gnupg.py 
new/python-gnupg-0.5.5/gnupg.py
--- old/python-gnupg-0.5.4/gnupg.py     2025-01-07 11:13:17.000000000 +0100
+++ new/python-gnupg-0.5.5/gnupg.py     2025-08-04 20:49:23.000000000 +0200
@@ -27,7 +27,7 @@
 and so does not work on Windows). Renamed to gnupg.py to avoid confusion with
 the previous versions.
 
-Modifications Copyright (C) 2008-2024 Vinay Sajip. All rights reserved.
+Modifications Copyright (C) 2008-2025 Vinay Sajip. All rights reserved.
 
 For the full documentation, see https://docs.red-dove.com/python-gnupg/ or
 https://gnupg.readthedocs.io/
@@ -39,15 +39,19 @@
 from io import StringIO
 import logging
 import os
+try:
+    from queue import Queue, Empty
+except ImportError:
+    from Queue import Queue, Empty
 import re
 import socket
 from subprocess import Popen, PIPE
 import sys
 import threading
 
-__version__ = '0.5.4'
+__version__ = '0.5.5'
 __author__ = 'Vinay Sajip'
-__date__ = '$07-Jan-2025 10:13:17$'
+__date__ = '$04-Aug-2025 19:49:23$'
 
 STARTUPINFO = None
 if os.name == 'nt':  # pragma: no cover
@@ -137,7 +141,7 @@
     return s
 
 
-def _copy_data(instream, outstream, buffer_size):
+def _copy_data(instream, outstream, buffer_size, error_queue):
     # Copy one stream to another
     assert buffer_size > 0
     sent = 0
@@ -150,8 +154,9 @@
         # for what is actually a binary file
         try:
             data = instream.read(buffer_size)
-        except Exception:  # pragma: no cover
+        except Exception as e:  # pragma: no cover
             logger.warning('Exception occurred while reading', exc_info=1)
+            error_queue.put_nowait(e)
             break
         if not data:
             break
@@ -161,10 +166,11 @@
             outstream.write(data)
         except UnicodeError:  # pragma: no cover
             outstream.write(data.encode(enc))
-        except Exception:  # pragma: no cover
+        except Exception as e:  # pragma: no cover
             # Can sometimes get 'broken pipe' errors even when the data has all
             # been sent
             logger.exception('Error sending data')
+            error_queue.put_nowait(e)
             break
     try:
         outstream.close()
@@ -173,9 +179,9 @@
     logger.debug('closed output, %d bytes sent', sent)
 
 
-def _threaded_copy_data(instream, outstream, buffer_size):
+def _threaded_copy_data(instream, outstream, buffer_size, error_queue):
     assert buffer_size > 0
-    wr = threading.Thread(target=_copy_data, args=(instream, outstream, 
buffer_size))
+    wr = threading.Thread(target=_copy_data, args=(instream, outstream, 
buffer_size, error_queue))
     wr.daemon = True
     logger.debug('data copier: %r, %r, %r', wr, instream, outstream)
     wr.start()
@@ -569,6 +575,7 @@
         self.curkey = None
         self.fingerprints = []
         self.uids = []
+        self.uid_map = {}
 
     def get_fields(self, args):
         """
@@ -597,6 +604,10 @@
             uid = uid.replace(k, v)
         self.curkey['uids'].append(uid)
         self.uids.append(uid)
+        uid_data = {}
+        self.uid_map[uid] = uid_data
+        for fn, fv in zip(self.FIELDS, args):
+            uid_data[fn] = fv
 
     def handle_status(self, key, value):  # pragma: no cover
         pass
@@ -1053,7 +1064,7 @@
         self.fingerprint = self.fingerprint or args[9]
 
 
-VERSION_RE = re.compile(r'^cfg:version:(\d+(\.\d+)*)'.encode('ascii'))
+VERSION_RE = re.compile(r'\bcfg:version:(\d+(\.\d+)*)'.encode('ascii'))
 HEX_DIGITS_RE = re.compile(r'[0-9a-f]+$', re.I)
 PUBLIC_KEY_RE = re.compile(r'gpg: public key is (\w+)')
 
@@ -1154,7 +1165,7 @@
         self._collect_output(p, result, stdin=p.stdin)
         if p.returncode != 0:  # pragma: no cover
             raise ValueError('Error invoking gpg: %s: %s' % (p.returncode, 
result.stderr))
-        m = VERSION_RE.match(result.data)
+        m = VERSION_RE.search(result.data)
         if not m:  # pragma: no cover
             self.version = None
         else:
@@ -1344,17 +1355,24 @@
         # Handle a basic data call - pass data to GPG, handle the output
         # including status information. Garbage In, Garbage Out :)
         fileobj = self._get_fileobj(fileobj_or_path)
+        writer = None  # See issue #237
         try:
             p = self._open_subprocess(args, passphrase is not None)
             if not binary:  # pragma: no cover
                 stdin = codecs.getwriter(self.encoding)(p.stdin)
             else:
                 stdin = p.stdin
-            writer = None  # See issue #237
             if passphrase:
                 _write_passphrase(stdin, passphrase, self.encoding)
-            writer = _threaded_copy_data(fileobj, stdin, self.buffer_size)
+            error_queue = Queue()
+            writer = _threaded_copy_data(fileobj, stdin, self.buffer_size, 
error_queue)
             self._collect_output(p, result, writer, stdin)
+            try:
+                exc = error_queue.get_nowait()
+                # if we get here, that means an error occurred in the copying 
thread
+                raise exc
+            except Empty:
+                pass
             return result
         finally:
             if writer:
@@ -1476,14 +1494,21 @@
         # passphrase is bad, gpg bails and you can't write the message.
         fileobj = self._get_fileobj(fileobj_or_path)
         p = self._open_subprocess(args, passphrase is not None)
+        writer = None
         try:
             stdin = p.stdin
             if passphrase:
                 _write_passphrase(stdin, passphrase, self.encoding)
-            writer = _threaded_copy_data(fileobj, stdin, self.buffer_size)
+            error_queue = Queue()
+            writer = _threaded_copy_data(fileobj, stdin, self.buffer_size, 
error_queue)
+            try:
+                exc = error_queue.get_nowait()
+                # if we get here, that means an error occurred in the copying 
thread
+                raise exc
+            except Empty:
+                pass
         except IOError:  # pragma: no cover
             logging.exception('error writing message')
-            writer = None
         finally:
             if writer:
                 writer.join(0.01)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.5.4/python_gnupg.egg-info/PKG-INFO 
new/python-gnupg-0.5.5/python_gnupg.egg-info/PKG-INFO
--- old/python-gnupg-0.5.4/python_gnupg.egg-info/PKG-INFO       2025-01-07 
12:57:56.000000000 +0100
+++ new/python-gnupg-0.5.5/python_gnupg.egg-info/PKG-INFO       2025-08-04 
21:16:45.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: python-gnupg
-Version: 0.5.4
+Version: 0.5.5
 Summary: A wrapper for the Gnu Privacy Guard (GPG or GnuPG)
 Home-page: https://github.com/vsajip/python-gnupg
 Author: Vinay Sajip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.5.4/test_gnupg.py 
new/python-gnupg-0.5.5/test_gnupg.py
--- old/python-gnupg-0.5.4/test_gnupg.py        2025-01-07 11:12:41.000000000 
+0100
+++ new/python-gnupg-0.5.5/test_gnupg.py        2025-08-04 20:50:21.000000000 
+0200
@@ -2,9 +2,10 @@
 """
 A test harness for gnupg.py.
 
-Copyright (C) 2008-2024 Vinay Sajip. All rights reserved.
+Copyright (C) 2008-2025 Vinay Sajip. All rights reserved.
 """
 import argparse
+import io
 import json
 import logging
 import os.path
@@ -35,7 +36,7 @@
 import gnupg
 
 __author__ = 'Vinay Sajip'
-__date__ = '$07-Jan-2025 10:12:41$'
+__date__ = '$04-Aug-2025 19:50:21$'
 
 ALL_TESTS = True
 
@@ -1167,12 +1168,9 @@
             # Try opening the encrypted file in text mode (Issue #39)
             # this doesn't fail in 2.x
             if gnupg._py3k:
-                efile = open(encfname, 'r')
-                ddata = self.gpg.decrypt_file(efile, passphrase='bbrown', 
output=decfname)
-                self.assertEqual(2, ddata.returncode, 'Unexpected return code')
-                self.assertFalse(ddata)
-                self.assertEqual(ddata.status, 'no data was provided')
-                efile.close()
+                logger.debug('about to pass text stream to decrypt_file')
+                with open(encfname, 'r') as efile:
+                    self.assertRaises(UnicodeDecodeError, 
self.gpg.decrypt_file, efile, passphrase='bbrown', output=decfname)
         finally:
             for fn in (encfname, decfname):
                 if os.name == 'posix' and mode is not None:
@@ -1206,8 +1204,13 @@
         data = 'Hello, world!'
         for badout, message in cases:
             stream = gnupg._make_binary_stream(data, self.gpg.encoding)
-            edata = self.gpg.encrypt_file(stream, barbara, armor=False, 
output=badout)
-            self.assertEqual(2, edata.returncode, 'Unexpecteds return code')
+            try:
+                # On Ubuntu and pypy-2.7, you often get an IOError "Broken 
pipe"
+                # during the encrypt operation ...
+                edata = self.gpg.encrypt_file(stream, barbara, armor=False, 
output=badout)
+                self.assertEqual(2, edata.returncode, 'Unexpected return code')
+            except IOError:
+                pass
             # on GnuPG 1.4, you sometimes don't get any FAILURE messages, in
             # which case status will not be set
             if edata.status:
@@ -1235,12 +1238,18 @@
 
                 for badout, message in cases:
                     stream = gnupg._make_binary_stream(data, self.gpg.encoding)
-                    edata = self.gpg.encrypt_file(stream, barbara, 
armor=False, output=badout)
-                    self.assertEqual(2, edata.returncode, 'Unexpected return 
code')
+                    try:
+                        # On Ubuntu and pypy-2.7, you often get an IOError 
"Broken pipe"
+                        # during the encrypt operation ...
+                        edata = self.gpg.encrypt_file(stream, barbara, 
armor=False, output=badout)
+                        self.assertEqual(2, edata.returncode, 'Unexpected 
return code')
+                    except IOError:
+                        pass
                     # on GnuPG 1.4, you sometimes don't get any FAILURE 
messages, in
                     # which case status will not be set
                     if edata.status:
-                        self.assertEqual(edata.status, message)
+                        message = '%s (%s)' % (message, badout)
+                        self.assertIn(edata.status, message)
             finally:
                 os.chmod(encfname, 0o700)
                 os.remove(encfname)
@@ -1578,6 +1587,24 @@
     def test_passphrase_encoding(self):
         self.assertRaises(UnicodeEncodeError, self.gpg.decrypt, 'foo', 
passphrase=u'I’ll')
 
+    def test_configured_group(self):
+        # See issue #249
+        conf = 'group somegroup = BADF00D15BAD\n'
+        fn = os.path.join(self.homedir, 'gpg.conf')
+        with open(fn, 'w') as f:
+            f.write(conf)
+        gpg = gnupg.GPG(gnupghome=self.homedir, gpgbinary=GPGBINARY)
+        self.assertEqual(gpg.version, self.gpg.version)
+
+    def test_exception_propagation(self):
+        if sys.version_info[0] < 3:
+            raise unittest.SkipTest('python 2 is too loose with Unicode')
+        key = self.generate_key('Andrew', 'Able', 'alpha.com', 
passphrase='andy')
+        self.assertEqual(0, key.returncode, 'Non-zero return code')
+        andrew = key.fingerprint
+        stream = io.StringIO(u'Hello, world!')  # make the wrong type of stream
+        self.assertRaises(TypeError, self.gpg.encrypt_file, stream, [andrew], 
armor=False)
+
 
 TEST_GROUPS = {
     'sign':
@@ -1600,7 +1627,7 @@
     'basic':
     set(['test_environment', 'test_list_keys_initial', 'test_nogpg', 
'test_make_args', 'test_quote_with_shell']),
     'test':
-    set(['test_passphrase_encoding']),
+    set(['test_filenames_with_spaces']),
 }
 
 
@@ -1621,11 +1648,19 @@
 
 
 def init_logging():
+    class PrimegenFilter(logging.Filter):
+        def filter(self, record):
+            arg = record.args
+            if isinstance(arg, (list, tuple)) and len(arg) > 0:
+                arg = arg[0]
+            return not arg or not isinstance(arg, unicode) or '[GNUPG:] 
PROGRESS primegen' not in arg
+
     logging.basicConfig(level=logging.DEBUG,
                         filename='test_gnupg.log',
                         filemode='w',
                         format='%(asctime)s %(levelname)-5s %(name)-10s '
                         '%(threadName)-10s %(lineno)4d %(message)s')
+    logging.root.handlers[0].addFilter(PrimegenFilter())
 
 
 def main():

Reply via email to