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 2021-12-09 19:45:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-gnupg (Old)
 and      /work/SRC/openSUSE:Factory/.python-python-gnupg.new.2520 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-python-gnupg"

Thu Dec  9 19:45:02 2021 rev:11 rq:934532 version:0.4.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-python-gnupg/python-python-gnupg.changes  
2021-08-04 22:28:31.965827955 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-python-gnupg.new.2520/python-python-gnupg.changes
        2021-12-09 19:45:05.257118188 +0100
@@ -1,0 +2,10 @@
+Mon Nov 29 11:57:11 UTC 2021 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 0.4.8:
+  * Return gpg's return code in all result instances.
+  * Add check for invalid file objects.
+  * Provide more useful status message when a secret key is absent.
+  * Added a get_recipients() API to find the recipients of an encrypted
+    message without decrypting it.
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ python-python-gnupg.spec ++++++
--- /var/tmp/diff_new_pack.NMufFG/_old  2021-12-09 19:45:05.869118482 +0100
+++ /var/tmp/diff_new_pack.NMufFG/_new  2021-12-09 19:45:05.869118482 +0100
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define         oldpython python
 Name:           python-python-gnupg
-Version:        0.4.7
+Version:        0.4.8
 Release:        0
 Summary:        A wrapper for the GNU Privacy Guard (GPG or GnuPG)
 License:        BSD-3-Clause

++++++ python-gnupg-0.4.7.tar.gz -> python-gnupg-0.4.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.4.7/PKG-INFO 
new/python-gnupg-0.4.8/PKG-INFO
--- old/python-gnupg-0.4.7/PKG-INFO     2021-03-11 09:23:20.000000000 +0100
+++ new/python-gnupg-0.4.8/PKG-INFO     2021-11-24 10:39:28.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: python-gnupg
-Version: 0.4.7
+Version: 0.4.8
 Summary: A wrapper for the Gnu Privacy Guard (GPG or GnuPG)
 Home-page: https://docs.red-dove.com/python-gnupg/
 Author: Vinay Sajip
@@ -8,7 +8,7 @@
 Maintainer: Vinay Sajip
 Maintainer-email: vinay_sa...@yahoo.co.uk
 License: Copyright (C) 2008-2021 by Vinay Sajip. All Rights Reserved. See 
LICENSE.txt for license.
-Download-URL: 
https://pypi.io/packages/source/p/python-gnupg/python-gnupg-0.4.7.tar.gz
+Download-URL: 
https://pypi.io/packages/source/p/python-gnupg/python-gnupg-0.4.8.tar.gz
 Description: This module allows easy access to GnuPG's key management, 
encryption and signature functionality from Python programs. It is intended for 
use with Python 2.4 or greater.
         
         Releases are normally signed using a GnuPG key with the user id 
vinay_sa...@yahoo.co.uk and the following fingerprint:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.4.7/README.rst 
new/python-gnupg-0.4.8/README.rst
--- old/python-gnupg-0.4.7/README.rst   2021-03-11 07:59:24.000000000 +0100
+++ new/python-gnupg-0.4.8/README.rst   2021-11-24 10:11:43.000000000 +0100
@@ -64,11 +64,26 @@
 .. note:: GCnn refers to an issue nn on Google Code.
 
 
-0.4.8 (future)
+0.4.9 (future)
 --------------
 
 Released: Not yet.
 
+0.4.8
+-----
+
+Released: 2021-11-24
+
+* Fixed #147: Return gpg's return code in all result instances.
+
+* Fixed #152: Add check for invalid file objects.
+
+* Fixed #157: Provide more useful status message when a secret key is absent.
+
+* Fixed #158: Added a get_recipients() API to find the recipients of an 
encrypted
+  message without decrypting it.
+
+
 0.4.7
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.4.7/gnupg.py 
new/python-gnupg-0.4.8/gnupg.py
--- old/python-gnupg-0.4.7/gnupg.py     2021-03-11 08:01:14.000000000 +0100
+++ new/python-gnupg-0.4.8/gnupg.py     2021-11-24 10:13:33.000000000 +0100
@@ -32,9 +32,9 @@
 A unittest harness (test_gnupg.py) has also been added.
 """
 
-__version__ = "0.4.7"
+__version__ = "0.4.8"
 __author__ = "Vinay Sajip"
-__date__  = "$11-Mar-2021 07:01:14$"
+__date__  = "$24-Nov-2021 09:13:33$"
 
 try:
     from io import StringIO
@@ -230,6 +230,8 @@
         11: 'incorrect passphrase',
     }
 
+    returncode = None
+
     def __init__(self, gpg):
         self.gpg = gpg
         self.valid = False
@@ -326,6 +328,10 @@
             self.valid = False
             self.key_id = value
             self.status = 'no public key'
+        elif key == "NO_SECKEY":  # pragma: no cover
+            self.valid = False
+            self.key_id = value
+            self.status = 'no secret key'
         elif key in ("EXPKEYSIG", "REVKEYSIG"):  # pragma: no cover
             # signed with expired or revoked key
             self.valid = False
@@ -366,7 +372,7 @@
                 if not self.status:
                     self.status = message
         elif key in ("DECRYPTION_INFO", "PLAINTEXT", "PLAINTEXT_LENGTH",
-                     "NO_SECKEY", "BEGIN_SIGNING"):
+                     "BEGIN_SIGNING"):
             pass
         else:  # pragma: no cover
             logger.debug('message ignored: %s, %s', key, value)
@@ -377,6 +383,9 @@
     counts = '''count no_user_id imported imported_rsa unchanged
             n_uids n_subk n_sigs n_revoc sec_read sec_imported
             sec_dups not_imported'''.split()
+
+    returncode = None
+
     def __init__(self, gpg):
         self.gpg = gpg
         self.results = []
@@ -469,6 +478,9 @@
 }
 
 class SendResult(object):
+
+    returncode = None
+
     def __init__(self, gpg):
         self.gpg = gpg
 
@@ -492,6 +504,7 @@
 
     UID_INDEX = 1
     FIELDS = 'type keyid algo length date expires'.split()
+    returncode = None
 
     def __init__(self, gpg):
         self.gpg = gpg
@@ -637,15 +650,19 @@
         if key in ("WARNING", "ERROR"):
             logger.warning('potential problem: %s: %s', key, value)
         elif key == "NODATA":
-            self.status = "no data was provided"
+            if self.status not in ("decryption failed",):
+                self.status = "no data was provided"
         elif key in ("NEED_PASSPHRASE", "BAD_PASSPHRASE", "GOOD_PASSPHRASE",
-                     "MISSING_PASSPHRASE", "DECRYPTION_FAILED",
-                     "KEY_NOT_CREATED", "NEED_PASSPHRASE_PIN"):
+                     "MISSING_PASSPHRASE", "KEY_NOT_CREATED", 
"NEED_PASSPHRASE_PIN"):
             self.status = key.replace("_", " ").lower()
+        elif key == "DECRYPTION_FAILED":
+            if self.status != 'no secret key':  # don't overwrite more useful 
message
+                self.status = 'decryption failed'
         elif key == "NEED_PASSPHRASE_SYM":
             self.status = 'need symmetric passphrase'
         elif key == "BEGIN_DECRYPTION":
-            self.status = 'decryption incomplete'
+            if self.status != 'no secret key':  # don't overwrite more useful 
message
+                self.status = 'decryption incomplete'
         elif key == "BEGIN_ENCRYPTION":
             self.status = 'encryption incomplete'
         elif key == "DECRYPTION_OKAY":
@@ -675,6 +692,9 @@
 
 class GenKey(object):
     "Handle status messages for --gen-key"
+
+    returncode = None
+
     def __init__(self, gpg):
         self.gpg = gpg
         self.type = None
@@ -713,6 +733,9 @@
 
 class DeleteResult(object):
     "Handle status messages for --delete-key and --delete-secret-key"
+
+    returncode = None
+
     def __init__(self, gpg):
         self.gpg = gpg
         self.status = 'ok'
@@ -745,6 +768,9 @@
 
 class Sign(TextHandler):
     "Handle status messages for --sign"
+
+    returncode = None
+
     def __init__(self, gpg):
         self.gpg = gpg
         self.type = None
@@ -782,6 +808,7 @@
 
 VERSION_RE = re.compile(r'gpg \(GnuPG(?:/MacGPG2)?\) 
(\d+(\.\d+)*)'.encode('ascii'), re.I)
 HEX_DIGITS_RE = re.compile(r'[0-9a-f]+$', re.I)
+PUBLIC_KEY_RE = re.compile(r'gpg: public key is (\w+)')
 
 class GPG(object):
 
@@ -1010,7 +1037,7 @@
         if writer is not None:
             writer.join()
         process.wait()
-        rc = process.returncode
+        result.returncode = rc = process.returncode
         if rc != 0:
             logger.warning('gpg returned a non-zero error code: %d', rc)
         if stdin is not None:
@@ -1020,11 +1047,20 @@
                 pass
         stderr.close()
         stdout.close()
+        return rc
+
+    def is_valid_file(self, fileobj):
+        """
+        Simplistic check for a file object
+        """
+        return hasattr(fileobj, 'read')
 
     def _handle_io(self, args, fileobj, result, passphrase=None, binary=False):
         "Handle a call to GPG - pass input data, collect output data"
         # Handle a basic data call - pass data to GPG, handle the output
         # including status information. Garbage In, Garbage Out :)
+        if not self.is_valid_file(fileobj):
+            raise TypeError('Not a valid file: %s' % fileobj)
         p = self._open_subprocess(args, passphrase is not None)
         if not binary:  # pragma: no cover
             stdin = codecs.getwriter(self.encoding)(p.stdin)
@@ -1618,6 +1654,23 @@
         logger.debug('decrypt result[:100]: %r', result.data[:100])
         return result
 
+    def get_recipients(self, message, **kwargs):
+        data = _make_binary_stream(message, self.encoding)
+        result = self.get_recipients_file(data, **kwargs)
+        data.close()
+        return result
+
+    def get_recipients_file(self, file, extra_args=None):
+        args = ['--decrypt', '--list-only', '-v']
+        if extra_args:
+            args.extend(extra_args)
+        result = self.result_map['crypt'](self)
+        self._handle_io(args, file, result, binary=True)
+        ids = []
+        for m in PUBLIC_KEY_RE.finditer(result.stderr):
+            ids.append(m.group(1))
+        return ids
+
     def trust_keys(self, fingerprints, trustlevel):
         levels = Verify.TRUST_LEVELS
         if trustlevel not in levels:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.4.7/python_gnupg.egg-info/PKG-INFO 
new/python-gnupg-0.4.8/python_gnupg.egg-info/PKG-INFO
--- old/python-gnupg-0.4.7/python_gnupg.egg-info/PKG-INFO       2021-03-11 
09:23:20.000000000 +0100
+++ new/python-gnupg-0.4.8/python_gnupg.egg-info/PKG-INFO       2021-11-24 
10:39:27.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: python-gnupg
-Version: 0.4.7
+Version: 0.4.8
 Summary: A wrapper for the Gnu Privacy Guard (GPG or GnuPG)
 Home-page: https://docs.red-dove.com/python-gnupg/
 Author: Vinay Sajip
@@ -8,7 +8,7 @@
 Maintainer: Vinay Sajip
 Maintainer-email: vinay_sa...@yahoo.co.uk
 License: Copyright (C) 2008-2021 by Vinay Sajip. All Rights Reserved. See 
LICENSE.txt for license.
-Download-URL: 
https://pypi.io/packages/source/p/python-gnupg/python-gnupg-0.4.7.tar.gz
+Download-URL: 
https://pypi.io/packages/source/p/python-gnupg/python-gnupg-0.4.8.tar.gz
 Description: This module allows easy access to GnuPG's key management, 
encryption and signature functionality from Python programs. It is intended for 
use with Python 2.4 or greater.
         
         Releases are normally signed using a GnuPG key with the user id 
vinay_sa...@yahoo.co.uk and the following fingerprint:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-gnupg-0.4.7/test_gnupg.py 
new/python-gnupg-0.4.8/test_gnupg.py
--- old/python-gnupg-0.4.7/test_gnupg.py        2021-03-11 08:01:41.000000000 
+0100
+++ new/python-gnupg-0.4.8/test_gnupg.py        2021-11-24 10:14:09.000000000 
+0100
@@ -30,7 +30,7 @@
 import gnupg
 
 __author__ = "Vinay Sajip"
-__date__  = "$11-Mar-2020 07:01:41$"
+__date__  = "$24-Nov-2021 09:14:09$"
 
 ALL_TESTS = True
 
@@ -257,6 +257,7 @@
         "Test that initially there are no keys"
         logger.debug("test_list_keys_initial begins")
         public_keys = self.gpg.list_keys()
+        self.assertEqual(0, public_keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(public_keys, 0),
                         "Empty list expected")
         private_keys = self.gpg.list_keys(secret=True)
@@ -310,6 +311,7 @@
         result = self.gpg.gen_key(cmd)
         self.assertFalse(result.data, 'Null data result')
         self.assertEqual(None, result.fingerprint, 'Null fingerprint result')
+        self.assertEqual(2, result.returncode, "Unexpected return code")
 
     def test_key_generation_with_colons(self):
         "Test that key generation handles colons in key fields"
@@ -323,7 +325,9 @@
             params['passphrase'] = 'foo'
         cmd = self.gpg.gen_key_input(**params)
         result = self.gpg.gen_key(cmd)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         keys = self.gpg.list_keys()
+        self.assertEqual(0, keys.returncode, "Non-zero return code")
         self.assertEqual(len(keys), 1)
         key = keys[0]
         uids = key['uids']
@@ -343,7 +347,9 @@
             params['passphrase'] = 'foo'
         cmd = self.gpg.gen_key_input(**params)
         result = self.gpg.gen_key(cmd)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         keys = self.gpg.list_keys()
+        self.assertEqual(0, keys.returncode, "Non-zero return code")
         self.assertEqual(len(keys), 1)
         key = keys[0]
         uids = key['uids']
@@ -381,6 +387,7 @@
         self.test_list_keys_initial()
         self.do_key_generation()
         public_keys = self.gpg.list_keys()
+        self.assertEqual(0, public_keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(public_keys, 1),
                         "1-element list expected")
         key_info = public_keys[0]
@@ -399,6 +406,7 @@
 
         # now test with sigs=True
         public_keys_sigs = self.gpg.list_keys(sigs=True)
+        self.assertEqual(0, public_keys_sigs.returncode, "Non-zero return 
code")
         self.assertTrue(is_list_with_len(public_keys_sigs, 1),
                         "1-element list expected")
         key_info = public_keys_sigs[0]
@@ -419,6 +427,7 @@
             self.assertTrue(public_keys_sigs.key_map[sfp] is key_info)
 
         private_keys = self.gpg.list_keys(secret=True)
+        self.assertEqual(0, private_keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(private_keys, 1),
                         "1-element list expected")
         self.assertEqual(len(private_keys.fingerprints), 1)
@@ -448,8 +457,10 @@
                         keyring=pkn, secret_keyring=skn)
         logger.debug('Using keyring and secret_keyring arguments')
         public_keys_2 = gpg.list_keys()
+        self.assertEqual(0, public_keys_2.returncode, "Non-zero return code")
         self.assertEqual(public_keys_2, public_keys)
         private_keys_2 = gpg.list_keys(secret=True)
+        self.assertEqual(0, private_keys_2.returncode, "Non-zero return code")
         self.assertEqual(private_keys_2, private_keys)
 
         # generate additional keys so that we can test listing a subset of
@@ -464,9 +475,12 @@
 
         result = self.generate_key("Charlie", "Clark", "gamma.com")
         self.assertNotEqual(None, result, "Non-null result")
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         result = self.generate_key("Donna", "Davis", "delta.com")
         self.assertNotEqual(None, result, "Non-null result")
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         public_keys = gpg.list_keys()
+        self.assertEqual(0, public_keys.returncode, "Non-zero return code")
         self.assertEqual(len(public_keys), 3)
         actual = get_names(public_keys.key_map)
         expected = set(['Barbara Brown <barbara.br...@beta.com>',
@@ -475,11 +489,13 @@
         self.assertEqual(actual, expected)
         # specify a single key as a string
         public_keys = gpg.list_keys(keys='Donna Davis')
+        self.assertEqual(0, public_keys.returncode, "Non-zero return code")
         actual = get_names(public_keys.key_map)
         expected = set(['Donna Davis <donna.da...@delta.com>'])
         self.assertEqual(actual, expected)
         # specify multiple keys
         public_keys = gpg.list_keys(keys=['Donna', 'Barbara'])
+        self.assertEqual(0, public_keys.returncode, "Non-zero return code")
         actual = get_names(public_keys.key_map)
         expected = set(['Barbara Brown <barbara.br...@beta.com>',
                         'Donna Davis <donna.da...@delta.com>'])
@@ -488,8 +504,10 @@
     def test_key_trust(self):
         "Test that trusting keys works"
         gpg = self.gpg
-        gpg.import_keys(KEYS_TO_IMPORT)
+        result = gpg.import_keys(KEYS_TO_IMPORT)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         keys = gpg.list_keys()
+        self.assertEqual(0, keys.returncode, "Non-zero return code")
         fingerprints = []
         for key in keys:
             self.assertEqual(key['ownertrust'], '-')
@@ -516,7 +534,9 @@
     def test_list_signatures(self):
         logger.debug("test_list_signatures begins")
         imported = self.gpg.import_keys(SIGNED_KEYS)
+        self.assertEqual(0, imported.returncode, "Non-zero return code")
         keys = self.gpg.list_keys(keys=["18897CA2"])
+        self.assertEqual(0, keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(keys, 1), "importing test signed key")
         sigs = self.gpg.list_keys(keys=["18897CA2"], sigs=True)[0]['sigs']
         logger.debug("testing self-signature")
@@ -539,6 +559,7 @@
             for fn in ('test_pubring.gpg', 'test_secring.gpg'):
                 logger.debug('scanning keys in %s', fn)
                 data = self.gpg.scan_keys(fn)
+                self.assertEqual(0, data.returncode, "Non-zero return code")
                 uids = set()
                 for d in data:
                     uids.add(d['uids'][0])
@@ -549,8 +570,10 @@
         logger.debug("test_encryption_and_decryption begins")
         key = self.generate_key("Andrew", "Able", "alpha.com",
                                 passphrase="andy")
+        self.assertEqual(0, key.returncode, "Non-zero return code")
         andrew = key.fingerprint
         key = self.generate_key("Barbara", "Brown", "beta.com")
+        self.assertEqual(0, key.returncode, "Non-zero return code")
         barbara = key.fingerprint
         gpg = self.gpg
         if gnupg._py3k:
@@ -558,23 +581,28 @@
         else:
             data = unicode('Hello, Andr??', gpg.encoding)
         data = data.encode(gpg.encoding)
-        edata = str(gpg.encrypt(data, barbara))
+        result = gpg.encrypt(data, barbara)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
+        edata = str(result)
         self.assertNotEqual(data, edata, "Data must have changed")
         self.assertRaises(ValueError, gpg.decrypt, edata, 
passphrase="bbr\x00own")
         self.assertRaises(ValueError, gpg.decrypt, edata, 
passphrase="bbr\rown")
         self.assertRaises(ValueError, gpg.decrypt, edata, 
passphrase="bbr\nown")
         ddata = gpg.decrypt(edata, passphrase="bbrown")
+        self.assertEqual(0, ddata.returncode, "Non-zero return code")
         if data != ddata.data:  # pragma: no cover
             logger.debug("was: %r", data)
             logger.debug("new: %r", ddata.data)
         self.assertEqual(data, ddata.data, "Round-trip must work")
-        edata = str(gpg.encrypt(data, [andrew, barbara]))
+        result = gpg.encrypt(data, [andrew, barbara])
+        self.assertEqual(0, result.returncode, "Non-zero return code")
+        edata = str(result)
         self.assertNotEqual(data, edata, "Data must have changed")
         ddata = gpg.decrypt(edata, passphrase="andy")
+        self.assertEqual(0, ddata.returncode, "Non-zero return code")
         self.assertEqual(data, ddata.data, "Round-trip must work")
         ddata = gpg.decrypt(edata, passphrase="bbrown")
         self.assertEqual(data, ddata.data, "Round-trip must work")
-        logger.debug("test_encryption_and_decryption ends")
         # Test symmetric encryption
         data = "chippy was here"
         self.assertRaises(ValueError, gpg.encrypt, data, None,
@@ -583,18 +611,25 @@
                           passphrase='bbr\rown', symmetric=True)
         self.assertRaises(ValueError, gpg.encrypt, data, None,
                           passphrase='bbr\nown', symmetric=True)
-        edata = str(gpg.encrypt(data, None, passphrase='bbrown', 
symmetric=True))
+        result = gpg.encrypt(data, None, passphrase='bbrown', symmetric=True)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
+        edata = str(result)
         ddata = gpg.decrypt(edata, passphrase='bbrown')
+        self.assertEqual(0, ddata.returncode, "Non-zero return code")
         self.assertEqual(data, str(ddata))
         # Test symmetric encryption with non-default cipher
-        edata = str(gpg.encrypt(data, None, passphrase='bbrown',
-                    symmetric='AES256'))
+        result = gpg.encrypt(data, None, passphrase='bbrown', 
symmetric='AES256')
+        self.assertEqual(0, result.returncode, "Non-zero return code")
+        edata = str(result)
         ddata = gpg.decrypt(edata, passphrase='bbrown')
+        self.assertEqual(0, ddata.returncode, "Non-zero return code")
         self.assertEqual(data, str(ddata))
         # Test that you can't encrypt with no recipients
         self.assertRaises(ValueError, self.gpg.encrypt, data, [])
         # Test extra_args parameter
-        edata = str(gpg.encrypt(data, barbara, extra_args=['-z', '0']))
+        result = gpg.encrypt(data, barbara, extra_args=['-z', '0'])
+        self.assertEqual(0, result.returncode, "Non-zero return code")
+        edata = str(result)
         ddata = gpg.decrypt(edata, passphrase='bbrown')
         self.assertEqual(data.encode('ascii'), ddata.data, 'Round-trip must 
work')
         # Test on_data functionality
@@ -605,12 +640,15 @@
             chunks.append(data)
 
         gpg.on_data = collector
-        edata = str(gpg.encrypt(data, barbara))
+        result = gpg.encrypt(data, barbara)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
+        edata = str(result)
         self.assertTrue(chunks)
         expected = type(chunks[0])().join(chunks)
         self.assertEqual(expected.decode('ascii'), edata)
         chunks = []
         ddata = gpg.decrypt(edata, passphrase='bbrown')
+        self.assertEqual(0, ddata.returncode, "Non-zero return code")
         self.assertEqual(data.encode('ascii'), ddata.data, 'Round-trip must 
work')
         expected = type(chunks[0])().join(chunks)
         self.assertEqual(expected.decode('ascii'), data)
@@ -618,15 +656,19 @@
         # test signing with encryption and verification during decryption
         logger.debug('encrypting with signature')
         gpg.on_data = None
-        edata = str(gpg.encrypt(data, barbara, sign=andrew, passphrase='andy'))
+        result = gpg.encrypt(data, barbara, sign=andrew, passphrase='andy')
+        self.assertEqual(0, result.returncode, "Non-zero return code")
+        edata = str(result)
         logger.debug('decrypting with verification')
         ddata = gpg.decrypt(edata, passphrase='bbrown')
+        self.assertEqual(0, ddata.returncode, "Non-zero return code")
         self.assertEqual(data.encode('ascii'), ddata.data, 'Round-trip must 
work')
         sig_values = list(ddata.sig_info.values())
         self.assertTrue(sig_values)
         sig_info = sig_values[0]
         self.assertEqual(sig_info['fingerprint'], andrew)
         logger.debug('decrypting with verification succeeded')
+        logger.debug("test_encryption_and_decryption ends")
 
     def test_import_and_export(self):
         "Test that key import and export works"
@@ -634,11 +676,14 @@
         self.test_list_keys_initial()
         gpg = self.gpg
         result = gpg.import_keys(KEYS_TO_IMPORT)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         self.assertEqual(result.summary(), '2 imported')
         public_keys = gpg.list_keys()
+        self.assertEqual(0, public_keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(public_keys, 2),
                         "2-element list expected")
         private_keys = gpg.list_keys(secret=True)
+        self.assertEqual(0, private_keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(private_keys, 0),
                         "Empty list expected")
         ascii = gpg.export_keys([k['keyid'] for k in public_keys])
@@ -666,6 +711,7 @@
         # import a secret key, and confirm that it's found in the list of
         # secret keys.
         result = gpg.import_keys(SECRET_KEY)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         self.assertEqual(result.summary(), '1 imported')
         private_keys = gpg.list_keys(secret=True)
         self.assertTrue(is_list_with_len(private_keys, 2))
@@ -682,11 +728,14 @@
         "Test that key import works"
         logger.debug("test_import_only begins")
         self.test_list_keys_initial()
-        self.gpg.import_keys(KEYS_TO_IMPORT)
+        result = self.gpg.import_keys(KEYS_TO_IMPORT)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         public_keys = self.gpg.list_keys()
+        self.assertEqual(0, public_keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(public_keys, 2),
                         "2-element list expected")
         private_keys = self.gpg.list_keys(secret=True)
+        self.assertEqual(0, private_keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(private_keys, 0),
                         "Empty list expected")
         ascii = self.gpg.export_keys([k['keyid'] for k in public_keys])
@@ -715,6 +764,7 @@
         sig = self.gpg.sign(data, keyid=key.fingerprint, passphrase='bbrown')
         self.assertFalse(sig, "Bad passphrase should fail")
         sig = self.gpg.sign(data, keyid=key.fingerprint, passphrase='aable')
+        self.assertEqual(0, sig.returncode, "Non-zero return code")
         self.assertTrue(sig, "Good passphrase should succeed")
         if sig.username:  # not set in recent versions of GnuPG e.g. 2.2.5
             self.assertTrue(sig.username.startswith('Andrew Able'))
@@ -723,6 +773,7 @@
         self.assertTrue(sig.hash_algo)
         logger.debug('verification start')
         verified = self.gpg.verify(sig.data)
+        self.assertEqual(0, verified.returncode, "Non-zero return code")
         logger.debug('verification end')
         if key.fingerprint != verified.fingerprint:  # pragma: no cover
             logger.debug("key: %r", key.fingerprint)
@@ -734,6 +785,7 @@
         data_file = open(self.test_fn, 'rb')
         sig = self.gpg.sign_file(data_file, keyid=key.fingerprint,
                                  passphrase='aable')
+        self.assertEqual(0, sig.returncode, "Non-zero return code")
         data_file.close()
         self.assertTrue(sig, "File signing should succeed")
         self.assertTrue(sig.hash_algo)
@@ -744,6 +796,7 @@
             # sometimes happens in Python 2.6
             from io import BytesIO
             verified = self.gpg.verify_file(BytesIO(sig.data))
+        self.assertEqual(0, verified.returncode, "Non-zero return code")
         if key.fingerprint != verified.fingerprint:  # pragma: no cover
             logger.debug("key: %r", key.fingerprint)
             logger.debug("ver: %r", verified.fingerprint)
@@ -752,6 +805,7 @@
         data_file = open(self.test_fn, 'rb')
         sig = self.gpg.sign_file(data_file, keyid=key.fingerprint,
                                  passphrase='aable', detach=True)
+        self.assertEqual(0, sig.returncode, "Non-zero return code")
         data_file.close()
         self.assertTrue(sig, "File signing should succeed")
         self.assertTrue(sig.hash_algo)
@@ -762,6 +816,7 @@
             # sometimes happens in Python 2.6
             from io import BytesIO
             verified = self.gpg.verify_file(BytesIO(sig.data))
+        self.assertEqual(0, verified.returncode, "Non-zero return code")
         if key.fingerprint != verified.fingerprint:  # pragma: no cover
             logger.debug("key: %r", key.fingerprint)
             logger.debug("ver: %r", verified.fingerprint)
@@ -778,6 +833,7 @@
             verified = self.gpg.verify_data(fn, data)
         finally:
             os.unlink(fn)
+        self.assertEqual(0, verified.returncode, "Non-zero return code")
         if key.fingerprint != verified.fingerprint:  # pragma: no cover
             logger.debug("key: %r", key.fingerprint)
             logger.debug("ver: %r", verified.fingerprint)
@@ -794,6 +850,7 @@
         sig = self.gpg.sign_file(data_file, keyid=key.fingerprint,
                                  passphrase='aable', detach=True,
                                  output=sig_file)
+        self.assertEqual(0, sig.returncode, "Non-zero return code")
         data_file.close()
         self.assertTrue(sig, "File signing should succeed")
         self.assertTrue(sig.hash_algo)
@@ -808,6 +865,7 @@
             self.assertTrue(key.fingerprint.endswith(verified.key_id))
         finally:
             os.unlink(sig_file)
+        self.assertEqual(0, verified.returncode, "Non-zero return code")
         if key.fingerprint != verified.fingerprint:
             logger.debug("key: %r", key.fingerprint)
             logger.debug("ver: %r", verified.fingerprint)
@@ -818,12 +876,16 @@
     def test_deletion(self):
         "Test that key deletion works"
         logger.debug("test_deletion begins")
-        self.gpg.import_keys(KEYS_TO_IMPORT)
+        result = self.gpg.import_keys(KEYS_TO_IMPORT)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         public_keys = self.gpg.list_keys()
+        self.assertEqual(0, public_keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(public_keys, 2),
                         "2-element list expected")
-        self.gpg.delete_keys(public_keys[0]['fingerprint'])
+        result = self.gpg.delete_keys(public_keys[0]['fingerprint'])
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         public_keys = self.gpg.list_keys()
+        self.assertEqual(0, public_keys.returncode, "Non-zero return code")
         self.assertTrue(is_list_with_len(public_keys, 1),
                         "1-element list expected")
         logger.debug("test_deletion ends")
@@ -864,17 +926,21 @@
         try:
             key = self.generate_key("Andrew", "Able", "alpha.com",
                                     passphrase="andy")
+            self.assertEqual(0, key.returncode, "Non-zero return code")
             andrew = key.fingerprint
             key = self.generate_key("Barbara", "Brown", "beta.com")
+            self.assertEqual(0, key.returncode, "Non-zero return code")
             barbara = key.fingerprint
             data = "Hello, world!"
             file = gnupg._make_binary_stream(data, self.gpg.encoding)
             edata = self.gpg.encrypt_file(file,
                                           barbara,
                                           armor=False, output=encfname)
+            self.assertEqual(0, edata.returncode, "Non-zero return code")
             efile = open(encfname, 'rb')
             ddata = self.gpg.decrypt_file(efile, passphrase="bbrown",
                                           output=decfname)
+            self.assertEqual(0, ddata.returncode, "Non-zero return code")
             efile.seek(0, 0) # can't use os.SEEK_SET in 2.4
             edata = efile.read()
             efile.close()
@@ -894,6 +960,7 @@
                 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()
@@ -934,6 +1001,7 @@
             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")
             # on GnuPG 1.4, you sometimes don't get any FAILURE messages, in
             # which case status will not be set
             if edata.status:
@@ -963,6 +1031,7 @@
                     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")
                     # on GnuPG 1.4, you sometimes don't get any FAILURE 
messages, in
                     # which case status will not be set
                     if edata.status:
@@ -988,9 +1057,11 @@
         "Test that searching for keys works"
         if 'NO_EXTERNAL_TESTS' not in os.environ:
             r = self.gpg.search_keys('<vinay_sa...@hotmail.com>')
+            self.assertEqual(0, r.returncode, "Non-zero return code")
             self.assertTrue(r)
             self.assertTrue('Vinay Sajip <vinay_sa...@hotmail.com>' in 
r[0]['uids'])
             r = self.gpg.search_keys('92905378')
+            self.assertEqual(0, r.returncode, "Non-zero return code")
             self.assertTrue(r)
             self.assertTrue('Vinay Sajip <vinay_sa...@hotmail.com>' in 
r[0]['uids'])
 
@@ -1031,6 +1102,7 @@
                                         detach=True)
         finally:
             signfile.close()
+        self.assertEqual(0, signed.returncode, "Non-zero return code")
         self.assertTrue(signed.data)
         logger.debug("test_signing_with_uid ends")
 
@@ -1090,6 +1162,7 @@
         fp1 = result.fingerprint
         inp = gpg.gen_key_input(name_email='user2@test', passphrase='pp2')
         result = gpg.gen_key(inp)
+        self.assertEqual(0, result.returncode, "Non-zero return code")
         fp2 = result.fingerprint
         pubkey1 = gpg.export_keys(fp1)
         if gpg.version >= (2, 1):
@@ -1098,23 +1171,31 @@
             passphrase = None
         seckey1 = gpg.export_keys(fp1, secret=True, passphrase=passphrase)
         seckeys = gpg.list_keys(secret=True)
+        self.assertEqual(0, seckeys.returncode, "Non-zero return code")
         pubkeys = gpg.list_keys()
+        self.assertEqual(0, pubkeys.returncode, "Non-zero return code")
         # avoid assertIn, etc. as absent in older Python versions
         self.assertTrue(fp1 in seckeys.fingerprints)
         self.assertTrue(fp1 in pubkeys.fingerprints)
         result = gpg.delete_keys(fp1)
+        self.assertEqual(2, result.returncode, "Unexpected return code")
         self.assertEqual(str(result), 'Must delete secret key first')
         if gpg.version < (2, 1):
             # Doesn't work on 2.1, and can't use SkipTest due to having
             # to support older Pythons
             result = gpg.delete_keys(fp1, secret=True, passphrase=passphrase)
+            self.assertEqual(0, result.returncode, "Non-zero return code")
             self.assertEqual(str(result), 'ok')
             result = gpg.delete_keys(fp1)
+            self.assertEqual(0, result.returncode, "Non-zero return code")
             self.assertEqual(str(result), 'ok')
             result = gpg.delete_keys('nosuchkey')
+            self.assertEqual(2, result.returncode, "Unexpected return code")
             self.assertEqual(str(result), 'No such key')
             seckeys = gpg.list_keys(secret=True)
+            self.assertEqual(0, seckeys.returncode, "Non-zero return code")
             pubkeys = gpg.list_keys()
+            self.assertEqual(0, pubkeys.returncode, "Non-zero return code")
             self.assertFalse(fp1 in seckeys.fingerprints)
             self.assertFalse(fp1 in pubkeys.fingerprints)
             result = gpg.import_keys('foo')
@@ -1123,15 +1204,74 @@
 
     def test_recv_keys_no_server(self):
         result = self.gpg.recv_keys('foo.bar.baz', '92905378')
+        self.assertEqual(2, result.returncode, "Unexpected return code")
         self.assertEqual(result.summary(), '0 imported')
 
+    def test_invalid_fileobject(self):
+        # accidentally on purpose pass in a filename rather than the file 
itself
+        with self.assertRaises(TypeError) as ec:
+            self.gpg.decrypt_file('foobar.txt', passphrase='',
+                                  output='/tmp/decrypted.txt')
+        self.assertEqual(str(ec.exception), 'Not a valid file: foobar.txt')
+
+    def remove_all_existing_keys(self):
+        for root, dirs, files in os.walk(self.homedir):
+            for d in dirs:
+                p = os.path.join(root, d)
+                shutil.rmtree(p)
+            for f in files:
+                if f.endswith('.conf'):
+                    continue
+                p = os.path.join(root, f)
+                os.remove(p)
+
+    def test_no_such_key(self):
+        logger.debug("test_no_such_key begins")
+        key = self.generate_key("Barbara", "Brown", "beta.com")
+        barbara = key.fingerprint
+        gpg = self.gpg
+        if gnupg._py3k:
+            data = 'Hello, Andr??!'
+        else:
+            data = unicode('Hello, Andr??', gpg.encoding)
+        try:
+            data = data.encode(gpg.encoding)
+            encrypted = gpg.encrypt(data, barbara)
+            self.remove_all_existing_keys()
+            decrypted = gpg.decrypt(str(encrypted), passphrase='bbrown')
+            self.assertFalse(decrypted.ok)
+            expected = {'decryption failed', 'no secret key', 'no data was 
provided'}
+            self.assertIn(decrypted.status, expected)
+        finally:
+            logger.debug("test_no_such_key ends")
+
+    def test_get_recipients(self):
+        logger.debug("test_get_recipients begins")
+        try:
+            gpg = self.gpg
+            inp = gpg.gen_key_input(name_email='user1@test', passphrase='pp1')
+            key1 = gpg.gen_key(inp)
+            inp = gpg.gen_key_input(name_email='user2@test', passphrase='pp2')
+            key2 = gpg.gen_key(inp)
+            data = 'super secret'.encode(gpg.encoding)
+            edata = gpg.encrypt(data, (key1.fingerprint, key2.fingerprint))
+            logger.debug('Getting recipients')
+            ids = gpg.get_recipients(edata.data.decode(gpg.encoding))
+            self.assertGreater(len(ids), 0)
+            idlen = len(ids[0])
+            ids = set(ids)
+            expected = set((key1.fingerprint[-idlen:], 
key2.fingerprint[-idlen:]))
+            self.assertEqual(expected, ids)
+        finally:
+            logger.debug("test_get_recipients ends")
 
 TEST_GROUPS = {
     'sign' : set(['test_signature_verification',
                   'test_signature_file']),
     'crypt' : set(['test_encryption_and_decryption',
                    'test_file_encryption_and_decryption',
-                   'test_filenames_with_spaces', 'test_invalid_outputs']),
+                   'test_filenames_with_spaces', 'test_invalid_outputs',
+                   'test_no_such_key']),
     'key' : set(['test_deletion', 'test_import_and_export',
                  'test_list_keys_after_generation',
                  'test_list_signatures',
@@ -1144,7 +1284,7 @@
     'basic' : set(['test_environment', 'test_list_keys_initial',
                    'test_nogpg', 'test_make_args',
                    'test_quote_with_shell']),
-    'test': set(['test_invalid_outputs']),
+    'test': set(['test_get_recipients']),
 }
 
 def suite(args=None):

Reply via email to