xotl.tools.values
– coercers (or checkers) for value types¶
Some generic coercers (or checkers) for value types.
This module coercion function are not related in any way to deprecated old python feature, are similar to a combination of object mold/check:
- Mold - Fit values to expected conventions.
- Check - These functions must return
nil
[1] special value to specify that expected fit is not possible.
[1] | We don’t use Python classic NotImplemented special value in order
to obtain False if the value is not coerced (nil ). |
A custom coercer could be created with closures, for an example see
create_int_range_coerce()
.
This module uses Unset
value to define absent -not being specified-
arguments.
Also contains sub-modules to obtain, convert and check values of common types.
New in version 1.7.0.
-
class
xotl.tools.values.
MetaCoercer
[source]¶ Meta-class for
coercer
.This meta-class allows that several objects are considered valid instances of
coercer
:- Functions decorated with
coercer
(used with its decorator facet). - Instances of any sub-class of
custom
. - Instances of
coercer
itself.
See the class declaration (
coercer
) for more information.- Functions decorated with
-
class
xotl.tools.values.
coercer
[source]¶ Special coercer class.
This class has several facets:
Pure type-checkers when a type or tuple of types are received as argument. See
istype
for more information.Return equivalent coercer from some special values:
- Any true value -> identity_coerce
- Any false or empty value -> void_coerce
A decorator for functions; when a function is given, decorate it to become a coercer. The mark itself is not enough, functions intended to be coercers must fulfills the protocol (not to produce exception and return
nil
on fails). For example:>>> @coercer ... def age_coerce(arg): ... res = int_coerce(arg) ... return res if t(res) and 0 < arg <= 120 else nil # TODO: Change next, don't use isinstance >>> isinstance(age_coerce, coercer) True
-
xotl.tools.values.
coercer_name
(arg, join=None)[source]¶ Get the name of a coercer.
Parameters: - arg – Coercer to get the name. Also processes collections (tuple, list, or set) of coercers. Any other value is considered invalid and raises an exception.
- join –
When a collection is used; if this argument is None a collection of names is returned, if not None then is used to join the items in a resulting string.
For example:
>>> coercer_name((int_coerce, float_coerce)) ('int', 'float') >>> coercer_name((int_coerce, float_coerce), join='-') 'int-float'
To obtain pretty-print tuples, use something like:
>>> coercer_name((int_coerce, float_coerce), ... join=lambda arg: '(%s)' % ', '.join(arg))
This function not only works with coercers, all objects that fulfill needed protocol to get names will also be valid.
-
class
xotl.tools.values.
combo
(*coercers)[source]¶ Represent a zip composition of several inner
coercers
.An instance of this class is constructed from a sequence of coercers and the its purpose is coerce a sequence of values. Return a sequence [2] where each item contains the i-th element from applying the i-th coercer to the i-th value from argument sequence:
coercers -> (coercer-1, coercer-2, ... ) values -> (value-1, value-2, ... ) combo(coercers)(values) -> (coercer-1(value-1), coercer-2(value-2), ...)
If any value is coerced invalid, the function returns
nil
and the combo’s instance variablescope
receives the duple(failed-value, failed-coercer)
.The returned sequence is truncated in length to the length of the shortest sequence (coercers or arguments).
If no coercer is given, all sequences are coerced as empty.
[2] The returned sequence is of the same type as the argument sequence if possible.
-
class
xotl.tools.values.
compose
(*args, **kwargs)[source]¶ Returns the composition of several inner
coercers
.compose(f1, ... fn)
is equivalent to f1(…(fn(arg))…)``.If no coercer is given return
identity_coerce()
.Could be considered an “AND” operator with some light differences because the nature of coercers: ordering the coercers is important when some can modify (adapt) original values.
If no value results in
coercers
, a default coercer could be given as a keyword argument;identity_coerce
is assumed if missing.
-
xotl.tools.values.
create_int_range_coerce
(min, max)[source]¶ Create a coercer to check integers between a range.
-
xotl.tools.values.
create_unique_member_coerce
(coerce, container)[source]¶ Useful to wrap member coercers when coercing containers.
Resulting coercer check that a member must be unique (not repeated) after it’s coerced.
For example:
>>> from xotl.tools.values import (mapping, create_unique_member_coerce, ... int_coerce, float_coerce) >>> sample = {'1': 1, 2.0: '3', 1.0 + 0j: '4.1'} >>> dc = mapping(int_coerce, float_coerce) >>> dc(dict(sample)) {1: 1.0, 2: 3.0} >>> dc = mapping(create_unique_member_coerce(int_coerce), float_coerce) >>> dc(dict(sample)) nil
-
class
xotl.tools.values.
custom
(*args, **kwargs)[source]¶ Base class for any custom coercer.
The field
inner
stores an internal data used for the custom coercer; could be a callable, an inner coercer, or a tuple of inner checkers if more than one is needed, …The field
scope
stores the exit (not regular) condition: the value that fails or -if needed- a tuple with (exit-value, exit-coercer) or (error-value, error). The exit condition is not always a failure, for example insome
it is the one that is valid among other inner coercers. To understand better this think on (AND, OR) operators a chain of ANDs exits with the first failure and a chains of ORs exits with the first success.All custom coercers are callable (must redefine
__call__()
) receiving one argument that must be coerced. For example:>>> def foobar(*args): ... coerce = pargs(int_coerce) ... return coerce(args)
This class has two protected fields (
_str_join
and_repr_join
) that are used to callcoercer_name()
in__str__()
and__repr__()
special methods.
-
xotl.tools.values.
float_coerce
(arg)[source]¶ Check if
arg
is a valid float.Other types are checked (string, int, complex).
-
xotl.tools.values.
full_identifier_coerce
(arg)[source]¶ Check if
arg
is a valid dotted Python identifier.See
identifier_coerce()
for what “validity” means.
-
xotl.tools.values.
identifier_coerce
(arg)[source]¶ Check if
arg
is a valid Python identifier.Note
Only Python 2’s version of valid identifier. This means that some Python 3 valid identifiers are not considered valid. This helps to keep things working the same in Python 2 and 3.
-
xotl.tools.values.
int_coerce
(arg)[source]¶ Check if
arg
is a valid integer.Other types are checked (string, float, complex).
-
class
xotl.tools.values.
istype
(*args, **kwargs)[source]¶ Pure type-checker.
It’s constructed from an argument valid for
types_tuple_coerce()
coercer.For example:
>>> int_coerce = istype(int) >>> int_coerce(1) 1 >>> int_coerce('1') nil >>> number_coerce = istype((int, float, complex)) >>> number_coerce(1.25) 1.25 >>> number_coerce('1.25') nil
-
class
xotl.tools.values.
iterable
(member_coerce, outer_coerce=True)[source]¶ Create a inner coercer that coerces an
iterable
member a member.See constructor for more information.
Return a list, or the same type of source iterable argument if possible.
For example:
>>> from xotl.tools.values import (iterable, int_coerce, ... create_unique_member_coerce) >>> sample = {'1', 1, '1.0'} >>> sc = iterable(int_coerce) >>> sc(set(sample)) == {1} True
See
mapping
for more details of this problem. The equivalent safe example is:>>> member_coerce = create_unique_member_coerce(int_coerce, sample) >>> sc = iterable(member_coerce) >>> sc(set(sample)) nil
when executed coerces
arg
(an iterable) member a member usingmember_coercer
. If any member coercion fails, the full execution also fails.There are three types of results when an instance is executed: (1) iterables that are coerced without modifications, (2) the modified ones but conserving its type, and (3) those that are returned in a list.
-
class
xotl.tools.values.
logical
(*args, **kwds)[source]¶ Represent Common Lisp two special values
t
andnil
.Include redefinition of
__call__()
to check values with special semantic:- When called as
t(arg)
, check ifarg
is notnil
returning a logical true: the same argument ifarg
is nil or a true boolean value, else returnt
. That means thatFalse
or0
are valid true values for Common Lisp but not for Python. - When called as
nil(arg)
, check ifarg
isnil
returningt
ornil
if not.
Constructor could receive a valid name (‘nil’ or ‘t’) or any other
boolean
instance.- When called as
-
class
xotl.tools.values.
mapping
(*args, **kwargs)[source]¶ Create a coercer to check dictionaries.
Receives two coercers, one for keys and one for values.
For example:
>>> from xotl.tools.values import (mapping, int_coerce, float_coerce, ... create_unique_member_coerce) >>> sample = {'1': 1, 2.0: '3', 1.0 + 0j: '4.1'} >>> dc = mapping(int_coerce, float_coerce) >>> dc(dict(sample)) == {1: 1.0, 2: 3.0} True
When coercing containers it’s probable that members become repeated after coercing them. This could be not desirable (mainly in sets and dictionaries). In those cases use
create_unique_member_coerce()
to wrap member coercer. For example:>>> key_coerce = create_unique_member_coerce(int_coerce, sample) >>> dc = mapping(key_coerce, float_coerce) >>> dc(dict(sample)) nil
Above problem is because it’s the same integer (same hash) coerced versions of
'1'
and1.0+0j
.This problem of objects of different types that have the same hash is a problem to use a example as below:
>>> {1: int, 1.0: float, 1+0j: complex} == {1: complex} True
-
xotl.tools.values.
names_coerce
(arg)[source]¶ Check
arg
as a tuple of valid object names (identifiers).If only one string is given, is returned as the only member of the resulting tuple.
-
xotl.tools.values.
number_coerce
(arg)[source]¶ Check if
arg
is a valid number (integer or float).Types that are checked (string, int, float, complex).
-
class
xotl.tools.values.
pargs
(arg_coerce)[source]¶ Create a inner coercer that check variable argument passing.
Created coercer closure must always receives an argument that is an valid iterable with all members coerced properly with the argument of this outer creator function.
If the inner closure argument has only a member and this one is not properly coerced but it’s an iterabled with all members that coerced well, this member will be the assumed iterable instead the original argument.
In the following example:
>>> from xotl.tools.values import (iterable, int_coerce) >>> def foobar(*args): ... coerce = iterable(int_coerce) ... return coerce(args) >>> args = (1, 2.0, '3.0') >>> foobar(*args) (1, 2, 3) >>> foobar(args) nil
An example using
pargs
>>> from xotl.tools.values import (pargs, int_coerce) >>> def foobar(*args): ... # Below, "coercer" receives the returned "inner" ... coerce = pargs(int_coerce) ... return coerce(args) >>> args = (1, 2.0, '3.0') >>> foobar(*args) (1, 2, 3) >>> foobar(args) (1, 2, 3)
The second form is an example of the real utility of this coercer closure: if by error a sequence is passed as it to a function that expect a variable number of argument, this coercer fixes it.
Instance variable
scope
stores the last processed invalid argument.When executed, usually
arg
is a tuple received by a function as*args
form.When executed, returns a tuple, or the same type of source iterable argument if possible.
See
xotl.tools.params
for a more specialized and full function arguments conformer.See
combo
for a combined coercer that validate each member with a separate member coercer.
-
class
xotl.tools.values.
safe
(func)[source]¶ Uses a function (or callable) in a safe way.
Receives a coercer that expects only one argument and returns another value.
If the returned value is a
boolean
(maybe the coercer is a predicate), it’s converted to alogical
instance.The wrapped coercer is called in a safe way (inside try/except); if an exception is raised the coercer returns
nil
and the error is saved in the instance attributescope
.
-
xotl.tools.values.
sized_coerce
(arg)[source]¶ Return a valid sized iterable from
arg
.If
arg
is iterable but not sized, is converted to a list. For example:>>> sized_coerce(i for i in range(1, 10, 2)) [1, 3, 5, 7, 9] >>> s = {1, 2, 3} >>> sized_coerce(s) is s True
-
class
xotl.tools.values.
some
(*args, **kwargs)[source]¶ Represent OR composition of several inner
coercers
.compose(f1, ... fn)
is equivalent to f1(arg) or f2(arg) … fn(arg)`` in the sense “the first notnil
”.If no coercer is given return
void_coerce()
.
-
class
xotl.tools.values.
typecast
(*args, **kwargs)[source]¶ A type-caster.
It’s constructed from an argument valid for
types_tuple_coerce()
coercer. Similar toistype
but try to convert the value if needed.For example:
>>> int_cast = typecast(int) >>> int_cast('1') 1 >>> int_cast('1x') nil
-
xotl.tools.values.
types_tuple_coerce
(arg)[source]¶ Check if
arg
is valid forisinstance
orissubclass
2nd argument.Type checkers are any class, a type or tuple of types. For example:
>>> types_tuple_coerce(object) == (object,) True >>> types_tuple_coerce((int, float)) == (int, float) true >>> types_tuple_coerce('not-a-type') is nil True
See
type_coerce
for more information.
Contents: