summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2008-08-12 21:45:54 +0000
committerJason Gerard DeRose <jderose@redhat.com>2008-08-12 21:45:54 +0000
commit86405236325204cb5750ce79f674a5ab01114fa7 (patch)
tree3e53d9fa91d8414c5c6d834687eed3cf31f95713
parent9ac8a8b49984ec5727b9da4803ae7823a9e44e13 (diff)
downloadfreeipa-86405236325204cb5750ce79f674a5ab01114fa7.tar.gz
freeipa-86405236325204cb5750ce79f674a5ab01114fa7.tar.xz
freeipa-86405236325204cb5750ce79f674a5ab01114fa7.zip
119: Added ProxyTarget.implemented_by() classmethod; added corresponding unit tests
-rw-r--r--ipalib/plugable.py12
-rw-r--r--ipalib/tests/test_plugable.py43
2 files changed, 55 insertions, 0 deletions
diff --git a/ipalib/plugable.py b/ipalib/plugable.py
index b607f0fac..a91063e7c 100644
--- a/ipalib/plugable.py
+++ b/ipalib/plugable.py
@@ -135,6 +135,18 @@ class ProxyTarget(ReadOnly):
"must be str, frozenset, or have frozenset '__public__' attribute"
)
+ @classmethod
+ def implemented_by(cls, arg):
+ if inspect.isclass(arg):
+ subclass = arg
+ else:
+ subclass = arg.__class__
+ assert issubclass(subclass, cls), 'must be subclass of %r' % cls
+ for name in cls.__public__:
+ if not hasattr(subclass, name):
+ return False
+ return True
+
class Proxy(ReadOnly):
"""
diff --git a/ipalib/tests/test_plugable.py b/ipalib/tests/test_plugable.py
index b8242dce3..8ce986102 100644
--- a/ipalib/tests/test_plugable.py
+++ b/ipalib/tests/test_plugable.py
@@ -183,6 +183,49 @@ class test_ProxyTarget(ClassChecker):
assert ex.implements(any_object)
assert ex.implements(any_object())
+ def test_implemented_by(self):
+ """
+ Tests the `implemented_by` classmethod.
+ """
+ class base(self.cls):
+ __public__ = frozenset((
+ 'attr0',
+ 'attr1',
+ 'attr2',
+ ))
+
+ class okay(base):
+ def attr0(self):
+ pass
+ def __get_attr1(self):
+ assert False # Make sure property isn't accesed on instance
+ attr1 = property(__get_attr1)
+ attr2 = 'hello world'
+ another_attr = 'whatever'
+
+ class fail(base):
+ def __init__(self):
+ # Check that class, not instance is inspected:
+ self.attr2 = 'hello world'
+ def attr0(self):
+ pass
+ def __get_attr1(self):
+ assert False # Make sure property isn't accesed on instance
+ attr1 = property(__get_attr1)
+ another_attr = 'whatever'
+
+ # Test that AssertionError is raised trying to pass something not
+ # subclass nor instance of base:
+ raises(AssertionError, base.implemented_by, object)
+
+ # Test on subclass with needed attributes:
+ assert base.implemented_by(okay) is True
+ assert base.implemented_by(okay()) is True
+
+ # Test on subclass *without* needed attributes:
+ assert base.implemented_by(fail) is False
+ assert base.implemented_by(fail()) is False
+
class test_Proxy(ClassChecker):
"""