"cereal" name already taken on pypi.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
cereal
|
colander
|
||||||
======
|
========
|
||||||
|
|
||||||
An extensible package which can be used to:
|
An extensible package which can be used to:
|
||||||
|
|
||||||
|
@@ -9,7 +9,7 @@ class Invalid(Exception):
|
|||||||
the value for a particular structure was not valid.
|
the value for a particular structure was not valid.
|
||||||
|
|
||||||
The constructor receives a mandatory ``struct`` argument. This
|
The constructor receives a mandatory ``struct`` argument. This
|
||||||
must be an instance of the :class:`cereal.Structure` class.
|
must be an instance of the :class:`colander.Structure` class.
|
||||||
|
|
||||||
The constructor also receives an optional ``msg`` keyword
|
The constructor also receives an optional ``msg`` keyword
|
||||||
argument, defaulting to ``None``. The ``msg`` argument is a
|
argument, defaulting to ``None``. The ``msg`` argument is a
|
||||||
@@ -26,7 +26,7 @@ class Invalid(Exception):
|
|||||||
|
|
||||||
def add(self, exc):
|
def add(self, exc):
|
||||||
""" Add a child exception; ``exc`` must be an instance of
|
""" Add a child exception; ``exc`` must be an instance of
|
||||||
:class:`cereal.Invalid`"""
|
:class:`colander.Invalid`"""
|
||||||
exc.parent = self
|
exc.parent = self
|
||||||
self.children.append(exc)
|
self.children.append(exc)
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ class Invalid(Exception):
|
|||||||
|
|
||||||
class All(object):
|
class All(object):
|
||||||
""" Composite validator which succeeds if none of its
|
""" Composite validator which succeeds if none of its
|
||||||
subvalidators raises an :class:`cereal.Invalid` exception"""
|
subvalidators raises an :class:`colander.Invalid` exception"""
|
||||||
def __init__(self, *validators):
|
def __init__(self, *validators):
|
||||||
self.validators = validators
|
self.validators = validators
|
||||||
|
|
||||||
@@ -119,8 +119,8 @@ class OneOf(object):
|
|||||||
class Mapping(object):
|
class Mapping(object):
|
||||||
""" A type which represents a mapping of names to structures.
|
""" A type which represents a mapping of names to structures.
|
||||||
|
|
||||||
The substructures of the :class:`cereal.Structure` that wraps this
|
The substructures of the :class:`colander.Structure` that wraps
|
||||||
type imply the named keys and values in the mapping.
|
this type imply the named keys and values in the mapping.
|
||||||
|
|
||||||
The constructor of a mapping type accepts a single optional
|
The constructor of a mapping type accepts a single optional
|
||||||
keyword argument named ``unknown_keys``. By default, this
|
keyword argument named ``unknown_keys``. By default, this
|
||||||
@@ -132,8 +132,8 @@ class Mapping(object):
|
|||||||
associated with this type will be ignored during
|
associated with this type will be ignored during
|
||||||
deserialization.
|
deserialization.
|
||||||
|
|
||||||
- ``raise`` will cause a :exc:`cereal.Invalid` exception to
|
- ``raise`` will cause a :exc:`colander.Invalid` exception to be
|
||||||
be raised when unknown keys are present during deserialization.
|
raised when unknown keys are present during deserialization.
|
||||||
|
|
||||||
- ``preserve`` will preserve the 'raw' unknown keys and values in
|
- ``preserve`` will preserve the 'raw' unknown keys and values in
|
||||||
the returned data structure during deserialization.
|
the returned data structure during deserialization.
|
||||||
@@ -215,9 +215,9 @@ class Positional(object):
|
|||||||
class Tuple(Positional):
|
class Tuple(Positional):
|
||||||
""" A type which represents a fixed-length sequence of structures.
|
""" A type which represents a fixed-length sequence of structures.
|
||||||
|
|
||||||
The substructures of the :class:`cereal.Structure` that wraps this
|
The substructures of the :class:`colander.Structure` that wraps
|
||||||
type imply the positional elements of the tuple in the order they
|
this type imply the positional elements of the tuple in the order
|
||||||
are added.
|
they are added.
|
||||||
|
|
||||||
This type is willing to serialize and deserialized iterables that,
|
This type is willing to serialize and deserialized iterables that,
|
||||||
when converted to a tuple, have the same number of elements as the
|
when converted to a tuple, have the same number of elements as the
|
||||||
@@ -270,14 +270,14 @@ class Tuple(Positional):
|
|||||||
class Sequence(Positional):
|
class Sequence(Positional):
|
||||||
"""
|
"""
|
||||||
A type which represents a variable-length sequence of structures,
|
A type which represents a variable-length sequence of structures,
|
||||||
all of which must be of the same type. This type is defined by the
|
all of which must be of the same type. This type is defined by
|
||||||
the :class:`cereal.Structure` instance passed to the constructor
|
the the :class:`colander.Structure` instance passed to the
|
||||||
as ``struct``.
|
constructor as ``struct``.
|
||||||
|
|
||||||
The ``struct`` argument to this type's constructor is required.
|
The ``struct`` argument to this type's constructor is required.
|
||||||
|
|
||||||
The substructures of the :class:`cereal.Structure` that wraps this
|
The substructures of the :class:`colander.Structure` that wraps
|
||||||
type are ignored.
|
this type are ignored.
|
||||||
"""
|
"""
|
||||||
def __init__(self, struct):
|
def __init__(self, struct):
|
||||||
self.struct = struct
|
self.struct = struct
|
||||||
@@ -326,8 +326,8 @@ class String(object):
|
|||||||
which should be applied to object serialization. It defaults to
|
which should be applied to object serialization. It defaults to
|
||||||
``utf-8`` if not provided.
|
``utf-8`` if not provided.
|
||||||
|
|
||||||
The substructures of the :class:`cereal.Structure` that wraps this
|
The substructures of the :class:`colander.Structure` that wraps
|
||||||
type are ignored.
|
this type are ignored.
|
||||||
"""
|
"""
|
||||||
def __init__(self, encoding=None):
|
def __init__(self, encoding=None):
|
||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
@@ -353,8 +353,8 @@ Str = String
|
|||||||
class Integer(object):
|
class Integer(object):
|
||||||
""" A type representing an integer.
|
""" A type representing an integer.
|
||||||
|
|
||||||
The substructures of the :class:`cereal.Structure` that wraps this
|
The substructures of the :class:`colander.Structure` that wraps
|
||||||
type are ignored.
|
this type are ignored.
|
||||||
"""
|
"""
|
||||||
def deserialize(self, struct, value):
|
def deserialize(self, struct, value):
|
||||||
try:
|
try:
|
||||||
@@ -373,8 +373,8 @@ Int = Integer
|
|||||||
class Float(object):
|
class Float(object):
|
||||||
""" A type representing a float.
|
""" A type representing a float.
|
||||||
|
|
||||||
The substructures of the :class:`cereal.Structure` that wraps this
|
The substructures of the :class:`colander.Structure` that wraps
|
||||||
type are ignored.
|
this type are ignored.
|
||||||
"""
|
"""
|
||||||
def deserialize(self, struct, value):
|
def deserialize(self, struct, value):
|
||||||
try:
|
try:
|
||||||
@@ -400,8 +400,8 @@ class Boolean(object):
|
|||||||
Serialization will produce ``true`` or ``false`` based on the
|
Serialization will produce ``true`` or ``false`` based on the
|
||||||
value.
|
value.
|
||||||
|
|
||||||
The substructures of the :class:`cereal.Structure` that wraps this
|
The substructures of the :class:`colander.Structure` that wraps
|
||||||
type are ignored.
|
this type are ignored.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def deserialize(self, struct, value):
|
def deserialize(self, struct, value):
|
||||||
@@ -448,11 +448,11 @@ class GlobalObject(object):
|
|||||||
argument to this type was passed the ``xml`` module object, the
|
argument to this type was passed the ``xml`` module object, the
|
||||||
resulting import would be for ``xml.minidom``. If a relative
|
resulting import would be for ``xml.minidom``. If a relative
|
||||||
package name is supplied to ``deserialize``, and no ``package``
|
package name is supplied to ``deserialize``, and no ``package``
|
||||||
was supplied to the constructor, an :exc:`cereal.Invalid` error
|
was supplied to the constructor, an :exc:`colander.Invalid` error
|
||||||
will be raised.
|
will be raised.
|
||||||
|
|
||||||
The substructures of the :class:`cereal.Structure` that wraps this
|
The substructures of the :class:`colander.Structure` that wraps
|
||||||
type are ignored.
|
this type are ignored.
|
||||||
"""
|
"""
|
||||||
def __init__(self, package):
|
def __init__(self, package):
|
||||||
self.package = package
|
self.package = package
|
||||||
@@ -533,7 +533,7 @@ class Structure(object):
|
|||||||
|
|
||||||
- ``typ`` (required): The 'type' for this structure. It should be
|
- ``typ`` (required): The 'type' for this structure. It should be
|
||||||
an instance of a class that implements the
|
an instance of a class that implements the
|
||||||
:class:`cereal.interfaces.Type` interface.
|
:class:`colander.interfaces.Type` interface.
|
||||||
|
|
||||||
- ``structs``: a sequence of substructures. If the substructures
|
- ``structs``: a sequence of substructures. If the substructures
|
||||||
of this structure are not known at construction time, they can
|
of this structure are not known at construction time, they can
|
||||||
@@ -545,9 +545,9 @@ class Structure(object):
|
|||||||
provided, this structure has no default value and it will be
|
provided, this structure has no default value and it will be
|
||||||
considered 'required' (the ``required`` attribute will be True).
|
considered 'required' (the ``required`` attribute will be True).
|
||||||
|
|
||||||
- ``validator``: Optional validator for this structure. It should be
|
- ``validator``: Optional validator for this structure. It should
|
||||||
an object that implements the
|
be an object that implements the
|
||||||
:class:`cereal.interfaces.Validator` interface.
|
:class:`colander.interfaces.Validator` interface.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_counter = itertools.count()
|
_counter = itertools.count()
|
@@ -2,10 +2,10 @@ def Validator(struct, value):
|
|||||||
"""
|
"""
|
||||||
A validator is called after deserialization of a value.
|
A validator is called after deserialization of a value.
|
||||||
|
|
||||||
If ``value`` is not valid, raise a :class:`cereal.Invalid`
|
If ``value`` is not valid, raise a :class:`colander.Invalid`
|
||||||
instance as an exception after.
|
instance as an exception after.
|
||||||
|
|
||||||
``struct`` is a :class:`cereal.Structure` instance which
|
``struct`` is a :class:`colander.Structure` instance which
|
||||||
contains, among other things, the default value, the name of the
|
contains, among other things, the default value, the name of the
|
||||||
value, and a ``required`` flag indicating whether this value is
|
value, and a ``required`` flag indicating whether this value is
|
||||||
required. It is often ignored in simple validators.
|
required. It is often ignored in simple validators.
|
||||||
@@ -17,18 +17,18 @@ class Type(object):
|
|||||||
Serialize the object represented by ``value`` to a
|
Serialize the object represented by ``value`` to a
|
||||||
data structure. The serialization should be composed of one or
|
data structure. The serialization should be composed of one or
|
||||||
more objects which can be deserialized by the
|
more objects which can be deserialized by the
|
||||||
:meth:`cereal.interfaces.Type.deserialize` method of this
|
:meth:`colander.interfaces.Type.deserialize` method of this
|
||||||
type.
|
type.
|
||||||
|
|
||||||
This method should also do type validation of ``value``.
|
This method should also do type validation of ``value``.
|
||||||
|
|
||||||
``struct`` is a :class:`cereal.Structure` instance which
|
``struct`` is a :class:`colander.Structure` instance which
|
||||||
contains, among other things, the default value, the name of
|
contains, among other things, the default value, the name of
|
||||||
the value, and a ``required`` flag indicating whether this
|
the value, and a ``required`` flag indicating whether this
|
||||||
value is required.
|
value is required.
|
||||||
|
|
||||||
If the object cannot be serialized, or type validation for
|
If the object cannot be serialized, or type validation for
|
||||||
``value`` fails, a :exc:`cereal.Invalid` exception should be
|
``value`` fails, a :exc:`colander.Invalid` exception should be
|
||||||
raised.
|
raised.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -38,18 +38,18 @@ class Type(object):
|
|||||||
Deserialze the serialization represented by ``value`` to a
|
Deserialze the serialization represented by ``value`` to a
|
||||||
data structure. The deserialization should be composed of one
|
data structure. The deserialization should be composed of one
|
||||||
or more objects which can be serialized by the
|
or more objects which can be serialized by the
|
||||||
:meth:`cereal.interfaces.Type.serialize` method of this
|
:meth:`colander.interfaces.Type.serialize` method of this
|
||||||
type.
|
type.
|
||||||
|
|
||||||
This method should also do type validation of ``value``.
|
This method should also do type validation of ``value``.
|
||||||
|
|
||||||
``struct`` is a :class:`cereal.Structure` instance which
|
``struct`` is a :class:`colander.Structure` instance which
|
||||||
contains, among other things, the default value, the name of
|
contains, among other things, the default value, the name of
|
||||||
the value, and a ``required`` flag indicating whether this
|
the value, and a ``required`` flag indicating whether this
|
||||||
value is required.
|
value is required.
|
||||||
|
|
||||||
If the object cannot be deserialized, or type validation for
|
If the object cannot be deserialized, or type validation for
|
||||||
``value`` fails, a :exc:`cereal.Invalid` exception should be
|
``value`` fails, a :exc:`colander.Invalid` exception should be
|
||||||
raised.
|
raised.
|
||||||
"""
|
"""
|
||||||
|
|
@@ -1,7 +1,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
def invalid_exc(func, *arg, **kw):
|
def invalid_exc(func, *arg, **kw):
|
||||||
from cereal import Invalid
|
from colander import Invalid
|
||||||
try:
|
try:
|
||||||
func(*arg, **kw)
|
func(*arg, **kw)
|
||||||
except Invalid, e:
|
except Invalid, e:
|
||||||
@@ -11,7 +11,7 @@ def invalid_exc(func, *arg, **kw):
|
|||||||
|
|
||||||
class TestInvalid(unittest.TestCase):
|
class TestInvalid(unittest.TestCase):
|
||||||
def _makeOne(self, struct, msg=None, pos=None):
|
def _makeOne(self, struct, msg=None, pos=None):
|
||||||
from cereal import Invalid
|
from colander import Invalid
|
||||||
exc = Invalid(struct, msg)
|
exc = Invalid(struct, msg)
|
||||||
exc.pos = pos
|
exc.pos = pos
|
||||||
return exc
|
return exc
|
||||||
@@ -36,7 +36,7 @@ class TestInvalid(unittest.TestCase):
|
|||||||
self.assertEqual(exc._keyname(), 'name')
|
self.assertEqual(exc._keyname(), 'name')
|
||||||
|
|
||||||
def test__keyname_positional_parent(self):
|
def test__keyname_positional_parent(self):
|
||||||
from cereal import Positional
|
from colander import Positional
|
||||||
parent = Dummy()
|
parent = Dummy()
|
||||||
parent.struct = DummyStructure(Positional())
|
parent.struct = DummyStructure(Positional())
|
||||||
exc = self._makeOne(None, '')
|
exc = self._makeOne(None, '')
|
||||||
@@ -65,7 +65,7 @@ class TestInvalid(unittest.TestCase):
|
|||||||
self.assertEqual(paths, [(exc1, exc2, exc3), (exc1, exc4)])
|
self.assertEqual(paths, [(exc1, exc2, exc3), (exc1, exc4)])
|
||||||
|
|
||||||
def test_asdict(self):
|
def test_asdict(self):
|
||||||
from cereal import Positional
|
from colander import Positional
|
||||||
struct1 = DummyStructure(None, 'struct1')
|
struct1 = DummyStructure(None, 'struct1')
|
||||||
struct2 = DummyStructure(Positional(), 'struct2')
|
struct2 = DummyStructure(Positional(), 'struct2')
|
||||||
struct3 = DummyStructure(Positional(), 'struct3')
|
struct3 = DummyStructure(Positional(), 'struct3')
|
||||||
@@ -84,7 +84,7 @@ class TestInvalid(unittest.TestCase):
|
|||||||
|
|
||||||
class TestAll(unittest.TestCase):
|
class TestAll(unittest.TestCase):
|
||||||
def _makeOne(self, validators):
|
def _makeOne(self, validators):
|
||||||
from cereal import All
|
from colander import All
|
||||||
return All(*validators)
|
return All(*validators)
|
||||||
|
|
||||||
def test_success(self):
|
def test_success(self):
|
||||||
@@ -102,7 +102,7 @@ class TestAll(unittest.TestCase):
|
|||||||
|
|
||||||
class TestRange(unittest.TestCase):
|
class TestRange(unittest.TestCase):
|
||||||
def _makeOne(self, min=None, max=None):
|
def _makeOne(self, min=None, max=None):
|
||||||
from cereal import Range
|
from colander import Range
|
||||||
return Range(min=min, max=max)
|
return Range(min=min, max=max)
|
||||||
|
|
||||||
def test_success_no_bounds(self):
|
def test_success_no_bounds(self):
|
||||||
@@ -133,7 +133,7 @@ class TestRange(unittest.TestCase):
|
|||||||
|
|
||||||
class TestOneOf(unittest.TestCase):
|
class TestOneOf(unittest.TestCase):
|
||||||
def _makeOne(self, values):
|
def _makeOne(self, values):
|
||||||
from cereal import OneOf
|
from colander import OneOf
|
||||||
return OneOf(values)
|
return OneOf(values)
|
||||||
|
|
||||||
def test_success(self):
|
def test_success(self):
|
||||||
@@ -147,7 +147,7 @@ class TestOneOf(unittest.TestCase):
|
|||||||
|
|
||||||
class TestMapping(unittest.TestCase):
|
class TestMapping(unittest.TestCase):
|
||||||
def _makeOne(self, unknown_keys='ignore'):
|
def _makeOne(self, unknown_keys='ignore'):
|
||||||
from cereal import Mapping
|
from colander import Mapping
|
||||||
return Mapping(unknown_keys=unknown_keys)
|
return Mapping(unknown_keys=unknown_keys)
|
||||||
|
|
||||||
def test_ctor_bad_unknown_keys(self):
|
def test_ctor_bad_unknown_keys(self):
|
||||||
@@ -295,7 +295,7 @@ class TestMapping(unittest.TestCase):
|
|||||||
|
|
||||||
class TestTuple(unittest.TestCase):
|
class TestTuple(unittest.TestCase):
|
||||||
def _makeOne(self):
|
def _makeOne(self):
|
||||||
from cereal import Tuple
|
from colander import Tuple
|
||||||
return Tuple()
|
return Tuple()
|
||||||
|
|
||||||
def test_deserialize_not_iterable(self):
|
def test_deserialize_not_iterable(self):
|
||||||
@@ -398,12 +398,12 @@ class TestTuple(unittest.TestCase):
|
|||||||
|
|
||||||
class TestSequence(unittest.TestCase):
|
class TestSequence(unittest.TestCase):
|
||||||
def _makeOne(self, substruct):
|
def _makeOne(self, substruct):
|
||||||
from cereal import Sequence
|
from colander import Sequence
|
||||||
return Sequence(substruct)
|
return Sequence(substruct)
|
||||||
|
|
||||||
def test_alias(self):
|
def test_alias(self):
|
||||||
from cereal import Seq
|
from colander import Seq
|
||||||
from cereal import Sequence
|
from colander import Sequence
|
||||||
self.assertEqual(Seq, Sequence)
|
self.assertEqual(Seq, Sequence)
|
||||||
|
|
||||||
def test_deserialize_not_iterable(self):
|
def test_deserialize_not_iterable(self):
|
||||||
@@ -466,12 +466,12 @@ class TestSequence(unittest.TestCase):
|
|||||||
|
|
||||||
class TestString(unittest.TestCase):
|
class TestString(unittest.TestCase):
|
||||||
def _makeOne(self, encoding='utf-8'):
|
def _makeOne(self, encoding='utf-8'):
|
||||||
from cereal import String
|
from colander import String
|
||||||
return String(encoding)
|
return String(encoding)
|
||||||
|
|
||||||
def test_alias(self):
|
def test_alias(self):
|
||||||
from cereal import Str
|
from colander import Str
|
||||||
from cereal import String
|
from colander import String
|
||||||
self.assertEqual(Str, String)
|
self.assertEqual(Str, String)
|
||||||
|
|
||||||
def test_deserialize_uncooperative(self):
|
def test_deserialize_uncooperative(self):
|
||||||
@@ -529,12 +529,12 @@ class TestString(unittest.TestCase):
|
|||||||
|
|
||||||
class TestInteger(unittest.TestCase):
|
class TestInteger(unittest.TestCase):
|
||||||
def _makeOne(self):
|
def _makeOne(self):
|
||||||
from cereal import Integer
|
from colander import Integer
|
||||||
return Integer()
|
return Integer()
|
||||||
|
|
||||||
def test_alias(self):
|
def test_alias(self):
|
||||||
from cereal import Int
|
from colander import Int
|
||||||
from cereal import Integer
|
from colander import Integer
|
||||||
self.assertEqual(Int, Integer)
|
self.assertEqual(Int, Integer)
|
||||||
|
|
||||||
def test_deserialize_fails(self):
|
def test_deserialize_fails(self):
|
||||||
@@ -567,7 +567,7 @@ class TestInteger(unittest.TestCase):
|
|||||||
|
|
||||||
class TestFloat(unittest.TestCase):
|
class TestFloat(unittest.TestCase):
|
||||||
def _makeOne(self):
|
def _makeOne(self):
|
||||||
from cereal import Float
|
from colander import Float
|
||||||
return Float()
|
return Float()
|
||||||
|
|
||||||
def test_deserialize_fails(self):
|
def test_deserialize_fails(self):
|
||||||
@@ -600,12 +600,12 @@ class TestFloat(unittest.TestCase):
|
|||||||
|
|
||||||
class TestBoolean(unittest.TestCase):
|
class TestBoolean(unittest.TestCase):
|
||||||
def _makeOne(self):
|
def _makeOne(self):
|
||||||
from cereal import Boolean
|
from colander import Boolean
|
||||||
return Boolean()
|
return Boolean()
|
||||||
|
|
||||||
def test_alias(self):
|
def test_alias(self):
|
||||||
from cereal import Bool
|
from colander import Bool
|
||||||
from cereal import Boolean
|
from colander import Boolean
|
||||||
self.assertEqual(Bool, Boolean)
|
self.assertEqual(Bool, Boolean)
|
||||||
|
|
||||||
def test_deserialize(self):
|
def test_deserialize(self):
|
||||||
@@ -633,37 +633,37 @@ class TestBoolean(unittest.TestCase):
|
|||||||
|
|
||||||
class TestGlobalObject(unittest.TestCase):
|
class TestGlobalObject(unittest.TestCase):
|
||||||
def _makeOne(self, package=None):
|
def _makeOne(self, package=None):
|
||||||
from cereal import GlobalObject
|
from colander import GlobalObject
|
||||||
return GlobalObject(package)
|
return GlobalObject(package)
|
||||||
|
|
||||||
def test_zope_dottedname_style_resolve_absolute(self):
|
def test_zope_dottedname_style_resolve_absolute(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
result = typ._zope_dottedname_style(None,
|
result = typ._zope_dottedname_style(None,
|
||||||
'cereal.tests.TestGlobalObject')
|
'colander.tests.TestGlobalObject')
|
||||||
self.assertEqual(result, self.__class__)
|
self.assertEqual(result, self.__class__)
|
||||||
|
|
||||||
def test_zope_dottedname_style_irrresolveable_absolute(self):
|
def test_zope_dottedname_style_irrresolveable_absolute(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
self.assertRaises(ImportError, typ._zope_dottedname_style, None,
|
self.assertRaises(ImportError, typ._zope_dottedname_style, None,
|
||||||
'cereal.tests.nonexisting')
|
'colander.tests.nonexisting')
|
||||||
|
|
||||||
def test__zope_dottedname_style_resolve_relative(self):
|
def test__zope_dottedname_style_resolve_relative(self):
|
||||||
import cereal
|
import colander
|
||||||
typ = self._makeOne(package=cereal)
|
typ = self._makeOne(package=colander)
|
||||||
result = typ._zope_dottedname_style(None, '.tests.TestGlobalObject')
|
result = typ._zope_dottedname_style(None, '.tests.TestGlobalObject')
|
||||||
self.assertEqual(result, self.__class__)
|
self.assertEqual(result, self.__class__)
|
||||||
|
|
||||||
def test__zope_dottedname_style_resolve_relative_leading_dots(self):
|
def test__zope_dottedname_style_resolve_relative_leading_dots(self):
|
||||||
import cereal
|
import colander
|
||||||
typ = self._makeOne(package=cereal.tests)
|
typ = self._makeOne(package=colander.tests)
|
||||||
result = typ._zope_dottedname_style(None, '..tests.TestGlobalObject')
|
result = typ._zope_dottedname_style(None, '..tests.TestGlobalObject')
|
||||||
self.assertEqual(result, self.__class__)
|
self.assertEqual(result, self.__class__)
|
||||||
|
|
||||||
def test__zope_dottedname_style_resolve_relative_is_dot(self):
|
def test__zope_dottedname_style_resolve_relative_is_dot(self):
|
||||||
import cereal.tests
|
import colander.tests
|
||||||
typ = self._makeOne(package=cereal.tests)
|
typ = self._makeOne(package=colander.tests)
|
||||||
result = typ._zope_dottedname_style(None, '.')
|
result = typ._zope_dottedname_style(None, '.')
|
||||||
self.assertEqual(result, cereal.tests)
|
self.assertEqual(result, colander.tests)
|
||||||
|
|
||||||
def test__zope_dottedname_style_irresolveable_relative_is_dot(self):
|
def test__zope_dottedname_style_irresolveable_relative_is_dot(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
@@ -679,57 +679,57 @@ class TestGlobalObject(unittest.TestCase):
|
|||||||
e.msg, "relative name '.whatever' irresolveable without package")
|
e.msg, "relative name '.whatever' irresolveable without package")
|
||||||
|
|
||||||
def test_zope_dottedname_style_irrresolveable_relative(self):
|
def test_zope_dottedname_style_irrresolveable_relative(self):
|
||||||
import cereal.tests
|
import colander.tests
|
||||||
typ = self._makeOne(package=cereal)
|
typ = self._makeOne(package=colander)
|
||||||
self.assertRaises(ImportError, typ._zope_dottedname_style, None,
|
self.assertRaises(ImportError, typ._zope_dottedname_style, None,
|
||||||
'.notexisting')
|
'.notexisting')
|
||||||
|
|
||||||
def test__zope_dottedname_style_resolveable_relative(self):
|
def test__zope_dottedname_style_resolveable_relative(self):
|
||||||
import cereal
|
import colander
|
||||||
typ = self._makeOne(package=cereal)
|
typ = self._makeOne(package=colander)
|
||||||
result = typ._zope_dottedname_style(None, '.tests')
|
result = typ._zope_dottedname_style(None, '.tests')
|
||||||
from cereal import tests
|
from colander import tests
|
||||||
self.assertEqual(result, tests)
|
self.assertEqual(result, tests)
|
||||||
|
|
||||||
def test__zope_dottedname_style_irresolveable_absolute(self):
|
def test__zope_dottedname_style_irresolveable_absolute(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
self.assertRaises(ImportError,
|
self.assertRaises(ImportError,
|
||||||
typ._zope_dottedname_style, None, 'cereal.fudge.bar')
|
typ._zope_dottedname_style, None, 'colander.fudge.bar')
|
||||||
|
|
||||||
def test__zope_dottedname_style_resolveable_absolute(self):
|
def test__zope_dottedname_style_resolveable_absolute(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
result = typ._zope_dottedname_style(None,
|
result = typ._zope_dottedname_style(None,
|
||||||
'cereal.tests.TestGlobalObject')
|
'colander.tests.TestGlobalObject')
|
||||||
self.assertEqual(result, self.__class__)
|
self.assertEqual(result, self.__class__)
|
||||||
|
|
||||||
def test__pkg_resources_style_resolve_absolute(self):
|
def test__pkg_resources_style_resolve_absolute(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
result = typ._pkg_resources_style(None,
|
result = typ._pkg_resources_style(None,
|
||||||
'cereal.tests:TestGlobalObject')
|
'colander.tests:TestGlobalObject')
|
||||||
self.assertEqual(result, self.__class__)
|
self.assertEqual(result, self.__class__)
|
||||||
|
|
||||||
def test__pkg_resources_style_irrresolveable_absolute(self):
|
def test__pkg_resources_style_irrresolveable_absolute(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
self.assertRaises(ImportError, typ._pkg_resources_style, None,
|
self.assertRaises(ImportError, typ._pkg_resources_style, None,
|
||||||
'cereal.tests:nonexisting')
|
'colander.tests:nonexisting')
|
||||||
|
|
||||||
def test__pkg_resources_style_resolve_relative_startswith_colon(self):
|
def test__pkg_resources_style_resolve_relative_startswith_colon(self):
|
||||||
import cereal.tests
|
import colander.tests
|
||||||
typ = self._makeOne(package=cereal.tests)
|
typ = self._makeOne(package=colander.tests)
|
||||||
result = typ._pkg_resources_style(None, ':TestGlobalObject')
|
result = typ._pkg_resources_style(None, ':TestGlobalObject')
|
||||||
self.assertEqual(result, self.__class__)
|
self.assertEqual(result, self.__class__)
|
||||||
|
|
||||||
def test__pkg_resources_style_resolve_relative_startswith_dot(self):
|
def test__pkg_resources_style_resolve_relative_startswith_dot(self):
|
||||||
import cereal
|
import colander
|
||||||
typ = self._makeOne(package=cereal)
|
typ = self._makeOne(package=colander)
|
||||||
result = typ._pkg_resources_style(None, '.tests:TestGlobalObject')
|
result = typ._pkg_resources_style(None, '.tests:TestGlobalObject')
|
||||||
self.assertEqual(result, self.__class__)
|
self.assertEqual(result, self.__class__)
|
||||||
|
|
||||||
def test__pkg_resources_style_resolve_relative_is_dot(self):
|
def test__pkg_resources_style_resolve_relative_is_dot(self):
|
||||||
import cereal.tests
|
import colander.tests
|
||||||
typ = self._makeOne(package=cereal.tests)
|
typ = self._makeOne(package=colander.tests)
|
||||||
result = typ._pkg_resources_style(None, '.')
|
result = typ._pkg_resources_style(None, '.')
|
||||||
self.assertEqual(result, cereal.tests)
|
self.assertEqual(result, colander.tests)
|
||||||
|
|
||||||
def test__pkg_resources_style_resolve_relative_nocurrentpackage(self):
|
def test__pkg_resources_style_resolve_relative_nocurrentpackage(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
@@ -737,8 +737,8 @@ class TestGlobalObject(unittest.TestCase):
|
|||||||
'.whatever')
|
'.whatever')
|
||||||
|
|
||||||
def test__pkg_resources_style_irrresolveable_relative(self):
|
def test__pkg_resources_style_irrresolveable_relative(self):
|
||||||
import cereal.tests
|
import colander.tests
|
||||||
typ = self._makeOne(package=cereal)
|
typ = self._makeOne(package=colander)
|
||||||
self.assertRaises(ImportError, typ._pkg_resources_style, None,
|
self.assertRaises(ImportError, typ._pkg_resources_style, None,
|
||||||
':notexisting')
|
':notexisting')
|
||||||
|
|
||||||
@@ -749,12 +749,12 @@ class TestGlobalObject(unittest.TestCase):
|
|||||||
|
|
||||||
def test_deserialize_using_pkgresources_style(self):
|
def test_deserialize_using_pkgresources_style(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
result = typ.deserialize(None, 'cereal.tests:TestGlobalObject')
|
result = typ.deserialize(None, 'colander.tests:TestGlobalObject')
|
||||||
self.assertEqual(result, self.__class__)
|
self.assertEqual(result, self.__class__)
|
||||||
|
|
||||||
def test_deserialize_using_zope_dottedname_style(self):
|
def test_deserialize_using_zope_dottedname_style(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
result = typ.deserialize(None, 'cereal.tests.TestGlobalObject')
|
result = typ.deserialize(None, 'colander.tests.TestGlobalObject')
|
||||||
self.assertEqual(result, self.__class__)
|
self.assertEqual(result, self.__class__)
|
||||||
|
|
||||||
def test_deserialize_style_raises(self):
|
def test_deserialize_style_raises(self):
|
||||||
@@ -764,10 +764,10 @@ class TestGlobalObject(unittest.TestCase):
|
|||||||
"The dotted name 'cant.be.found' cannot be imported")
|
"The dotted name 'cant.be.found' cannot be imported")
|
||||||
|
|
||||||
def test_serialize_ok(self):
|
def test_serialize_ok(self):
|
||||||
import cereal.tests
|
import colander.tests
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
result = typ.serialize(None, cereal.tests)
|
result = typ.serialize(None, colander.tests)
|
||||||
self.assertEqual(result, 'cereal.tests')
|
self.assertEqual(result, 'colander.tests')
|
||||||
|
|
||||||
def test_serialize_fail(self):
|
def test_serialize_fail(self):
|
||||||
typ = self._makeOne()
|
typ = self._makeOne()
|
||||||
@@ -776,7 +776,7 @@ class TestGlobalObject(unittest.TestCase):
|
|||||||
|
|
||||||
class TestStructure(unittest.TestCase):
|
class TestStructure(unittest.TestCase):
|
||||||
def _makeOne(self, *arg, **kw):
|
def _makeOne(self, *arg, **kw):
|
||||||
from cereal import Structure
|
from colander import Structure
|
||||||
return Structure(*arg, **kw)
|
return Structure(*arg, **kw)
|
||||||
|
|
||||||
def test_new_sets_order(self):
|
def test_new_sets_order(self):
|
||||||
@@ -825,50 +825,50 @@ class TestStructure(unittest.TestCase):
|
|||||||
|
|
||||||
class TestSchema(unittest.TestCase):
|
class TestSchema(unittest.TestCase):
|
||||||
def test_alias(self):
|
def test_alias(self):
|
||||||
from cereal import Schema
|
from colander import Schema
|
||||||
from cereal import MappingSchema
|
from colander import MappingSchema
|
||||||
self.assertEqual(Schema, MappingSchema)
|
self.assertEqual(Schema, MappingSchema)
|
||||||
|
|
||||||
def test_it(self):
|
def test_it(self):
|
||||||
import cereal
|
import colander
|
||||||
class MySchema(cereal.Schema):
|
class MySchema(colander.Schema):
|
||||||
thing = cereal.Structure(cereal.String())
|
thing = colander.Structure(colander.String())
|
||||||
structure = MySchema(unknown_keys='raise')
|
structure = MySchema(unknown_keys='raise')
|
||||||
self.failUnless(hasattr(structure, '_order'))
|
self.failUnless(hasattr(structure, '_order'))
|
||||||
self.assertEqual(structure.__class__, cereal.Structure)
|
self.assertEqual(structure.__class__, colander.Structure)
|
||||||
self.assertEqual(structure.typ.__class__, cereal.Mapping)
|
self.assertEqual(structure.typ.__class__, colander.Mapping)
|
||||||
self.assertEqual(structure.typ.unknown_keys, 'raise')
|
self.assertEqual(structure.typ.unknown_keys, 'raise')
|
||||||
self.assertEqual(structure.structs[0].typ.__class__, cereal.String)
|
self.assertEqual(structure.structs[0].typ.__class__, colander.String)
|
||||||
|
|
||||||
class TestSequenceSchema(unittest.TestCase):
|
class TestSequenceSchema(unittest.TestCase):
|
||||||
def test_it(self):
|
def test_it(self):
|
||||||
import cereal
|
import colander
|
||||||
class MySchema(cereal.SequenceSchema):
|
class MySchema(colander.SequenceSchema):
|
||||||
pass
|
pass
|
||||||
inner = cereal.Structure(cereal.String())
|
inner = colander.Structure(colander.String())
|
||||||
structure = MySchema(inner)
|
structure = MySchema(inner)
|
||||||
self.failUnless(hasattr(structure, '_order'))
|
self.failUnless(hasattr(structure, '_order'))
|
||||||
self.assertEqual(structure.__class__, cereal.Structure)
|
self.assertEqual(structure.__class__, colander.Structure)
|
||||||
self.assertEqual(structure.typ.__class__, cereal.Sequence)
|
self.assertEqual(structure.typ.__class__, colander.Sequence)
|
||||||
self.assertEqual(structure.typ.struct, inner)
|
self.assertEqual(structure.typ.struct, inner)
|
||||||
|
|
||||||
class TestTupleSchema(unittest.TestCase):
|
class TestTupleSchema(unittest.TestCase):
|
||||||
def test_it(self):
|
def test_it(self):
|
||||||
import cereal
|
import colander
|
||||||
class MySchema(cereal.TupleSchema):
|
class MySchema(colander.TupleSchema):
|
||||||
thing = cereal.Structure(cereal.String())
|
thing = colander.Structure(colander.String())
|
||||||
structure = MySchema()
|
structure = MySchema()
|
||||||
self.failUnless(hasattr(structure, '_order'))
|
self.failUnless(hasattr(structure, '_order'))
|
||||||
self.assertEqual(structure.__class__, cereal.Structure)
|
self.assertEqual(structure.__class__, colander.Structure)
|
||||||
self.assertEqual(structure.typ.__class__, cereal.Tuple)
|
self.assertEqual(structure.typ.__class__, colander.Tuple)
|
||||||
self.assertEqual(structure.structs[0].typ.__class__, cereal.String)
|
self.assertEqual(structure.structs[0].typ.__class__, colander.String)
|
||||||
|
|
||||||
class TestFunctional(object):
|
class TestFunctional(object):
|
||||||
def test_deserialize_ok(self):
|
def test_deserialize_ok(self):
|
||||||
import cereal.tests
|
import colander.tests
|
||||||
data = {
|
data = {
|
||||||
'int':'10',
|
'int':'10',
|
||||||
'ob':'cereal.tests',
|
'ob':'colander.tests',
|
||||||
'seq':[('1', 's'),('2', 's'), ('3', 's'), ('4', 's')],
|
'seq':[('1', 's'),('2', 's'), ('3', 's'), ('4', 's')],
|
||||||
'seq2':[{'key':'1', 'key2':'2'}, {'key':'3', 'key2':'4'}],
|
'seq2':[{'key':'1', 'key2':'2'}, {'key':'3', 'key2':'4'}],
|
||||||
'tup':('1', 's'),
|
'tup':('1', 's'),
|
||||||
@@ -876,7 +876,7 @@ class TestFunctional(object):
|
|||||||
schema = self._makeSchema()
|
schema = self._makeSchema()
|
||||||
result = schema.deserialize(data)
|
result = schema.deserialize(data)
|
||||||
self.assertEqual(result['int'], 10)
|
self.assertEqual(result['int'], 10)
|
||||||
self.assertEqual(result['ob'], cereal.tests)
|
self.assertEqual(result['ob'], colander.tests)
|
||||||
self.assertEqual(result['seq'],
|
self.assertEqual(result['seq'],
|
||||||
[(1, 's'), (2, 's'), (3, 's'), (4, 's')])
|
[(1, 's'), (2, 's'), (3, 's'), (4, 's')])
|
||||||
self.assertEqual(result['seq2'],
|
self.assertEqual(result['seq2'],
|
||||||
@@ -911,47 +911,47 @@ class TestFunctional(object):
|
|||||||
class TestImperative(unittest.TestCase, TestFunctional):
|
class TestImperative(unittest.TestCase, TestFunctional):
|
||||||
|
|
||||||
def _makeSchema(self):
|
def _makeSchema(self):
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
integer = cereal.Structure(
|
integer = colander.Structure(
|
||||||
cereal.Integer(),
|
colander.Integer(),
|
||||||
name='int',
|
name='int',
|
||||||
validator=cereal.Range(0, 10)
|
validator=colander.Range(0, 10)
|
||||||
)
|
)
|
||||||
|
|
||||||
ob = cereal.Structure(
|
ob = colander.Structure(
|
||||||
cereal.GlobalObject(package=cereal),
|
colander.GlobalObject(package=colander),
|
||||||
name='ob',
|
name='ob',
|
||||||
)
|
)
|
||||||
|
|
||||||
tup = cereal.Structure(
|
tup = colander.Structure(
|
||||||
cereal.Tuple(),
|
colander.Tuple(),
|
||||||
cereal.Structure(
|
colander.Structure(
|
||||||
cereal.Integer(),
|
colander.Integer(),
|
||||||
name='tupint',
|
name='tupint',
|
||||||
),
|
),
|
||||||
cereal.Structure(
|
colander.Structure(
|
||||||
cereal.String(),
|
colander.String(),
|
||||||
name='tupstring',
|
name='tupstring',
|
||||||
),
|
),
|
||||||
name='tup',
|
name='tup',
|
||||||
)
|
)
|
||||||
|
|
||||||
seq = cereal.Structure(
|
seq = colander.Structure(
|
||||||
cereal.Sequence(tup),
|
colander.Sequence(tup),
|
||||||
name='seq',
|
name='seq',
|
||||||
)
|
)
|
||||||
|
|
||||||
seq2 = cereal.Structure(
|
seq2 = colander.Structure(
|
||||||
cereal.Sequence(
|
colander.Sequence(
|
||||||
cereal.Structure(
|
colander.Structure(
|
||||||
cereal.Mapping(),
|
colander.Mapping(),
|
||||||
cereal.Structure(
|
colander.Structure(
|
||||||
cereal.Integer(),
|
colander.Integer(),
|
||||||
name='key',
|
name='key',
|
||||||
),
|
),
|
||||||
cereal.Structure(
|
colander.Structure(
|
||||||
cereal.Integer(),
|
colander.Integer(),
|
||||||
name='key2',
|
name='key2',
|
||||||
),
|
),
|
||||||
name='mapping',
|
name='mapping',
|
||||||
@@ -960,8 +960,8 @@ class TestImperative(unittest.TestCase, TestFunctional):
|
|||||||
name='seq2',
|
name='seq2',
|
||||||
)
|
)
|
||||||
|
|
||||||
schema = cereal.Structure(
|
schema = colander.Structure(
|
||||||
cereal.Mapping(),
|
colander.Mapping(),
|
||||||
integer,
|
integer,
|
||||||
ob,
|
ob,
|
||||||
tup,
|
tup,
|
||||||
@@ -974,22 +974,23 @@ class TestDeclarative(unittest.TestCase, TestFunctional):
|
|||||||
|
|
||||||
def _makeSchema(self):
|
def _makeSchema(self):
|
||||||
|
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
class TupleSchema(cereal.TupleSchema):
|
class TupleSchema(colander.TupleSchema):
|
||||||
tupint = cereal.Structure(cereal.Int())
|
tupint = colander.Structure(colander.Int())
|
||||||
tupstring = cereal.Structure(cereal.String())
|
tupstring = colander.Structure(colander.String())
|
||||||
|
|
||||||
class MappingSchema(cereal.MappingSchema):
|
class MappingSchema(colander.MappingSchema):
|
||||||
key = cereal.Structure(cereal.Int())
|
key = colander.Structure(colander.Int())
|
||||||
key2 = cereal.Structure(cereal.Int())
|
key2 = colander.Structure(colander.Int())
|
||||||
|
|
||||||
class MainSchema(cereal.MappingSchema):
|
class MainSchema(colander.MappingSchema):
|
||||||
int = cereal.Structure(cereal.Int(), validator=cereal.Range(0, 10))
|
int = colander.Structure(colander.Int(),
|
||||||
ob = cereal.Structure(cereal.GlobalObject(package=cereal))
|
validator=colander.Range(0, 10))
|
||||||
seq = cereal.Structure(cereal.Sequence(TupleSchema()))
|
ob = colander.Structure(colander.GlobalObject(package=colander))
|
||||||
|
seq = colander.Structure(colander.Sequence(TupleSchema()))
|
||||||
tup = TupleSchema()
|
tup = TupleSchema()
|
||||||
seq2 = cereal.SequenceSchema(MappingSchema())
|
seq2 = colander.SequenceSchema(MappingSchema())
|
||||||
|
|
||||||
schema = MainSchema()
|
schema = MainSchema()
|
||||||
return schema
|
return schema
|
||||||
@@ -1007,13 +1008,13 @@ class DummyStructure(object):
|
|||||||
self.structs = []
|
self.structs = []
|
||||||
|
|
||||||
def deserialize(self, val):
|
def deserialize(self, val):
|
||||||
from cereal import Invalid
|
from colander import Invalid
|
||||||
if self.exc:
|
if self.exc:
|
||||||
raise Invalid(self, self.exc)
|
raise Invalid(self, self.exc)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def serialize(self, val):
|
def serialize(self, val):
|
||||||
from cereal import Invalid
|
from colander import Invalid
|
||||||
if self.exc:
|
if self.exc:
|
||||||
raise Invalid(self, self.exc)
|
raise Invalid(self, self.exc)
|
||||||
return val
|
return val
|
||||||
@@ -1023,7 +1024,7 @@ class DummyValidator(object):
|
|||||||
self.msg = msg
|
self.msg = msg
|
||||||
|
|
||||||
def __call__(self, struct, value):
|
def __call__(self, struct, value):
|
||||||
from cereal import Invalid
|
from colander import Invalid
|
||||||
if self.msg:
|
if self.msg:
|
||||||
raise Invalid(struct, self.msg)
|
raise Invalid(struct, self.msg)
|
||||||
|
|
@@ -1,10 +1,10 @@
|
|||||||
Cereal API
|
Colander API
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Exceptions
|
Exceptions
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
.. automodule:: cereal
|
.. automodule:: colander
|
||||||
|
|
||||||
.. autoclass:: Invalid
|
.. autoclass:: Invalid
|
||||||
:members:
|
:members:
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# cereal documentation build configuration file
|
# colander documentation build configuration file
|
||||||
#
|
#
|
||||||
# This file is execfile()d with the current directory set to its containing
|
# This file is execfile()d with the current directory set to its containing
|
||||||
# dir.
|
# dir.
|
||||||
@@ -45,7 +45,7 @@ source_suffix = '.rst'
|
|||||||
master_doc = 'index'
|
master_doc = 'index'
|
||||||
|
|
||||||
# General substitutions.
|
# General substitutions.
|
||||||
project = 'cereal'
|
project = 'colander'
|
||||||
copyright = '2010, Repoze Developers <repoze-dev@lists.repoze.org>'
|
copyright = '2010, Repoze Developers <repoze-dev@lists.repoze.org>'
|
||||||
|
|
||||||
# The default replacements for |version| and |release|, also used in various
|
# The default replacements for |version| and |release|, also used in various
|
||||||
@@ -172,7 +172,7 @@ htmlhelp_basename = 'atemplatedoc'
|
|||||||
# (source start file, target name, title,
|
# (source start file, target name, title,
|
||||||
# author, document class [howto/manual]).
|
# author, document class [howto/manual]).
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
('index', 'atemplate.tex', 'cereal Documentation',
|
('index', 'atemplate.tex', 'colander Documentation',
|
||||||
'Repoze Developers', 'manual'),
|
'Repoze Developers', 'manual'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
198
docs/index.rst
198
docs/index.rst
@@ -1,9 +1,9 @@
|
|||||||
Cereal
|
Colander
|
||||||
======
|
========
|
||||||
|
|
||||||
Cereal is useful as a system for validating and deserializing data
|
Colander is useful as a system for validating and deserializing data
|
||||||
obtained via XML, JSON, an HTML form post or any other equally simple
|
obtained via XML, JSON, an HTML form post or any other equally simple
|
||||||
data serialization. Cereal can be used to:
|
data serialization. Colander can be used to:
|
||||||
|
|
||||||
- Define a data schema
|
- Define a data schema
|
||||||
|
|
||||||
@@ -14,8 +14,8 @@ data serialization. Cereal can be used to:
|
|||||||
- Serialize an arbitrary Python structure to a data structure composed
|
- Serialize an arbitrary Python structure to a data structure composed
|
||||||
of strings, mappings, and lists.
|
of strings, mappings, and lists.
|
||||||
|
|
||||||
Out of the box, Cereal can serialize and deserialize various types of
|
Out of the box, Colander can serialize and deserialize various types
|
||||||
objects, including:
|
of objects, including:
|
||||||
|
|
||||||
- A mapping object (e.g. dictionary)
|
- A mapping object (e.g. dictionary)
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@ objects, including:
|
|||||||
|
|
||||||
- An importable Python object (to a dotted Python object path).
|
- An importable Python object (to a dotted Python object path).
|
||||||
|
|
||||||
Cereal allows additional data structures to be serialized and
|
Colander allows additional data structures to be serialized and
|
||||||
deserialized by allowing a developer to define new "types".
|
deserialized by allowing a developer to define new "types".
|
||||||
|
|
||||||
Defining A Cereal Schema
|
Defining A Colander Schema
|
||||||
------------------------
|
--------------------------
|
||||||
|
|
||||||
Imagine you want to deserialize and validate a serialization of data
|
Imagine you want to deserialize and validate a serialization of data
|
||||||
you've obtained by reading a YAML document. An example of such a data
|
you've obtained by reading a YAML document. An example of such a data
|
||||||
@@ -69,22 +69,24 @@ different types.
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
class Friend(cereal.TupleSchema):
|
class Friend(colander.TupleSchema):
|
||||||
rank = cereal.Structure(cereal.Int(), validator=cereal.Range(0, 9999))
|
rank = colander.Structure(colander.Int(),
|
||||||
name = cereal.Structure(cereal.String())
|
validator=colander.Range(0, 9999))
|
||||||
|
name = colander.Structure(colander.String())
|
||||||
|
|
||||||
class Phone(cereal.MappingSchema):
|
class Phone(colander.MappingSchema):
|
||||||
location = cereal.Structure(cereal.String(),
|
location = colander.Structure(colander.String(),
|
||||||
validator=cereal.OneOf(['home', 'work']))
|
validator=colander.OneOf(['home', 'work']))
|
||||||
number = cereal.Structure(cereal.String())
|
number = colander.Structure(colander.String())
|
||||||
|
|
||||||
class Person(cereal.MappingSchema):
|
class Person(colander.MappingSchema):
|
||||||
name = cereal.Structure(cereal.String())
|
name = colander.Structure(colander.String())
|
||||||
age = cereal.Structure(cereal.Int(), validator=cereal.Range(0, 200))
|
age = colander.Structure(colander.Int(),
|
||||||
friends = cereal.Structure(cereal.Sequence(Friend()))
|
validator=colander.Range(0, 200))
|
||||||
phones = cereal.Structure(cereal.Sequence(Phone()))
|
friends = colander.Structure(colander.Sequence(Friend()))
|
||||||
|
phones = colander.Structure(colander.Sequence(Phone()))
|
||||||
|
|
||||||
For ease of reading, we've actually defined *three* schemas above, but
|
For ease of reading, we've actually defined *three* schemas above, but
|
||||||
we coalesce them all into a single ``Person`` schema. As the result
|
we coalesce them all into a single ``Person`` schema. As the result
|
||||||
@@ -115,12 +117,12 @@ optional deserialization *validator*, an optional *default*, and a
|
|||||||
slightly less optional *name*.
|
slightly less optional *name*.
|
||||||
|
|
||||||
The *type* of a structure indicates its data type (such as
|
The *type* of a structure indicates its data type (such as
|
||||||
``cereal.Int`` or ``cereal.String``).
|
``colander.Int`` or ``colander.String``).
|
||||||
|
|
||||||
The *validator* of a structure is called after deserialization; it
|
The *validator* of a structure is called after deserialization; it
|
||||||
makes sure the deserialized value matches a constraint. An example of
|
makes sure the deserialized value matches a constraint. An example of
|
||||||
such a validator is provided in the schema above:
|
such a validator is provided in the schema above:
|
||||||
``validator=cereal.Range(0, 200)``. A validator is not called after
|
``validator=colander.Range(0, 200)``. A validator is not called after
|
||||||
serialization, only after deserialization.
|
serialization, only after deserialization.
|
||||||
|
|
||||||
The *default* of a structure indicates its default value if a value
|
The *default* of a structure indicates its default value if a value
|
||||||
@@ -131,35 +133,35 @@ If a structure does not have a default, it is considered required.
|
|||||||
The *name* of a structure appears in error reports.
|
The *name* of a structure appears in error reports.
|
||||||
|
|
||||||
The name of a structure that is introduced as a class-level attribute
|
The name of a structure that is introduced as a class-level attribute
|
||||||
of a ``cereal.MappingSchema`` or ``cereal.TupleSchema`` is its class
|
of a ``colander.MappingSchema`` or ``colander.TupleSchema`` is its
|
||||||
attribute name. For example:
|
class attribute name. For example:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
class Phone(cereal.MappingSchema):
|
class Phone(colander.MappingSchema):
|
||||||
location = cereal.Structure(cereal.String(),
|
location = colander.Structure(colander.String(),
|
||||||
validator=cereal.OneOf(['home', 'work']))
|
validator=colander.OneOf(['home', 'work']))
|
||||||
number = cereal.Structure(cereal.String())
|
number = colander.Structure(colander.String())
|
||||||
|
|
||||||
The name of the structure defined via ``location =
|
The name of the structure defined via ``location =
|
||||||
cereal.Structure(..)`` within the schema above is ``location``.
|
colander.Structure(..)`` within the schema above is ``location``.
|
||||||
|
|
||||||
Schema Objects
|
Schema Objects
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The result of creating an instance of a ``cereal.MappingSchema`` or
|
The result of creating an instance of a ``colander.MappingSchema`` or
|
||||||
``cereal.TupleSchema`` object is also a *structure* object.
|
``colander.TupleSchema`` object is also a *structure* object.
|
||||||
|
|
||||||
Instantiating a ``cereal.MappingSchema`` creates a structure which has
|
Instantiating a ``colander.MappingSchema`` creates a structure which
|
||||||
a *type* value of ``cereal.Mapping``. Instantiating a
|
has a *type* value of ``colander.Mapping``. Instantiating a
|
||||||
``cereal.TupleSchema`` creates a structure which has a *type* value of
|
``colander.TupleSchema`` creates a structure which has a *type* value
|
||||||
``cereal.Tuple``.
|
of ``colander.Tuple``.
|
||||||
|
|
||||||
A structure defined by instantiating a ``cereal.MappingSchema`` or a
|
A structure defined by instantiating a ``colander.MappingSchema`` or a
|
||||||
``cereal.TupleSchema`` usually has no validator, and has the empty
|
``colander.TupleSchema`` usually has no validator, and has the empty
|
||||||
string as its name.
|
string as its name.
|
||||||
|
|
||||||
Deserializing A Data Structure Using a Schema
|
Deserializing A Data Structure Using a Schema
|
||||||
@@ -170,22 +172,24 @@ Earlier we defined a schema:
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
class Friend(cereal.TupleSchema):
|
class Friend(colander.TupleSchema):
|
||||||
rank = cereal.Structure(cereal.Int(), validator=cereal.Range(0, 9999))
|
rank = colander.Structure(colander.Int(),
|
||||||
name = cereal.Structure(cereal.String())
|
validator=colander.Range(0, 9999))
|
||||||
|
name = colander.Structure(colander.String())
|
||||||
|
|
||||||
class Phone(cereal.MappingSchema):
|
class Phone(colander.MappingSchema):
|
||||||
location = cereal.Structure(cereal.String(),
|
location = colander.Structure(colander.String(),
|
||||||
validator=cereal.OneOf(['home', 'work']))
|
validator=colander.OneOf(['home', 'work']))
|
||||||
number = cereal.Structure(cereal.String())
|
number = colander.Structure(colander.String())
|
||||||
|
|
||||||
class Person(cereal.MappingSchema):
|
class Person(colander.MappingSchema):
|
||||||
name = cereal.Structure(cereal.String())
|
name = colander.Structure(colander.String())
|
||||||
age = cereal.Structure(cereal.Int(), validator=cereal.Range(0, 200))
|
age = colander.Structure(colander.Int(),
|
||||||
friends = cereal.Structure(cereal.Sequence(Friend()))
|
validator=colander.Range(0, 200))
|
||||||
phones = cereal.Structure(cereal.Sequence(Phone()))
|
friends = colander.Structure(colander.Sequence(Friend()))
|
||||||
|
phones = colander.Structure(colander.Sequence(Phone()))
|
||||||
|
|
||||||
Let's now use this schema to try to deserialize some concrete data
|
Let's now use this schema to try to deserialize some concrete data
|
||||||
structures.
|
structures.
|
||||||
@@ -237,7 +241,7 @@ or a validation error?
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'name':'keith',
|
'name':'keith',
|
||||||
@@ -249,7 +253,7 @@ or a validation error?
|
|||||||
schema = Person()
|
schema = Person()
|
||||||
try:
|
try:
|
||||||
schema.deserialize(data)
|
schema.deserialize(data)
|
||||||
except cereal.Invalid, e:
|
except colander.Invalid, e:
|
||||||
print e.asdict()
|
print e.asdict()
|
||||||
|
|
||||||
The ``deserialize`` method will raise an exception, and the ``except``
|
The ``deserialize`` method will raise an exception, and the ``except``
|
||||||
@@ -278,53 +282,56 @@ Defining A Schema Imperatively
|
|||||||
|
|
||||||
The above schema we defined was defined declaratively via a set of
|
The above schema we defined was defined declaratively via a set of
|
||||||
``class`` statements. It's often useful to create schemas more
|
``class`` statements. It's often useful to create schemas more
|
||||||
dynamically. For this reason, Cereal offers an "imperative" mode of
|
dynamically. For this reason, Colander offers an "imperative" mode of
|
||||||
schema configuration. Here's our previous declarative schema:
|
schema configuration. Here's our previous declarative schema:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
class Friend(cereal.TupleSchema):
|
class Friend(colander.TupleSchema):
|
||||||
rank = cereal.Structure(cereal.Int(), validator=cereal.Range(0, 9999))
|
rank = colander.Structure(colander.Int(),
|
||||||
name = cereal.Structure(cereal.String())
|
validator=colander.Range(0, 9999))
|
||||||
|
name = colander.Structure(colander.String())
|
||||||
|
|
||||||
class Phone(cereal.MappingSchema):
|
class Phone(colander.MappingSchema):
|
||||||
location = cereal.Structure(cereal.String(),
|
location = colander.Structure(colander.String(),
|
||||||
validator=cereal.OneOf(['home', 'work']))
|
validator=colander.OneOf(['home', 'work']))
|
||||||
number = cereal.Structure(cereal.String())
|
number = colander.Structure(colander.String())
|
||||||
|
|
||||||
class Person(cereal.MappingSchema):
|
class Person(colander.MappingSchema):
|
||||||
name = cereal.Structure(cereal.String())
|
name = colander.Structure(colander.String())
|
||||||
age = cereal.Structure(cereal.Int(), validator=cereal.Range(0, 200))
|
age = colander.Structure(colander.Int(),
|
||||||
friends = cereal.Structure(cereal.Sequence(Friend()))
|
validator=colander.Range(0, 200))
|
||||||
phones = cereal.Structure(cereal.Sequence(Phone()))
|
friends = colander.Structure(colander.Sequence(Friend()))
|
||||||
|
phones = colander.Structure(colander.Sequence(Phone()))
|
||||||
|
|
||||||
We can imperatively construct a completely equivalent schema like so:
|
We can imperatively construct a completely equivalent schema like so:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
friend = cereal.Structure(Tuple())
|
friend = colander.Structure(Tuple())
|
||||||
friend.add(cereal.Structure(cereal.Int(), validator=cereal.Range(0, 9999),
|
friend.add(colander.Structure(colander.Int(),
|
||||||
|
validator=colander.Range(0, 9999),
|
||||||
name='rank'))
|
name='rank'))
|
||||||
friend.add(cereal.Structure(cereal.String()), name='name')
|
friend.add(colander.Structure(colander.String()), name='name')
|
||||||
|
|
||||||
phone = cereal.Structure(Mapping())
|
phone = colander.Structure(Mapping())
|
||||||
phone.add(cereal.Structure(cereal.String(),
|
phone.add(colander.Structure(colander.String(),
|
||||||
validator=cereal.OneOf(['home', 'work']),
|
validator=colander.OneOf(['home', 'work']),
|
||||||
name='location'))
|
name='location'))
|
||||||
phone.add(cereal.Structure(cereal.String(), name='number'))
|
phone.add(colander.Structure(colander.String(), name='number'))
|
||||||
|
|
||||||
schema = cereal.Structure(Mapping())
|
schema = colander.Structure(Mapping())
|
||||||
schema.add(cereal.Structure(cereal.String(), name='name'))
|
schema.add(colander.Structure(colander.String(), name='name'))
|
||||||
schema.add(cereal.Structure(cereal.Int(), name='age'),
|
schema.add(colander.Structure(colander.Int(), name='age'),
|
||||||
validator=cereal.Range(0, 200))
|
validator=colander.Range(0, 200))
|
||||||
schema.add(cereal.Structure(cereal.Sequence(friend), name='friends'))
|
schema.add(colander.Structure(colander.Sequence(friend), name='friends'))
|
||||||
schema.add(cereal.Structure(cereal.Sequence(phone), name='phones'))
|
schema.add(colander.Structure(colander.Sequence(phone), name='phones'))
|
||||||
|
|
||||||
Defining a schema imperatively is a lot uglier than defining a schema
|
Defining a schema imperatively is a lot uglier than defining a schema
|
||||||
declaratively, but it's often more useful when you need to define a
|
declaratively, but it's often more useful when you need to define a
|
||||||
@@ -385,10 +392,10 @@ Here's how you would use the resulting class as part of a schema:
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
class Schema(cereal.MappingSchema):
|
class Schema(colander.MappingSchema):
|
||||||
interested = cereal.Structure(Boolean())
|
interested = colander.Structure(Boolean())
|
||||||
|
|
||||||
The above schema has a member named ``interested`` which will now be
|
The above schema has a member named ``interested`` which will now be
|
||||||
serialized and deserialized as a boolean, according to the logic
|
serialized and deserialized as a boolean, according to the logic
|
||||||
@@ -399,15 +406,16 @@ Note that the only real constraint of a type class is that its
|
|||||||
by its ``deserialize`` method and vice versa.
|
by its ``deserialize`` method and vice versa.
|
||||||
|
|
||||||
For a more formal definition of a the interface of a type, see
|
For a more formal definition of a the interface of a type, see
|
||||||
:class:`cereal.interfaces.Type`.
|
:class:`colander.interfaces.Type`.
|
||||||
|
|
||||||
Defining a New Validator
|
Defining a New Validator
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
A validator is a callable which accepts two positional arguments:
|
A validator is a callable which accepts two positional arguments:
|
||||||
``struct`` and ``value``. It returns ``None`` if the value is valid.
|
``struct`` and ``value``. It returns ``None`` if the value is valid.
|
||||||
It raises a ``cereal.Invalid`` exception if the value is not valid.
|
It raises a ``colander.Invalid`` exception if the value is not valid.
|
||||||
Here's a validator that checks if the value is a valid credit card number.
|
Here's a validator that checks if the value is a valid credit card
|
||||||
|
number.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
@@ -438,18 +446,18 @@ schema:
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
import cereal
|
import colander
|
||||||
|
|
||||||
class Schema(cereal.MappingSchema):
|
class Schema(colander.MappingSchema):
|
||||||
cc_number = cereal.Structure(cereal.String(), validator=lunhnok)
|
cc_number = colander.Structure(colander.String(), validator=lunhnok)
|
||||||
|
|
||||||
Note that the validator doesn't need to check if the ``value`` is a
|
Note that the validator doesn't need to check if the ``value`` is a
|
||||||
string: this has already been done as the result of the type of the
|
string: this has already been done as the result of the type of the
|
||||||
``cc_number`` structure being ``cereal.String``. Validators are always
|
``cc_number`` structure being ``colander.String``. Validators are
|
||||||
passed the *deserialized* value when they are invoked.
|
always passed the *deserialized* value when they are invoked.
|
||||||
|
|
||||||
For a more formal definition of a the interface of a validator, see
|
For a more formal definition of a the interface of a validator, see
|
||||||
:class:`cereal.interfaces.Validator`.
|
:class:`colander.interfaces.Validator`.
|
||||||
|
|
||||||
Interface and API Documentation
|
Interface and API Documentation
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
Interfaces
|
Interfaces
|
||||||
----------
|
----------
|
||||||
|
|
||||||
.. automodule:: cereal.interfaces
|
.. automodule:: colander.interfaces
|
||||||
|
|
||||||
.. autofunction:: Validator
|
.. autofunction:: Validator
|
||||||
|
|
||||||
|
@@ -3,8 +3,8 @@ zip_ok = false
|
|||||||
|
|
||||||
[nosetests]
|
[nosetests]
|
||||||
match=^test
|
match=^test
|
||||||
where=cereal
|
where=colander
|
||||||
nocapture=1
|
nocapture=1
|
||||||
cover-package=cereal
|
cover-package=colander
|
||||||
cover-erase=1
|
cover-erase=1
|
||||||
|
|
||||||
|
6
setup.py
6
setup.py
@@ -23,7 +23,7 @@ CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
|
|||||||
|
|
||||||
requires = []
|
requires = []
|
||||||
|
|
||||||
setup(name='cereal',
|
setup(name='colander',
|
||||||
version='0.0',
|
version='0.0',
|
||||||
description=('A simple schema-based serialization and deserialization '
|
description=('A simple schema-based serialization and deserialization '
|
||||||
'library'),
|
'library'),
|
||||||
@@ -35,13 +35,13 @@ setup(name='cereal',
|
|||||||
keywords='serialize deserialize validate schema validation',
|
keywords='serialize deserialize validate schema validation',
|
||||||
author="Agendaless Consulting",
|
author="Agendaless Consulting",
|
||||||
author_email="repoze-dev@lists.repoze.org",
|
author_email="repoze-dev@lists.repoze.org",
|
||||||
url="http://docs.repoze.org/cereal",
|
url="http://docs.repoze.org/colander",
|
||||||
license="BSD-derived (http://www.repoze.org/LICENSE.txt)",
|
license="BSD-derived (http://www.repoze.org/LICENSE.txt)",
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
tests_require = requires,
|
tests_require = requires,
|
||||||
install_requires = requires,
|
install_requires = requires,
|
||||||
test_suite="cereal",
|
test_suite="colander",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user