trafaret — Validation atoms definition

exception trafaret.DataError(error=None, name=None, value=<object object>, trafaret=None)

Error with data preserve error can be a message or None if error raised in childs data can be anything

class trafaret.Trafaret

Base class for trafarets, provides only one method for trafaret validation failure reporting

append(other)

Appends new converter to list.

check(value, context=None)

Common logic. In subclasses you need to implement check_value or check_and_return.

class trafaret.Call(fn)
>>> def validator(value):
...     if value != "foo":
...         return DataError("I want only foo!")
...     return 'foo'
...
>>> trafaret = Call(validator)
>>> trafaret
<Call(validator)>
>>> trafaret.check("foo")
'foo'
>>> extract_error(trafaret, "bar")
'I want only foo!'
class trafaret.Or(*trafarets)
>>> nullString = Or(String, Null)
>>> nullString
<Or(<String>, <Null>)>
>>> nullString.check(None)
>>> nullString.check("test")
'test'
>>> extract_error(nullString, 1)
{0: 'value is not a string', 1: 'value should be None'}
class trafaret.And(trafaret, other)

Will work over trafarets sequentially

class trafaret.Forward
>>> node = Forward()
>>> node << Dict(name=String, children=List[node])
>>> node
<Forward(<Dict(children=<List(<recur>)>, name=<String>)>)>
>>> node.check({"name": "foo", "children": []}) == {'children': [], 'name': 'foo'}
True
>>> extract_error(node, {"name": "foo", "children": [1]})
{'children': {0: 'value is not a dict'}}
>>> node.check({"name": "foo", "children": [                         {"name": "bar", "children": []}                      ]}) == {'children': [{'children': [], 'name': 'bar'}], 'name': 'foo'}
True
>>> empty_node = Forward()
>>> empty_node
<Forward(None)>
>>> extract_error(empty_node, 'something')
'trafaret not set yet'
class trafaret.Any
>>> Any()
<Any>
>>> (Any() >> ignore).check(object())
class trafaret.Null
>>> Null()
<Null>
>>> Null().check(None)
>>> extract_error(Null(), 1)
'value should be None'
class trafaret.List(trafaret, min_length=0, max_length=None)
>>> List(Int)
<List(<Int>)>
>>> List(Int, min_length=1)
<List(min_length=1 | <Int>)>
>>> List(Int, min_length=1, max_length=10)
<List(min_length=1, max_length=10 | <Int>)>
>>> extract_error(List(Int), 1)
'value is not a list'
>>> List(Int).check([1, 2, 3])
[1, 2, 3]
>>> List(String).check(["foo", "bar", "spam"])
['foo', 'bar', 'spam']
>>> extract_error(List(Int), [1, 2, 1 + 3j])
{2: 'value is not int'}
>>> List(Int, min_length=1).check([1, 2, 3])
[1, 2, 3]
>>> extract_error(List(Int, min_length=1), [])
'list length is less than 1'
>>> List(Int, max_length=2).check([1, 2])
[1, 2]
>>> extract_error(List(Int, max_length=2), [1, 2, 3])
'list length is greater than 2'
>>> extract_error(List(Int), ["a"])
{0: "value can't be converted to int"}
class trafaret.Key(name, default=<object object>, optional=False, to_name=None, trafaret=None)

Helper class for Dict.

It gets name, and provides method extract(data) that extract key value from data through mapping get method. Key __call__ method yields (key name, Maybe(DataError), [touched keys]) triples.

You can redefine get_data(data, default) method in subclassed Key if you want to use something other then .get(...) method.

Like this for the aiohttp MultiDict:

class MDKey(t.Key):
    def get_data(data, default):
        return data.get_all(self.name, default)
class trafaret.Dict(*args, **trafarets)
>>> trafaret = Dict(foo=Int, bar=String) >> ignore
>>> trafaret.check({"foo": 1, "bar": "spam"})
>>> extract_error(trafaret, {"foo": 1, "bar": 2})
{'bar': 'value is not a string'}
>>> extract_error(trafaret, {"foo": 1})
{'bar': 'is required'}
>>> extract_error(trafaret, {"foo": 1, "bar": "spam", "eggs": None})
{'eggs': 'eggs is not allowed key'}
>>> trafaret.allow_extra("eggs")
<Dict(extras=(eggs) | bar=<String>, foo=<Int>)>
>>> trafaret.check({"foo": 1, "bar": "spam", "eggs": None})
>>> trafaret.check({"foo": 1, "bar": "spam"})
>>> extract_error(trafaret, {"foo": 1, "bar": "spam", "ham": 100})
{'ham': 'ham is not allowed key'}
>>> trafaret.allow_extra("*")
<Dict(any, extras=(eggs) | bar=<String>, foo=<Int>)>
>>> trafaret.check({"foo": 1, "bar": "spam", "ham": 100})
>>> trafaret.check({"foo": 1, "bar": "spam", "ham": 100, "baz": None})
>>> extract_error(trafaret, {"foo": 1, "ham": 100, "baz": None})
{'bar': 'is required'}
>>> trafaret = Dict({Key('bar', optional=True): String}, foo=Int)
>>> trafaret.allow_extra("*")
<Dict(any | bar=<String>, foo=<Int>)>
>>> _dd(trafaret.check({"foo": 1, "ham": 100, "baz": None}))
"{'baz': None, 'foo': 1, 'ham': 100}"
>>> _dd(extract_error(trafaret, {"bar": 1, "ham": 100, "baz": None}))
"{'bar': 'value is not a string', 'foo': 'is required'}"
>>> extract_error(trafaret, {"foo": 1, "bar": 1, "ham": 100, "baz": None})
{'bar': 'value is not a string'}
>>> trafaret = Dict({Key('bar', default='nyanya') >> 'baz': String}, foo=Int)
>>> _dd(trafaret.check({'foo': 4}))
"{'baz': 'nyanya', 'foo': 4}"
>>> _ = trafaret.ignore_extra('fooz')
>>> _dd(trafaret.check({'foo': 4, 'fooz': 5}))
"{'baz': 'nyanya', 'foo': 4}"
>>> _ = trafaret.ignore_extra('*')
>>> _dd(trafaret.check({'foo': 4, 'foor': 5}))
"{'baz': 'nyanya', 'foo': 4}"
merge(other)

Extends one Dict with other Dict Key`s or Key`s list, or dict instance supposed for Dict

class trafaret.Enum(*variants)
>>> trafaret = Enum("foo", "bar", 1) >> ignore
>>> trafaret
<Enum('foo', 'bar', 1)>
>>> trafaret.check("foo")
>>> trafaret.check(1)
>>> extract_error(trafaret, 2)
"value doesn't match any variant"
class trafaret.Tuple(*args)

Tuple checker can be used to check fixed tuples, like (Int, Int, String).

>>> t = Tuple(Int, Int, String)
>>> t.check([3, 4, '5'])
(3, 4, '5')
>>> extract_error(t, [3, 4, 5])
{2: 'value is not a string'}
>>> t
<Tuple(<Int>, <Int>, <String>)>
class trafaret.Atom(value)
>>> Atom('atom').check('atom')
'atom'
>>> extract_error(Atom('atom'), 'molecule')
"value is not exactly 'atom'"
class trafaret.String(allow_blank=False, min_length=None, max_length=None)
>>> String()
<String>
>>> String(allow_blank=True)
<String(blank)>
>>> String().check("foo")
'foo'
>>> extract_error(String(), "")
'blank value is not allowed'
>>> String(allow_blank=True).check("")
''
>>> extract_error(String(), 1)
'value is not a string'
>>> String(min_length=2, max_length=3).check('123')
'123'
>>> extract_error(String(min_length=2, max_length=6), '1')
'String is shorter than 2 characters'
>>> extract_error(String(min_length=2, max_length=6), '1234567')
'String is longer than 6 characters'
>>> String(min_length=2, max_length=6, allow_blank=True)
Traceback (most recent call last):
...
AssertionError: Either allow_blank or min_length should be specified, not both
>>> String(min_length=0, max_length=6, allow_blank=True).check('123')
'123'
class trafaret.Float(gte=None, lte=None, gt=None, lt=None)

Checks that value is a float. Or if value is a string converts this string to float

class trafaret.FloatRaw(gte=None, lte=None, gt=None, lt=None)

Tests that value is a float or a string that is convertable to float.

>>> Float()
<Float>
>>> Float(gte=1)
<Float(gte=1)>
>>> Float(lte=10)
<Float(lte=10)>
>>> Float(gte=1, lte=10)
<Float(gte=1, lte=10)>
>>> Float().check(1.0)
1.0
>>> extract_error(Float(), 1 + 3j)
'value is not float'
>>> extract_error(Float(), 1)
1.0
>>> Float(gte=2).check(3.0)
3.0
>>> extract_error(Float(gte=2), 1.0)
'value is less than 2'
>>> Float(lte=10).check(5.0)
5.0
>>> extract_error(Float(lte=3), 5.0)
'value is greater than 3'
>>> Float().check("5.0")
5.0
value_type

alias of float

class trafaret.IntRaw(gte=None, lte=None, gt=None, lt=None)
>>> Int()
<Int>
>>> Int().check(5)
5
>>> extract_error(Int(), 1.1)
'value is not int'
>>> extract_error(Int(), 1 + 1j)
'value is not int'
value_type

alias of int

class trafaret.Callable
>>> (Callable() >> ignore).check(lambda: 1)
>>> extract_error(Callable(), 1)
'value is not callable'
class trafaret.Bool
>>> Bool()
<Bool>
>>> Bool().check(True)
True
>>> Bool().check(False)
False
>>> extract_error(Bool(), 1)
'value should be True or False'
class trafaret.Type(type_)
>>> Type(int)
<Type(int)>
>>> Type[int]
<Type(int)>
>>> c = Type[int]
>>> c.check(1)
1
>>> extract_error(c, "foo")
'value is not int'
typing_checker()

isinstance(object, class-or-type-or-tuple) -> bool

Return whether an object is an instance of a class or of a subclass thereof. With a type as second argument, return whether that is the object’s type. The form using a tuple, isinstance(x, (A, B, …)), is a shortcut for isinstance(x, A) or isinstance(x, B) or … (etc.).

class trafaret.Subclass(type_)
>>> Subclass(type)
<Subclass(type)>
>>> Subclass[type]
<Subclass(type)>
>>> s = Subclass[type]
>>> s.check(type)
<type 'type'>
>>> extract_error(s, object)
'value is not subclass of type'
typing_checker()

issubclass(C, B) -> bool

Return whether class C is a subclass (i.e., a derived class) of class B. When using a tuple as the second argument issubclass(X, (A, B, …)), is a shortcut for issubclass(X, A) or issubclass(X, B) or … (etc.).

class trafaret.Mapping(key, value)

Mapping gets two trafarets as arguments, one for key and one for value, like Mapping(t.Int, t.List(t.Str)).

class trafaret.StrBool
>>> extract_error(StrBool(), 'aloha')
"value can't be converted to Bool"
>>> StrBool().check(1)
True
>>> StrBool().check(0)
False
>>> StrBool().check('y')
True
>>> StrBool().check('n')
False
>>> StrBool().check(None)
False
>>> StrBool().check('1')
True
>>> StrBool().check('0')
False
>>> StrBool().check('YeS')
True
>>> StrBool().check('No')
False
>>> StrBool().check(True)
True
>>> StrBool().check(False)
False
trafaret.DictKeys(keys)

Checks if dict has all given keys

Parameters:keys
>>> _dd(DictKeys(['a','b']).check({'a':1,'b':2,}))
"{'a': 1, 'b': 2}"
>>> extract_error(DictKeys(['a','b']), {'a':1,'b':2,'c':3,})
{'c': 'c is not allowed key'}
>>> extract_error(DictKeys(['key','key2']), {'key':'val'})
{'key2': 'is required'}
trafaret.guard(trafaret=None, **kwargs)

Decorator for protecting function with trafarets

>>> @guard(a=String, b=Int, c=String)
... def fn(a, b, c="default"):
...     '''docstring'''
...     return (a, b, c)
...
>>> fn.__module__ = None
>>> help(fn)
Help on function fn:

fn(*args, **kwargs)
    guarded with <Dict(a=<String>, b=<Int>, c=<String>)>

    docstring

>>> fn("foo", 1)
('foo', 1, 'default')
>>> extract_error(fn, "foo", 1, 2)
{'c': 'value is not a string'}
>>> extract_error(fn, "foo")
{'b': 'is required'}
>>> g = guard(Dict())
>>> c = Forward()
>>> c << Dict(name=str, children=List[c])
>>> g = guard(c)
>>> g = guard(Int())
Traceback (most recent call last):
...
RuntimeError: trafaret should be instance of Dict or Forward
class trafaret.RegexpRaw(regexp, re_flags=0)

Check if given string match given regexp

trafaret.ensure_trafaret(trafaret)

Helper for complex trafarets, takes trafaret instance or class and returns trafaret instance

trafaret.extract_error(checker, *a, **kw)

Helper for tests - catch error and return it as dict

trafaret.ignore(val)

Stub to ignore value from trafaret Use it like:

>>> a = Int >> ignore
>>> a.check(7)
trafaret.catch(checker, *a, **kw)

Helper for tests - catch error and return it as dict

trafaret.catch_error(checker, *a, **kw)

Helper for tests - catch error and return it as dict