summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2008-08-08 22:45:09 +0000
committerJason Gerard DeRose <jderose@redhat.com>2008-08-08 22:45:09 +0000
commit5a1223e94367c4370a94f271ef7e087dbdb02615 (patch)
tree353cbc374d224c6136c23f59f37fba4c72b30a71 /ipalib
parent6f144fbaf062d9644af06fdd11020e3d5d349639 (diff)
downloadfreeipa-5a1223e94367c4370a94f271ef7e087dbdb02615.tar.gz
freeipa-5a1223e94367c4370a94f271ef7e087dbdb02615.tar.xz
freeipa-5a1223e94367c4370a94f271ef7e087dbdb02615.zip
90: Renamed plugable.Abstract to ProxyTarget, which now subclasses from ReadOnly; updated unit tests
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/plugable.py104
-rw-r--r--ipalib/tests/test_plugable.py155
2 files changed, 139 insertions, 120 deletions
diff --git a/ipalib/plugable.py b/ipalib/plugable.py
index 092e3bdd7..3f53fd4ad 100644
--- a/ipalib/plugable.py
+++ b/ipalib/plugable.py
@@ -43,7 +43,11 @@ class ReadOnly(object):
__locked = False
def __lock__(self):
- assert self.__locked is False
+ """
+ Puts this instance into a read-only state, after which attempting to
+ set or delete an attribute will raise AttributeError.
+ """
+ assert self.__locked is False, '__lock__() can only be called once'
self.__locked = True
def __setattr__(self, name, value):
@@ -69,7 +73,7 @@ class ReadOnly(object):
return object.__delattr__(self, name)
-class Abstract(object):
+class ProxyTarget(ReadOnly):
__public__ = frozenset()
@classmethod
@@ -86,52 +90,6 @@ class Abstract(object):
)
-class Plugin(object):
- """
- Base class for all plugins.
- """
-
- __api = None
-
- def __get_api(self):
- """
- Returns the plugable.API instance passed to Plugin.finalize(), or
- or returns None if finalize() has not yet been called.
- """
- return self.__api
- api = property(__get_api)
-
- def finalize(self, api):
- """
- After all the plugins are instantiated, the plugable.API calls this
- method, passing itself as the only argument. This is where plugins
- should check that other plugins they depend upon have actually be
- loaded.
- """
- assert self.__api is None, 'finalize() can only be called once'
- assert api is not None, 'finalize() argument cannot be None'
- self.__api = api
-
- def __get_name(self):
- """
- Returns the class name of this instance.
- """
- return self.__class__.__name__
- name = property(__get_name)
-
- def __repr__(self):
- """
- Returns a fully qualified <module><name> representation of the class.
- """
- return '%s.%s()' % (
- self.__class__.__module__,
- self.__class__.__name__
- )
-
-
-
-
-
class Proxy(ReadOnly):
__slots__ = (
'__base',
@@ -155,7 +113,6 @@ class Proxy(ReadOnly):
check_identifier(self.name)
self.__lock__()
-
def __iter__(self):
for name in sorted(self.__public__):
yield name
@@ -185,6 +142,55 @@ class Proxy(ReadOnly):
)
+class Plugin(object):
+ """
+ Base class for all plugins.
+ """
+
+ __api = None
+
+ def __get_api(self):
+ """
+ Returns the plugable.API instance passed to Plugin.finalize(), or
+ or returns None if finalize() has not yet been called.
+ """
+ return self.__api
+ api = property(__get_api)
+
+ def finalize(self, api):
+ """
+ After all the plugins are instantiated, the plugable.API calls this
+ method, passing itself as the only argument. This is where plugins
+ should check that other plugins they depend upon have actually be
+ loaded.
+ """
+ assert self.__api is None, 'finalize() can only be called once'
+ assert api is not None, 'finalize() argument cannot be None'
+ self.__api = api
+
+ def __get_name(self):
+ """
+ Returns the class name of this instance.
+ """
+ return self.__class__.__name__
+ name = property(__get_name)
+
+ def __repr__(self):
+ """
+ Returns a fully qualified <module><name> representation of the class.
+ """
+ return '%s.%s()' % (
+ self.__class__.__module__,
+ self.__class__.__name__
+ )
+
+
+
+
+
+
+
+
class NameSpace(ReadOnly):
"""
A read-only namespace of (key, value) pairs that can be accessed
diff --git a/ipalib/tests/test_plugable.py b/ipalib/tests/test_plugable.py
index 1f42aa85c..c3245e775 100644
--- a/ipalib/tests/test_plugable.py
+++ b/ipalib/tests/test_plugable.py
@@ -26,6 +26,33 @@ from tstutil import ClassChecker
from ipalib import plugable, errors
+def test_valid_identifier():
+ """
+ Test the plugable.valid_identifier function.
+ """
+ f = plugable.check_identifier
+ okay = [
+ 'user_add',
+ 'stuff2junk',
+ 'sixty9',
+ ]
+ nope = [
+ '_user_add',
+ '__user_add',
+ 'user_add_',
+ 'user_add__',
+ '_user_add_',
+ '__user_add__',
+ '60nine',
+ ]
+ for name in okay:
+ f(name)
+ for name in nope:
+ raises(errors.NameSpaceError, f, name)
+ for name in okay:
+ raises(errors.NameSpaceError, f, name.upper())
+
+
class test_ReadOnly(ClassChecker):
"""
Test the plugable.ReadOnly class
@@ -34,6 +61,7 @@ class test_ReadOnly(ClassChecker):
def test_class(self):
assert self.cls.__bases__ == (object,)
+ assert callable(self.cls.__lock__)
def test_when_unlocked(self):
"""
@@ -73,79 +101,64 @@ class test_ReadOnly(ClassChecker):
assert read_only(obj, 'an_attribute') == 'Hello world!'
+class test_ProxyTarget(ClassChecker):
+ """
+ Test the plugable.ProxyTarget class.
+ """
+ _cls = plugable.ProxyTarget
-def test_valid_identifier():
- f = plugable.check_identifier
- okay = [
- 'user_add',
- 'stuff2junk',
- 'sixty9',
- ]
- nope = [
- '_user_add',
- '__user_add',
- 'user_add_',
- 'user_add__',
- '_user_add_',
- '__user_add__',
- '60nine',
- ]
- for name in okay:
- f(name)
- for name in nope:
- raises(errors.NameSpaceError, f, name)
- for name in okay:
- raises(errors.NameSpaceError, f, name.upper())
-
-
-def test_Abstract():
- cls = plugable.Abstract
-
- class example(cls):
- __public__ = frozenset((
- 'some_method',
- 'some_property',
- ))
-
- # Test using str:
- assert example.implements('some_method')
- assert not example.implements('another_method')
-
- # Test using frozenset:
- assert example.implements(frozenset(['some_method']))
- assert not example.implements(
- frozenset(['some_method', 'another_method'])
- )
-
- # Test using another object/class with __public__ frozenset:
- assert example.implements(example)
- assert example().implements(example)
- assert example.implements(example())
- assert example().implements(example())
-
- class subset(cls):
- __public__ = frozenset((
- 'some_property',
- ))
- assert example.implements(subset)
- assert not subset.implements(example)
-
- class superset(cls):
- __public__ = frozenset((
- 'some_method',
- 'some_property',
- 'another_property',
- ))
- assert not example.implements(superset)
- assert superset.implements(example)
+ def test_class(self):
+ assert self.cls.__bases__ == (plugable.ReadOnly,)
+ assert self.cls.implements(frozenset())
- class any_object(object):
- __public__ = frozenset((
- 'some_method',
- 'some_property',
- ))
- assert example.implements(any_object)
- assert example.implements(any_object())
+ def test_implements(self):
+ """
+ Test the implements() classmethod
+ """
+ class example(self.cls):
+ __public__ = frozenset((
+ 'some_method',
+ 'some_property',
+ ))
+ class superset(self.cls):
+ __public__ = frozenset((
+ 'some_method',
+ 'some_property',
+ 'another_property',
+ ))
+ class subset(self.cls):
+ __public__ = frozenset((
+ 'some_property',
+ ))
+ class any_object(object):
+ __public__ = frozenset((
+ 'some_method',
+ 'some_property',
+ ))
+
+ for ex in (example, example()):
+ # Test using str:
+ assert ex.implements('some_method')
+ assert not ex.implements('another_method')
+
+ # Test using frozenset:
+ assert ex.implements(frozenset(['some_method']))
+ assert not ex.implements(
+ frozenset(['some_method', 'another_method'])
+ )
+
+ # Test using another object/class with __public__ frozenset:
+ assert ex.implements(example)
+ assert ex.implements(example())
+
+ assert ex.implements(subset)
+ assert not subset.implements(ex)
+
+ assert not ex.implements(superset)
+ assert superset.implements(ex)
+
+ assert ex.implements(any_object)
+ assert ex.implements(any_object())
def test_Plugin():