diff options
author | Jason Gerard DeRose <jderose@redhat.com> | 2008-08-06 02:00:18 +0000 |
---|---|---|
committer | Jason Gerard DeRose <jderose@redhat.com> | 2008-08-06 02:00:18 +0000 |
commit | c6f69e1c66b86f8f375a3c561922a42fdc0b1afb (patch) | |
tree | e4e3ea28fb18234a4ec5d841913a8eb38f7eb7c2 | |
parent | f31f7813febf0665a072d474166ea883bc7365dc (diff) | |
download | freeipa-c6f69e1c66b86f8f375a3c561922a42fdc0b1afb.tar.gz freeipa-c6f69e1c66b86f8f375a3c561922a42fdc0b1afb.tar.xz freeipa-c6f69e1c66b86f8f375a3c561922a42fdc0b1afb.zip |
54: Added plugable.Proxy._clone() method; fleshed out public.obj; updated unit tests; port ipa script
-rwxr-xr-x | ipa | 75 | ||||
-rw-r--r-- | ipalib/plugable.py | 26 | ||||
-rw-r--r-- | ipalib/public.py | 52 | ||||
-rw-r--r-- | ipalib/tests/test_plugable.py | 7 |
4 files changed, 145 insertions, 15 deletions
@@ -28,12 +28,48 @@ Just proof of concept stuff in here right now. import sys from ipalib.startup import api +TAB_WIDTH = 2 + def _(msg): """ Dummy gettext function for testing. """ return msg +class row(object): + def __init__(self, tab, c1, c2=None): + assert type(tab) is int + assert type(c1) is str + assert type(c2) is str or c2 is None + self.tab = tab + self.c1 = c1 + self.c2 = c2 + + def __len__(self): + return len(str(self.c1)) + + def pretty_print(self, ljust): + tab = ' ' * (self.tab * TAB_WIDTH) + if self.c2 is None: + print '%s%s' % (tab, self.c1) + else: + print '%s%s %s' % (tab, self.c1.ljust(ljust), self.c2) + +def pretty_print(rows): + def at_tab(tab): + for r in rows: + if r.tab == tab: + yield len(r) + + _max_len = {} + def max_len(tab): + if tab not in _max_len: + _max_len[tab] = max(at_tab(tab)) + return _max_len[tab] + + for r in rows: + r.pretty_print(max_len(r.tab)) + def print_commands(): print 'Commands:' @@ -44,17 +80,36 @@ def print_commands(): def print_help(cmd): print 'Help on %s' % cmd + + + + + + + +def iter_ns(tab, name): + ns = getattr(api, name) + yield row( + tab, + '%d %s:' % (len(ns), name) + ) + for i in ns: + yield row( + tab + 1, + i.name, + repr(i) + ) + + + def print_api(): - def print_ns(name): - ns = getattr(api, name) - print '%d %s:' % (len(ns), name) - m = max(len(i.name) for i in ns) - for i in ns: - print ' %s %r' % (i.name.ljust(m), i) - - for n in ['cmd', 'obj', 'mthd', 'prop']: - print_ns(n) - print '' + rows = [] + for name in ['cmd', 'obj', 'mthd', 'prop']: + rows.extend(iter_ns(0, name)) + + pretty_print(rows) + + if len(sys.argv) < 2: 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): |