54: Added plugable.Proxy._clone() method; fleshed out public.obj; updated unit tests; port ipa script

This commit is contained in:
Jason Gerard DeRose
2008-08-06 02:00:18 +00:00
parent f31f7813fe
commit c6f69e1c66
4 changed files with 147 additions and 17 deletions

75
ipa
View File

@@ -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 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 ''
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():
rows = []
for name in ['cmd', 'obj', 'mthd', 'prop']:
rows.extend(iter_ns(0, name))
pretty_print(rows)
if len(sys.argv) < 2:

View File

@@ -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):

View File

@@ -49,10 +49,45 @@ class cmd(plugable.Plugin):
print repr(self)
class obj(plugable.Plugin):
proxy = generic_proxy
class obj_proxy(plugable.Proxy):
__slots__ = (
'mthd',
'prop',
)
class obj(plugable.Plugin):
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(attr, cmd):
proxy = generic_proxy
class mthd_proxy(plugable.Proxy):
__slots__ = (
'__call__',
'get_doc',
) + ATTR_SLOTS
class mthd(attr, cmd):
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')

View File

@@ -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):