diff options
Diffstat (limited to 'ipalib')
-rw-r--r-- | ipalib/plugable.py | 26 | ||||
-rw-r--r-- | ipalib/public.py | 52 | ||||
-rw-r--r-- | ipalib/tests/test_plugable.py | 7 |
3 files changed, 80 insertions, 5 deletions
diff --git a/ipalib/plugable.py b/ipalib/plugable.py index a8996cf2..6e6c6973 100644 --- a/ipalib/plugable.py +++ b/ipalib/plugable.py @@ -145,8 +145,8 @@ class Proxy(ReadOnly): assert isinstance(proxy_name, str) object.__setattr__(self, '_Proxy__obj', obj) object.__setattr__(self, 'name', proxy_name) - for name in self.__slots__: - object.__setattr__(self, name, getattr(obj, name)) + #for name in self.__slots__: + # object.__setattr__(self, name, getattr(obj, name)) def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self.__obj) @@ -154,6 +154,18 @@ class Proxy(ReadOnly): def __str__(self): return to_cli(self.name) + def _clone(self, new_name): + return self.__class__(self.__obj, proxy_name=new_name) + + def __getattr__(self, name): + if name in self.__slots__: + return getattr(self.__obj, name) + raise AttributeError('attribute %r not in %s.__slots__' % ( + name, + self.__class__.__name__ + ) + ) + class NameSpace(ReadOnly): """ @@ -161,6 +173,8 @@ class NameSpace(ReadOnly): both as instance attributes and as dictionary items. """ + __max_len = None + def __init__(self, items): """ `items` should be an iterable providing the members of this @@ -214,6 +228,14 @@ class NameSpace(ReadOnly): return self.__hname[key] raise KeyError('NameSpace has no item for key %r' % key) + def __call__(self): + if self.__max_len is None: + ml = max(len(k) for k in self.__pname) + object.__setattr__(self, '_NameSpace__max_len', ml) + return self.__max_len + + + class Registrar(object): def __init__(self, *allowed): diff --git a/ipalib/public.py b/ipalib/public.py index e5e579f1..941011b6 100644 --- a/ipalib/public.py +++ b/ipalib/public.py @@ -49,10 +49,45 @@ class cmd(plugable.Plugin): print repr(self) +class obj_proxy(plugable.Proxy): + __slots__ = ( + 'mthd', + 'prop', + ) + + class obj(plugable.Plugin): - proxy = generic_proxy + proxy = obj_proxy + __mthd = None + __prop = None + + def __get_mthd(self): + return self.__mthd + mthd = property(__get_mthd) + + def __get_prop(self): + return self.__prop + prop = property(__get_prop) + + def finalize(self, api): + super(obj, self).finalize(api) + self.__mthd = self.__create_ns('mthd') + self.__prop = self.__create_ns('prop') + + def __create_ns(self, name): + return plugable.NameSpace(self.__filter(name)) + + def __filter(self, name): + for i in getattr(self.api, name): + if i.obj_name == self.name: + yield i._clone(i.attr_name) +ATTR_SLOTS = ( + 'obj_name', + 'attr_name', +) + class attr(plugable.Plugin): __obj = None proxy = generic_proxy @@ -84,12 +119,23 @@ class attr(plugable.Plugin): self.__obj = api.obj[self.obj_name] +class mthd_proxy(plugable.Proxy): + __slots__ = ( + '__call__', + 'get_doc', + ) + ATTR_SLOTS + class mthd(attr, cmd): - proxy = generic_proxy + proxy = mthd_proxy +class prop_proxy(plugable.Proxy): + __slots__ = ( + 'get_doc', + ) + ATTR_SLOTS + class prop(attr): - proxy = generic_proxy + proxy = prop_proxy def get_doc(self, _): return _('prop doc') diff --git a/ipalib/tests/test_plugable.py b/ipalib/tests/test_plugable.py index a9a6492d..6949fdeb 100644 --- a/ipalib/tests/test_plugable.py +++ b/ipalib/tests/test_plugable.py @@ -161,6 +161,13 @@ def test_Proxy(): assert getattr(p, name)(1) == 3 assert read_only(p, name)(1) == 3 + # Test cloning: + i = do_something() + p = CommandProxy(i) + c = p._clone('do_a_thing') + assert isinstance(c, CommandProxy) + assert c.name == 'do_a_thing' + def test_Registrar(): class Base1(object): |