Hi,

I think this behavior happens because mixed is used here
https://bitbucket.org/ianb/formencode/src/d95237b33f3c/formencode/api.py#cl-403.
If you don't want that to happen ever then I think you need to cast params
to a regular dictionary, with something like dict(request.params.items()).
This will silently ignore one of the names though which might be worse.

If you want to be EXTRA strict then you could try ConfirmType and
UnicodeString combined in an All validator to catch this error.  Or
something to that effect.

Also note that someone could actually send ?username=[u'John', u'Mike'] in
the query which would exhibit similar behavior.  So as far as I can tell if
that is a problem you'd need to validate it either way.

I agree that this might be misleading but its a difficult problem to solve.
If we don't use mixed then how do we get the multiple values when we want
them?  I think formencode might just need better internal integration with
multiple value dictionaries so that different types don't show up depending
on the input.  It tries to be input agnostic though.

-Ian


On Tue, Feb 8, 2011 at 10:25 AM, Maxim Avanov <[email protected]>wrote:

> Here's an example.
>
> # =====================
> from formencode import Schema, Invalid
> from formencode.validators import UnicodeString, Int
> from webob import Request
>
> class StrictSchema(Schema):
>    allow_extra_fields = False
>
> class IntegerTestSchema(StrictSchema):
>    testfield = Int(not_empty=True)
>
> class StringTestSchema(StrictSchema):
>    testfield = UnicodeString(not_empty=True)
>
> # Testing.
> # =====================
> req = Request.blank('/?testfield=111')
> print IntegerTestSchema.to_python(req.params)
>
> # This raises an exception
> req = Request.blank('/?testfield=111&testfield=222')
> try:
>    IntegerTestSchema.to_python(req.params)
> except Invalid as e:
>    print "Caught Exception: {0}".format(e)
>
> req = Request.blank('/?testfield=aaa')
> print StringTestSchema.to_python(req.params)
>
> # This will be passed successfully (!)
> # The output will be {'testfield': u"[u'aaa', u'bbb']"}
> req = Request.blank('/?testfield=aaa&testfield=bbb')
> print StringTestSchema.to_python(req.params)
>
> # ========================
>
> Please note we do not use formencode.ForEach() or formencode.Set()
> here. I think this is very unclear behaviour.
> Imagine an UsernameValidator (or something related to "not-so-strict-
> string-validator"). Instead of indicating an input error, we show the
> service realization details to our users -- "{'username': u"[u'John',
> u'Mike']"}" - "Ok. This is Python list inside the dict".
>
> According to WebOb documentation (http://pythonpaste.org/webob/
> #multidict), we probably should use request.GET.getone() instead of
> request.GET.getall().
>
> --
> You received this message because you are subscribed to the Google Groups
> "pylons-discuss" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/pylons-discuss?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en.

Reply via email to