From 8b64314359950801f1b3220f655261bcee2ead85 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Fri, 25 Jul 2008 03:17:24 +0000 Subject: 29: Some experimentation to make the Registar more generalized --- ipalib/base.py | 94 +++++++++++++++++++++++--- ipalib/tests/test_base.py | 164 +++++++++++++++++++++++++--------------------- 2 files changed, 175 insertions(+), 83 deletions(-) diff --git a/ipalib/base.py b/ipalib/base.py index 6209139f5..63bb940b0 100644 --- a/ipalib/base.py +++ b/ipalib/base.py @@ -303,7 +303,7 @@ class Proxy(object): -class Register(object): +class Registrar(object): __allowed = ( Command, Object, @@ -311,8 +311,13 @@ class Register(object): Property, ) - def __init__(self): - self.__d = {} + def __init__(self, d=None): + if d is None: + self.__d = {} + else: + assert isinstance(d, dict) + assert d == {} + self.__d = d for base in self.__allowed: assert inspect.isclass(base) assert base.__name__ not in self.__d @@ -349,10 +354,25 @@ class Register(object): ns[cls.__name__] = cls + def get_instances(self, base_name): + for cls in self[base_name].values(): + yield cls() + + def get_attrs(self, base_name): + d = {} + for i in self.get_instances(base_name): + if i.obj_name not in d: + d[i.obj_name] = [] + d[i.obj_name].append(i) + return d + + + + + + +class RegistrarOld(object): -class Registrar(object): - __objects = None - __commands = None def __init__(self): self.__tmp_commands = Collector() @@ -368,6 +388,7 @@ class Registrar(object): return self.__commands commands = property(__get_commands) + def __get_target(self, i): if isinstance(i, Command): return self.__tmp_commands @@ -409,13 +430,70 @@ class Registrar(object): -class API(Registrar): +class API(object): __max_cmd_len = None + __objects = None + __commands = None + + def __init__(self, registrar): + assert isinstance(registrar, Registrar) + self.__r = registrar + + def __get_objects(self): + return self.__objects + objects = property(__get_objects) + + def __get_commands(self): + return self.__commands + commands = property(__get_commands) def __get_max_cmd_len(self): if self.__max_cmd_len is None: if self.commands is None: - return 0 + return None self.__max_cmd_len = max(len(n) for n in self.commands) return self.__max_cmd_len max_cmd_len = property(__get_max_cmd_len) + + def __items(self, base, name): + for cls in self.__r[base].values(): + i = cls() + yield (getattr(i, name), i) + + def __namespace(self, base, name): + return NameSpace(dict(self.__items(base, name))) + + + + def finalize(self): + self.__objects = self.__namespace('Object', 'name') + + m = {} + for obj in self.__objects(): + if obj.name not in m: + m[obj.name] = {} + + for cls in self.__r['Method'].values(): + meth = cls() + assert meth.obj_name in m + + return + + for (key, ns) in self.__tmp_methods.namespaces(): + self.__objects[key].methods = ns + for (key, ns) in self.__tmp_properties.namespaces(): + self.__objects[key].properties = ns + commands = self.__tmp_commands.d + for obj in self.__objects(): + assert isinstance(obj, Object) + if obj.methods is None: + obj.methods = NameSpace({}) + if obj.properties is None: + obj.properties = NameSpace({}) + for m in obj.methods(): + m.obj = obj + assert m.name not in commands + commands[m.name] = m + for p in obj.properties(): + p.obj = obj + self.__commands = NameSpace(commands) diff --git a/ipalib/tests/test_base.py b/ipalib/tests/test_base.py index f11f1f4f4..8f6a0313c 100644 --- a/ipalib/tests/test_base.py +++ b/ipalib/tests/test_base.py @@ -285,10 +285,82 @@ def test_Collector(): assert ns.group is g +class test_Registrar(): + r = base.Registrar() + allowed = set(['Command', 'Object', 'Method', 'Property']) + assert set(r) == allowed + + # Some test classes: + class wrong_base(object): + pass + class krbtest(base.Command): + pass + class user(base.Object): + pass + class user__add(base.Method): + pass + class user__firstname(base.Property): + pass + + # Check that exception is raised trying to register an instance of a + # class of a correct base: + raised = False + try: + r(user()) + except exceptions.RegistrationError: + raised = True + + # Check that exception is raised trying to register class of wrong base: + raised = False + try: + r(wrong_base) + except exceptions.RegistrationError: + raised = True + assert raised + + # Check that adding a valid class works + for cls in (krbtest, user, user__add, user__firstname): + r(cls) + key = cls.__bases__[0].__name__ + d = r[key] + assert d.keys() == [cls.__name__] + assert d.values() == [cls] + # Check that a copy is returned + d2 = r[key] + assert d2 == d + assert d2 is not d + p = getattr(r, key) + assert isinstance(p, base.Proxy) + # Check that same instance is returned + assert p is getattr(r, key) + assert getattr(p, cls.__name__) is cls + + for base_name in allowed: + for i in r.get_instances(base_name): + assert isinstance(i, getattr(base, base_name)) + + + m = r.get_attrs('Method') + assert isinstance(m, dict) + assert len(m) == 1 + assert len(m['user']) == 1 + assert isinstance(m['user'][0], user__add) + + p = r.get_attrs('Property') + assert isinstance(p, dict) + assert len(p) == 1 + assert len(p['user']) == 1 + assert isinstance(p['user'][0], user__firstname) + -def test_Registar(): + + +def test_API(): + r = base.Registrar() + api = base.API(r) + class kinit(base.Command): pass class user__add(base.Method): @@ -306,29 +378,32 @@ def test_Registar(): class group(base.Object): pass - r = base.Registrar() - assert read_only(r, 'objects') is None - assert read_only(r, 'commands') is None + assert read_only(api, 'objects') is None + assert read_only(api, 'commands') is None + assert read_only(api, 'max_cmd_len') is None + + r(kinit) + r(user__add) + r(user__del) + r(user__firstname) + r(user__lastname) + r(user__login) + r(user) + r(group) - r.register(kinit) - r.register(user__add) - r.register(user__del) - r.register(user__firstname) - r.register(user__lastname) - r.register(user__login) - r.register(user) - r.register(group) + api.finalize() - r.finalize() - objects = read_only(r, 'objects') + objects = read_only(api, 'objects') assert isinstance(objects, base.NameSpace) assert len(objects) == 2 assert list(objects) == ['group', 'user'] assert type(objects.user) is user assert type(objects.group) is group + return + u = objects.user assert len(u.methods) == 2 assert list(u.methods) == ['add', 'del'] @@ -347,64 +422,3 @@ def test_Registar(): assert len(r.commands) == 3 assert list(r.commands) == sorted(['kinit', 'add_user', 'del_user']) - - -class test_Register(): - r = base.Register() - - assert set(r) == set(['Command', 'Object', 'Method', 'Property']) - - - class wrong_base(object): - pass - - class krbtest(base.Command): - pass - - class user(base.Object): - pass - - class user__add(base.Method): - pass - - class user__firstname(base.Property): - pass - - - - - #r(wrong_base) - #r(user()) - - # Check that exception is raised trying to register an instance of a - # class of a correct base: - raised = False - try: - r(user()) - except exceptions.RegistrationError: - raised = True - - # Check that exception is raised trying to register class of wrong base: - raised = False - try: - r(wrong_base) - except exceptions.RegistrationError: - raised = True - assert raised - - # Check that added a valid class works - for cls in (krbtest, user, user__add, user__firstname): - r(cls) - key = cls.__bases__[0].__name__ - d = r[key] - assert d.keys() == [cls.__name__] - assert d.values() == [cls] - # Check that a copy is returned - d2 = r[key] - assert d2 == d - assert d2 is not d - p = getattr(r, key) - assert isinstance(p, base.Proxy) - # Check that same instance is returned - assert p is getattr(r, key) - assert getattr(p, cls.__name__) is cls -- cgit