mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 07:33:27 -06:00
23: Added base.Attribute class that determins the object association via class naming convention instead of through the _obj attribute
This commit is contained in:
parent
f3faaf2d29
commit
6f58880dcd
@ -21,6 +21,7 @@
|
||||
Base classes for plug-in architecture and generative API.
|
||||
"""
|
||||
|
||||
import re
|
||||
import inspect
|
||||
import exceptions
|
||||
|
||||
@ -141,6 +142,53 @@ class Named(object):
|
||||
name = property(__get_name)
|
||||
|
||||
|
||||
class AbstractCommand(object):
|
||||
def __call__(self):
|
||||
print 'You called %s()' % self.name
|
||||
|
||||
class Attribute(Named):
|
||||
__locked = False
|
||||
__obj = None
|
||||
|
||||
def __init__(self):
|
||||
m = re.match('^([a-z]+)__([a-z]+)$', self.__class__.__name__)
|
||||
assert m
|
||||
self.__obj_name = m.group(1)
|
||||
self.__attr_name = m.group(2)
|
||||
|
||||
def __get_obj(self):
|
||||
return self.__obj
|
||||
obj = property(__get_obj)
|
||||
|
||||
def set_obj(self, obj=None):
|
||||
if self.__locked:
|
||||
raise exceptions.TwiceSetError(self.__class__.__name__, 'obj')
|
||||
self.__locked = True
|
||||
if obj is None:
|
||||
return
|
||||
assert isinstance(obj, Object)
|
||||
assert obj.name == self.__obj_name
|
||||
self.__obj = obj
|
||||
|
||||
def __get_obj_name(self):
|
||||
return self.__obj_name
|
||||
obj_name = property(__get_obj_name)
|
||||
|
||||
def __get_attr_name(self):
|
||||
return self.__attr_name
|
||||
attr_name = property(__get_attr_name)
|
||||
|
||||
|
||||
class Method(AbstractCommand, Attribute):
|
||||
def _get_name(self):
|
||||
return '%s_%s' % (self.attr_name, self.obj_name)
|
||||
|
||||
|
||||
class Property(Attribute):
|
||||
def _get_name(self):
|
||||
return self.attr_name
|
||||
|
||||
|
||||
class WithObj(Named):
|
||||
_obj = None
|
||||
__obj = None
|
||||
@ -168,8 +216,7 @@ class Command(WithObj):
|
||||
def __call__(self):
|
||||
print 'You called %s()' % self.name
|
||||
|
||||
class Property(WithObj):
|
||||
pass
|
||||
|
||||
|
||||
class Object(Named):
|
||||
__commands = None
|
||||
@ -187,6 +234,31 @@ class Object(Named):
|
||||
commands = property(__get_commands, __set_commands)
|
||||
|
||||
|
||||
|
||||
|
||||
class AttributeCollector(object):
|
||||
def __init__(self):
|
||||
self.__d = {}
|
||||
|
||||
def __getitem__(self, key):
|
||||
assert isinstance(key, str)
|
||||
if key not in self.__d:
|
||||
self.__d[key] = {}
|
||||
return self.__d[key]
|
||||
|
||||
def __iter__(self):
|
||||
for key in self.__d:
|
||||
yield key
|
||||
|
||||
def add(self, i):
|
||||
assert isinstance(i, Attribute)
|
||||
self[i.obj_name][i.attr_name] = i
|
||||
|
||||
def namespaces(self):
|
||||
for key in self:
|
||||
yield (key, NameSpace(self[key]))
|
||||
|
||||
|
||||
class Collector(object):
|
||||
def __init__(self):
|
||||
self.__d = {}
|
||||
|
@ -191,6 +191,77 @@ def test_Named():
|
||||
assert i.name == 'named_class'
|
||||
|
||||
|
||||
def test_Attribute():
|
||||
class user__add(base.Attribute):
|
||||
pass
|
||||
i = user__add()
|
||||
assert i.obj_name == 'user'
|
||||
assert i.attr_name == 'add'
|
||||
assert read_only(i, 'obj') is None
|
||||
class user(base.Object):
|
||||
pass
|
||||
u = user()
|
||||
i.set_obj(u)
|
||||
assert read_only(i, 'obj') is u
|
||||
raised = False
|
||||
try:
|
||||
i.set_obj(u)
|
||||
except exceptions.TwiceSetError:
|
||||
raised = True
|
||||
assert raised
|
||||
|
||||
|
||||
def test_Method():
|
||||
class user__mod(base.Method):
|
||||
pass
|
||||
i = user__mod()
|
||||
assert isinstance(i, base.Attribute)
|
||||
assert isinstance(i, base.AbstractCommand)
|
||||
assert i.obj_name == 'user'
|
||||
assert i.attr_name == 'mod'
|
||||
assert i.name == 'mod_user'
|
||||
|
||||
|
||||
def test_Property():
|
||||
class user__firstname(base.Property):
|
||||
pass
|
||||
i = user__firstname()
|
||||
assert isinstance(i, base.Attribute)
|
||||
assert i.obj_name == 'user'
|
||||
assert i.attr_name == 'firstname'
|
||||
assert i.name == 'firstname'
|
||||
|
||||
|
||||
def test_AttributeCollector():
|
||||
class user__add(base.Attribute):
|
||||
pass
|
||||
class user__mod(base.Attribute):
|
||||
pass
|
||||
class group__add(base.Attribute):
|
||||
pass
|
||||
u_a = user__add()
|
||||
u_m = user__mod()
|
||||
g_a = group__add()
|
||||
|
||||
ac = base.AttributeCollector()
|
||||
ac.add(u_a)
|
||||
ac.add(u_m)
|
||||
ac.add(g_a)
|
||||
|
||||
assert set(ac) == set(['user', 'group'])
|
||||
|
||||
u = ac['user']
|
||||
assert set(u) == set(['add', 'mod'])
|
||||
assert set(u.values()) == set([u_a, u_m])
|
||||
|
||||
g = ac['group']
|
||||
assert g.keys() == ['add']
|
||||
assert g.values() == [g_a]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_WithObj():
|
||||
class some_object(base.Named):
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user