Pylons / colander

A serialization/deserialization/validation library for strings, mappings and lists.
https://docs.pylonsproject.org/projects/colander/en/latest/
Other
448 stars 145 forks source link

Validation for colander.Mapping() too liberal #8

Open deno opened 13 years ago

deno commented 13 years ago

In colander/init.py:405-412 (class Mapping(SchemaType)) there's this validation procedure:

def _validate(self, node, value):
    try:
        return dict(value)
    except Exception, e:
        raise Invalid(…)

The problem is that dict.init will convert to dictionary almost anything:

|  dict(iterable) -> new dictionary initialized as if via:
|      d = {}
|      for k, v in iterable:
|          d[k] = v

Which means that all of these validate correctly:

This is inconsistent with, for example, behavior of colander.String. Zero-value list will result in colander.null:

In colander/init.py:793-759 (class String(SchemaType))

def deserialize(self, node, cstruct):
    if not cstruct:
        return null

And any([bool( [] ), bool( {} ), bool( "" ), bool( set() ), bool( frozenset() )]) => False

I'd like to propose to either check explicitly for dict-like functionality (setitem, getitem), or to at least make the behavior consistent with colander.String (“if not cstruct” instead of “if cstruct is null” in colander/init.py:456).

jayd3e commented 11 years ago

All of those types(lists, strings, sets, frozensets) all implement getitem/setitem, so we can't explicitly check for those. So should we just allow a 'dict' to pass through?