Colander

Latest version: v2.0

Safety actively analyzes 629811 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 4 of 8

1.0a5

Not secure
==================

- Fix bug introduced by supporting spec-mandated truncations of ISO-8601
timezones. A TypeError would be raised instead of Invalid. See
https://github.com/Pylons/colander/issues/111.

1.0a4

Not secure
==================

- Loosen Email validator regex (permit apostrophes, bang, etc in localpart).

- Allow for timezone info objects to be pickled and unpickled "more correctly"
(Use '__getinitargs__' to provide unpickling-only defaults). See
https://github.com/Pylons/colander/pull/108.

1.0a3

Not secure
==================

Features
--------

- Support spec-mandated truncations of ISO-8601 timezones.

- Support spec-mandated truncations of ISO-8601 datetimes.

- Allow specifying custom representations of values for boolean fields.

Bug Fixes
---------

- Ensure that ``colander.iso8601.FixedOffset`` instances can be unpickled.

- Avoid validating strings as sequences under Py3k.

- Sync documentation with 0.9.9 change to use ``insert_before`` rather than
``schema_order``. See https://github.com/Pylons/colander/issues/104

1.0a2

Not secure
==================

Features
--------

- Add ``colander.ContainsOnly`` and ``colander.url`` validators.

- Add ``colander.instantiate`` to help define schemas containing
mappings and sequences more succinctly.

1.0a1

Not secure
==================

Bug Fixes
---------

- Work around a regression in Python 3.3 for ``colander.Decimal`` when it's
used with a ``quant`` argument but without a ``rounding`` argument.
See https://github.com/Pylons/colander/issues/66

- Using ``SchemaNode(String, default='', ..)`` now works properly, or at least
more intuitively. Previously if an empty-string ``default`` was supplied,
serialization would return a defaulted value as ``colander.null``. See
https://github.com/Pylons/colander/pull/73.

- Stricter checking in colander.Mapping to prevent items which are logically
not mappings from being accepted during validation (see
https://github.com/Pylons/colander/pull/96).

Features
--------

- Add ``colander.Set`` type, ported from ``deform.Set``

- Add Python 3.3 to tox configuration and use newer tox testing regime
(setup.py dev).

- Add Python 3.3 Trove classifier.

- Calling ``bind`` on a schema node e.g. ``cloned_node = somenode.bind(a=1,
b=2)`` on a schema node now results in the cloned node having a
``bindings`` attribute of the value ``{'a':1, 'b':2}``.

- It is no longer necessary to pass a ``typ`` argument to a SchemaNode
constructor if the node class has a ``schema_type`` callable as a class
attribute which, when called with no arguments, returns a schema type.
This callable will be called to obtain the schema type if a ``typ`` is not
supplied to the constructor. The default ``SchemaNode`` object's
``schema_type`` callable raises a ``NotImplementedError`` when it is
called.

- SchemaNode now has a ``raise_invalid`` method which accepts a message and
raises a colander.Invalid exception using ``self`` as the node and the
message as its message.

- It is now possible and advisable to subclass ``SchemaNode`` in order to
create a bundle of default node behavior. The subclass can define the
following methods and attributes: ``preparer``, ``validator``, ``default``,
``missing``, ``name``, ``title``, ``description``, ``widget``, and
``after_bind``.

For example, the older, more imperative style that looked like this still
works, of course::

from colander import SchemaNode

ranged_int = colander.SchemaNode(
validator=colander.Range(0, 10),
default = 10,
title='Ranged Int'
)

But you can alternately now do something like this::

from colander import SchemaNode

class RangedIntSchemaNode(SchemaNode):
validator = colander.Range(0, 10)
default = 10
title = 'Ranged Int'

ranged_int = RangedInt()

Values that are expected to be callables can now alternately be methods of
the schemanode subclass instead of plain attributes::

from colander import SchemaNode

class RangedIntSchemaNode(SchemaNode):
default = 10
title = 'Ranged Int'

def validator(self, node, cstruct):
if not 0 < cstruct < 10:
raise colander.Invalid(node, 'Must be between 0 and 10')

ranged_int = RangedInt()

Note that when implementing a method value such as ``validator`` that
expects to receive a ``node`` argument, ``node`` must be provided in the
call signature, even though ``node`` will almost always be the same as
``self``. This is because Colander simply treats the method as another
kind of callable, be it a method, or a function, or an instance that has a
``__call__`` method. It doesn't care that it happens to be a method of
``self``, and it needs to support callables that are not methods, so it
sends ``node`` in regardless.

You can't currently use *method* definitions as ``colander.deferred``
callables. For example this will *not* work::

from colander import SchemaNode

class RangedIntSchemaNode(SchemaNode):
default = 10
title = 'Ranged Int'

colander.deferred
def validator(self, node, kw):
request = kw['request']
def avalidator(node, cstruct):
if not 0 < cstruct < 10:
if request.user != 'admin':
raise colander.Invalid(node, 'Must be between 0 and 10')
return avalidator

ranged_int = RangedInt()
bound_ranged_int = ranged_int.bind(request=request)

This will result in::

TypeError: avalidator() takes exactly 3 arguments (2 given)

However, if you treat the thing being decorated as a function instead of a
method (remove the ``self`` argument from the argument list), it will
indeed work)::

from colander import SchemaNode

class RangedIntSchemaNode(SchemaNode):
default = 10
title = 'Ranged Int'

colander.deferred
def validator(node, kw):
request = kw['request']
def avalidator(node, cstruct):
if not 0 < cstruct < 10:
if request.user != 'admin':
raise colander.Invalid(node, 'Must be between 0 and 10')
return avalidator

ranged_int = RangedInt()
bound_ranged_int = ranged_int.bind(request=request)

In previous releases of Colander, the only way to defer the computation of
values was via the ``colander.deferred`` decorator. In this release,
however, you can instead use the ``bindings`` attribute of ``self`` to
obtain access to the bind parameters within values that are plain old
methods::

from colander import SchemaNode

class RangedIntSchemaNode(SchemaNode):
default = 10
title = 'Ranged Int'

def validator(self, node, cstruct):
request = self.bindings['request']
if not 0 < cstruct < 10:
if request.user != 'admin':
raise colander.Invalid(node, 'Must be between 0 and 10')

ranged_int = RangedInt()
bound_range_int = ranged_int.bind(request=request)

If the things you're trying to defer aren't callables like ``validator``,
but they're instead just plain attributes like ``missing`` or ``default``,
instead of using a ``colander.deferred``, you can use ``after_bind`` to set
attributes of the schemanode that rely on binding variables::

from colander import SchemaNode

class UserIdSchemaNode(SchemaNode):
title = 'User Id'

def after_bind(self, node, kw):
self.default = kw['request'].user.id

You can override the default values of a schemanode subclass in its
constructor::

from colander import SchemaNode

class RangedIntSchemaNode(SchemaNode):
default = 10
title = 'Ranged Int'
validator = colander.Range(0, 10)

ranged_int = RangedInt(validator=colander.Range(0, 20))

In the above example, the validation will be done on 0-20, not 0-10.

If a schema node name conflicts with a schema value attribute name on the
same class, you can work around it by giving the schema node a bogus name
in the class definition but providing a correct ``name`` argument to the
schema node constructor::

from colander import SchemaNode, Schema

class SomeSchema(Schema):
title = 'Some Schema'
thisnamewillbeignored = colander.SchemaNode(
colander.String(),
name='title'
)

Note that such a workaround is only required if the conflicting names are
attached to the *exact same* class definition. Colander scrapes off schema
node definitions at each class' construction time, so it's not an issue for
inherited values. For example::

from colander import SchemaNode, Schema

class SomeSchema(Schema):
title = colander.SchemaNode(colander.String())

class AnotherSchema(SomeSchema):
title = 'Some Schema'

schema = AnotherSchema()

In the above example, even though the ``title = 'Some Schema'`` appears to
override the superclass' ``title`` SchemaNode, a ``title`` SchemaNode will
indeed be present in the child list of the ``schema`` instance
(``schema['title']`` will return the ``title`` SchemaNode) and the schema's
``title`` attribute will be ``Some Schema`` (``schema.title`` will return
``Some Schema``).

Normal inheritance rules apply to class attributes and methods defined in
a schemanode subclass. If your schemanode subclass inherits from another
schemanode class, your schemanode subclass' methods and class attributes
will override the superclass' methods and class attributes.

Ordering of child schema nodes when inheritance is used works like this:
the "deepest" SchemaNode class in the MRO of the inheritance chain is
consulted first for nodes, then the next deepest, then the next, and so on.
So the deepest class' nodes come first in the relative ordering of schema
nodes, then the next deepest, and so on. For example::

class One(colander.Schema):
a = colander.SchemaNode(
colander.String(),
id='a1',
)
b = colander.SchemaNode(
colander.String(),
id='b1',
)
d = colander.SchemaNode(
colander.String(),
id='d1',
)

class Two(One):
a = colander.SchemaNode(
colander.String(),
id='a2',
)
c = colander.SchemaNode(
colander.String(),
id='c2',
)
e = colander.SchemaNode(
colander.String(),
id='e2',
)

class Three(Two):
b = colander.SchemaNode(
colander.String(),
id='b3',
)
d = colander.SchemaNode(
colander.String(),
id='d3',
)
f = colander.SchemaNode(
colander.String(),
id='f3',
)

three = Three()

The ordering of child nodes computed in the schema node ``three`` will be
``['a2', 'b3', 'd3', 'c2', 'e2', 'f3']``. The ordering starts ``a1``,
``b1``, ``d1`` because that's the ordering of nodes in ``One``, and
``One`` is the deepest SchemaNode in the inheritance hierarchy. Then it
processes the nodes attached to ``Two``, the next deepest, which causes
``a1`` to be replaced by ``a2``, and ``c2`` and ``e2`` to be appended to
the node list. Then finally it processes the nodes attached to ``Three``,
which causes ``b1`` to be replaced by ``b3``, and ``d1`` to be replaced by
``d3``, then finally ``f`` is appended.

Multiple inheritance works the same way::

class One(colander.Schema):
a = colander.SchemaNode(
colander.String(),
id='a1',
)
b = colander.SchemaNode(
colander.String(),
id='b1',
)
d = colander.SchemaNode(
colander.String(),
id='d1',
)

class Two(colander.Schema):
a = colander.SchemaNode(
colander.String(),
id='a2',
)
c = colander.SchemaNode(
colander.String(),
id='c2',
)
e = colander.SchemaNode(
colander.String(),
id='e2',
)

class Three(Two, One):
b = colander.SchemaNode(
colander.String(),
id='b3',
)
d = colander.SchemaNode(
colander.String(),
id='d3',
)
f = colander.SchemaNode(
colander.String(),
id='f3',
)

three = Three()

The resulting node ordering of ``three`` is the same as the single
inheritance example: ``['a2', 'b3', 'd3', 'c2', 'e2', 'f3']`` due to the
MRO deepest-first ordering (``One``, then ``Two``, then ``Three``).

Backwards Incompatibilities
---------------------------

- Passing non-SchemaNode derivative instances as ``*children`` into a
SchemaNode constructor is no longer supported. Symptom: ``AttributeError:
name`` when constructing a SchemaNode.

0.9.9

Not secure
==================

Features
--------

- Allow the use of ``missing=None`` for Number. See
https://github.com/Pylons/colander/pull/59 .

- Create a ``colander.Money`` type that is a Decimal type with
two-decimal-point precision rounded-up.

- Allow ``quant`` and ``rounding`` args to ``colander.Decimal`` constructor.

- ``luhnok`` validator added (credit card luhn mod10 validator).

- Add an ``insert`` method to SchemaNode objects.

- Add an ``insert_before`` method to SchemaNode objects.

- Better class-based mapping schema inheritance model.

* A node declared in a subclass of a mapping schema superclass now
overrides any node with the same name inherited from any superclass.
Previously, it just repeated and didn't override.

* An ``insert_before`` keyword argument may be passed to a SchemaNode
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.

- The ``preparer=`` argument to SchemaNodes may now be a sequence of
preparers.

- Added a ``cstruct_children`` method to SchemaNode.

- A new ``cstruct_children`` API should exist on schema types. If
``SchemaNode.cstruct_children`` is called on a node with a type that does
not have a ``cstruct_children`` method, a deprecation warning is emitted
and ``[]`` is returned (this may or may not be the correct value for your
custom type).

Backwards Incompatibilities
---------------------------

- The inheritance changes required a minor backwards incompatibility: calling
``__setitem__`` on a SchemaNode will no longer raise ``KeyError`` when
attempting to set a subnode into a node that doesn't already have an
existing subnode by that name. Instead, the subnode will be appended to
the child list.

Documentation
-------------

- A "Schema Inheritance" section was added to the Basics chapter
documentation.

Page 4 of 8

© 2024 Safety CLI Cybersecurity Inc. All Rights Reserved.