summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/public.py66
-rw-r--r--ipalib/tests/test_public.py64
2 files changed, 86 insertions, 44 deletions
diff --git a/ipalib/public.py b/ipalib/public.py
index d97f519b..564f6c8b 100644
--- a/ipalib/public.py
+++ b/ipalib/public.py
@@ -168,8 +168,8 @@ class Command(plugable.Plugin):
'get_doc',
'options',
))
- __options = None
- option_classes = tuple()
+ __Option = None
+ options = tuple()
def get_doc(self, _):
"""
@@ -183,26 +183,18 @@ class Command(plugable.Plugin):
raise NotImplementedError('%s.get_doc()' % self.name)
def get_options(self):
- """
- Returns iterable with option proxy objects used to create the option
- NameSpace when __get_option() is called.
- """
- for cls in self.option_classes:
- assert inspect.isclass(cls)
- o = cls()
- o.__lock__()
- yield plugable.PluginProxy(Option, o)
+ return self.options
- def __get_options(self):
+ def __get_Option(self):
"""
- Returns the NameSpace containing the option proxy objects.
+ Returns the NameSpace containing the Option instances.
"""
- if self.__options is None:
- object.__setattr__(self, '_Command__options',
+ if self.__Option is None:
+ object.__setattr__(self, '_Command__Option',
plugable.NameSpace(self.get_options()),
)
- return self.__options
- options = property(__get_options)
+ return self.__Option
+ Option = property(__get_Option)
def normalize_iter(self, kw):
for (key, value) in kw.items():
@@ -332,11 +324,11 @@ class Method(Attribute, Command):
__public__ = Attribute.__public__.union(Command.__public__)
def get_options(self):
- for proxy in Command.get_options(self):
- yield proxy
+ for option in Command.options:
+ yield option
if self.obj is not None and self.obj.Property is not None:
for proxy in self.obj.Property():
- yield proxy
+ yield proxy.option
class Property(Attribute):
@@ -346,19 +338,27 @@ class Property(Attribute):
'type',
)).union(Attribute.__public__)
- def __get_rules(self):
- """
- Returns the tuple of rule methods used for input validation. This
- tuple is lazily initialized the first time the property is accessed.
- """
- if self.__rules is None:
- rules = tuple(sorted(
- self.__rules_iter(),
- key=lambda f: getattr(f, '__name__'),
- ))
- object.__setattr__(self, '_Property__rules', rules)
- return self.__rules
- rules = property(__get_rules)
+ type = ipa_types.Unicode()
+ required = False
+ multivalue = False
+ default = None
+ default_from = None
+ normalize = None
+
+ def __init__(self):
+ super(Property, self).__init__()
+ self.rules = tuple(sorted(
+ self.__rules_iter(),
+ key=lambda f: getattr(f, '__name__'),
+ ))
+ self.option = Option(self.attr_name, self.doc, self.type,
+ required=self.required,
+ multivalue=self.multivalue,
+ default=self.default,
+ default_from=self.default_from,
+ rules=self.rules,
+ normalize=self.normalize,
+ )
def __rules_iter(self):
"""
diff --git a/ipalib/tests/test_public.py b/ipalib/tests/test_public.py
index 2e732179..3000cfe3 100644
--- a/ipalib/tests/test_public.py
+++ b/ipalib/tests/test_public.py
@@ -304,30 +304,47 @@ class test_Option(ClassChecker):
assert o.get_values() == values
-class test_Command(ClassChecker):
+class dont_Command(ClassChecker):
"""
Tests the `public.Command` class.
"""
_cls = public.Command
def get_subcls(self):
- class my_option(public.Option):
- def normalize(self, value):
- return super(my_option, self).normalize(value).lower()
- @public.rule
- def my_rule(self, value):
+ class Rule(object):
+ def __init__(self, name):
+ self.name = name
+
+ def __call__(self, value):
if value != self.name:
return 'must equal %r' % self.name
- default_from = public.DefaultFrom(
- lambda arg: arg, 'default_from'
- )
+
+ default_from = public.DefaultFrom(
+ lambda arg: arg,
+ 'default_from'
+ )
+ normalize = lambda value: value.lower()
+ type_ = ipa_types.Unicode()
class option0(my_option):
pass
class option1(my_option):
required = True
+
class example(self.cls):
- option_classes = (option0, option1)
+ options = (
+ public.Option('option0', 'Option zero', type_,
+ normalize=normalize,
+ default_from=default_from,
+ rules=(Rule('option0'),)
+ ),
+ public.Option('option1', 'Option one', type_,
+ normalize=normalize,
+ default_from=default_from,
+ rules=(Rule('option1'),),
+ required=True,
+ ),
+ )
return example
def test_class(self):
@@ -550,7 +567,7 @@ class test_Attribute(ClassChecker):
assert read_only(o, 'obj') is user_obj
-class test_Method(ClassChecker):
+class dont_Method(ClassChecker):
"""
Tests the `public.Method` class.
"""
@@ -608,5 +625,30 @@ class test_Property(ClassChecker):
"""
_cls = public.Property
+ def get_subcls(self):
+ class user_givenname(self.cls):
+ 'User first name'
+
+ @public.rule
+ def rule0_lowercase(self, value):
+ if not value.islower():
+ return 'Must be lowercase'
+ return user_givenname
+
def test_class(self):
assert self.cls.__bases__ == (public.Attribute,)
+ assert isinstance(self.cls.type, ipa_types.Unicode)
+ assert self.cls.required is False
+ assert self.cls.multivalue is False
+ assert self.cls.default is None
+ assert self.cls.default_from is None
+ assert self.cls.normalize is None
+
+ def test_init(self):
+ o = self.subcls()
+ assert len(o.rules) == 1
+ assert o.rules[0].__name__ == 'rule0_lowercase'
+ opt = o.option
+ assert isinstance(opt, public.Option)
+ assert opt.name == 'givenname'
+ assert opt.doc == 'User first name'