You can subscribe to this list here.
| 2004 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(10) |
Dec
(4) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2005 |
Jan
(1) |
Feb
(8) |
Mar
(8) |
Apr
(4) |
May
(19) |
Jun
(1) |
Jul
(1) |
Aug
(18) |
Sep
(18) |
Oct
(19) |
Nov
(75) |
Dec
(80) |
| 2006 |
Jan
(86) |
Feb
(61) |
Mar
(60) |
Apr
(47) |
May
(39) |
Jun
(16) |
Jul
(30) |
Aug
(13) |
Sep
(13) |
Oct
(21) |
Nov
(1) |
Dec
(10) |
| 2007 |
Jan
(2) |
Feb
(7) |
Mar
(9) |
Apr
(3) |
May
(9) |
Jun
(4) |
Jul
(1) |
Aug
(2) |
Sep
|
Oct
(12) |
Nov
(1) |
Dec
(7) |
| 2008 |
Jan
|
Feb
(2) |
Mar
(14) |
Apr
(9) |
May
(23) |
Jun
(4) |
Jul
|
Aug
(13) |
Sep
(8) |
Oct
(15) |
Nov
(40) |
Dec
(14) |
| 2009 |
Jan
|
Feb
(4) |
Mar
(10) |
Apr
(2) |
May
(2) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <sub...@co...> - 2008-05-14 16:14:28
|
Author: ianb
Date: 2008-05-14 10:14:10 -0600 (Wed, 14 May 2008)
New Revision: 3427
Modified:
FormEncode/trunk/formencode/validators.py
Log:
added (passing) doctest for dates with 3-digit years
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-05-14 16:11:52 UTC (rev 3426)
+++ FormEncode/trunk/formencode/validators.py 2008-05-14 16:14:10 UTC (rev 3427)
@@ -1815,7 +1815,12 @@
Traceback (most recent call last):
...
Invalid: Please enter a month from 1 to 12
+ >>> d.to_python('1/1/200')
+ Traceback (most recent call last):
+ ...
+ Invalid: Please enter a four-digit year after 1899
+
If you change ``month_style`` you can get European-style dates::
>>> d = DateConverter(month_style='dd/mm/yyyy')
|
|
From: <sub...@co...> - 2008-05-14 16:12:26
|
Author: ianb
Date: 2008-05-14 10:11:52 -0600 (Wed, 14 May 2008)
New Revision: 3426
Modified:
FormEncode/trunk/formencode/validators.py
Log:
Fix FieldStorageUploadConverter docstring
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-05-14 16:07:05 UTC (rev 3425)
+++ FormEncode/trunk/formencode/validators.py 2008-05-14 16:11:52 UTC (rev 3426)
@@ -1689,9 +1689,11 @@
class FieldStorageUploadConverter(FancyValidator):
"""
- Converts a cgi.FieldStorage instance to
- a value that FormEncode can use for file
- uploads.
+ Handles cgi.FieldStorage instances that are file uploads.
+
+ This doesn't do any conversion, but it can detect empty upload
+ fields (which appear like normal fields, but have no filename when
+ no upload was given).
"""
def _to_python(self, value, state=None):
if isinstance(value, cgi.FieldStorage):
|
|
From: <sub...@co...> - 2008-05-14 16:09:10
|
Author: ianb
Date: 2008-05-14 10:07:05 -0600 (Wed, 14 May 2008)
New Revision: 3425
Modified:
FormEncode/trunk/formencode/validators.py
Log:
Make FieldStorageUploadConverter handle empty values more gracefully
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-05-14 15:43:45 UTC (rev 3424)
+++ FormEncode/trunk/formencode/validators.py 2008-05-14 16:07:05 UTC (rev 3425)
@@ -1695,12 +1695,17 @@
"""
def _to_python(self, value, state=None):
if isinstance(value, cgi.FieldStorage):
- if value.filename:
+ if getattr(value, 'filename', None):
return value
raise Invalid('invalid', value, state)
else:
return value
+ def is_empty(self, value):
+ if isinstance(value, cgi.FieldStorage):
+ return bool(getattr(value, 'filename', None))
+ return FancyValidator.is_empty(self, value)
+
class FileUploadKeeper(FancyValidator):
"""
Takes two inputs (a dictionary with keys ``static`` and
|
|
From: <sub...@co...> - 2008-05-14 15:43:44
|
Author: ianb
Date: 2008-05-14 09:43:45 -0600 (Wed, 14 May 2008)
New Revision: 3424
Modified:
FormEncode/trunk/formencode/validators.py
Log:
added an example of DateConverter with month_style
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-05-14 15:37:37 UTC (rev 3423)
+++ FormEncode/trunk/formencode/validators.py 2008-05-14 15:43:45 UTC (rev 3424)
@@ -1808,6 +1808,15 @@
Traceback (most recent call last):
...
Invalid: Please enter a month from 1 to 12
+
+ If you change ``month_style`` you can get European-style dates::
+
+ >>> d = DateConverter(month_style='dd/mm/yyyy')
+ >>> date = d.to_python('12/3/09')
+ >>> date
+ datetime.date(2009, 3, 12)
+ >>> d.from_python(date)
+ '12/03/2009'
"""
## @@: accepts only US-style dates
|
|
From: <sub...@co...> - 2008-05-14 15:37:34
|
Author: ianb
Date: 2008-05-14 09:37:37 -0600 (Wed, 14 May 2008)
New Revision: 3423
Modified:
FormEncode/trunk/tests/test_htmlfill.py
Log:
Added some more (passing) tests for form:iferror
Modified: FormEncode/trunk/tests/test_htmlfill.py
===================================================================
--- FormEncode/trunk/tests/test_htmlfill.py 2008-05-14 15:35:56 UTC (rev 3422)
+++ FormEncode/trunk/tests/test_htmlfill.py 2008-05-14 15:37:37 UTC (rev 3423)
@@ -112,4 +112,10 @@
== 'no errors')
assert (htmlfill.render('<form:iferror name="not field1">no errors</form:iferror>', errors={'field1': 'foo'}, auto_insert_errors=False)
== '')
-
+ assert (htmlfill.render('<form:iferror name="field1">errors</form:iferror><form:iferror name="not field1">no errors</form:iferror>',
+ errors={}, auto_insert_errors=False)
+ == 'no errors')
+ assert (htmlfill.render('<form:iferror name="field1">errors</form:iferror><form:iferror name="not field1">no errors</form:iferror>',
+ errors={'field1': 'foo'}, auto_insert_errors=False)
+ == 'errors')
+
|
|
From: <sub...@co...> - 2008-05-14 15:36:06
|
Author: ianb
Date: 2008-05-14 09:35:56 -0600 (Wed, 14 May 2008)
New Revision: 3422
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/validators.py
Log:
close SF bug 1834389, bad error when CC fields missing. Also treat {} as not-empty for FormValidators
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-05-13 23:02:17 UTC (rev 3421)
+++ FormEncode/trunk/docs/news.txt 2008-05-14 15:35:56 UTC (rev 3422)
@@ -21,6 +21,9 @@
* The validators ``Int`` and ``Number`` both take min/max arguments
(from Shannon Behrens).
+* Validators based on ``formencode.validators.FormValidator`` will not
+ treat ``{}`` as an empty (unvalidated) value.
+
* Some adjustments to the URL validator.
1.0.1
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-05-13 23:02:17 UTC (rev 3421)
+++ FormEncode/trunk/formencode/validators.py 2008-05-14 15:35:56 UTC (rev 3422)
@@ -2474,6 +2474,9 @@
validate_partial_python = None
validate_partial_other = None
+ def is_empty(self, value):
+ return False
+
class RequireIfMissing(FormValidator):
"""
@@ -2612,6 +2615,10 @@
Traceback (most recent call last):
...
Invalid: ccNumber: You did not enter a valid number of digits
+ >>> cc().to_python({})
+ Traceback (most recent call last):
+ ...
+ Invalid: The field ccType is missing
"""
validate_partial_form = True
@@ -2624,6 +2631,7 @@
'notANumber': _("Please enter only the number, no other characters"),
'badLength': _("You did not enter a valid number of digits"),
'invalidNumber': _("That number is not valid"),
+ 'missing_key': _("The field %(key)s is missing"),
}
def validate_partial(self, field_dict, state):
@@ -2643,6 +2651,10 @@
field_dict, state, error_dict=errors)
def _validateReturn(self, field_dict, state):
+ for field in self.cc_type_field, self.cc_number_field:
+ if field not in field_dict:
+ raise Invalid(
+ self.message('missing_key', state, key=field), value, state)
ccType = field_dict[self.cc_type_field].lower().strip()
number = field_dict[self.cc_number_field].strip()
number = number.replace(' ', '')
|
|
From: <sub...@co...> - 2008-05-13 23:02:14
|
Author: ianb
Date: 2008-05-13 17:02:17 -0600 (Tue, 13 May 2008)
New Revision: 3421
Modified:
FormEncode/trunk/tests/test_schema.py
Log:
Test chained validator with no input to the schema (trying to reproduce SF bug 1939813)
Modified: FormEncode/trunk/tests/test_schema.py
===================================================================
--- FormEncode/trunk/tests/test_schema.py 2008-05-13 22:55:26 UTC (rev 3420)
+++ FormEncode/trunk/tests/test_schema.py 2008-05-13 23:02:17 UTC (rev 3421)
@@ -160,8 +160,14 @@
validators.FieldsMatch('b', 'b_confirm')]
def test_multiple_chained_validators_errors():
+ s = ChainedTest()
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'))
+ try:
+ s.to_python({})
+ except Invalid, e:
+ pass
+ else:
+ assert 0
|
|
From: <sub...@co...> - 2008-05-13 22:55:23
|
Author: ianb
Date: 2008-05-13 16:55:26 -0600 (Tue, 13 May 2008)
New Revision: 3420
Modified:
FormEncode/trunk/tests/test_htmlfill.py
Log:
Added some tests for iferror
Modified: FormEncode/trunk/tests/test_htmlfill.py
===================================================================
--- FormEncode/trunk/tests/test_htmlfill.py 2008-05-13 22:48:50 UTC (rev 3419)
+++ FormEncode/trunk/tests/test_htmlfill.py 2008-05-13 22:55:26 UTC (rev 3420)
@@ -102,3 +102,14 @@
assert (htmlfill.render('<select name="type"><option value="foo">foo</option></select>', errors={'type': 'error'},
prefix_error=False)
== '<select name="type" class="error"><option value="foo">foo</option></select><!-- for: type -->\n<span class="error-message">error</span><br />\n')
+
+def test_iferror():
+ assert (htmlfill.render('<form:iferror name="field1">an error</form:iferror>', errors={}, auto_insert_errors=False)
+ == '')
+ assert (htmlfill.render('<form:iferror name="field1">an error</form:iferror>', errors={'field1': 'foo'}, auto_insert_errors=False)
+ == 'an error')
+ assert (htmlfill.render('<form:iferror name="not field1">no errors</form:iferror>', errors={}, auto_insert_errors=False)
+ == 'no errors')
+ assert (htmlfill.render('<form:iferror name="not field1">no errors</form:iferror>', errors={'field1': 'foo'}, auto_insert_errors=False)
+ == '')
+
|
|
From: <sub...@co...> - 2008-05-13 22:48:47
|
Author: ianb
Date: 2008-05-13 16:48:50 -0600 (Tue, 13 May 2008)
New Revision: 3419
Modified:
FormEncode/trunk/formencode/validators.py
Log:
Add a docstring to explain RequireIfMissing/Present
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-05-13 22:40:04 UTC (rev 3418)
+++ FormEncode/trunk/formencode/validators.py 2008-05-13 22:48:50 UTC (rev 3419)
@@ -2476,6 +2476,41 @@
class RequireIfMissing(FormValidator):
+ """
+ This requires one field based on another field being present or
+ missing. This is applied to a form, not an individual field
+ (usually using a Schema's ``pre_validators`` or
+ ``chained_validators``).
+
+ If you provide a ``missing`` value (a string key name) then if
+ that field is missing the field must be entered. This gives you
+ an either/or situation.
+
+ If you provide a ``present`` value (another string key name) then
+ if that field is present, the required field must also be present.
+
+ ::
+
+ >>> from formencode import validators
+ >>> v = validators.RequireIfPresent('phone_type',
+ ... present='phone')
+ >>> v.to_python({'phone_type':'', 'phone':'510 420 4577'})
+ Traceback (most recent call last):
+ ...
+ Invalid: You must give a value for phone_type
+ >>> v.to_python({'phone': ''})
+ {'phone': ''}
+
+ Note that if you have a validator on the optionally-required
+ field, you should probably use ``if_missing=None``. This way you
+ won't get an error from the Schema about a missing value. For example::
+
+ class PhoneInput(Schema):
+ phone = PhoneNumber()
+ phone_type = String(if_missing=None)
+ chained_validators = [RequireifPresent('phone_type', present='phone')]
+ """
+
# Field that potentially is required:
required = None
# If this field is missing, then it is required:
|
|
From: <sub...@co...> - 2008-05-13 22:40:02
|
Author: ianb
Date: 2008-05-13 16:40:04 -0600 (Tue, 13 May 2008)
New Revision: 3418
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/validators.py
Log:
Adjustments to the URL validator (SF bug 1940971) from Jonathan Vanesco
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-05-13 21:47:44 UTC (rev 3417)
+++ FormEncode/trunk/docs/news.txt 2008-05-13 22:40:04 UTC (rev 3418)
@@ -21,6 +21,8 @@
* The validators ``Int`` and ``Number`` both take min/max arguments
(from Shannon Behrens).
+* Some adjustments to the URL validator.
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-05-13 21:47:44 UTC (rev 3417)
+++ FormEncode/trunk/formencode/validators.py 2008-05-13 22:40:04 UTC (rev 3418)
@@ -1379,10 +1379,26 @@
check_exists = False
add_http = True
- url_re = re.compile(r'^(http|https)://'
- r'(?:[a-z0-9\-]+|[a-z0-9][a-z0-9\-\.\_]*\.[a-z]+)'
- r'(?::[0-9]+)?'
- r'(?:/.*)?$', re.I)
+ url_re = re.compile(r'''
+ ^(http|https)://
+ (?:[%:\w]*@)? # authenticator
+ (?:[a-z0-9][a-z0-9\-]{1,62}\.)* # (sub)domain - alpha followed by 62max chars (63 total)
+ [a-z]+ # TLD
+ (?:[0-9]+)? # port
+
+ # files/delims/etc
+ (?:/[
+ # rfc3986 valid chars
+ # unreserved
+ a-z0-9\-\._~
+ # delims - general
+ :/\?#\[\]@
+ # delims - sub
+ !\$&\'\(\)\*\+,;=
+ ]*)?
+ $
+ ''', re.I | re.VERBOSE)
+
scheme_re = re.compile(r'^[a-zA-Z]+:')
messages = {
|
|
From: <sub...@co...> - 2008-05-13 21:47:39
|
Author: ianb Date: 2008-05-13 15:47:44 -0600 (Tue, 13 May 2008) New Revision: 3417 Modified: FormEncode/trunk/docs/Validator.txt Log: some typos from Shannon Behrens Modified: FormEncode/trunk/docs/Validator.txt =================================================================== --- FormEncode/trunk/docs/Validator.txt 2008-05-13 21:37:19 UTC (rev 3416) +++ FormEncode/trunk/docs/Validator.txt 2008-05-13 21:47:44 UTC (rev 3417) @@ -265,7 +265,7 @@ schema fails (the values are invalid) then ``ValidateState`` will not be run, unless you set ``validate_partial_form`` to True (like ``ValidateState = SimpleFormValidator(validate_state, -validate_partial_form=True). If you validate a partial form you +validate_partial_form=True)``. If you validate a partial form you should be careful that you handle missing keys and other possibly-invalid values gracefully. @@ -502,8 +502,8 @@ Localization of Error Messages (i18n) ------------------------------------- -When a failed validation accurs FormEncode tries to output the error -message in the appropirate language. For this it uses the standard +When a failed validation occurs FormEncode tries to output the error +message in the appropriate language. For this it uses the standard `gettext <http://python.org/doc/current/lib/module-gettext.html>`_ mechanism of python. To translate the message in the appropirate message FormEncode has to find a gettext function that translates the @@ -521,7 +521,7 @@ 3. formencode builtin ``_stdtrans`` function for standalone use of FormEncode. The language to use is determined - out of the local system (see gettext documentation). Optionally you + out of the locale system (see gettext documentation). Optionally you can also set the language or the domain explicitly with the function:: @@ -546,7 +546,7 @@ currently available languages in the source under the directory ``formencode/i18n``. -If your's is not present yet, please consider contributing a +If your language is not present yet, please consider contributing a translation (where ``<lang>`` is you language code):: $ svn co http://svn.formencode.org/FormEncode/trunk/`` |
|
From: <sub...@co...> - 2008-05-13 21:37:16
|
Author: ianb
Date: 2008-05-13 15:37:19 -0600 (Tue, 13 May 2008)
New Revision: 3416
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/validators.py
Log:
patch from Shannon JJ Behrens, adding min/max support to Int and Number
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-05-13 21:35:50 UTC (rev 3415)
+++ FormEncode/trunk/docs/news.txt 2008-05-13 21:37:19 UTC (rev 3416)
@@ -18,6 +18,9 @@
* In ``formencode.htmlfill``, non-string values are compared usefully
(e.g., a select box with integer values).
+* The validators ``Int`` and ``Number`` both take min/max arguments
+ (from Shannon Behrens).
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-05-13 21:35:50 UTC (rev 3415)
+++ FormEncode/trunk/formencode/validators.py 2008-05-13 21:37:19 UTC (rev 3416)
@@ -909,11 +909,41 @@
def empty_value(self, value):
return False
-class Int(FancyValidator):
+class RangeValidator(FancyValidator):
+ """This is an abstract base class for Int and Number.
+
+ It verifies that a value is within range. It accepts min and max
+ values in the constructor.
+
+ (Since this is an abstract base class, the tests are in Int and
+ Number.)
+
"""
- Convert a value to an integer.
+ messages = {
+ 'tooLow': _("Please enter a number that is %(min)s or greater"),
+ 'tooHigh': _("Please enter a number that is %(max)s or smaller"),
+ }
+
+ min = None
+ max = None
+
+ def validate_python(self, value, state):
+ if self.min is not None:
+ if value < self.min:
+ msg = self.message("tooLow", state, min=self.min)
+ raise Invalid(msg, value, state)
+ if self.max is not None:
+ if value > self.max:
+ msg = self.message("tooHigh", state, max=self.max)
+ raise Invalid(msg, value, state)
+
+
+class Int(RangeValidator):
+
+ """Convert a value to an integer.
+
Example::
>>> Int.to_python('10')
@@ -922,24 +952,19 @@
Traceback (most recent call last):
...
Invalid: Please enter an integer value
+ >>> Int(min=5).to_python('6')
+ 6
+ >>> Int(max=10).to_python('11')
+ Traceback (most recent call last):
+ ...
+ Invalid: Please enter a number that is 10 or smaller
+
"""
messages = {
- 'integer': _("Please enter an integer value"),
- 'tooLow': _("Please enter an integer above %(min)i"),
- 'tooHigh': _("Please enter an integer below %(max)i"),
- }
+ 'integer': _("Please enter an integer value")
+ }
- min = None
- max = None
-
- def __initargs__(self, args):
- if self.min != None:
- self.min = int(self.min)
- if self.max != None:
- self.max = int(self.max)
-
-
def _to_python(self, value, state):
try:
return int(value)
@@ -947,24 +972,17 @@
raise Invalid(self.message('integer', state),
value, state)
- def validate_python(self, value, state):
- if self.min != None and value < self.min:
- msg = self.message("tooLow", state, min=self.min)
- raise Invalid(msg, value, state)
- if self.max != None and value > self.max:
- msg = self.message("tooHigh", state, max=self.max)
- raise Invalid(msg, value, state)
-
_from_python = _to_python
-class Number(FancyValidator):
- """
- Convert a value to a float or integer. Tries to convert it to
- an integer if no information is lost.
+class Number(RangeValidator):
- ::
+ """Convert a value to a float or integer.
+ Tries to convert it to an integer if no information is lost.
+
+ Example::
+
>>> Number.to_python('10')
10
>>> Number.to_python('10.5')
@@ -973,13 +991,19 @@
Traceback (most recent call last):
...
Invalid: Please enter a number
+ >>> Number(min=5).to_python('6.5')
+ 6.5
+ >>> Number(max=10.5).to_python('11.5')
+ Traceback (most recent call last):
+ ...
+ Invalid: Please enter a number that is 10.5 or smaller
"""
-
+
messages = {
- 'number': _("Please enter a number"),
- }
-
+ 'number': _("Please enter a number")
+ }
+
def _to_python(self, value, state):
try:
value = float(value)
@@ -990,6 +1014,7 @@
raise Invalid(self.message('number', state),
value, state)
+
class String(FancyValidator):
"""
Converts things to string, but treats empty things as the empty
|
|
From: <sub...@co...> - 2008-05-05 18:53:18
|
Author: ianb
Date: 2008-05-05 12:53:17 -0600 (Mon, 05 May 2008)
New Revision: 3414
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/htmlfill.py
Log:
compare values in checkboxes, etc, properly, even if the defaults aren't given as strings
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-05-04 14:08:34 UTC (rev 3413)
+++ FormEncode/trunk/docs/news.txt 2008-05-05 18:53:17 UTC (rev 3414)
@@ -15,6 +15,9 @@
* Added ``formencode.htmlrename``, which renames HTML inputs.
+* In ``formencode.htmlfill``, non-string values are compared usefully
+ (e.g., a select box with integer values).
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/htmlfill.py
===================================================================
--- FormEncode/trunk/formencode/htmlfill.py 2008-05-04 14:08:34 UTC (rev 3413)
+++ FormEncode/trunk/formencode/htmlfill.py 2008-05-05 18:53:17 UTC (rev 3414)
@@ -194,6 +194,24 @@
self.encoding = encoding
self.prefix_error = prefix_error
+ def str_compare(self, str1, str2):
+ """
+ Compare the two objects as strings (coercing to strings if necessary).
+ Also uses encoding to compare the strings.
+ """
+ if not isinstance(str1, basestring):
+ if hasattr(str1, '__unicode__'):
+ str1 = unicode(str1)
+ else:
+ str1 = str(str1)
+ if type(str1) == type(str2):
+ return str1 == str2
+ if isinstance(str1, unicode):
+ str1 = str1.encode(self.encoding)
+ else:
+ str2 = str2.encode(self.encoding)
+ return str1 == str2
+
def close(self):
self.handle_misc(None)
RewritingParser.close(self)
@@ -346,7 +364,7 @@
self.skip_next = True
self.add_key(name)
elif t == 'radio':
- if str(value) == self.get_attr(attrs, 'value'):
+ if self.str_compare(value, self.get_attr(attrs, 'value')):
self.set_attr(attrs, 'checked', 'checked')
else:
self.del_attr(attrs, 'checked')
@@ -458,9 +476,9 @@
return True
if hasattr(obj, '__iter__'):
for inner in obj:
- if str(inner) == value:
+ if self.str_compare(inner, value):
return True
- return str(obj) == value
+ return self.str_compare(obj, value)
def write_marker(self, marker):
self._content.append((marker,))
|
|
From: <sub...@co...> - 2008-04-24 06:47:43
|
Author: ianb
Date: 2008-04-24 00:47:45 -0600 (Thu, 24 Apr 2008)
New Revision: 3396
Modified:
FormEncode/trunk/formencode/rewritingparser.py
FormEncode/trunk/tests/test_htmlrename.py
Log:
handle end tags in htmlrename properly
Modified: FormEncode/trunk/formencode/rewritingparser.py
===================================================================
--- FormEncode/trunk/formencode/rewritingparser.py 2008-04-23 06:55:04 UTC (rev 3395)
+++ FormEncode/trunk/formencode/rewritingparser.py 2008-04-24 06:47:45 UTC (rev 3396)
@@ -65,7 +65,8 @@
handle_decl = handle_misc
handle_pi = handle_misc
unknown_decl = handle_misc
-
+ handle_endtag = handle_misc
+
def write_tag(self, tag, attrs, startend=False):
attr_text = ''.join([' %s="%s"' % (n, html_quote(v))
for (n, v) in attrs
Modified: FormEncode/trunk/tests/test_htmlrename.py
===================================================================
--- FormEncode/trunk/tests/test_htmlrename.py 2008-04-23 06:55:04 UTC (rev 3395)
+++ FormEncode/trunk/tests/test_htmlrename.py 2008-04-24 06:47:45 UTC (rev 3396)
@@ -5,4 +5,8 @@
== '<input type="text" name="A_NAME">')
assert (add_prefix('<input type="text" name="a_name"><input type="text" name="">', 'test', dotted=True)
== '<input type="text" name="test.a_name"><input type="text" name="test">')
-
+ assert (add_prefix('text<textarea name="a_name">value</textarea>text2', 'prefix.')
+ == 'text<textarea name="prefix.a_name">value</textarea>text2')
+ assert (add_prefix('<textarea name="" rows=2 style="width: 100%" id="field-0"></textarea>',
+ 'street', dotted=True)
+ == '<textarea name="street" rows="2" style="width: 100%" id="field-0"></textarea>')
|
|
From: <sub...@co...> - 2008-04-23 06:54:59
|
Author: ianb
Date: 2008-04-23 00:55:04 -0600 (Wed, 23 Apr 2008)
New Revision: 3395
Added:
FormEncode/trunk/formencode/htmlrename.py
FormEncode/trunk/formencode/rewritingparser.py
FormEncode/trunk/tests/test_htmlrename.py
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/htmlfill.py
Log:
Added htmlrename, which renames input field names
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-04-23 06:53:03 UTC (rev 3394)
+++ FormEncode/trunk/docs/news.txt 2008-04-23 06:55:04 UTC (rev 3395)
@@ -13,6 +13,8 @@
* Remove deprecated modules: ``fields``, ``formgen``, ``htmlform``,
``sqlformgen``, and ``sqlschema``.
+* Added ``formencode.htmlrename``, which renames HTML inputs.
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/htmlfill.py
===================================================================
--- FormEncode/trunk/formencode/htmlfill.py 2008-04-23 06:53:03 UTC (rev 3394)
+++ FormEncode/trunk/formencode/htmlfill.py 2008-04-23 06:55:04 UTC (rev 3395)
@@ -4,9 +4,8 @@
"""
import HTMLParser
-import cgi
import re
-from htmlentitydefs import name2codepoint
+from formencode.rewritingparser import RewritingParser, html_quote
__all__ = ['render', 'htmlliteral', 'default_formatter',
'none_formatter', 'escape_formatter',
@@ -102,17 +101,6 @@
def __html__(self):
return self.html
-def html_quote(v):
- if v is None:
- return ''
- elif hasattr(v, '__html__'):
- return v.__html__()
- elif isinstance(v, basestring):
- return cgi.escape(v, 1)
- else:
- # @@: Should this be unicode(v) or str(v)?
- return cgi.escape(str(v), 1)
-
def default_formatter(error):
"""
Formatter that escapes the error, wraps the error in a span with
@@ -140,7 +128,7 @@
error = error.replace('\n', '<br>\n')
return error
-class FillingParser(HTMLParser.HTMLParser):
+class FillingParser(RewritingParser):
r"""
Fills HTML with default values, as in a form.
@@ -177,8 +165,7 @@
add_attributes=None, listener=None,
auto_error_formatter=None,
text_as_default=False, encoding=None, prefix_error=True):
- HTMLParser.HTMLParser.__init__(self)
- self._content = []
+ RewritingParser.__init__(self)
self.source = None
self.lines = None
self.source_pos = None
@@ -207,18 +194,9 @@
self.encoding = encoding
self.prefix_error = prefix_error
- def feed(self, data):
- self.data_is_str = isinstance(data, str)
- self.source = data
- self.lines = data.split('\n')
- self.source_pos = 1, 0
- if self.listener:
- self.listener.reset()
- HTMLParser.HTMLParser.feed(self, data)
-
def close(self):
self.handle_misc(None)
- HTMLParser.HTMLParser.close(self)
+ RewritingParser.close(self)
unused_errors = self.errors.copy()
for key in self.used_errors.keys():
if unused_errors.has_key(key):
@@ -252,50 +230,14 @@
item = item.decode(self.encoding)
new_content.append(item)
self._content = new_content
- try:
- self._text = ''.join([
- t for t in self._content if not isinstance(t, tuple)])
- except UnicodeDecodeError, e:
- if self.data_is_str:
- e.reason += (
- " the form was passed in as an encoded string, but "
- "some data or error messages were unicode strings; "
- "the form should be passed in as a unicode string")
- else:
- e.reason += (
- " the form was passed in as an unicode string, but "
- "some data or error message was an encoded string; "
- "the data and error messages should be passed in as "
- "unicode strings")
- raise
+ self._text = self._get_text()
+ def skip_output(self):
+ return self.in_textarea or self.skip_error
+
def add_key(self, key):
self.used_keys[key] = 1
- _entityref_re = re.compile('&([a-zA-Z][-.a-zA-Z\d]*);')
- _charref_re = re.compile('&#(\d+|[xX][a-fA-F\d]+);')
-
- def unescape(self, s):
- s = self._entityref_re.sub(self._sub_entityref, s)
- s = self._charref_re.sub(self._sub_charref, s)
- return s
-
- def _sub_entityref(self, match):
- name = match.group(1)
- if name not in name2codepoint:
- # If we don't recognize it, pass it through as though it
- # wasn't an entity ref at all
- return match.group(0)
- return unichr(name2codepoint[name])
-
- def _sub_charref(self, match):
- num = match.group(1)
- if num.lower().startswith('x'):
- num = int(num[1:], 16)
- else:
- num = int(num)
- return unichr(num)
-
def handle_starttag(self, tag, attrs, startend=False):
self.write_pos()
if tag == 'input':
@@ -318,16 +260,6 @@
if self.listener:
self.listener.listen_input(self, tag, attrs)
- def handle_misc(self, whatever):
- self.write_pos()
- handle_charref = handle_misc
- handle_entityref = handle_misc
- handle_data = handle_misc
- handle_comment = handle_misc
- handle_decl = handle_misc
- handle_pi = handle_misc
- unknown_decl = handle_misc
-
def handle_endtag(self, tag):
self.write_pos()
if tag == 'textarea':
@@ -530,9 +462,6 @@
return True
return str(obj) == value
- def write_text(self, text):
- self._content.append(text)
-
def write_marker(self, marker):
self._content.append((marker,))
@@ -544,68 +473,6 @@
else:
self._content.insert(0, text)
- def write_tag(self, tag, attrs, startend=False):
- attr_text = ''.join([' %s="%s"' % (n, html_quote(v))
- for (n, v) in attrs
- if not n.startswith('form:')])
- if startend:
- attr_text += " /"
- self.write_text('<%s%s>' % (tag, attr_text))
-
- def write_pos(self):
- cur_line, cur_offset = self.getpos()
- if self.in_textarea or self.skip_error:
- self.source_pos = self.getpos()
- return
- if self.skip_next:
- self.skip_next = False
- self.source_pos = self.getpos()
- return
- if cur_line == self.source_pos[0]:
- self.write_text(
- self.lines[cur_line-1][self.source_pos[1]:cur_offset])
- else:
- self.write_text(
- self.lines[self.source_pos[0]-1][self.source_pos[1]:])
- self.write_text('\n')
- for i in range(self.source_pos[0]+1, cur_line):
- self.write_text(self.lines[i-1])
- self.write_text('\n')
- self.write_text(self.lines[cur_line-1][:cur_offset])
- self.source_pos = self.getpos()
-
- def get_attr(self, attr, name, default=None):
- for n, value in attr:
- if n.lower() == name:
- return value
- return default
-
- def set_attr(self, attr, name, value):
- for i in range(len(attr)):
- if attr[i][0].lower() == name:
- attr[i] = (name, value)
- return
- attr.append((name, value))
-
- def del_attr(self, attr, name):
- for i in range(len(attr)):
- if attr[i][0].lower() == name:
- del attr[i]
- break
-
- def add_class(self, attr, class_name):
- current = self.get_attr(attr, 'class', '')
- new = current + ' ' + class_name
- self.set_attr(attr, 'class', new.strip())
-
- def text(self):
- try:
- return self._text
- except AttributeError:
- raise Exception(
- "You must .close() a parser instance before getting "
- "the text from it")
-
# This can potentially be extended globally
default_formatter_dict = {'default': default_formatter,
'none': none_formatter,
Added: FormEncode/trunk/formencode/htmlrename.py
===================================================================
--- FormEncode/trunk/formencode/htmlrename.py (rev 0)
+++ FormEncode/trunk/formencode/htmlrename.py 2008-04-23 06:55:04 UTC (rev 3395)
@@ -0,0 +1,76 @@
+"""
+Module to rename form fields
+"""
+
+import HTMLParser
+from formencode.rewritingparser import RewritingParser
+
+__all__ = ['rename', 'add_prefix']
+
+def rename(form, rename_func):
+ """
+ Rename all the form fields in the form (a string), using rename_func
+
+ rename_func will be called with one argument, the name of the
+ field, and should return a new name.
+ """
+ p = RenamingParser(rename_func)
+ p.feed(form)
+ p.close()
+ return p.text()
+
+def add_prefix(form, prefix, dotted=False):
+ """
+ Add the given prefix to all the fields in the form.
+
+ If dotted is true, then add a dot between prefix and the previous
+ name. Empty fields will use the prefix as the name (with no dot).
+ """
+ def rename_func(field_name):
+ if dotted:
+ if field_name:
+ return prefix + '.' + field_name
+ else:
+ return prefix
+ else:
+ return prefix + field_name
+ return rename(form, rename_func)
+
+class RenamingParser(RewritingParser):
+
+ def __init__(self, rename_func):
+ RewritingParser.__init__(self)
+ self.rename_func = rename_func
+
+ def close(self):
+ self.handle_misc(None)
+ RewritingParser.close(self)
+ self._text = self._get_text()
+
+ def text(self):
+ try:
+ return self._text
+ except AttributeError:
+ raise Exception(
+ "You must .close() a parser instance before getting "
+ "the text from it")
+
+ def handle_starttag(self, tag, attrs, startend=False):
+ self.write_pos()
+ if tag in ('input', 'textarea', 'select'):
+ self.handle_field(tag, attrs, startend)
+ else:
+ return
+
+ def handle_startendtag(self, tag, attrs):
+ return self.handle_starttag(tag, attrs, True)
+
+ def handle_field(self, tag, attrs, startend):
+ name = self.get_attr(attrs, 'name', '')
+ new_name = self.rename_func(name)
+ if name is None:
+ self.del_attr(attrs, 'name')
+ else:
+ self.set_attr(attrs, 'name', new_name)
+ self.write_tag(tag, attrs)
+ self.skip_next = True
Property changes on: FormEncode/trunk/formencode/htmlrename.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: FormEncode/trunk/formencode/rewritingparser.py
===================================================================
--- FormEncode/trunk/formencode/rewritingparser.py (rev 0)
+++ FormEncode/trunk/formencode/rewritingparser.py 2008-04-23 06:55:04 UTC (rev 3395)
@@ -0,0 +1,153 @@
+import HTMLParser
+import re
+import cgi
+from htmlentitydefs import name2codepoint
+
+def html_quote(v):
+ if v is None:
+ return ''
+ elif hasattr(v, '__html__'):
+ return v.__html__()
+ elif isinstance(v, basestring):
+ return cgi.escape(v, 1)
+ else:
+ # @@: Should this be unicode(v) or str(v)?
+ return cgi.escape(str(v), 1)
+
+class RewritingParser(HTMLParser.HTMLParser):
+
+ listener = None
+ skip_next = False
+
+ def __init__(self):
+ self._content = []
+ HTMLParser.HTMLParser.__init__(self)
+
+ def feed(self, data):
+ self.data_is_str = isinstance(data, str)
+ self.source = data
+ self.lines = data.split('\n')
+ self.source_pos = 1, 0
+ if self.listener:
+ self.listener.reset()
+ HTMLParser.HTMLParser.feed(self, data)
+
+ _entityref_re = re.compile('&([a-zA-Z][-.a-zA-Z\d]*);')
+ _charref_re = re.compile('&#(\d+|[xX][a-fA-F\d]+);')
+
+ def unescape(self, s):
+ s = self._entityref_re.sub(self._sub_entityref, s)
+ s = self._charref_re.sub(self._sub_charref, s)
+ return s
+
+ def _sub_entityref(self, match):
+ name = match.group(1)
+ if name not in name2codepoint:
+ # If we don't recognize it, pass it through as though it
+ # wasn't an entity ref at all
+ return match.group(0)
+ return unichr(name2codepoint[name])
+
+ def _sub_charref(self, match):
+ num = match.group(1)
+ if num.lower().startswith('x'):
+ num = int(num[1:], 16)
+ else:
+ num = int(num)
+ return unichr(num)
+
+ def handle_misc(self, whatever):
+ self.write_pos()
+ handle_charref = handle_misc
+ handle_entityref = handle_misc
+ handle_data = handle_misc
+ handle_comment = handle_misc
+ handle_decl = handle_misc
+ handle_pi = handle_misc
+ unknown_decl = handle_misc
+
+ def write_tag(self, tag, attrs, startend=False):
+ attr_text = ''.join([' %s="%s"' % (n, html_quote(v))
+ for (n, v) in attrs
+ if not n.startswith('form:')])
+ if startend:
+ attr_text += " /"
+ self.write_text('<%s%s>' % (tag, attr_text))
+
+ def skip_output(self):
+ return False
+
+ def write_pos(self):
+ cur_line, cur_offset = self.getpos()
+ if self.skip_output():
+ self.source_pos = self.getpos()
+ return
+ if self.skip_next:
+ self.skip_next = False
+ self.source_pos = self.getpos()
+ return
+ if cur_line == self.source_pos[0]:
+ self.write_text(
+ self.lines[cur_line-1][self.source_pos[1]:cur_offset])
+ else:
+ self.write_text(
+ self.lines[self.source_pos[0]-1][self.source_pos[1]:])
+ self.write_text('\n')
+ for i in range(self.source_pos[0]+1, cur_line):
+ self.write_text(self.lines[i-1])
+ self.write_text('\n')
+ self.write_text(self.lines[cur_line-1][:cur_offset])
+ self.source_pos = self.getpos()
+
+ def write_text(self, text):
+ self._content.append(text)
+
+ def get_attr(self, attr, name, default=None):
+ for n, value in attr:
+ if n.lower() == name:
+ return value
+ return default
+
+ def set_attr(self, attr, name, value):
+ for i in range(len(attr)):
+ if attr[i][0].lower() == name:
+ attr[i] = (name, value)
+ return
+ attr.append((name, value))
+
+ def del_attr(self, attr, name):
+ for i in range(len(attr)):
+ if attr[i][0].lower() == name:
+ del attr[i]
+ break
+
+ def add_class(self, attr, class_name):
+ current = self.get_attr(attr, 'class', '')
+ new = current + ' ' + class_name
+ self.set_attr(attr, 'class', new.strip())
+
+ def text(self):
+ try:
+ return self._text
+ except AttributeError:
+ raise Exception(
+ "You must .close() a parser instance before getting "
+ "the text from it")
+
+ def _get_text(self):
+ try:
+ return ''.join([
+ t for t in self._content if not isinstance(t, tuple)])
+ except UnicodeDecodeError, e:
+ if self.data_is_str:
+ e.reason += (
+ " the form was passed in as an encoded string, but "
+ "some data or error messages were unicode strings; "
+ "the form should be passed in as a unicode string")
+ else:
+ e.reason += (
+ " the form was passed in as an unicode string, but "
+ "some data or error message was an encoded string; "
+ "the data and error messages should be passed in as "
+ "unicode strings")
+ raise
Property changes on: FormEncode/trunk/formencode/rewritingparser.py
___________________________________________________________________
Name: svn:eol-style
+ native
Added: FormEncode/trunk/tests/test_htmlrename.py
===================================================================
--- FormEncode/trunk/tests/test_htmlrename.py (rev 0)
+++ FormEncode/trunk/tests/test_htmlrename.py 2008-04-23 06:55:04 UTC (rev 3395)
@@ -0,0 +1,8 @@
+from formencode.htmlrename import rename, add_prefix
+
+def test_rename():
+ assert (rename('<input type="text" name="a_name">', lambda name: name.upper())
+ == '<input type="text" name="A_NAME">')
+ assert (add_prefix('<input type="text" name="a_name"><input type="text" name="">', 'test', dotted=True)
+ == '<input type="text" name="test.a_name"><input type="text" name="test">')
+
Property changes on: FormEncode/trunk/tests/test_htmlrename.py
___________________________________________________________________
Name: svn:eol-style
+ native
|
|
From: <sub...@co...> - 2008-04-23 06:53:03
|
Author: ianb
Date: 2008-04-23 00:53:03 -0600 (Wed, 23 Apr 2008)
New Revision: 3394
Removed:
FormEncode/trunk/tests/disabled_makeform.py
FormEncode/trunk/tests/test_formgen.py
Log:
removing tests for removed modules
Deleted: FormEncode/trunk/tests/disabled_makeform.py
===================================================================
--- FormEncode/trunk/tests/disabled_makeform.py 2008-04-23 06:22:12 UTC (rev 3393)
+++ FormEncode/trunk/tests/disabled_makeform.py 2008-04-23 06:53:03 UTC (rev 3394)
@@ -1,70 +0,0 @@
-# @@: Note, this is an experimental (TDD) test
-from sqlobject import *
-from formencode.formgen import makeform
-from formencode.fields import Context
-from formencode.doctest_xml_compare import xml_compare, make_xml
-from formencode import sqlformgen
-
-sqlhub.processConnection = connectionForURI('sqlite:/:memory:')
-
-CONTEXT = Context()
-CONTEXT.secret = 'foo'
-
-def printer(s):
- print s
-
-def xcmp(a, b):
- try:
- a = '<xml>%s</xml>' % a
- xml_a = make_xml(a)
- except:
- print prxml(a)
- raise
- try:
- b = '<xml>%s</xml>' % b
- xml_b = make_xml(b)
- except:
- print prxml(b)
- raise
- prxml(a)
- prxml(b)
- assert xml_compare(xml_a, xml_b, reporter=printer)
-
-def prxml(xml):
- for lineno, line in enumerate(xml.splitlines()):
- print '%2i %s' % (lineno+1, line)
-
-class SimpleForm(SQLObject):
-
- name = StringCol()
- address = StringCol()
- city = StringCol()
-
-SimpleForm.createTable()
-
-def test_simple():
- f, v = makeform(SimpleForm, CONTEXT)
- yield (xcmp, f(requires_label=True).render(CONTEXT), """
- name: <input type="text" name="name" /> <br />
- address: <input type="text" name="address" /> <br />
- city: <input type="text" name="city" /> <br />
- """)
-
- f.name = 'simp'
-
- yield (xcmp, f(requires_label=True).render(CONTEXT), """
- name: <input type="text" name="simp.name" /> <br />
- address: <input type="text" name="simp.address" /> <br />
- city: <input type="text" name="simp.city" /> <br />
- """)
-
- # This test isn't really ready, so we'll skip
- return
- s = SimpleForm(name='Tom', address='123', city='Chicago')
- f, v = makeform(s, CONTEXT)
- yield (xcmp, f(requires_label=True).render(CONTEXT), """
- name: <input type="text" name="name" value="Tom" /> <br />
- address: <input type="text" name="address" value="123" /> <br />
- city: <input type="text" name="city" value="Chicago" /> <br />
- """)
-
Deleted: FormEncode/trunk/tests/test_formgen.py
===================================================================
--- FormEncode/trunk/tests/test_formgen.py 2008-04-23 06:22:12 UTC (rev 3393)
+++ FormEncode/trunk/tests/test_formgen.py 2008-04-23 06:53:03 UTC (rev 3394)
@@ -1,13 +0,0 @@
-try:
- import doctest
- doctest.OutputChecker
-except AttributeError:
- import formencode.util.doctest24 as doctest
-from formencode import formgen
-from formencode import doctest_xml_compare
-
-doctest_xml_compare.install()
-
-if __name__ == '__main__':
- doctest.testmod(formgen)
-
|
|
From: <sub...@co...> - 2008-04-18 18:52:52
|
Author: ianb
Date: 2008-04-18 12:52:53 -0600 (Fri, 18 Apr 2008)
New Revision: 3387
Modified:
FormEncode/trunk/formencode/htmlfill.py
FormEncode/trunk/tests/test_htmlfill.py
Log:
Fixed case for </select>
Modified: FormEncode/trunk/formencode/htmlfill.py
===================================================================
--- FormEncode/trunk/formencode/htmlfill.py 2008-04-18 16:55:37 UTC (rev 3386)
+++ FormEncode/trunk/formencode/htmlfill.py 2008-04-18 18:52:53 UTC (rev 3387)
@@ -489,8 +489,10 @@
self.add_key(self.in_select)
def handle_end_select(self):
+ self.write_text('</select>')
+ self.skip_next = True
if not self.prefix_error and self.in_select:
- self.write_marker(name)
+ self.write_marker(self.in_select)
self.in_select = None
def handle_option(self, attrs):
Modified: FormEncode/trunk/tests/test_htmlfill.py
===================================================================
--- FormEncode/trunk/tests/test_htmlfill.py 2008-04-18 16:55:37 UTC (rev 3386)
+++ FormEncode/trunk/tests/test_htmlfill.py 2008-04-18 18:52:53 UTC (rev 3387)
@@ -99,4 +99,6 @@
assert (htmlfill.render('<textarea name="content"></textarea>', errors={'content': 'error'},
prefix_error=False)
== '<textarea name="content" class="error"></textarea><!-- for: content -->\n<span class="error-message">error</span><br />\n')
-
+ assert (htmlfill.render('<select name="type"><option value="foo">foo</option></select>', errors={'type': 'error'},
+ prefix_error=False)
+ == '<select name="type" class="error"><option value="foo">foo</option></select><!-- for: type -->\n<span class="error-message">error</span><br />\n')
|
|
From: <sub...@co...> - 2008-04-18 16:56:02
|
Author: ianb
Date: 2008-04-18 10:55:37 -0600 (Fri, 18 Apr 2008)
New Revision: 3386
Modified:
FormEncode/trunk/formencode/htmlfill.py
FormEncode/trunk/tests/test_htmlfill.py
Log:
Fixed prefix_error to work with select and textarea (only worked with input before)
Modified: FormEncode/trunk/formencode/htmlfill.py
===================================================================
--- FormEncode/trunk/formencode/htmlfill.py 2008-04-16 18:27:58 UTC (rev 3385)
+++ FormEncode/trunk/formencode/htmlfill.py 2008-04-18 16:55:37 UTC (rev 3386)
@@ -184,6 +184,7 @@
self.source_pos = None
self.defaults = defaults
self.in_textarea = None
+ self.last_textarea_name = None
self.in_select = None
self.skip_next = False
self.errors = errors or {}
@@ -204,10 +205,7 @@
self.auto_error_formatter = auto_error_formatter
self.text_as_default = text_as_default
self.encoding = encoding
- if prefix_error:
- self._marker_offset = 0
- else:
- self._marker_offset = 2
+ self.prefix_error = prefix_error
def feed(self, data):
self.data_is_str = isinstance(data, str)
@@ -380,7 +378,8 @@
def handle_input(self, attrs, startend):
t = (self.get_attr(attrs, 'type') or 'text').lower()
name = self.get_attr(attrs, 'name')
- self.write_marker(name)
+ if self.prefix_error:
+ self.write_marker(name)
value = self.defaults.get(name)
if self.add_attributes.has_key(name):
for attr_name, attr_value in self.add_attributes[name].items():
@@ -452,10 +451,13 @@
else:
assert 0, "I don't know about this kind of <input>: %s (pos: %s)" \
% (t, self.getpos())
+ if not self.prefix_error:
+ self.write_marker(name)
def handle_textarea(self, attrs):
name = self.get_attr(attrs, 'name')
- self.write_marker(name)
+ if self.prefix_error:
+ self.write_marker(name)
if (self.error_class
and self.errors.get(name)):
self.add_class(attrs, self.error_class)
@@ -464,15 +466,19 @@
self.write_text(html_quote(value))
self.write_text('</textarea>')
self.in_textarea = True
+ self.last_textarea_name = name
self.add_key(name)
def handle_end_textarea(self):
self.in_textarea = False
self.skip_next = True
+ if not self.prefix_error:
+ self.write_marker(self.last_textarea_name)
+ self.last_textarea_name = None
def handle_select(self, attrs):
name = self.get_attr(attrs, 'name', False)
- if name:
+ if name and self.prefix_error:
self.write_marker(name)
if (self.error_class
and self.errors.get(name)):
@@ -483,6 +489,8 @@
self.add_key(self.in_select)
def handle_end_select(self):
+ if not self.prefix_error and self.in_select:
+ self.write_marker(name)
self.in_select = None
def handle_option(self, attrs):
@@ -527,10 +535,9 @@
self._content.append((marker,))
def insert_at_marker(self, marker, text):
-
for i, item in enumerate(self._content):
if item == (marker,):
- self._content.insert(i + self._marker_offset, text)
+ self._content.insert(i, text)
break
else:
self._content.insert(0, text)
Modified: FormEncode/trunk/tests/test_htmlfill.py
===================================================================
--- FormEncode/trunk/tests/test_htmlfill.py 2008-04-16 18:27:58 UTC (rev 3385)
+++ FormEncode/trunk/tests/test_htmlfill.py 2008-04-18 16:55:37 UTC (rev 3386)
@@ -91,5 +91,12 @@
def test_xhtml():
result = htmlfill.render('<form:error name="code"/>', errors={'code': 'an error'})
- print result
+def test_trailing_error():
+ assert (htmlfill.render('<input type="text" name="email">', errors={'email': 'error'},
+ prefix_error=False)
+ == '<input type="text" name="email" class="error" value=""><!-- for: email -->\n<span class="error-message">error</span><br />\n')
+ assert (htmlfill.render('<textarea name="content"></textarea>', errors={'content': 'error'},
+ prefix_error=False)
+ == '<textarea name="content" class="error"></textarea><!-- for: content -->\n<span class="error-message">error</span><br />\n')
+
|
|
From: <sub...@co...> - 2008-04-13 00:55:21
|
Author: pjenvey
Date: 2008-04-12 18:55:25 -0600 (Sat, 12 Apr 2008)
New Revision: 3379
Modified:
FormEncode/trunk/formencode/formgen.py
Log:
don't blow up if pkg_resources can't find RuleDispatch
Modified: FormEncode/trunk/formencode/formgen.py
===================================================================
--- FormEncode/trunk/formencode/formgen.py 2008-04-13 00:53:32 UTC (rev 3378)
+++ FormEncode/trunk/formencode/formgen.py 2008-04-13 00:55:25 UTC (rev 3379)
@@ -15,7 +15,7 @@
import pkg_resources
pkg_resources.require('RuleDispatch')
import dispatch
-except ImportError:
+except (ImportError, pkg_resources.DistributionNotFound):
pass
if dispatch:
|
|
From: <sub...@co...> - 2008-04-13 00:53:31
|
Author: pjenvey
Date: 2008-04-12 18:53:32 -0600 (Sat, 12 Apr 2008)
New Revision: 3378
Modified:
FormEncode/trunk/tests/test_htmlfill.py
Log:
o __builtins__ is CPython specific, use __builtin__ instead
o fix test_xhtml
Modified: FormEncode/trunk/tests/test_htmlfill.py
===================================================================
--- FormEncode/trunk/tests/test_htmlfill.py 2008-04-11 16:16:35 UTC (rev 3377)
+++ FormEncode/trunk/tests/test_htmlfill.py 2008-04-13 00:53:32 UTC (rev 3378)
@@ -2,6 +2,7 @@
import sys
import os
import re
+import __builtin__
from htmlentitydefs import name2codepoint
base_dir = os.path.dirname(os.path.dirname(os.path.dirname(
@@ -50,7 +51,7 @@
def checker(p, s):
pass
for name in data.keys():
- if name.startswith('_') or hasattr(__builtins__, name):
+ if name.startswith('_') or hasattr(__builtin__, name):
del data[name]
listener = htmlfill_schemabuilder.SchemaBuilder()
p = htmlfill.FillingParser(listener=listener, **data)
@@ -91,5 +92,4 @@
def test_xhtml():
result = htmlfill.render('<form:error name="code"/>', errors={'code': 'an error'})
print result
- assert 0
|
|
From: <sub...@co...> - 2008-04-11 16:16:47
|
Author: ianb
Date: 2008-04-11 10:16:35 -0600 (Fri, 11 Apr 2008)
New Revision: 3377
Modified:
FormEncode/trunk/docs/download.txt
Log:
remove old download links
Modified: FormEncode/trunk/docs/download.txt
===================================================================
--- FormEncode/trunk/docs/download.txt 2008-04-10 23:18:24 UTC (rev 3376)
+++ FormEncode/trunk/docs/download.txt 2008-04-11 16:16:35 UTC (rev 3377)
@@ -7,14 +7,3 @@
The repository can be checked out with::
svn co http://svn.colorstudy.com/FormEncode/trunk FormEncode
-
-Available files:
-
-* `FormEncode-0.4.tar.gz
- <http://cheeseshop.python.org/packages/source/F/FormEncode/FormEncode-0.4.tar.gz>`_
-
-* `FormEncode-0.4-py2.4.egg
- <http://cheeseshop.python.org/packages/2.4/F/FormEncode/FormEncode-0.4-py2.4.egg>`_
-
-* `FormEncode-0.4-py2.3.egg
- <http://cheeseshop.python.org/packages/2.4/F/FormEncode/FormEncode-0.4-py2.3.egg>`_
|
|
From: <sub...@co...> - 2008-04-10 08:19:19
|
Author: ianb
Date: 2008-04-10 02:19:18 -0600 (Thu, 10 Apr 2008)
New Revision: 3374
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/htmlfill.py
Log:
Added prefix_error option to htmlfill.render
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-04-09 13:19:11 UTC (rev 3373)
+++ FormEncode/trunk/docs/news.txt 2008-04-10 08:19:18 UTC (rev 3374)
@@ -3,6 +3,13 @@
.. contents::
+svn trunk
+---------
+
+* Added a parameter to ``htmlfill.render()``: ``prefix_error``. If
+ this parameter is true (the default) then errors automatically go
+ before the input field; if false then they go after the input field.
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/htmlfill.py
===================================================================
--- FormEncode/trunk/formencode/htmlfill.py 2008-04-09 13:19:11 UTC (rev 3373)
+++ FormEncode/trunk/formencode/htmlfill.py 2008-04-10 08:19:18 UTC (rev 3374)
@@ -16,7 +16,7 @@
error_formatters=None, add_attributes=None,
auto_insert_errors=True, auto_error_formatter=None,
text_as_default=False, listener=None, encoding=None,
- error_class='error'):
+ error_class='error', prefix_error=True):
"""
Render the ``form`` (which should be a string) given the defaults
and errors. Defaults are the values that go in the input fields
@@ -57,6 +57,9 @@
``encoding`` specifies an encoding to assume when mixing str and
unicode text in the template.
+
+ ``prefix_error`` specifies if the HTML created by auto_error_formatter is
+ put before the input control (default) or after the control.
"""
if defaults is None:
defaults = {}
@@ -70,6 +73,7 @@
auto_error_formatter=auto_error_formatter,
text_as_default=text_as_default,
listener=listener, encoding=encoding,
+ prefix_error=prefix_error,
error_class=error_class,
)
p.feed(form)
@@ -172,7 +176,7 @@
error_formatters=None, error_class='error',
add_attributes=None, listener=None,
auto_error_formatter=None,
- text_as_default=False, encoding=None):
+ text_as_default=False, encoding=None, prefix_error=True):
HTMLParser.HTMLParser.__init__(self)
self._content = []
self.source = None
@@ -200,6 +204,10 @@
self.auto_error_formatter = auto_error_formatter
self.text_as_default = text_as_default
self.encoding = encoding
+ if prefix_error:
+ self._marker_offset = 0
+ else:
+ self._marker_offset = 2
def feed(self, data):
self.data_is_str = isinstance(data, str)
@@ -519,9 +527,10 @@
self._content.append((marker,))
def insert_at_marker(self, marker, text):
+
for i, item in enumerate(self._content):
if item == (marker,):
- self._content.insert(i, text)
+ self._content.insert(i + self._marker_offset, text)
break
else:
self._content.insert(0, text)
|
|
From: <sub...@co...> - 2008-03-27 15:24:51
|
Author: ianb Date: 2008-03-27 09:24:48 -0600 (Thu, 27 Mar 2008) New Revision: 3365 Modified: FormEncode/tags/1.0.1/setup.cfg Log: Auto-update of version strings Modified: FormEncode/tags/1.0.1/setup.cfg =================================================================== --- FormEncode/tags/1.0.1/setup.cfg 2008-03-27 15:24:38 UTC (rev 3364) +++ FormEncode/tags/1.0.1/setup.cfg 2008-03-27 15:24:48 UTC (rev 3365) @@ -1,43 +1,39 @@ [global] command_packages = buildutils.pudge_command, buildutils.publish_command -[egg_info] -tag_build = dev -tag_svn_revision = true +[nosetests] +detailed-errors = 1 +[publish] +doc-dest = scp://ianbicking@shell.sf.net/home/groups/f/fo/formencode/htdocs/ +doc-dir = docs/html + [pudge] -theme = pythonpaste.org -docs = docs/index.txt docs/Validator.txt docs/ToDo.txt - docs/news.txt docs/htmlfill.txt docs/Design.txt - docs/community.txt docs/download.txt - docs/history.txt docs/i18n.txt -doc_base = docs/ +organization = FormEncode +title = FormEncode dest = docs/html +docs = docs/index.txt docs/Validator.txt docs/ToDo.txt + docs/news.txt docs/htmlfill.txt docs/Design.txt + docs/community.txt docs/download.txt + docs/history.txt docs/i18n.txt +settings = normal_link_color=#083 + visited_color=#038 + hover_color=#dfd + body_outer_bg_color=#173 + body_border_color=#0f0 + nav_container_color=#7d9 + nav_button_color=#073 + nav_border_color=#0f5 + doctitle_color=#009900 + no_about=true + link1=/Validator.html Documentation modules = formencode -exclude_modules = formencode.fields formencode.formgen - formencode.sqlformgen formencode.sqlschema -title = FormEncode +doc_base = docs/ +theme = pythonpaste.org mailing_list_url = http://formencode.org/community.html -organization = FormEncode -settings = normal_link_color=#083 - visited_color=#038 - hover_color=#dfd - body_outer_bg_color=#173 - body_border_color=#0f0 - nav_container_color=#7d9 - nav_button_color=#073 - nav_border_color=#0f5 - doctitle_color=#009900 +exclude_modules = formencode.fields formencode.formgen + formencode.sqlformgen formencode.sqlschema - no_about=true - link1=/Validator.html Documentation - -[publish] -doc-dir = docs/html -doc-dest = scp://ianbicking@shell.sf.net/home/groups/f/fo/formencode/htdocs/ - [aliases] distribute = register sdist bdist_egg upload pudge publish -[nosetests] -detailed-errors = 1 |
|
From: <sub...@co...> - 2008-03-27 15:24:47
|
Author: ianb
Date: 2008-03-27 09:24:51 -0600 (Thu, 27 Mar 2008)
New Revision: 3366
Modified:
FormEncode/trunk/setup.py
Log:
Auto-update of version strings
Modified: FormEncode/trunk/setup.py
===================================================================
--- FormEncode/trunk/setup.py 2008-03-27 15:24:48 UTC (rev 3365)
+++ FormEncode/trunk/setup.py 2008-03-27 15:24:51 UTC (rev 3366)
@@ -6,7 +6,7 @@
use_setuptools()
from setuptools import setup
-version = '1.0.1'
+version = '1.0.2'
tests_require = ['nose']
if sys.version < '2.5':
|
|
From: <sub...@co...> - 2008-03-27 15:24:35
|
Author: ianb Date: 2008-03-27 09:24:38 -0600 (Thu, 27 Mar 2008) New Revision: 3364 Added: FormEncode/tags/1.0.1/ Log: Tagging 1.0.1 version Copied: FormEncode/tags/1.0.1 (from rev 3363, FormEncode/trunk) |