Removed all stray whitespace.
This commit is contained in:
@@ -28,7 +28,7 @@ Features
|
||||
constructor. This is a string naming a node in a superclass. A node
|
||||
with an ``insert_before`` will be placed before the named node in a
|
||||
parent mapping schema.
|
||||
|
||||
|
||||
Backwards Incompatibilities
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@@ -2,7 +2,7 @@ def Preparer(value):
|
||||
"""
|
||||
A preparer is called after deserialization of a value but before
|
||||
that value is validated.
|
||||
|
||||
|
||||
Any modifications to ``value`` required should be made by
|
||||
returning the modified value rather than modifying in-place.
|
||||
|
||||
@@ -10,11 +10,11 @@ def Preparer(value):
|
||||
as-is.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
def Validator(node, value):
|
||||
"""
|
||||
A validator is called after preparation of the deserialized value.
|
||||
|
||||
|
||||
If ``value`` is not valid, raise a :class:`colander.Invalid`
|
||||
instance as an exception after.
|
||||
|
||||
@@ -57,4 +57,4 @@ class Type(object):
|
||||
If the object cannot be deserialized for any reason, a
|
||||
:exc:`colander.Invalid` exception should be raised.
|
||||
"""
|
||||
|
||||
|
||||
|
@@ -53,7 +53,7 @@ class ParseError(Exception):
|
||||
ZERO = timedelta(0)
|
||||
class Utc(tzinfo):
|
||||
"""UTC
|
||||
|
||||
|
||||
"""
|
||||
def utcoffset(self, dt):
|
||||
return ZERO
|
||||
@@ -67,7 +67,7 @@ UTC = Utc()
|
||||
|
||||
class FixedOffset(tzinfo):
|
||||
"""Fixed offset in hours and minutes from UTC
|
||||
|
||||
|
||||
"""
|
||||
def __init__(self, offset_hours, offset_minutes, name):
|
||||
self.__offset = timedelta(hours=offset_hours, minutes=offset_minutes)
|
||||
@@ -81,13 +81,13 @@ class FixedOffset(tzinfo):
|
||||
|
||||
def dst(self, dt):
|
||||
return ZERO
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "<FixedOffset %r>" % self.__name
|
||||
|
||||
def parse_timezone(tzstring, default_timezone=UTC):
|
||||
"""Parses ISO 8601 time zone specs into tzinfo offsets
|
||||
|
||||
|
||||
"""
|
||||
if tzstring == "Z":
|
||||
return default_timezone
|
||||
@@ -106,7 +106,7 @@ def parse_timezone(tzstring, default_timezone=UTC):
|
||||
|
||||
def parse_date(datestring, default_timezone=UTC):
|
||||
"""Parses ISO 8601 dates into datetime objects
|
||||
|
||||
|
||||
The timezone is parsed from the date string. However it is quite common to
|
||||
have dates without a timezone (not strictly correct). In this case the
|
||||
default timezone specified in default_timezone is used. This is UTC by
|
||||
|
@@ -110,7 +110,7 @@ class TestInvalid(unittest.TestCase):
|
||||
exc1.add(exc2, 2)
|
||||
exc2.add(exc3, 3)
|
||||
d = exc1.asdict()
|
||||
self.assertEqual(d,
|
||||
self.assertEqual(d,
|
||||
{'node1.node2.3': 'exc1; exc2; validator1; validator2',
|
||||
'node1.node3': 'exc1; message1'})
|
||||
|
||||
@@ -187,7 +187,7 @@ class TestInvalid(unittest.TestCase):
|
||||
node = DummySchemaNode(None)
|
||||
exc = self._makeOne(node, None)
|
||||
self.assertEqual(exc.messages(), [])
|
||||
|
||||
|
||||
class TestAll(unittest.TestCase):
|
||||
def _makeOne(self, validators):
|
||||
from colander import All
|
||||
@@ -218,7 +218,7 @@ class TestAll(unittest.TestCase):
|
||||
validator = self._makeOne([validator1, validator2])
|
||||
exc = invalid_exc(validator, node, None)
|
||||
self.assertEqual(exc.children, [exc1, exc2])
|
||||
|
||||
|
||||
class TestFunction(unittest.TestCase):
|
||||
def _makeOne(self, *arg, **kw):
|
||||
from colander import Function
|
||||
@@ -1433,7 +1433,7 @@ class TestGlobalObject(unittest.TestCase):
|
||||
typ = self._makeOne(package=colander)
|
||||
node = DummySchemaNode(None)
|
||||
result = typ._zope_dottedname_style(
|
||||
node,
|
||||
node,
|
||||
'.tests.test_colander.TestGlobalObject')
|
||||
self.assertEqual(result, self.__class__)
|
||||
|
||||
@@ -1442,7 +1442,7 @@ class TestGlobalObject(unittest.TestCase):
|
||||
typ = self._makeOne(package=colander.tests)
|
||||
node = DummySchemaNode(None)
|
||||
result = typ._zope_dottedname_style(
|
||||
node,
|
||||
node,
|
||||
'..tests.test_colander.TestGlobalObject')
|
||||
self.assertEqual(result, self.__class__)
|
||||
|
||||
@@ -1513,7 +1513,7 @@ class TestGlobalObject(unittest.TestCase):
|
||||
import colander
|
||||
typ = self._makeOne(package=colander)
|
||||
result = typ._pkg_resources_style(
|
||||
None,
|
||||
None,
|
||||
'.tests.test_colander:TestGlobalObject')
|
||||
self.assertEqual(result, self.__class__)
|
||||
|
||||
@@ -1559,7 +1559,7 @@ class TestGlobalObject(unittest.TestCase):
|
||||
typ = self._makeOne()
|
||||
node = DummySchemaNode(None)
|
||||
result = typ.deserialize(
|
||||
node,
|
||||
node,
|
||||
'colander.tests.test_colander:TestGlobalObject')
|
||||
self.assertEqual(result, self.__class__)
|
||||
|
||||
@@ -1567,7 +1567,7 @@ class TestGlobalObject(unittest.TestCase):
|
||||
typ = self._makeOne()
|
||||
node = DummySchemaNode(None)
|
||||
result = typ.deserialize(
|
||||
node,
|
||||
node,
|
||||
'colander.tests.test_colander.TestGlobalObject')
|
||||
self.assertEqual(result, self.__class__)
|
||||
|
||||
@@ -2258,8 +2258,8 @@ class TestSchemaNode(unittest.TestCase):
|
||||
import colander
|
||||
class FnordSchema(colander.Schema):
|
||||
fnord = colander.SchemaNode(
|
||||
colander.Sequence(),
|
||||
colander.SchemaNode(colander.Integer(), name=''),
|
||||
colander.Sequence(),
|
||||
colander.SchemaNode(colander.Integer(), name=''),
|
||||
name="fnord[]"
|
||||
)
|
||||
schema = FnordSchema()
|
||||
@@ -2291,7 +2291,7 @@ class TestMappingSchemaInheritance(unittest.TestCase):
|
||||
colander.Bool(),
|
||||
insert_before='name',
|
||||
)
|
||||
|
||||
|
||||
class Friend(colander.Schema):
|
||||
rank = rank_node
|
||||
name = name_node
|
||||
@@ -2558,7 +2558,7 @@ class TestFunctional(object):
|
||||
self.assertEqual(result[k], v)
|
||||
for k, v in result.items():
|
||||
self.assertEqual(expected[k], v)
|
||||
|
||||
|
||||
def test_unflatten_ok(self):
|
||||
import colander
|
||||
fstruct = {
|
||||
@@ -2630,7 +2630,7 @@ class TestFunctional(object):
|
||||
self.assertEqual(result[k], v)
|
||||
for k, v in result.items():
|
||||
self.assertEqual(expected[k], v)
|
||||
|
||||
|
||||
def test_flatten_unflatten_roundtrip(self):
|
||||
import colander
|
||||
appstruct = {
|
||||
|
@@ -16,13 +16,13 @@ class Test_Utc(unittest.TestCase):
|
||||
inst = self._makeOne()
|
||||
result = inst.tzname(None)
|
||||
self.assertEqual(result, "UTC")
|
||||
|
||||
|
||||
def test_dst(self):
|
||||
from ..iso8601 import ZERO
|
||||
inst = self._makeOne()
|
||||
result = inst.dst(None)
|
||||
self.assertEqual(result, ZERO)
|
||||
|
||||
|
||||
class Test_FixedOffset(unittest.TestCase):
|
||||
def _makeOne(self):
|
||||
from ..iso8601 import FixedOffset
|
||||
@@ -67,15 +67,15 @@ class Test_parse_timezone(unittest.TestCase):
|
||||
def test_positive(self):
|
||||
tzstring = "+01:00"
|
||||
result = self._callFUT(tzstring)
|
||||
self.assertEqual(result.utcoffset(None),
|
||||
self.assertEqual(result.utcoffset(None),
|
||||
datetime.timedelta(hours=1, minutes=0))
|
||||
|
||||
def test_negative(self):
|
||||
tzstring = "-01:00"
|
||||
result = self._callFUT(tzstring)
|
||||
self.assertEqual(result.utcoffset(None),
|
||||
self.assertEqual(result.utcoffset(None),
|
||||
datetime.timedelta(hours=-1, minutes=0))
|
||||
|
||||
|
||||
class Test_parse_date(unittest.TestCase):
|
||||
def _callFUT(self, datestring):
|
||||
from ..iso8601 import parse_date
|
||||
@@ -92,13 +92,13 @@ class Test_parse_date(unittest.TestCase):
|
||||
def test_normal(self):
|
||||
from ..iso8601 import UTC
|
||||
result = self._callFUT("2007-01-25T12:00:00Z")
|
||||
self.assertEqual(result,
|
||||
self.assertEqual(result,
|
||||
datetime.datetime(2007, 1, 25, 12, 0, tzinfo=UTC))
|
||||
|
||||
|
||||
def test_fraction(self):
|
||||
from ..iso8601 import UTC
|
||||
result = self._callFUT("2007-01-25T12:00:00.123Z")
|
||||
self.assertEqual(result,
|
||||
self.assertEqual(result,
|
||||
datetime.datetime(2007, 1, 25, 12, 0, 0, 123000,
|
||||
tzinfo=UTC))
|
||||
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
body {
|
||||
background-color: #006339;
|
||||
}
|
||||
|
||||
|
||||
div.document {
|
||||
background-color: #dad3bd;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ div.related {
|
||||
color: #dad3bd !important;
|
||||
background-color: #00744a;
|
||||
}
|
||||
|
||||
|
||||
div.related a {
|
||||
color: #dad3bd !important;
|
||||
}
|
||||
|
@@ -42,12 +42,12 @@ different types.
|
||||
import colander
|
||||
|
||||
class Friend(colander.TupleSchema):
|
||||
rank = colander.SchemaNode(colander.Int(),
|
||||
rank = colander.SchemaNode(colander.Int(),
|
||||
validator=colander.Range(0, 9999))
|
||||
name = colander.SchemaNode(colander.String())
|
||||
|
||||
class Phone(colander.MappingSchema):
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
validator=colander.OneOf(['home', 'work']))
|
||||
number = colander.SchemaNode(colander.String())
|
||||
|
||||
@@ -63,7 +63,7 @@ different types.
|
||||
validator=colander.Range(0, 200))
|
||||
friends = Friends()
|
||||
phones = Phones()
|
||||
|
||||
|
||||
For ease of reading, we've actually defined *five* schemas above, but
|
||||
we coalesce them all into a single ``Person`` schema. As the result
|
||||
of our definitions, a ``Person`` represents:
|
||||
@@ -144,7 +144,7 @@ attached to the node unmolested (e.g. when ``foo=1`` is passed, the
|
||||
resulting schema node will have an attribute named ``foo`` with the
|
||||
value ``1``).
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
You may see some higher-level systems (such as Deform) pass a ``widget``
|
||||
argument to a SchemaNode constructor. Such systems make use of the fact
|
||||
@@ -167,7 +167,7 @@ its class attribute name. For example:
|
||||
import colander
|
||||
|
||||
class Phone(colander.MappingSchema):
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
validator=colander.OneOf(['home', 'work']))
|
||||
number = colander.SchemaNode(colander.String())
|
||||
|
||||
@@ -181,7 +181,7 @@ Schema Objects
|
||||
In the examples above, if you've been paying attention, you'll have
|
||||
noticed that we're defining classes which subclass from
|
||||
:class:`colander.MappingSchema`, :class:`colander.TupleSchema` and
|
||||
:class:`colander.SequenceSchema`.
|
||||
:class:`colander.SequenceSchema`.
|
||||
|
||||
It's turtles all the way down: the result of creating an instance of
|
||||
any of :class:`colander.MappingSchema`, :class:`colander.TupleSchema`
|
||||
@@ -208,12 +208,12 @@ Earlier we defined a schema:
|
||||
import colander
|
||||
|
||||
class Friend(colander.TupleSchema):
|
||||
rank = colander.SchemaNode(colander.Int(),
|
||||
rank = colander.SchemaNode(colander.Int(),
|
||||
validator=colander.Range(0, 9999))
|
||||
name = colander.SchemaNode(colander.String())
|
||||
|
||||
class Phone(colander.MappingSchema):
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
validator=colander.OneOf(['home', 'work']))
|
||||
number = colander.SchemaNode(colander.String())
|
||||
|
||||
@@ -370,13 +370,13 @@ error reporting in a different way. In particular, such a system may
|
||||
need to present the errors next to a field in a form. It may need to
|
||||
translate error messages to another language. To do these things
|
||||
effectively, it will almost certainly need to walk and introspect the
|
||||
exception graph manually.
|
||||
exception graph manually.
|
||||
|
||||
The :exc:`colander.Invalid` exceptions raised by Colander validation
|
||||
are very rich. They contain detailed information about the
|
||||
circumstances of an error. If you write a system based on Colander
|
||||
that needs to display and format Colander exceptions specially, you
|
||||
will need to get comfy with the Invalid exception API.
|
||||
will need to get comfy with the Invalid exception API.
|
||||
|
||||
When a validation-related error occurs during deserialization, each
|
||||
node in the schema that had an error (and any of its parents) will be
|
||||
@@ -396,7 +396,7 @@ attribute with the value ``None``. Each exception instance will also
|
||||
have an attribute named ``node``, representing the schema node to
|
||||
which the exception is related.
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
Translation strings are objects which behave like Unicode objects but have
|
||||
extra metadata associated with them for use in translation systems. See
|
||||
@@ -421,7 +421,7 @@ value before validating it.
|
||||
For example, a :class:`~colander.String` node may be required to
|
||||
contain content, but that content may come from a rich text
|
||||
editor. Such an editor may return ``<b></b>`` which may appear to be
|
||||
valid but doesn't contain content, or
|
||||
valid but doesn't contain content, or
|
||||
``<a href="javascript:alert('evil'')">good</a>`` which is valid, but
|
||||
only after some processing.
|
||||
|
||||
@@ -653,12 +653,12 @@ schema configuration. Here's our previous declarative schema:
|
||||
import colander
|
||||
|
||||
class Friend(colander.TupleSchema):
|
||||
rank = colander.SchemaNode(colander.Int(),
|
||||
rank = colander.SchemaNode(colander.Int(),
|
||||
validator=colander.Range(0, 9999))
|
||||
name = colander.SchemaNode(colander.String())
|
||||
|
||||
class Phone(colander.MappingSchema):
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
validator=colander.OneOf(['home', 'work']))
|
||||
number = colander.SchemaNode(colander.String())
|
||||
|
||||
@@ -696,7 +696,7 @@ We can imperatively construct a completely equivalent schema like so:
|
||||
|
||||
schema = colander.SchemaNode(Mapping())
|
||||
schema.add(colander.SchemaNode(colander.String(), name='name'))
|
||||
schema.add(colander.SchemaNode(colander.Int(), name='age'),
|
||||
schema.add(colander.SchemaNode(colander.Int(), name='age'),
|
||||
validator=colander.Range(0, 200))
|
||||
schema.add(colander.SchemaNode(colander.Sequence(), friend, name='friends'))
|
||||
schema.add(colander.SchemaNode(colander.Sequence(), phone, name='phones'))
|
||||
|
@@ -1,7 +1,7 @@
|
||||
Schema Binding
|
||||
==============
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
Schema binding is new in colander 0.8.
|
||||
|
||||
@@ -150,7 +150,7 @@ Let's take a look at an example:
|
||||
validator = deferred_category_validator,
|
||||
widget = deferred_category_widget,
|
||||
)
|
||||
|
||||
|
||||
schema = BlogPostSchema().bind(
|
||||
max_date = datetime.date.max,
|
||||
max_bodylen = 5000,
|
||||
@@ -164,7 +164,7 @@ decorator to a function that takes two arguments. For a schema node
|
||||
value to be considered deferred, it must be an instance of
|
||||
``colander.deferred`` and using that class as a decorator is the
|
||||
easiest way to ensure that this happens.
|
||||
|
||||
|
||||
To perform binding, the ``bind`` method of a schema node must be
|
||||
called. ``bind`` returns a *clone* of the schema node (and its
|
||||
children, recursively), with all ``colander.deferred`` values
|
||||
|
@@ -111,7 +111,7 @@ within its ``deserialize`` method.
|
||||
|
||||
Type Constructors
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
A type class does not need to implement a constructor (``__init__``),
|
||||
but it isn't prevented from doing so if it needs to accept arguments;
|
||||
Colander itself doesn't construct any types, only users of Colander
|
||||
@@ -157,9 +157,9 @@ card number.
|
||||
sum = sum + digit
|
||||
|
||||
if not (sum % 10) == 0:
|
||||
raise Invalid(node,
|
||||
raise Invalid(node,
|
||||
'%r is not a valid credit card number' % value)
|
||||
|
||||
|
||||
Here's how the resulting ``luhnok`` validator might be used in a
|
||||
schema:
|
||||
|
||||
|
@@ -4,9 +4,9 @@ Manipulating Data Structures
|
||||
============================
|
||||
|
||||
Colander schemas have some utility functions which can be used to manipulate
|
||||
an :term:`appstruct` or a :term:`cstruct`. Nested data structures can be
|
||||
flattened into a single dictionary or a single flattened dictionary can be used
|
||||
to produce a nested data structure. Values of particular nodes can also be set
|
||||
an :term:`appstruct` or a :term:`cstruct`. Nested data structures can be
|
||||
flattened into a single dictionary or a single flattened dictionary can be used
|
||||
to produce a nested data structure. Values of particular nodes can also be set
|
||||
or retrieved based on a flattened path spec.
|
||||
|
||||
Flattening a Data Structure
|
||||
@@ -24,12 +24,12 @@ Consider the following schema:
|
||||
import colander
|
||||
|
||||
class Friend(colander.TupleSchema):
|
||||
rank = colander.SchemaNode(colander.Int(),
|
||||
rank = colander.SchemaNode(colander.Int(),
|
||||
validator=colander.Range(0, 9999))
|
||||
name = colander.SchemaNode(colander.String())
|
||||
|
||||
class Phone(colander.MappingSchema):
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
location = colander.SchemaNode(colander.String(),
|
||||
validator=colander.OneOf(['home', 'work']))
|
||||
number = colander.SchemaNode(colander.String())
|
||||
|
||||
@@ -63,7 +63,7 @@ This data can be flattened:
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
|
||||
schema = Person()
|
||||
fstruct = schema.flatten(appstruct)
|
||||
|
||||
@@ -103,7 +103,7 @@ Accessing and Mutating Nodes in a Data Structure
|
||||
------------------------------------------------
|
||||
|
||||
:attr:`colander.SchemaNode.get_value` and :attr:`colander.SchemaNode.set_value`
|
||||
can be used to access and mutate nodes in an :term:`appstruct` or
|
||||
can be used to access and mutate nodes in an :term:`appstruct` or
|
||||
:term:`cstruct`. Using the example from above:
|
||||
|
||||
.. code-block:: python
|
||||
|
@@ -70,7 +70,7 @@ for serialization which had the :attr:`colander.null` sentinel as the
|
||||
import colander
|
||||
|
||||
schema = Person()
|
||||
serialized = schema.serialize({'name':'Fred', 'age':20,
|
||||
serialized = schema.serialize({'name':'Fred', 'age':20,
|
||||
'hair_color':colander.null})
|
||||
|
||||
When the above is run, the value of ``serialized`` will be
|
||||
@@ -188,7 +188,7 @@ colander.null <missing> null serialized
|
||||
colander.null value null serialized
|
||||
===================== ===================== ===========================
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
``<missing>`` in the above table represents the circumstance in which a
|
||||
key present in a :class:`colander.MappingSchema` is not present in a
|
||||
@@ -230,7 +230,7 @@ a schema, the node will take the following steps:
|
||||
with an explicit ``missing`` value), a :exc:`colander.Invalid` exception
|
||||
will be raised with a message indicating that the field is required.
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
There are differences between serialization and deserialization involving
|
||||
the :attr:`colander.null` value. During serialization, if an
|
||||
@@ -310,7 +310,7 @@ value colander.null value used
|
||||
value_a value_b value_a used
|
||||
===================== ===================== ===========================
|
||||
|
||||
.. note::
|
||||
.. note::
|
||||
|
||||
``<missing>`` in the above table represents the circumstance in which a
|
||||
key present in a :class:`colander.MappingSchema` is not present in a
|
||||
|
8
tox.ini
8
tox.ini
@@ -1,17 +1,17 @@
|
||||
[tox]
|
||||
envlist =
|
||||
envlist =
|
||||
py26,py27,py32,pypy,cover
|
||||
|
||||
[testenv]
|
||||
commands =
|
||||
commands =
|
||||
python setup.py test -q
|
||||
|
||||
[testenv:cover]
|
||||
basepython =
|
||||
python2.6
|
||||
commands =
|
||||
commands =
|
||||
python setup.py nosetests --with-xunit --with-xcoverage
|
||||
deps =
|
||||
deps =
|
||||
nose
|
||||
coverage==3.4
|
||||
nosexcover
|
||||
|
Reference in New Issue
Block a user