An Example

Here's a type which implements boolean serialization and deserialization. It
serializes a boolean to the string true or false or the special
:attr:`colander.null` sentinel; it then deserializes a string (presumably
true or false, but allows some wiggle room for t, on,
yes, y, and 1) to a boolean value.

Here's how you would use the resulting class as part of a schema:

The above schema has a member named interested which will now be
serialized and deserialized as a boolean, according to the logic defined in
the Boolean type class.

its serialize method must be able to make sense of a value generated by
its deserialize method and vice versa.

The serialize method of a type accepts two values: node, and
appstruct. node will be the schema node associated with this type.
The node is used when the type must raise a :exc:`colander.Invalid` error,
which expects a schema node as its first constructor argument. appstruct
will be the :term:`appstruct` value that needs to be serialized.

The deserialize and method of a type accept two values: node, and
cstruct. node will be the schema node associated with this type.
The node is used when the type must raise a :exc:`colander.Invalid` error,
which expects a schema node as its first constructor argument. cstruct
will be the :term:`cstruct` value that needs to be deserialized.

Null Values

The framework requires that both the serialize method and the
deserialize method of a type explicitly deal with the potential to
receive a :attr:`colander.null` value. :attr:`colander.null` will be sent to
the type during serialization and deserialization in circumstances where a
value has not been provided by the data structure being serialized or
deserialized. In the common case, when the serialize or deserialize
method of type receives the :attr:`colander.null` value, it should just
return :attr:`colander.null` to its caller.

A type might also choose to return :attr:`colander.null` if the value it
receives is logically (but not literally) null. For example,
:class:`colander.String` type converts the empty string to colander.null
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
schemas do, so how types are constructed is beyond the scope of
Colander itself.

The :exc:`colander.Invalid` exception may be raised during
serialization or deserialization as necessary for whatever reason the
type feels appropriate (the inability to serialize or deserialize a
value being the most common case).

Defining a New Validator

A validator is a callable which accepts two positional arguments:
node and value. It returns None if the value is valid.
It raises a :class:`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 how the resulting luhnok validator might be used in a
schema:

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
cc_number schema node being :class:`colander.String`. Validators
are always passed the deserialized value when they are invoked.

The node value passed to the validator is a schema node object; it
must in turn be passed to the :exc:`colander.Invalid` exception
constructor if one needs to be raised.