diff options
author | Paul Kehrer <paul.l.kehrer@gmail.com> | 2014-10-31 13:14:39 -0500 |
---|---|---|
committer | Paul Kehrer <paul.l.kehrer@gmail.com> | 2014-10-31 13:14:39 -0500 |
commit | eeb81c52648404dad2c5122ec0319334ebc48e5c (patch) | |
tree | db724961a2a99d4a3df4a338bfe6cf212b111af3 /cryptography | |
parent | 87f8a23d8e182164d820c99d6de66c8771f30ae5 (diff) | |
parent | eb29be13ca8f1c2d2d0138ee22339f64511f4011 (diff) | |
download | cryptography-eeb81c52648404dad2c5122ec0319334ebc48e5c.tar.gz cryptography-eeb81c52648404dad2c5122ec0319334ebc48e5c.tar.bz2 cryptography-eeb81c52648404dad2c5122ec0319334ebc48e5c.zip |
Merge pull request #1424 from alex/verify-interfaces
Fixes #1024 -- a utility function for checking an implementor against an ABC
Diffstat (limited to 'cryptography')
-rw-r--r-- | cryptography/utils.py | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/cryptography/utils.py b/cryptography/utils.py index 1deb3d1d..03c8c0e8 100644 --- a/cryptography/utils.py +++ b/cryptography/utils.py @@ -13,6 +13,8 @@ from __future__ import absolute_import, division, print_function +import abc +import inspect import sys @@ -21,6 +23,7 @@ DeprecatedIn06 = DeprecationWarning def register_interface(iface): def register_decorator(klass): + verify_interface(iface, klass) iface.register(klass) return klass return register_decorator @@ -30,6 +33,30 @@ def read_only_property(name): return property(lambda self: getattr(self, name)) +class InterfaceNotImplemented(Exception): + pass + + +def verify_interface(iface, klass): + for method in iface.__abstractmethods__: + if not hasattr(klass, method): + raise InterfaceNotImplemented( + "{0} is missing a {1!r} method".format(klass, method) + ) + if isinstance(getattr(iface, method), abc.abstractproperty): + # Can't properly verify these yet. + continue + spec = inspect.getargspec(getattr(iface, method)) + actual = inspect.getargspec(getattr(klass, method)) + if spec != actual: + raise InterfaceNotImplemented( + "{0}.{1}'s signature differs from the expected. Expected: " + "{2!r}. Received: {3!r}".format( + klass, method, spec, actual + ) + ) + + def bit_length(x): if sys.version_info >= (2, 7): return x.bit_length() |