xotl.tools.params – Tools for managing function arguments

Tools for managing function arguments.

Process function arguments could be messy when a flexible schema is needed. With this module you can outline parameters schema using a smart way of processing actual arguments:

A parameter row (see ParamSchemeRow), allow several keywords IDs (one is required used as the final identifier for the actual argument). Also integer IDs expressing logical order for positional argument passing (negative values are for right-to-left indexing, like in sequences). Several values means several possibilities.

New in version 1.8.0.

Examples

In next example, the parameter key-named “stream” could be also passed as name “output”, must be a file, default value is stdout, and if passed as positional, could be the first or the last one.

>>> import sys
>>> from xotl.tools.values import file_coerce as is_file
>>> from xotl.tools.values import positive_int_coerce as positive_int
>>> from xotl.tools.params import ParamScheme as scheme, ParamSchemeRow as row
>>> sample_scheme = scheme(
...     row('stream', 0, -1, 'output', default=sys.stdout, coerce=is_file),
...     row('indent', 0, 1, default=1, coerce=positive_int),
...     row('width', 0, 1, 2, 'max_width', default=79, coerce=positive_int),
...     row('newline', default='\n', coerce=(str, )))

Some tests:

>>> def test(*args, **kwargs):
...     return sample_scheme(args, kwargs)

>>> test(4, 80)
{'indent': 4,
 'newline': '\n',
 'stream': <open file '<stdout>', mode 'w' at 0x7f927b32b150>,
 'width': 80}

>>> test(2, '80')    # Because positive int coercer use valid string values
{'indent': 2,
 'newline': '\n',
 'stream': <open file '<stdout>', mode 'w' at 0x7f927b32b150>,
 'width': 80}

>>> test(sys.stderr, 4, 80)
{'indent': 4,
 'newline': '\n',
 'stream': <open file '<stderr>', mode 'w' at 0x7f927b32b1e0>,
 'width': 80}

>>> test(4, sys.stderr, newline='\n\r')
{'indent': 4,
 'newline': '\n\r',
 'stream': <open file '<stderr>', mode 'w' at 0x7f927b32b1e0>,
 'width': 79}

>>> sample_scheme((4, 80), {'extra': 'extra param'}, strict=False)
{'extra': 'extra param',
 'indent': 4,
 'newline': '\n',
 'stream': <open file '<stdout>', mode 'w' at 0x7f3c6815c150>,
 'width': 80}

Another way of use this is through a ParamManager instance, using the actual arguments of a function to create it:

>>> def slugify(value, *args, **kwds):
...     from xotl.tools.params import ParamManager
...     getarg = ParamManager(args, kwds)
...     replacement = getarg('replacement', 0, default='-',
...                          coercers=(str, ))
...     invalid_chars = getarg('invalid_chars', 'invalid', 'invalids', 0,
...                            default='', coercers=_ascii)
...     valid_chars = getarg('valid_chars', 'valid', 'valids', 0,
...                          default='', coercers=_ascii)
...     # And so on.

Notice that each call has the same protocol than a parameter definition row (see ParamSchemeRow).

Module Members

xotl.tools.params.issue_9137(args)[source]

Parse arguments for methods, fixing issue 9137 (self ambiguity).

There are methods that expect ‘self’ as valid keyword argument, this is not possible if this name is used explicitly:

def update(self, *args, **kwds):
    ...

To solve this, declare the arguments as method_name(*args, **kwds), and in the function code:

self, args = issue_9137(args)
Returns:(self, remainder positional arguments in a tuple)

New in version 1.8.0.

xotl.tools.params.check_count(args, low, high=1048576, caller=None)[source]

Check the positional arguments actual count against constrains.

Parameters:
  • args – The args to check count, normally is a tuple, but an integer is directly accepted.
  • low – Integer expressing the minimum count allowed.
  • high – Integer expressing the maximum count allowed.
  • caller – Name of the function issuing the check, its value is used only for error reporting.

New in version 1.8.0.

xotl.tools.params.check_default(absent=Undefined)[source]

Get a default value passed as a last excess positional argument.

Parameters:absent – The value to be used by default if no one is given. Defaults to Undefined.

For example:

def get(self, name, *default):
    from xotl.tools.params import check_default, Undefined
    if name in self.inner_data:
        return self.inner_data[name]
    elif check_default()(*default) is not Undefined:
        return default[0]
    else:
        raise KeyError(name)

New in version 1.8.0.

xotl.tools.params.single(args, kwds)[source]

Return a true value only when a unique argument is given.

When needed, the most suitable result will be wrapped using the Maybe.

New in version 1.8.0.

xotl.tools.params.pop_keyword_arg(kwargs, names, default=Undefined)[source]

Return the value of a keyword argument.

Parameters:
  • kwargs – The mapping with passed keyword arguments.
  • names – Could be a single name, or a collection of names.
  • default – The default value to return if no value is found.

New in version 1.8.0.

xotl.tools.params.pop_keyword_values(kwargs, *names, **options)[source]

Return a list with all keyword argument values.

Parameters:
  • kwargs – The mapping with passed keyword arguments.
  • names – Each item will be a definition of keyword argument name to retrieve. Could be a string with a name, or a list of alternatives (aliases).
  • default – Keyword only option to define a default value to be used in place of not given arguments. If not given, it is used special value Undefined.
  • defaults

    A dictionary with default values per argument name. If none is given, use default.

    Note

    defaults trumps default.

    Warning

    For the case where a single name has several alternatives, you may choose any of the alternatives. If you pass several diverging defaults for different alternatives, the result is undefined.

  • ignore_error – By default, when there are remaining values in kwargs, after all names are processed, a TypeError is raised. If this keyword only option is True, this function returns normally.

Examples:

>>> pop_keyword_values({'b': 1}, 'a', 'b')
[Undefined, 1]

>>> kwargs = {'a': 1, 'b': 2, 'c': 3}
>>> try:
...     res = pop_keyword_values(kwargs, 'a', 'b')
... except TypeError as error:
...     res = error
>>> type(res)
TypeError

>>> kwargs = {'a': 1, 'b': 2, 'c': 3}
>>> options = dict(ignore_error=True, default=None)
>>> pop_keyword_values(kwargs, 'a', ('B', 'b'), **options)
[1, 2]

New in version 1.8.3.

class xotl.tools.params.ParamManager(args, kwds)[source]

Function parameters parser.

For example:

def wraps(*args, **kwargs):
    pm = ParamManager(args, kwargs)
    name = pm(0, 1, 'name', coerce=str)
    wrapped = pm(0, 1, 'wrapped', coerce=valid(callable))
    ...

When an instance of this class is called (__call__ operator), it is used the same protocol as when creating an instance of a parameter definition row (ParamSchemeRow).

See ParamScheme class as another way to define and validate schemes for extracting parameter values in a consistent way.

New in version 1.8.0.

__call__(*ids, **options)[source]

Get a parameter value.

__init__(args, kwds)[source]

Created with actual parameters of a client function.

remainder()[source]

Return not consumed values in a mapping.

class xotl.tools.params.ParamScheme(*rows)[source]

Full scheme for a ParamManager instance call.

This class receives a set of ParamSchemeRow instances and validate them as a whole.

New in version 1.8.0.

__call__(args, kwds, strict=True)[source]

Get a mapping with all resulting values.

If special value ‘none’ is used as ‘default’ option in a scheme-row, corresponding value isn’t returned in the mapping if the parameter value is missing.

__getitem__(idx)[source]

Obtain the scheme-row by a given index.

__iter__()[source]

Iterate over all defined scheme-rows.

__len__()[source]

The defined scheme-rows number.

defaults

Return a mapping with all valid default values.

class xotl.tools.params.ParamSchemeRow(*ids, **options)[source]

Scheme row for a ParamManager instance call.

This class validates identifiers and options at this level; these checks are not done in a call to get a parameter value.

Normally this class is used as part of a full ParamScheme composition.

Additionally to the options can be passed to ParamManager.__call__()’, this class can be instanced with:

Parameters:
  • ids – positional variable number arguments, could be aliases for keyword parameter passing, or integers for order (negative values are means right-to-left indexing, like in sequences);
  • key – an identifier to be used when the parameter is only positional or when none of the possible keyword aliases must be used as the primary-key;
  • default – keyword argument, value used if the parameter is absent;
  • coerce – check if a value is valid or not and convert to its definitive value; see xotl.tools.values module for more information.

New in version 1.8.0.

__call__(*args, **kwds)[source]

Execute a scheme-row using as argument a ParamManager instance.

The concept of ParamManager instance argument is a little tricky: when a variable number of arguments is used, if only one positional and is already an instance of ParamManager, it is directly used; if two, the first is a tuple and the second is a dict, these are considered the constructor arguments of the new instance; otherwise all arguments are used to build the new instance.

default

Returned value if parameter value is absent.

If not defined, special value none is returned.

key

The primary key for this scheme-row definition.

This concept is a little tricky (the first string identifier if some is given, if not then the first integer). This definition is useful, for example, to return remainder not consumed values after a scheme process is completed (see ParamManager.remainder() for more information).