summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/plugable.py26
-rw-r--r--ipalib/public.py52
-rw-r--r--ipalib/tests/test_plugable.py7
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):