colander icon indicating copy to clipboard operation
colander copied to clipboard

Validation for colander.Mapping() too liberal

Open deno opened this issue 13 years ago • 1 comments

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:

  • dict( "" )
  • dict( [] )
  • dict( () )

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).

deno avatar Apr 18 '11 01:04 deno

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?

jayd3e avatar Mar 19 '13 19:03 jayd3e