|
From: <sub...@co...> - 2008-02-02 17:35:31
|
Author: ianb
Date: 2008-02-02 10:35:32 -0700 (Sat, 02 Feb 2008)
New Revision: 3240
Modified:
FormEncode/trunk/docs/Validator.txt
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/schema.py
FormEncode/trunk/tests/test_schema.py
Log:
Changed the algorithm a bit for how chained validators are called, so they are called even if there are previous errors; from hax
Modified: FormEncode/trunk/docs/Validator.txt
===================================================================
--- FormEncode/trunk/docs/Validator.txt 2008-02-01 14:48:56 UTC (rev 3239)
+++ FormEncode/trunk/docs/Validator.txt 2008-02-02 17:35:32 UTC (rev 3240)
@@ -217,13 +217,20 @@
``chained_validators`` are validators that are run on the entire
dictionary after other validation is done (``pre_validators`` are
-applied before the schema validation). You could actually achieve the
-same thing by using ``All`` with the schema validators (`FieldsMatch
-<class-formencode.validators.FieldsMatch.html>`_ is just another
-validator that can be applied to dictionaries). In this case
-``validators.FieldsMatch`` checks that the value of the two fields are
-the same (i.e., that the password matches the confirmation).
+applied before the schema validation). chained_validtors will also
+allow for multiple validators to fail and report to the error_dict
+so, for example, if you have an email_confirm and a password_confirm
+fields and use FieldsMatch on both of them as follows:
+ >>> chained_validators [ validators.FieldsMatch('password',
+ ... 'password_confirm'),
+ ... validators.FieldsMatch('email',
+ ... 'email_confirm') ]
+
+This will leave the error_dict with both password_confirm and
+email_confirm error keys, which is likely the desired behavior
+for web forms.
+
Since a `Schema <class-formencode.schema.Schema.html>`_ is just
another kind of validator, you can nest these indefinitely, validating
dictionaries of dictionaries.
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-02-01 14:48:56 UTC (rev 3239)
+++ FormEncode/trunk/docs/news.txt 2008-02-02 17:35:32 UTC (rev 3240)
@@ -9,6 +9,10 @@
* Added ``formencode.schema.SimpleFormValidator``, which wraps a
simple function to make it a validator.
+* Changed the use of ``chained_validators`` in Schemas, so that all
+ chained validators get run even when there are previous errors (to
+ detect all the errors).
+
0.9
---
Modified: FormEncode/trunk/formencode/schema.py
===================================================================
--- FormEncode/trunk/formencode/schema.py 2008-02-01 14:48:56 UTC (rev 3239)
+++ FormEncode/trunk/formencode/schema.py 2008-02-02 17:35:32 UTC (rev 3240)
@@ -177,19 +177,18 @@
else:
new[name] = validator.if_missing
- if errors:
- for validator in self.chained_validators:
- if (not hasattr(validator, 'validate_partial')
- or not getattr(validator, 'validate_partial_form', False)):
+ for validator in self.chained_validators:
+ if (not hasattr(validator, 'validate_partial')
+ or not getattr(validator, 'validate_partial_form', False)):
+ continue
+ try:
+ validator.validate_partial(value_dict, state)
+ except Invalid, e:
+ sub_errors = e.unpack_errors()
+ if not isinstance(sub_errors, dict):
+ # Can't do anything here
continue
- try:
- validator.validate_partial(value_dict, state)
- except Invalid, e:
- sub_errors = e.unpack_errors()
- if not isinstance(sub_errors, dict):
- # Can't do anything here
- continue
- merge_dicts(errors, sub_errors)
+ merge_dicts(errors, sub_errors)
if errors:
raise Invalid(
@@ -197,9 +196,6 @@
value_dict, state,
error_dict=errors)
- for validator in self.chained_validators:
- new = validator.to_python(new, state)
-
return new
finally:
Modified: FormEncode/trunk/tests/test_schema.py
===================================================================
--- FormEncode/trunk/tests/test_schema.py 2008-02-01 14:48:56 UTC (rev 3239)
+++ FormEncode/trunk/tests/test_schema.py 2008-02-02 17:35:32 UTC (rev 3240)
@@ -149,4 +149,19 @@
== dict(a=['a1\naa1', 'a2'], b=['b\nbb', 'bbb'],
c=['c']))
+class ChainedTest(Schema):
+ a = validators.String()
+ a_confirm = validators.String()
+ b = validators.String()
+ b_confirm = validators.String()
+
+ chained_validators = [validators.FieldsMatch('a', 'a_confirm'),
+ validators.FieldsMatch('b', 'b_confirm')]
+
+def test_multiple_chained_validators_errors():
+ try:
+ s = ChainedTest()
+ s.to_python({'a':'1', 'a_confirm':'2', 'b':'3', 'b_confirm':'4'})
+ except Invalid, e:
+ assert(e.error_dict.has_key('a_confirm') and e.error_dict.has_key('b_confirm'))
|