Not really, I think you have a point.  If it is inconvenient to extend the
existing string validators then the addition of a new more web form friendly
string validator sounds like a good idea.

On Fri, Feb 11, 2011 at 9:53 AM, Maxim Avanov <[email protected]>wrote:

> Thanks for the snippet above, Ian.
>
> > What outcome do you actually want?  Only the first or last thing from the
> > list to get validated? Or an error if there is more than one thing ?
>
> I think the validator must raise an exception in such a case.
>
> I'm going to create a ticket in the formencode's tracker. Do you have
> any additional suggestions that should be mentioned in it?
>
>
> On Feb 11, 5:10 am, Ian Wilson <[email protected]> wrote:
> > After thinking about this more it would probably be better if
> UnicodeString
> > just had a parameter that turned coercion of everything but instances of
> > basestring and None off.  Or maybe another validator was created that did
> > that.  It makes more sense for the validator that is assigned that key to
> > respond to both lists and non-lists.
> >
> > What outcome do you actually want?  Only the first or last thing from the
> > list to get validated? Or an error if there is more than one thing ?
> >
> > Here is a validator I hacked together from the String and UnicodeString
> > validators that only accepts None and basestrings.  None and non-unicode
> > strings are both converted to unicode.
> >
> > class StrictUnicodeString(FancyValidator):
> >     """"""
> >
> >     min = None
> >     max = None
> >     not_empty = None
> >     convert_none = True
> >     encoding = 'utf-8'
> >
> >     messages = {
> >         'notString': "Please enter a string",
> >         'tooLong': "Enter a value less than %(max)i characters long",
> >         'tooShort': "Enter a value %(min)i characters long or more",
> >         'badEncoding' : "Invalid data or incorrect encoding",
> >     }
> >
> >     def __initargs__(self, new_attrs):
> >         if self.not_empty is None and self.min:
> >             self.not_empty = True
> >
> >     def __init__(self, input_encoding=None, output_encoding=None,
> >             convert_none=True, **kw):
> >         FancyValidator.__init__(self, **kw)
> >         self.input_encoding = input_encoding or self.encoding
> >         self.output_encoding = output_encoding or self.encoding
> >         self.convert_none = convert_none
> >
> >     def _to_python(self, value, state):
> >         """ Converts to unicode. """
> >         if self.convert_none and value is None:
> >             value = u''
> >         if not isinstance(value, basestring):
> >             raise Invalid(self.message('notString', state), value, state)
> >         if not isinstance(value, unicode):
> >             try:
> >                 value = unicode(value, self.input_encoding)
> >             except UnicodeDecodeError:
> >                 raise Invalid(self.message('badEncoding', state), value,
> > state)
> >         return value
> >
> >     def _from_python(self, value, state):
> >         """ Converts to a bytestring. """
> >         if not isinstance(value, unicode):
> >             if hasattr(value, '__unicode__'):
> >                 value = unicode(value)
> >             else:
> >                 value = str(value)
> >         if isinstance(value, unicode):
> >             value = value.encode(self.output_encoding)
> >         return value
> >
> >     def validate_other(self, value, state):
> >         if (self.max is not None and value is not None
> >             and len(value) > self.max):
> >             raise Invalid(self.message('tooLong', state,
> >                                        max=self.max),
> >                           value, state)
> >         if (self.min is not None
> >             and (not value or len(value) < self.min)):
> >             raise Invalid(self.message('tooShort', state,
> >                                        min=self.min),
> >                           value, state)
> >
> >     def empty_value(self, value):
> >         return u''
> >
> > -Ian
> >
> > On Thu, Feb 10, 2011 at 2:52 PM, Maxim Avanov <[email protected]
> >wrote:
> >
> > > Hi, Ian. Thanks for reply.
> >
> > > >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.
> >
> > > This solution will work, but I wouldn't like to use it for several
> > > reasons. First of all, we already have a huge code base that
> > > intensively uses UnicodeStrings.  Surely, we could define our own
> > > UnicodeString validator like below,
> >
> > > UnicodeString =
> > > formencode.All(formencode.ConfirmType(subclass=unicode),
> > > formencode.UnicodeString())
> >
> > > but we trying to keep our design clean.  Moreover, "All" and
> > > "ConfirmType" require extra validation steps (and hence more function
> > > calls). I think it has to be solved in more generic and concise way
> > > (i.e. in formencode's internal api level).
> >
> > > > Also note that someone could actually send ?username=[u'John',
> u'Mike']
> > > in
> > > > the query which would exhibit similar behavior.
> >
> > > Yes, and it is the place where the inconsistency of validators
> > > behaviour comes. if we'd have an unified behaviour for all single-
> > > value validators (Int, UnicodeString, Bool etc.) we could get
> > > "[u'John', u'Mike']" result only for "/?username=[u'John', u'Mike']"
> > > request. But now, we can get the same result by the two different
> > > requests - by "/?username=[u'John', u'Mike']" and by "/?
> > > username=John&username=Mike". This shouldn't be allowed. And it's not
> > > allowed for all single-value validators except the UnicodeString.
> >
> > > > If we don't use mixed then how do we get the multiple values when we
> want
> > > > them?
> >
> > > We might explicitly specify our expectations with ForEach() and Set()
> > > validators.
> > > formencode's FancyValidator could internally test currently running
> > > validator by calling something like
> >
> > > isinstance(current_validator, ForEach)
> >
> > > and then perform appropriate actions for this case (i.e. call single-
> > > value validator for each found item with the same key).
> >
> > > P.S. I hope Ian Bicking will see this topic and give his opinion all
> > > about this, as I might miss something important here.
> >
> > > On Feb 9, 6:38 am, Ian Wilson <[email protected]> wrote:
> > > > Hi,
> >
> > > > I think this behavior happens because mixed is used herehttps://
> > > bitbucket.org/ianb/formencode/src/d95237b33f3c/formencode/api....
> > > > 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.
>
> --
> 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