summaryrefslogtreecommitdiffstats
path: root/ipalib/plugable.py
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2008-08-06 21:54:56 +0000
committerJason Gerard DeRose <jderose@redhat.com>2008-08-06 21:54:56 +0000
commitf13f1226b4b798fd901ece6b9a37c06ca25c3c2e (patch)
tree3f3f10033a937f0817bf3f7f9370975290991872 /ipalib/plugable.py
parent0c7769473ca01facdcb1768868bfd053e726fddf (diff)
downloadfreeipa.git-f13f1226b4b798fd901ece6b9a37c06ca25c3c2e.tar.gz
freeipa.git-f13f1226b4b798fd901ece6b9a37c06ca25c3c2e.tar.xz
freeipa.git-f13f1226b4b798fd901ece6b9a37c06ca25c3c2e.zip
65: Finished simplified Proxy2 class; updated unit tests
Diffstat (limited to 'ipalib/plugable.py')
-rw-r--r--ipalib/plugable.py80
1 files changed, 23 insertions, 57 deletions
diff --git a/ipalib/plugable.py b/ipalib/plugable.py
index 43dd50ca..bf0f52b4 100644
--- a/ipalib/plugable.py
+++ b/ipalib/plugable.py
@@ -25,29 +25,6 @@ import re
import inspect
import errors
-EXPORT_FLAG = 'exported'
-
-def export(obj):
- """
- Decorator function to set the 'exported' flag to True.
-
- For example:
-
- >>> @export
- >>> def my_func():
- >>> pass
- >>> assert my_func.exported is True
- """
- assert not hasattr(obj, EXPORT_FLAG)
- setattr(obj, EXPORT_FLAG, True)
- return obj
-
-def is_exported(obj):
- """
- Returns True if `obj` as an 'exported' attribute that is True.
- """
- return getattr(obj, EXPORT_FLAG, False) is True
-
def to_cli(name):
"""
@@ -192,53 +169,42 @@ class Proxy(ReadOnly):
class Proxy2(ReadOnly):
- def __init__(self, base, target):
+ __slots__ = (
+ 'base',
+ 'name',
+ '__target',
+ )
+ def __init__(self, base, target, name_attr='name'):
if not inspect.isclass(base):
raise TypeError('arg1 must be a class, got %r' % base)
if not isinstance(target, base):
raise ValueError('arg2 must be instance of arg1, got %r' % target)
object.__setattr__(self, 'base', base)
object.__setattr__(self, '_Proxy2__target', target)
- object.__setattr__(self, '_Proxy2__props', dict())
-
- names = [] # The names of exported attributes
- # This matches implied property fget methods like '_get_user'
- r = re.compile(r'^_get_([a-z][_a-z0-9]*[a-z0-9])$')
- for name in dir(base):
- match = r.match(name)
- if name != '__call__' and name.startswith('_') and not match:
- continue # Skip '_SomeClass__private', etc.
- base_attr = getattr(base, name)
- if is_exported(base_attr):
- target_attr = getattr(target, name)
- assert not hasattr(self, name), 'Cannot override %r' % name
- object.__setattr__(self, name, target_attr)
- names.append(name)
- if match:
- assert callable(target_attr), '%s must be callable' % name
- key = match.group(1)
- assert not hasattr(self, key), (
- '%r cannot override %r' % (name, key)
- )
- self.__props[key] = target_attr
- object.__setattr__(self, '_Proxy2__names', tuple(names))
- def __call__(self, *args, **kw):
- return self.__target(*args, **kw)
+ # Check base.public
+ assert type(self.base.public) is frozenset
+
+ # Check name
+ object.__setattr__(self, 'name', getattr(target, name_attr))
+ check_identifier(self.name)
def __iter__(self):
- for name in self.__names:
+ for name in sorted(self.base.public):
yield name
- def __getattr__(self, name):
- if name in self.__props:
- return self.__props[name]()
- raise AttributeError(name)
-
-
-
+ def __getitem__(self, key):
+ if key in self.base.public:
+ return getattr(self.__target, key)
+ raise KeyError('no proxy attribute %r' % key)
+ def __getattr__(self, name):
+ if name in self.base.public:
+ return getattr(self.__target, name)
+ raise AttributeError('no proxy attribute %r' % name)
+ def __call__(self, *args, **kw):
+ return self['__call__'](*args, **kw)
class NameSpace(ReadOnly):