I do it at the beginning of the main function before the Configurator
is created. I pass the settings through a FormEncode validator.My main
reason for doing this is to ensure that any exceptions occur at
startup rather than intermittently during request processing. I also
parse the settings to their proper types.

I tried both FormEncode, Colander, and a simple homegrown library.
Each had different advantages and disadvantages. The homegrown library
allowed a simpler API (a validation function calling type-specific
functions)but as it got more complex it felt like reinventing the
wheel too much.

With FormEncode I set it to pass through unknown settings (which may
be for Pyramid or includes), and I set Validator.fields to a dict of
validators, because attribute-based declarative is incompatible with
keys containing dots. And now I do it in Validator.__init__ so I can
pass runtime data (e.g., OneOf options from the database), and again
set ``self.fields[setting] = validator``.

With Colander, I originally tried it because FormEncode didn't support
Python 3 (which was later fixed), and the API is a bit primitive. I
first ran into the problem of dotted keys, but found I could use
imperative mode to build up the schema. Also, I couldn't get it to
pass through unknown keys, so I did that in postprocessing: I merged
the validated settings back into the original sedttings. I finally
went back to FormEncode for three reasons:

1) Formencode has combined type-and-validate validators, while
Colander separates the two. I found I often wanted to do both: coerce
to int and validate against a list of choices, and that was tricky to
get right. And in custom validators I often wanted to do the two
together, because they are the same thing in my mind.

2) The multiple layers of classes and methods; e.g., "must instantiate
a SchemaNode before attaching it to a schema". Why can't the schema
create the SchemaNode wrapper for you? And late binding, which I never
did get right, and has two completely different ways of doing it
depending on if it's an attribute, method, or constructor arg.
3) Cases regarding optional values and None. It took a lot of trial
and error to get these right. Especially things like "convert to int,
but pass None through as None".

So with that I finally went to FormEncode. But Colander works if you prefer it.

-- 
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to pylons-discuss+unsubscr...@googlegroups.com.
To post to this group, send email to pylons-discuss@googlegroups.com.
Visit this group at https://groups.google.com/group/pylons-discuss.
For more options, visit https://groups.google.com/d/optout.

Reply via email to