summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2008-08-06 02:00:18 +0000
committerJason Gerard DeRose <jderose@redhat.com>2008-08-06 02:00:18 +0000
commitc6f69e1c66b86f8f375a3c561922a42fdc0b1afb (patch)
treee4e3ea28fb18234a4ec5d841913a8eb38f7eb7c2
parentf31f7813febf0665a072d474166ea883bc7365dc (diff)
downloadfreeipa-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-xipa75
-rw-r--r--ipalib/plugable.py26
-rw-r--r--ipalib/public.py52
-rw-r--r--ipalib/tests/test_plugable.py7
4 files changed, 145 insertions, 15 deletions
diff --git a/ipa b/ipa
index a4bc2cb07..77bdb6ce7 100755
--- a/ipa
+++ b/ipa
@@ -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 a8996cf26..6e6c6973b 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 e5e579f1e..941011b6f 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 a9a6492d1..6949fdeb1 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):