python: Make 'get_key' more idiomatic.

* lang/python/pyme/core.py (Context.get_key): Raise errors.KeyNotFound
if the key is not found.  This error is both a KeyError for idiomatic
error handling as well as a GPGMEError so we don't break existing
code.
* lang/python/pyme/errors.py (KeyNotFound): New class.
* lang/python/tests/support.py (no_such_key): New variable.
* lang/python/tests/t-keylist.py: Test the new behavior.

Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
Justus Winter 2016-10-13 13:13:23 +02:00
parent 1e6073ffa9
commit f526d0e22e
No known key found for this signature in database
GPG Key ID: DD1A52F9DA8C9020
4 changed files with 52 additions and 4 deletions

View File

@ -680,11 +680,19 @@ class Context(GpgmeWrapper):
-- the matching key
Raises:
KeyError -- if the key was not found
GPGMEError -- as signaled by the underlying library
"""
ptr = gpgme.new_gpgme_key_t_p()
errorcheck(gpgme.gpgme_get_key(self.wrapped, fpr, ptr, secret))
try:
errorcheck(gpgme.gpgme_get_key(self.wrapped, fpr, ptr, secret))
except errors.GPGMEError as e:
if e.getcode() == errors.EOF:
raise errors.KeyNotFound(fpr)
raise e
key = gpgme.gpgme_key_t_p_value(ptr)
gpgme.delete_gpgme_key_t_p(ptr)
assert key

View File

@ -21,10 +21,12 @@ del absolute_import, print_function, unicode_literals
from . import gpgme
from . import util
util.process_constants('GPG_ERR_', globals())
# To appease static analysis tools, we define some constants here.
# They are overwritten with the proper values by process_constants.
NO_ERROR = None
EOF = None
# To appease static analysis tools, we define some constants here:
NO_ERROR = 0
util.process_constants('GPG_ERR_', globals())
class PymeError(Exception):
pass
@ -58,6 +60,20 @@ def errorcheck(retval, extradata = None):
if retval:
raise GPGMEError(retval, extradata)
class KeyNotFound(GPGMEError, KeyError):
"""Raised if a key was not found
GPGME indicates this condition with EOF, which is not very
idiomatic. We raise this error that is both a GPGMEError
indicating EOF, and a KeyError.
"""
def __init__(self, keystr):
self.keystr = keystr
GPGMEError.__init__(self, EOF)
def __str__(self):
return self.keystr
# These errors are raised in the idiomatic interface code.
class EncryptionError(PymeError):

View File

@ -27,6 +27,7 @@ alpha = "A0FF4590BB6122EDEF6E3C542D727CC768697734"
bob = "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2"
encrypt_only = "F52770D5C4DB41408D918C9F920572769B9FE19C"
sign_only = "7CCA20CCDE5394CEE71C9F0BFED153F12F18F45D"
no_such_key = "A" * 40
def make_filename(name):
return os.path.join(os.environ['top_srcdir'], 'tests', 'gpg', name)

View File

@ -20,6 +20,7 @@
from __future__ import absolute_import, print_function, unicode_literals
del absolute_import, print_function, unicode_literals
import pyme
from pyme import core, constants
import support
@ -244,3 +245,25 @@ for i, key in enumerate(c.keylist()):
if misc_check:
misc_check (uids[0][0], key)
# check get_key()
with pyme.Context() as c:
c.get_key(support.alpha)
c.get_key(support.alpha, secret=True)
c.get_key(support.bob)
try:
c.get_key(support.bob, secret=True)
except KeyError:
pass
else:
assert False, "Expected KeyError"
# Legacy error
try:
c.get_key(support.no_such_key)
except pyme.errors.GPGMEError:
pass
else:
assert False, "Expected GPGMEError"