Files
PGPy-3_13_patch/pgpy/decorators.py
2014-09-30 18:38:10 -07:00

114 lines
3.5 KiB
Python

""" decorators.py
"""
import contextlib
import functools
import warnings
from singledispatch import singledispatch
from .errors import PGPError
def classproperty(fget):
class ClassProperty(object):
def __init__(self, fget):
self.fget = fget
self.__doc__ = fget.__doc__
def __get__(self, cls, owner):
return self.fget(owner)
def __set__(self, obj, value): # pragma: no cover
raise AttributeError("Read-only attribute")
def __delete__(self, obj): # pragma: no cover
raise AttributeError("Read-only attribute")
return ClassProperty(fget)
def sdmethod(meth):
sd = singledispatch(meth)
def wrapper(obj, *args, **kwargs):
return sd.dispatch(args[0].__class__)(obj, *args, **kwargs)
wrapper.register = sd.register
wrapper.dispatch = sd.dispatch
wrapper.registry = sd.registry
wrapper._clear_cache = sd._clear_cache
functools.update_wrapper(wrapper, meth)
return wrapper
def sdproperty(fget):
def defset(obj, val): # pragma: no cover
raise TypeError(str(val.__class__))
class _(property):
def register(self, cls=None, fset=None):
return self.fset.register(cls, fset)
def setter(self, fset):
self.register(object, fset)
return type(self)(self.fget, self.fset, self.fdel, self.__doc__)
return _(fget, sdmethod(defset))
class KeyAction(object):
def __init__(self, *usage, **conditions):
super(KeyAction, self).__init__()
self.flags = set(usage)
self.conditions = conditions
@contextlib.contextmanager
def usage(self, key):
def _preiter(first, iterable):
yield first
for item in iterable:
yield item
em = {}
em['keyid'] = key.fingerprint.keyid
em['flags'] = ', '.join(flag.name for flag in self.flags)
for _key in _preiter(key, key.subkeys.values()):
if self.flags & _key.usageflags:
break
else: # pragma: no cover
raise PGPError("Key {keyid:s} does not have the required usage flag {flags:s}".format(**em))
if _key is not key:
em['subkeyid'] = _key.fingerprint.keyid
warnings.warn("Key {keyid:s} does not have the required usage flag {flags:s}; using subkey {subkeyid:s}"
"".format(**em), stacklevel=4)
yield _key
def __call__(self, action):
@functools.wraps(action)
def _action(key, *args, **kwargs):
ignore_usage = kwargs.pop('ignore_usage', False)
if ignore_usage:
for prop, expected in self.conditions.items():
if getattr(key, prop) != expected: # pragma: no cover
raise PGPError("Expected: {prop:s} == {eval:s}. Got: {got:s}"
"".format(prop=prop, eval=str(expected), got=str(getattr(key, prop))))
# do the thing
return action(key, *args, **kwargs)
with self.usage(key) as _key:
# check properties
for prop, expected in self.conditions.items():
if getattr(_key, prop) != expected:
raise PGPError("Expected: {prop:s} == {eval:s}. Got: {got:s}"
"".format(prop=prop, eval=str(expected), got=str(getattr(key, prop))))
# do the thing
return action(_key, *args, **kwargs)
return _action