New Param: all docstring examples now pass under doctests

This commit is contained in:
Jason Gerard DeRose
2009-01-14 20:36:17 -07:00
parent cd3508bace
commit 0327b83899
4 changed files with 55 additions and 31 deletions

View File

@@ -405,13 +405,13 @@ Defining arguments and options for your command
You can define a command that will accept specific arguments and options. You can define a command that will accept specific arguments and options.
For example: For example:
>>> from ipalib import Param >>> from ipalib import Str
>>> class nudge(Command): >>> class nudge(Command):
... """Takes one argument, one option""" ... """Takes one argument, one option"""
... ...
... takes_args = ['programmer'] ... takes_args = ['programmer']
... ...
... takes_options = [Param('stuff', default=u'documentation')] ... takes_options = [Str('stuff', default=u'documentation')]
... ...
... def execute(self, programmer, **kw): ... def execute(self, programmer, **kw):
... return '%s, go write more %s!' % (programmer, kw['stuff']) ... return '%s, go write more %s!' % (programmer, kw['stuff'])
@@ -420,9 +420,9 @@ For example:
>>> api.env.in_server = True >>> api.env.in_server = True
>>> api.register(nudge) >>> api.register(nudge)
>>> api.finalize() >>> api.finalize()
>>> api.Command.nudge('Jason') >>> api.Command.nudge(u'Jason')
u'Jason, go write more documentation!' u'Jason, go write more documentation!'
>>> api.Command.nudge('Jason', stuff='unit tests') >>> api.Command.nudge(u'Jason', stuff=u'unit tests')
u'Jason, go write more unit tests!' u'Jason, go write more unit tests!'
The ``args`` and ``options`` attributes are `plugable.NameSpace` instances The ``args`` and ``options`` attributes are `plugable.NameSpace` instances
@@ -431,11 +431,11 @@ containing a command's arguments and options, respectively, as you can see:
>>> list(api.Command.nudge.args) # Iterates through argument names >>> list(api.Command.nudge.args) # Iterates through argument names
['programmer'] ['programmer']
>>> api.Command.nudge.args.programmer >>> api.Command.nudge.args.programmer
Param('programmer') Str('programmer')
>>> list(api.Command.nudge.options) # Iterates through option names >>> list(api.Command.nudge.options) # Iterates through option names
['stuff'] ['stuff']
>>> api.Command.nudge.options.stuff >>> api.Command.nudge.options.stuff
Param('stuff', default=u'documentation') Str('stuff', default=u'documentation')
>>> api.Command.nudge.options.stuff.default >>> api.Command.nudge.options.stuff.default
u'documentation' u'documentation'
@@ -451,7 +451,7 @@ NameSpace(<2 members>, sort=False)
When calling a command, its positional arguments can also be provided as When calling a command, its positional arguments can also be provided as
keyword arguments, and in any order. For example: keyword arguments, and in any order. For example:
>>> api.Command.nudge(stuff='lines of code', programmer='Jason') >>> api.Command.nudge(stuff=u'lines of code', programmer=u'Jason')
u'Jason, go write more lines of code!' u'Jason, go write more lines of code!'
When a command plugin is called, the values supplied for its parameters are When a command plugin is called, the values supplied for its parameters are
@@ -465,20 +465,20 @@ here is a quick teaser:
... takes_options = [ ... takes_options = [
... 'first', ... 'first',
... 'last', ... 'last',
... Param('nick', ... Str('nick',
... normalize=lambda value: value.lower(), ... normalizer=lambda value: value.lower(),
... default_from=lambda first, last: first[0] + last, ... default_from=lambda first, last: first[0] + last,
... ), ... ),
... Param('points', type=Int(), default=0), ... Int('points', default=0),
... ] ... ]
... ...
>>> cp = create_player() >>> cp = create_player()
>>> cp.finalize() >>> cp.finalize()
>>> cp.convert(points=" 1000 ") >>> cp.convert(points=u' 1000 ')
{'points': 1000} {'points': 1000}
>>> cp.normalize(nick=u'NickName') >>> cp.normalize(nick=u'NickName')
{'nick': u'nickname'} {'nick': u'nickname'}
>>> cp.get_default(first='Jason', last='DeRose') >>> cp.get_default(first=u'Jason', last=u'DeRose')
{'nick': u'jderose', 'points': 0} {'nick': u'jderose', 'points': 0}
For the full details on the parameter system, see the For the full details on the parameter system, see the
@@ -575,7 +575,7 @@ For example, say we setup a command like this:
... ...
... takes_args = ['key?'] ... takes_args = ['key?']
... ...
... takes_options = [Param('reverse', type=Bool(), default=False)] ... takes_options = [Flag('reverse')]
... ...
... def execute(self, key, **options): ... def execute(self, key, **options):
... items = dict( ... items = dict(
@@ -643,7 +643,7 @@ show-items:
Lastly, providing a ``key`` would result in the following: Lastly, providing a ``key`` would result in the following:
>>> result = api.Command.show_items('city') >>> result = api.Command.show_items(u'city')
>>> api.Command.show_items.output_for_cli(textui, result, 'city', reverse=False) >>> api.Command.show_items.output_for_cli(textui, result, 'city', reverse=False)
city = 'Berlin' city = 'Berlin'

View File

@@ -27,8 +27,7 @@ import plugable
from plugable import lock, check_name from plugable import lock, check_name
import errors import errors
from errors import check_type, check_isinstance, raise_TypeError from errors import check_type, check_isinstance, raise_TypeError
import parameters from parameters import create_param, Param, Str, Flag
from parameters import create_param, Param
from util import make_repr from util import make_repr
@@ -53,7 +52,8 @@ class Command(plugable.Plugin):
Plugins that subclass from Command are registered in the ``api.Command`` Plugins that subclass from Command are registered in the ``api.Command``
namespace. For example: namespace. For example:
>>> api = plugable.API(Command) >>> from ipalib import create_api
>>> api = create_api()
>>> class my_command(Command): >>> class my_command(Command):
... pass ... pass
... ...
@@ -161,14 +161,14 @@ class Command(plugable.Plugin):
>>> class my_command(Command): >>> class my_command(Command):
... takes_options = ( ... takes_options = (
... Param('first', normalize=lambda value: value.lower()), ... Param('first', normalizer=lambda value: value.lower()),
... Param('last'), ... Param('last'),
... ) ... )
... ...
>>> c = my_command() >>> c = my_command()
>>> c.finalize() >>> c.finalize()
>>> c.normalize(first='JOHN', last='DOE') >>> c.normalize(first=u'JOHN', last=u'DOE')
{'last': 'DOE', 'first': 'john'} {'last': u'DOE', 'first': u'john'}
""" """
return dict( return dict(
(k, self.params[k].normalize(v)) for (k, v) in kw.iteritems() (k, self.params[k].normalize(v)) for (k, v) in kw.iteritems()
@@ -178,10 +178,10 @@ class Command(plugable.Plugin):
""" """
Return a dictionary of values converted to correct type. Return a dictionary of values converted to correct type.
>>> from ipalib import ipa_types >>> from ipalib import Int
>>> class my_command(Command): >>> class my_command(Command):
... takes_args = ( ... takes_args = (
... Param('one', type=ipa_types.Int()), ... Int('one'),
... 'two', ... 'two',
... ) ... )
... ...
@@ -200,14 +200,15 @@ class Command(plugable.Plugin):
For example: For example:
>>> from ipalib import Str
>>> class my_command(Command): >>> class my_command(Command):
... takes_args = [Param('color', default='Red')] ... takes_args = [Str('color', default=u'Red')]
... ...
>>> c = my_command() >>> c = my_command()
>>> c.finalize() >>> c.finalize()
>>> c.get_default() >>> c.get_default()
{'color': 'Red'} {'color': u'Red'}
>>> c.get_default(color='Yellow') >>> c.get_default(color=u'Yellow')
{} {}
""" """
return dict(self.__get_default_iter(kw)) return dict(self.__get_default_iter(kw))
@@ -363,7 +364,7 @@ class LocalOrRemote(Command):
""" """
takes_options = ( takes_options = (
parameters.Flag('server?', Flag('server?',
doc='Forward to server instead of running locally', doc='Forward to server instead of running locally',
), ),
) )
@@ -562,7 +563,8 @@ class Method(Attribute, Command):
say you created a `Method` plugin and its corresponding `Object` plugin say you created a `Method` plugin and its corresponding `Object` plugin
like this: like this:
>>> api = plugable.API(Command, Object, Method, Property) >>> from ipalib import create_api
>>> api = create_api()
>>> class user_add(Method): >>> class user_add(Method):
... def run(self): ... def run(self):
... return 'Added the user!' ... return 'Added the user!'
@@ -617,7 +619,7 @@ class Property(Attribute):
'type', 'type',
)).union(Attribute.__public__) )).union(Attribute.__public__)
klass = parameters.Str klass = Str
default = None default = None
default_from = None default_from = None
normalizer = None normalizer = None

View File

@@ -490,6 +490,7 @@ class Param(ReadOnly):
:param value: A proposed value for this parameter. :param value: A proposed value for this parameter.
""" """
# FIXME: this should be after 'if value is None:'
if self.query: if self.query:
return return
if value is None: if value is None:
@@ -695,7 +696,28 @@ class Flag(Bool):
super(Flag, self).__init__(name, *rules, **kw) super(Flag, self).__init__(name, *rules, **kw)
class Int(Param): class Number(Param):
"""
Base class for the `Int` and `Float` parameters.
"""
def _convert_scalar(self, value, index=None):
"""
Convert a single scalar value.
"""
if type(value) is self.type:
return value
if type(value) in (unicode, int, float):
try:
return self.type(value)
except ValueError:
pass
raise ConversionError(name=self.name, index=index,
error=ugettext(self.type_error),
)
class Int(Number):
""" """
A parameter for integer values (stored in the ``int`` type). A parameter for integer values (stored in the ``int`` type).
""" """
@@ -704,7 +726,7 @@ class Int(Param):
type_error = _('must be an integer') type_error = _('must be an integer')
class Float(Param): class Float(Number):
""" """
A parameter for floating-point values (stored in the ``float`` type). A parameter for floating-point values (stored in the ``float`` type).
""" """

View File

@@ -10,7 +10,7 @@ do
if [[ -f $executable ]]; then if [[ -f $executable ]]; then
echo "[ $name: Starting tests... ]" echo "[ $name: Starting tests... ]"
((runs += 1)) ((runs += 1))
if $executable /usr/bin/nosetests -v if $executable /usr/bin/nosetests -v --with-doctest
then then
echo "[ $name: Tests OK ]" echo "[ $name: Tests OK ]"
else else