diff --git a/ipalib/public.py b/ipalib/public.py index f6bad7ec9..071d905d3 100644 --- a/ipalib/public.py +++ b/ipalib/public.py @@ -39,6 +39,10 @@ def is_rule(obj): class option(object): + """ + The option class represents a kw argument from a command. + """ + __public__ = frozenset(( 'normalize', 'validate', @@ -64,6 +68,21 @@ class option(object): self.__class__.__name__, value, self.type ) + def validate(self, value): + """ + Calls each validation rule and if any rule fails, raises RuleError, + which is a subclass of ValidationError. + """ + for rule in self.rules: + msg = rule(value) + if msg is not None: + raise errors.RuleError( + self.__class__.__name__, + value, + rule, + msg, + ) + def __get_rules(self): """ Returns the tuple of rule methods used for input validation. This @@ -91,21 +110,12 @@ class option(object): if is_rule(attr): yield attr - def validate(self, value): - for rule in self.rules: - msg = rule(value) - if msg is not None: - raise errors.RuleError( - self.__class__.__name__, - value, - rule, - msg, - ) - - - - - + def default(self, **kw): + """ + Returns a default or auto-completed value for this option. If no + default is available, this method should return None. + """ + return None class cmd(plugable.Plugin): @@ -146,7 +156,6 @@ class cmd(plugable.Plugin): return self.__opt opt = property(__get_opt) - def normalize_iter(self, kw): for (key, value) in kw.items(): if key in self.options: @@ -164,9 +173,12 @@ class cmd(plugable.Plugin): if key in self.options: self.options.validate(value) - - - + def default(self, **kw): + for opt in self.options: + if opt.name not in kw: + value = opt.default(**kw) + if value is not None: + kw[opt.name] = value def __call__(self, **kw): (args, kw) = self.normalize(*args, **kw) diff --git a/ipalib/tests/test_public.py b/ipalib/tests/test_public.py index 3ef7ad087..f05a9c31b 100644 --- a/ipalib/tests/test_public.py +++ b/ipalib/tests/test_public.py @@ -93,32 +93,9 @@ class test_option(): #assert issubclass(cls, plugable.ReadOnly) assert type(cls.rules) is property - def test_rules(self): - """ - Test the rules property. - """ - o = self.sub()() - assert len(o.rules) == 3 - def get_rule(i): - return getattr(o, 'rule_%d' % i) - rules = tuple(get_rule(i) for i in xrange(3)) - assert o.rules == rules - - def test_validation(self): - """ - Test the validation method. - """ - o = self.sub()() - o.validate(9) - for i in xrange(3): - e = raises(errors.RuleError, o.validate, i) - assert e.error == 'cannot be %d' % i - def test_normalize(self): sub = self.sub() - i = sub() - # Test with values that can't be converted: nope = ( '7.0' @@ -145,6 +122,30 @@ class test_option(): for val in okay: assert i.normalize(val) == 7 + def test_rules(self): + """ + Test the rules property. + """ + o = self.sub()() + assert len(o.rules) == 3 + def get_rule(i): + return getattr(o, 'rule_%d' % i) + rules = tuple(get_rule(i) for i in xrange(3)) + assert o.rules == rules + + def test_validation(self): + """ + Test the validation method. + """ + o = self.sub()() + o.validate(9) + for i in xrange(3): + e = raises(errors.RuleError, o.validate, i) + assert e.error == 'cannot be %d' % i + assert e.value == i + + + def test_cmd(): cls = public.cmd assert issubclass(cls, plugable.Plugin)