From 33db9fee6017c0777f4fc5da8b020aefd714e387 Mon Sep 17 00:00:00 2001 From: Jason Gerard DeRose Date: Tue, 13 Jan 2009 00:27:06 -0700 Subject: New Param: ported create_param() function and unit tests --- ipalib/parameter.py | 52 ++++++++++++++++++++++++++++++++++--- tests/test_ipalib/test_parameter.py | 32 +++++++++++++++++++++++ 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/ipalib/parameter.py b/ipalib/parameter.py index b5adf58f8..1c88d286f 100644 --- a/ipalib/parameter.py +++ b/ipalib/parameter.py @@ -142,10 +142,10 @@ class DefaultFrom(ReadOnly): def parse_param_spec(spec): """ - Parse a param spec into to (name, kw). + Parse shorthand ``spec`` into to ``(name, kw)``. - The ``spec`` string determines the param name, whether the param is - required, and whether the param is multivalue according the following + The ``spec`` string determines the parameter name, whether the parameter is + required, and whether the parameter is multivalue according the following syntax: ====== ===== ======== ========== @@ -605,12 +605,16 @@ class Int(Param): """ + type = int + class Float(Param): """ """ + type = float + class Bytes(Param): """ @@ -752,3 +756,45 @@ class Str(Bytes): name=name, length=self.length, ) + + +def create_param(spec): + """ + Create an `Str` instance from the shorthand ``spec``. + + This function allows you to create `Str` parameters (the most common) from + a convenient shorthand that defines the parameter name, whether it is + required, and whether it is multivalue. (For a definition shorthand + syntax, see the `parse_param_spec()` function.) + + If ``spec`` is an ``str`` instance, it will be used to create a new `Str` + parameter, which will be returned. For example: + + >>> s = create_param('hometown?') + >>> s + Str('hometown?') + >>> (s.name, s.required, s.multivalue) + ('hometown', False, False) + + On the other hand, if ``spec`` is already a `Param` instance, it is + returned unchanged. For example: + + >>> b = Bytes('cert') + >>> create_param(b) is b + True + + As a plugin author, you will not call this function directly (which would + be no more convenient than simply creating the `Str` instance). Instead, + `frontend.Command` will call it for you when it evaluates the + ``takes_args`` and ``takes_options`` attributes, and `frontend.Object` + will call it for you when it evaluates the ``takes_params`` attribute. + + :param spec: A spec string or a `Param` instance. + """ + if isinstance(spec, Param): + return spec + if type(spec) is not str: + raise TypeError( + TYPE_ERROR % ('spec', (str, Param), spec, type(spec)) + ) + return Str(spec) diff --git a/tests/test_ipalib/test_parameter.py b/tests/test_ipalib/test_parameter.py index 7f1b11ea4..8abba496a 100644 --- a/tests/test_ipalib/test_parameter.py +++ b/tests/test_ipalib/test_parameter.py @@ -748,3 +748,35 @@ class test_Str(ClassChecker): assert dummy.message == \ '%(name)s must be exactly %(length)d characters' dummy = dummy_ugettext(translation) + + +def test_create_param(): + """ + Test the `ipalib.parameter.create_param` function. + """ + f = parameter.create_param + + # Test that Param instances are returned unchanged: + params = ( + parameter.Param('one?'), + parameter.Int('two+'), + parameter.Str('three*'), + parameter.Bytes('four'), + ) + for p in params: + assert f(p) is p + + # Test that the spec creates an Str instance: + for spec in ('one?', 'two+', 'three*', 'four'): + (name, kw) = parameter.parse_param_spec(spec) + p = f(spec) + assert p.param_spec is spec + assert p.name == name + assert p.required is kw['required'] + assert p.multivalue is kw['multivalue'] + + # Test that TypeError is raised when spec is neither a Param nor a str: + for spec in (u'one', 42, parameter.Param, parameter.Str): + e = raises(TypeError, f, spec) + assert str(e) == \ + TYPE_ERROR % ('spec', (str, parameter.Param), spec, type(spec)) -- cgit