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-10-29 16:32:07
|
Author: ianb
Date: 2008-10-29 10:32:02 -0600 (Wed, 29 Oct 2008)
New Revision: 3638
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/api.py
Log:
Added __unicode__ method to Invalid
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-10-28 15:53:47 UTC (rev 3637)
+++ FormEncode/trunk/docs/news.txt 2008-10-29 16:32:02 UTC (rev 3638)
@@ -3,6 +3,11 @@
.. contents::
+svn trunk
+---------
+
+* Added :meth:`formencode.api.Invalid.__unicode__`
+
1.1
---
Modified: FormEncode/trunk/formencode/api.py
===================================================================
--- FormEncode/trunk/formencode/api.py 2008-10-28 15:53:47 UTC (rev 3637)
+++ FormEncode/trunk/formencode/api.py 2008-10-29 16:32:02 UTC (rev 3638)
@@ -118,6 +118,9 @@
# val += " (value: %s)" % repr(self.value)
return val
+ def __unicode__(self):
+ return self.msg
+
def unpack_errors(self, encode_variables=False, dict_char='.',
list_char='-'):
"""
|
|
From: <sub...@co...> - 2008-10-28 15:53:52
|
Author: ianb
Date: 2008-10-28 09:53:47 -0600 (Tue, 28 Oct 2008)
New Revision: 3637
Modified:
FormEncode/trunk/formencode/schema.py
Log:
Fix the SimpleFormValidator's return value, and allow it to validate partial forms
Modified: FormEncode/trunk/formencode/schema.py
===================================================================
--- FormEncode/trunk/formencode/schema.py 2008-10-28 15:39:27 UTC (rev 3636)
+++ FormEncode/trunk/formencode/schema.py 2008-10-28 15:53:47 UTC (rev 3637)
@@ -451,7 +451,10 @@
else:
raise TypeError(
"Invalid error value: %r" % errors)
+ return value_dict
+ validate_partial = to_python
+
def decorate(cls, **kw):
def decorator(func):
return cls(func, **kw)
|
|
From: <sub...@co...> - 2008-10-28 15:39:42
|
Author: ianb
Date: 2008-10-28 09:39:27 -0600 (Tue, 28 Oct 2008)
New Revision: 3636
Modified:
FormEncode/trunk/formencode/api.py
Log:
fall back on in-package location when os.access doesn't exist
Modified: FormEncode/trunk/formencode/api.py
===================================================================
--- FormEncode/trunk/formencode/api.py 2008-10-27 21:38:29 UTC (rev 3635)
+++ FormEncode/trunk/formencode/api.py 2008-10-28 15:39:27 UTC (rev 3636)
@@ -32,6 +32,9 @@
except NotImplementedError:
# resource_filename doesn't work with non-egg zip files
pass
+ if not hasattr(os, 'access'):
+ # This happens on Google App Engine
+ os.path.join(os.path.dirname(__file__), 'i18n')
if os.access(locale_dir, os.R_OK | os.X_OK):
# If the resource is present in the egg, use it
return locale_dir
|
|
From: <sub...@co...> - 2008-10-27 22:38:27
|
Author: ianb Date: 2008-10-27 15:31:27 -0600 (Mon, 27 Oct 2008) New Revision: 3632 Added: FormEncode/tags/1.1/ Log: Tagging 1.1 version Copied: FormEncode/tags/1.1 (from rev 3631, FormEncode/trunk) |
|
From: <sub...@co...> - 2008-10-27 22:38:23
|
Author: ianb Date: 2008-10-27 15:31:40 -0600 (Mon, 27 Oct 2008) New Revision: 3633 Modified: FormEncode/tags/1.1/setup.cfg FormEncode/tags/1.1/setup.py Log: Auto-update of version strings Modified: FormEncode/tags/1.1/setup.cfg =================================================================== --- FormEncode/tags/1.1/setup.cfg 2008-10-27 21:31:27 UTC (rev 3632) +++ FormEncode/tags/1.1/setup.cfg 2008-10-27 21:31:40 UTC (rev 3633) @@ -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 Modified: FormEncode/tags/1.1/setup.py =================================================================== --- FormEncode/tags/1.1/setup.py 2008-10-27 21:31:27 UTC (rev 3632) +++ FormEncode/tags/1.1/setup.py 2008-10-27 21:31:40 UTC (rev 3633) @@ -1,7 +1,7 @@ import sys from setuptools import setup -version = '1.0.2' +version = '1.1' tests_require = ['nose'] if sys.version < '2.5': |
|
From: <sub...@co...> - 2008-10-27 22:38:19
|
Author: ianb Date: 2008-10-27 15:31:43 -0600 (Mon, 27 Oct 2008) New Revision: 3634 Modified: FormEncode/trunk/setup.py Log: Auto-update of version strings Modified: FormEncode/trunk/setup.py =================================================================== --- FormEncode/trunk/setup.py 2008-10-27 21:31:40 UTC (rev 3633) +++ FormEncode/trunk/setup.py 2008-10-27 21:31:43 UTC (rev 3634) @@ -1,7 +1,7 @@ import sys from setuptools import setup -version = '1.0.2' +version = '1.1.1' tests_require = ['nose'] if sys.version < '2.5': |
|
From: <sub...@co...> - 2008-10-27 22:38:17
|
Author: ianb Date: 2008-10-27 15:38:29 -0600 (Mon, 27 Oct 2008) New Revision: 3635 Added: FormEncode/trunk/regen-docs Log: Added doc generation script Added: FormEncode/trunk/regen-docs =================================================================== --- FormEncode/trunk/regen-docs (rev 0) +++ FormEncode/trunk/regen-docs 2008-10-27 21:38:29 UTC (rev 3635) @@ -0,0 +1,9 @@ +#!/bin/sh + +mkdir -p docs/_static docs/_build +sphinx-build -E -b html docs/ docs/_build || exit 1 +if [ "$1" = "publish" ] ; then + cd docs/ + echo "Uploading files..." + scp -r _build/* ian...@we...:/home/groups/f/fo/formencode/htdocs/ +fi Property changes on: FormEncode/trunk/regen-docs ___________________________________________________________________ Name: svn:executable + * |
|
From: <sub...@co...> - 2008-10-27 22:38:12
|
Author: ianb Date: 2008-10-27 15:31:10 -0600 (Mon, 27 Oct 2008) New Revision: 3631 Modified: FormEncode/trunk/docs/conf.py FormEncode/trunk/docs/news.txt Log: update news for release Modified: FormEncode/trunk/docs/conf.py =================================================================== --- FormEncode/trunk/docs/conf.py 2008-10-21 17:21:18 UTC (rev 3630) +++ FormEncode/trunk/docs/conf.py 2008-10-27 21:31:10 UTC (rev 3631) @@ -40,9 +40,9 @@ # other places throughout the built documents. # # The short X.Y version. -version = '1.0' +version = '1.1' # The full version, including alpha/beta/rc tags. -release = '1.0.2' +release = '1.1' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: Modified: FormEncode/trunk/docs/news.txt =================================================================== --- FormEncode/trunk/docs/news.txt 2008-10-21 17:21:18 UTC (rev 3630) +++ FormEncode/trunk/docs/news.txt 2008-10-27 21:31:10 UTC (rev 3631) @@ -3,8 +3,8 @@ .. contents:: -svn trunk ---------- +1.1 +--- * Fixed the ``is_empty()`` method in :class:`formencode.validators.FieldStorageUploadConverter`; |
|
From: <sub...@co...> - 2008-10-21 17:21:27
|
Author: ltucker
Date: 2008-10-21 11:21:18 -0600 (Tue, 21 Oct 2008)
New Revision: 3630
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/validators.py
Log:
Fix is_empty() method in FieldStorageUploadConverter; was returning opposite of intent.
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-10-19 00:40:31 UTC (rev 3629)
+++ FormEncode/trunk/docs/news.txt 2008-10-21 17:21:18 UTC (rev 3630)
@@ -6,6 +6,10 @@
svn trunk
---------
+* Fixed the ``is_empty()`` method in
+ :class:`formencode.validators.FieldStorageUploadConverter`;
+ previously it returned the opposite of the intended result.
+
* 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.
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-10-19 00:40:31 UTC (rev 3629)
+++ FormEncode/trunk/formencode/validators.py 2008-10-21 17:21:18 UTC (rev 3630)
@@ -1762,7 +1762,7 @@
def is_empty(self, value):
if isinstance(value, cgi.FieldStorage):
- return bool(getattr(value, 'filename', None))
+ return not bool(getattr(value, 'filename', None))
return FancyValidator.is_empty(self, value)
class FileUploadKeeper(FancyValidator):
|
|
From: <sub...@co...> - 2008-10-19 00:40:39
|
Author: jab
Date: 2008-10-18 18:40:31 -0600 (Sat, 18 Oct 2008)
New Revision: 3629
Modified:
FormEncode/trunk/formencode/validators.py
Log:
allow % in urls
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-10-17 22:22:44 UTC (rev 3628)
+++ FormEncode/trunk/formencode/validators.py 2008-10-19 00:40:31 UTC (rev 3629)
@@ -1384,6 +1384,10 @@
'http://hahaha.ha/bar.html'
>>> u.to_python('http://xn--m7r7ml7t24h.com')
'http://xn--m7r7ml7t24h.com'
+ >>> u.to_python('http://foo.com/test?bar=baz&fleem=morx')
+ 'http://foo.com/test?bar=baz&fleem=morx'
+ >>> u.to_python('http://foo.com/login?came_from=http%3A%2F%2Ffoo.com%2Ftest')
+ 'http://foo.com/login?came_from=http%3A%2F%2Ffoo.com%2Ftest'
>>> u.to_python('http://foo.com:8000/test.html')
'http://foo.com:8000/test.html'
>>> u.to_python('http://foo.com/something\\nelse')
@@ -1432,10 +1436,10 @@
(?:[%:\w]*@)? # authenticator
(?P<domain>[a-z0-9][a-z0-9\-]{1,62}\.)* # (sub)domain - alpha followed by 62max chars (63 total)
(?P<tld>[a-z]{2,}) # TLD
- (?::[0-9]+)? # port
+ (?::[0-9]+)? # port
# files/delims/etc
- (?P<path>/[a-z0-9\-\._~:/\?#\[\]@!\$&\'\(\)\*\+,;=]*)?
+ (?P<path>/[a-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]*)?
$
''', re.I | re.VERBOSE)
|
|
From: <sub...@co...> - 2008-10-17 22:22:50
|
Author: jab
Date: 2008-10-17 16:22:44 -0600 (Fri, 17 Oct 2008)
New Revision: 3628
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/validators.py
Log:
Fix :PORT in validators.URL, and remove the newlines in the path matcher for URL, as you can't actually use verbose comments and newlines in a character group
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-10-17 20:06:22 UTC (rev 3627)
+++ FormEncode/trunk/docs/news.txt 2008-10-17 22:22:44 UTC (rev 3628)
@@ -46,6 +46,9 @@
* Quiet Python 2.6 deprecation warnings.
+* Fix :class:`formencode.validators.URL`, which was accepting illegal
+ characters (like newlines) and did not accept http://domain:PORT/
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-10-17 20:06:22 UTC (rev 3627)
+++ FormEncode/trunk/formencode/validators.py 2008-10-17 22:22:44 UTC (rev 3628)
@@ -1384,6 +1384,12 @@
'http://hahaha.ha/bar.html'
>>> u.to_python('http://xn--m7r7ml7t24h.com')
'http://xn--m7r7ml7t24h.com'
+ >>> u.to_python('http://foo.com:8000/test.html')
+ 'http://foo.com:8000/test.html'
+ >>> u.to_python('http://foo.com/something\\nelse')
+ Traceback (most recent call last):
+ ...
+ Invalid: That is not a valid URL
>>> u.to_python('https://test.com')
'https://test.com'
>>> u.to_python('http://test')
@@ -1426,18 +1432,10 @@
(?:[%:\w]*@)? # authenticator
(?P<domain>[a-z0-9][a-z0-9\-]{1,62}\.)* # (sub)domain - alpha followed by 62max chars (63 total)
(?P<tld>[a-z]{2,}) # TLD
- (?:[0-9]+)? # port
+ (?::[0-9]+)? # port
# files/delims/etc
- (?:/[
- # rfc3986 valid chars
- # unreserved
- a-z0-9\-\._~
- # delims - general
- :/\?#\[\]@
- # delims - sub
- !\$&\'\(\)\*\+,;=
- ]*)?
+ (?P<path>/[a-z0-9\-\._~:/\?#\[\]@!\$&\'\(\)\*\+,;=]*)?
$
''', re.I | re.VERBOSE)
|
|
From: <sub...@co...> - 2008-10-09 05:50:05
|
Author: pjenvey
Date: 2008-10-08 23:49:53 -0600 (Wed, 08 Oct 2008)
New Revision: 3620
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/validators.py
Log:
more set vs sets to quiet 2.6 deprecation warnings
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-10-07 16:48:37 UTC (rev 3619)
+++ FormEncode/trunk/docs/news.txt 2008-10-09 05:49:53 UTC (rev 3620)
@@ -44,6 +44,8 @@
* Look in ``/usr/share/locale`` for locale files, in addition to the
normal locations.
+* Quiet Python 2.6 deprecation warnings.
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-10-07 16:48:37 UTC (rev 3619)
+++ FormEncode/trunk/formencode/validators.py 2008-10-09 05:49:53 UTC (rev 3620)
@@ -32,10 +32,14 @@
from interfaces import *
from api import *
sha1 = random = None
+
+warnings.simplefilter('ignore', DeprecationWarning)
+import sets
+warnings.resetwarnings()
try:
- import sets
-except ImportError:
- sets = None
+ set
+except NameError:
+ set = sets.Set
import cgi
@@ -1185,7 +1189,7 @@
one result. It's equivalent to ForEach(convertToList=True).
If you give ``use_set=True``, then it will return an actual
- ``sets.Set`` object.
+ ``set`` object.
::
@@ -1197,11 +1201,11 @@
['this', 'that']
>>> s = Set(use_set=True)
>>> s.to_python(None)
- Set([])
+ set([])
>>> s.to_python('this')
- Set(['this'])
+ set(['this'])
>>> s.to_python(('this',))
- Set(['this'])
+ set(['this'])
"""
use_set = False
@@ -1210,18 +1214,18 @@
def _to_python(self, value, state):
if self.use_set:
- if isinstance(value, sets.Set):
+ if isinstance(value, (set, sets.Set)):
return value
elif isinstance(value, (list, tuple)):
- return sets.Set(value)
+ return set(value)
elif value is None:
- return sets.Set()
+ return set()
else:
- return sets.Set([value])
+ return set([value])
else:
if isinstance(value, list):
return value
- elif sets and isinstance(value, sets.Set):
+ elif sets and isinstance(value, (set, sets.Set)):
return list(value)
elif isinstance(value, tuple):
return list(value)
@@ -1232,7 +1236,7 @@
def empty_value(self, value):
if self.use_set:
- return sets.Set([])
+ return set()
else:
return []
|
|
From: <sub...@co...> - 2008-10-05 22:28:11
|
Author: pjenvey
Date: 2008-10-05 16:28:04 -0600 (Sun, 05 Oct 2008)
New Revision: 3618
Modified:
FormEncode/trunk/formencode/foreach.py
Log:
fix Python < 2.4
Modified: FormEncode/trunk/formencode/foreach.py
===================================================================
--- FormEncode/trunk/formencode/foreach.py 2008-10-03 22:55:20 UTC (rev 3617)
+++ FormEncode/trunk/formencode/foreach.py 2008-10-05 22:28:04 UTC (rev 3618)
@@ -5,6 +5,10 @@
warnings.simplefilter('ignore', DeprecationWarning)
from sets import Set
warnings.resetwarnings()
+try:
+ set
+except NameError:
+ set = Set
from api import NoDefault, Invalid
from compound import CompoundValidator, to_python, from_python
|
|
From: <sub...@co...> - 2008-10-03 22:55:30
|
Author: pjenvey
Date: 2008-10-03 16:55:20 -0600 (Fri, 03 Oct 2008)
New Revision: 3617
Modified:
FormEncode/trunk/formencode/foreach.py
FormEncode/trunk/formencode/validators.py
Log:
python 2.6 deprecations:
prefer hashlib over the sha module, special case sets
Modified: FormEncode/trunk/formencode/foreach.py
===================================================================
--- FormEncode/trunk/formencode/foreach.py 2008-10-03 18:54:23 UTC (rev 3616)
+++ FormEncode/trunk/formencode/foreach.py 2008-10-03 22:55:20 UTC (rev 3617)
@@ -1,14 +1,13 @@
"""
Validator for repeating items.
"""
+import warnings
+warnings.simplefilter('ignore', DeprecationWarning)
+from sets import Set
+warnings.resetwarnings()
from api import NoDefault, Invalid
from compound import CompoundValidator, to_python, from_python
-try:
- from sets import Set
-except ImportError:
- # We only use it for type information now:
- Set = None
__all__ = ['ForEach']
@@ -37,7 +36,7 @@
and a single Invalid exception will be raised at the end (with
error_list set).
- If the incoming value is a Set, then we return a Set.
+ If the incoming value is a set, then we return a set.
"""
convert_to_list = True
@@ -59,7 +58,7 @@
new_list = []
errors = []
all_good = True
- is_set = isinstance(value, Set)
+ is_set = isinstance(value, (set, Set))
if state is not None:
previous_index = getattr(state, 'index', NoDefault)
previous_full_list = getattr(state, 'full_list', NoDefault)
@@ -84,7 +83,7 @@
new_list.append(sub_value)
if all_good:
if is_set:
- new_list = Set(new_list)
+ new_list = set(new_list)
return new_list
else:
raise Invalid(
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-10-03 18:54:23 UTC (rev 3616)
+++ FormEncode/trunk/formencode/validators.py 2008-10-03 22:55:20 UTC (rev 3617)
@@ -31,7 +31,7 @@
import socket
from interfaces import *
from api import *
-sha = random = None
+sha1 = random = None
try:
import sets
except ImportError:
@@ -2358,9 +2358,12 @@
nonce_length = 4
def _to_python(self, value, state):
- global sha
- if not sha:
- import sha
+ global sha1
+ if not sha1:
+ try:
+ from hashlib import sha1
+ except ImportError:
+ from sha import sha as sha1
assert self.secret is not None, (
"You must give a secret")
parts = value.split(None, 1)
@@ -2372,19 +2375,22 @@
rest = rest.decode('base64')
nonce = rest[:self.nonce_length]
rest = rest[self.nonce_length:]
- expected = sha.new(str(self.secret)+nonce+rest).digest()
+ expected = sha1(str(self.secret)+nonce+rest).digest()
if expected != sig:
raise Invalid(self.message('badsig', state),
value, state)
return rest
def _from_python(self, value, state):
- global sha
- if not sha:
- import sha
+ global sha1
+ if not sha1:
+ try:
+ from hashlib import sha1
+ except ImportError:
+ from sha import sha as sha1
nonce = self.make_nonce()
value = str(value)
- digest = sha.new(self.secret+nonce+value).digest()
+ digest = sha1(self.secret+nonce+value).digest()
return self.encode(digest)+' '+self.encode(nonce+value)
def encode(self, value):
|
|
From: <sub...@co...> - 2008-10-03 18:54:33
|
Author: gh
Date: 2008-10-03 12:54:23 -0600 (Fri, 03 Oct 2008)
New Revision: 3616
Added:
FormEncode/trunk/formencode/i18n/tw/
Removed:
FormEncode/trunk/formencode/i18n/big5/
Modified:
FormEncode/trunk/tests/test_i18n.py
Log:
renamed big5 to tw (Chinese traditional)
Copied: FormEncode/trunk/formencode/i18n/tw (from rev 3615, FormEncode/trunk/formencode/i18n/big5)
Modified: FormEncode/trunk/tests/test_i18n.py
===================================================================
--- FormEncode/trunk/tests/test_i18n.py 2008-10-02 21:04:20 UTC (rev 3615)
+++ FormEncode/trunk/tests/test_i18n.py 2008-10-03 18:54:23 UTC (rev 3616)
@@ -66,8 +66,8 @@
def test_pt_BR():
_test_lang("pt_BR", u"Por favor digite um valor")
-def test_big5():
- _test_lang("big5", u"請輸入一個值")
+def test_tw():
+ _test_lang("tw", u"請輸入一個值")
def test_sk():
_test_lang("sk",u"Zadajte hodnotu, prosím")
|
|
From: <sub...@co...> - 2008-09-30 17:35:31
|
Author: ianb Date: 2008-09-30 11:35:26 -0600 (Tue, 30 Sep 2008) New Revision: 3609 Modified: FormEncode/trunk/ FormEncode/trunk/setup.py Log: Remove ez_setup Property changes on: FormEncode/trunk ___________________________________________________________________ Name: svn:externals - ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup Modified: FormEncode/trunk/setup.py =================================================================== --- FormEncode/trunk/setup.py 2008-09-30 17:34:29 UTC (rev 3608) +++ FormEncode/trunk/setup.py 2008-09-30 17:35:26 UTC (rev 3609) @@ -1,10 +1,5 @@ import sys -try: - from setuptools import setup -except ImportError: - from ez_setup import use_setuptools - use_setuptools() - from setuptools import setup +from setuptools import setup version = '1.0.2' |
|
From: <sub...@co...> - 2008-09-30 17:34:41
|
Author: ianb
Date: 2008-09-30 11:34:29 -0600 (Tue, 30 Sep 2008)
New Revision: 3608
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/api.py
Log:
Look in /usr/share/locale for locale files, in addition to the normal locations. From Toshio Kuratomi
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-09-29 21:01:24 UTC (rev 3607)
+++ FormEncode/trunk/docs/news.txt 2008-09-30 17:34:29 UTC (rev 3608)
@@ -41,6 +41,9 @@
* Added :class:`formencode.validators.XRI` for validation i-names,
i-numbers, URLs, etc (as used in OpenID).
+* Look in ``/usr/share/locale`` for locale files, in addition to the
+ normal locations.
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/api.py
===================================================================
--- FormEncode/trunk/formencode/api.py 2008-09-29 21:01:24 UTC (rev 3607)
+++ FormEncode/trunk/formencode/api.py 2008-09-30 17:34:29 UTC (rev 3608)
@@ -17,17 +17,36 @@
import gettext
def get_localedir():
+ """
+ Retrieve the location of locales.
+
+ If we're built as an egg, we need to find the resource within the egg.
+ Otherwise, we need to look for the locales on the filesystem or in the
+ system message catalog.
+ """
+ locale_dir = ''
+ # Check the egg first
if resource_filename is not None:
try:
- return resource_filename(__name__, "/i18n")
+ locale_dir = resource_filename(__name__, "/i18n")
except NotImplementedError:
# resource_filename doesn't work with non-egg zip files
pass
- return os.path.join(os.path.dirname(__file__), 'i18n')
+ if os.access(locale_dir, os.R_OK | os.X_OK):
+ # If the resource is present in the egg, use it
+ return locale_dir
+ # Otherwise, search the filesystem
+ locale_dir = os.path.join(os.path.dirname(__file__), 'i18n')
+ if not os.access(locale_dir, os.R_OK | os.X_OK):
+ # Fallback on the system catalog
+ locale_dir = os.path.normpath('/usr/share/locale')
+
+ return locale_dir
+
def set_stdtranslation(domain="FormEncode", languages=None, \
localedir = get_localedir()):
-
+
t = gettext.translation(domain=domain, \
languages=languages, \
localedir=localedir, fallback=True)
|
|
From: <sub...@co...> - 2008-09-18 17:01:52
|
Author: ianb
Date: 2008-09-18 18:02:05 -0600 (Thu, 18 Sep 2008)
New Revision: 3594
Modified:
FormEncode/trunk/formencode/foreach.py
Log:
Make ForEach.if_missing act even better and more conformant (handle ForEach(if_missing=NoDefault), and ForEach.if_missing)
Modified: FormEncode/trunk/formencode/foreach.py
===================================================================
--- FormEncode/trunk/formencode/foreach.py 2008-09-18 23:58:45 UTC (rev 3593)
+++ FormEncode/trunk/formencode/foreach.py 2008-09-19 00:02:05 UTC (rev 3594)
@@ -43,7 +43,7 @@
convert_to_list = True
if_empty = NoDefault
repeating = True
- _if_missing = NoDefault
+ _if_missing = ()
def attempt_convert(self, value, state, validate):
if self.convert_to_list:
@@ -112,19 +112,22 @@
def empty_value(self, value):
return []
- def _if_missing__get(self):
- if self._if_missing is NoDefault:
- return []
- return self._if_missing
+ class _IfMissing(object):
+ def __get__(self, obj, type=None):
+ if obj is None:
+ return []
+ elif obj._if_missing is ForEach._if_missing:
+ return []
+ else:
+ return obj._if_missing
+ def __set__(self, obj, value):
+ obj._if_missing = value
+ def __delete__(self, obj):
+ obj._if_missing = NoDefault
- def _if_missing__set(self, value):
- self._if_missing = value
+ if_missing = _IfMissing()
+ del _IfMissing
- def _if_missing__del(self):
- self._if_missing = NoDefault
-
- if_missing = property(_if_missing__get, _if_missing__set, _if_missing__del)
-
def _convert_to_list(self, value):
if isinstance(value, (str, unicode)):
return [value]
|
|
From: <sub...@co...> - 2008-09-18 16:58:35
|
Author: ianb
Date: 2008-09-18 17:58:45 -0600 (Thu, 18 Sep 2008)
New Revision: 3593
Modified:
FormEncode/trunk/formencode/foreach.py
Log:
Make ForEach(if_missing=None) work (previous commit had made it unsettable)
Modified: FormEncode/trunk/formencode/foreach.py
===================================================================
--- FormEncode/trunk/formencode/foreach.py 2008-09-18 18:16:52 UTC (rev 3592)
+++ FormEncode/trunk/formencode/foreach.py 2008-09-18 23:58:45 UTC (rev 3593)
@@ -43,6 +43,7 @@
convert_to_list = True
if_empty = NoDefault
repeating = True
+ _if_missing = NoDefault
def attempt_convert(self, value, state, validate):
if self.convert_to_list:
@@ -111,10 +112,19 @@
def empty_value(self, value):
return []
- @property
- def if_missing(self):
- return []
+ def _if_missing__get(self):
+ if self._if_missing is NoDefault:
+ return []
+ return self._if_missing
+ def _if_missing__set(self, value):
+ self._if_missing = value
+
+ def _if_missing__del(self):
+ self._if_missing = NoDefault
+
+ if_missing = property(_if_missing__get, _if_missing__set, _if_missing__del)
+
def _convert_to_list(self, value):
if isinstance(value, (str, unicode)):
return [value]
|
|
From: <sub...@co...> - 2008-09-16 19:48:49
|
Author: ianb Date: 2008-09-16 13:49:00 -0600 (Tue, 16 Sep 2008) New Revision: 3591 Modified: FormEncode/trunk/docs/news.txt Log: news for last commit Modified: FormEncode/trunk/docs/news.txt =================================================================== --- FormEncode/trunk/docs/news.txt 2008-09-16 19:47:05 UTC (rev 3590) +++ FormEncode/trunk/docs/news.txt 2008-09-16 19:49:00 UTC (rev 3591) @@ -38,6 +38,9 @@ ``<form:error name="field_name" formatter="ignore" />`` -- this will cause the error to be swallowed, not shown to the user. +* Added :class:`formencode.validators.XRI` for validation i-names, + i-numbers, URLs, etc (as used in OpenID). + 1.0.1 ----- |
|
From: <sub...@co...> - 2008-09-16 19:46:56
|
Author: ianb
Date: 2008-09-16 13:47:05 -0600 (Tue, 16 Sep 2008)
New Revision: 3590
Modified:
FormEncode/trunk/formencode/htmlfill.py
FormEncode/trunk/formencode/validators.py
FormEncode/trunk/tests/test_validators.py
Log:
typo in 'ignore'
Modified: FormEncode/trunk/formencode/htmlfill.py
===================================================================
--- FormEncode/trunk/formencode/htmlfill.py 2008-09-16 18:53:55 UTC (rev 3589)
+++ FormEncode/trunk/formencode/htmlfill.py 2008-09-16 19:47:05 UTC (rev 3590)
@@ -502,5 +502,5 @@
'none': none_formatter,
'escape': escape_formatter,
'escapenl': escapenl_formatter,
- 'ingore': ignore_formatter,
+ 'ignore': ignore_formatter,
}
Modified: FormEncode/trunk/formencode/validators.py
===================================================================
--- FormEncode/trunk/formencode/validators.py 2008-09-16 18:53:55 UTC (rev 3589)
+++ FormEncode/trunk/formencode/validators.py 2008-09-16 19:47:05 UTC (rev 3590)
@@ -1515,6 +1515,214 @@
self.message('status', state, status=res.status),
state, url)
+
+class XRI(FancyValidator):
+ r"""
+ Validator for XRIs.
+
+ It supports both i-names and i-numbers, of the first version of the XRI
+ standard.
+
+ ::
+
+ >>> inames = XRI(xri_type="i-name")
+ >>> inames.to_python(" =John.Smith ")
+ '=John.Smith'
+ >>> inames.to_python("@Free.Software.Foundation")
+ '@Free.Software.Foundation'
+ >>> inames.to_python("Python.Software.Foundation")
+ Traceback (most recent call last):
+ ...
+ Invalid: The type of i-name is not defined; it may be either individual or organizational
+ >>> inames.to_python("http://example.org")
+ Traceback (most recent call last):
+ ...
+ Invalid: The type of i-name is not defined; it may be either individual or organizational
+ >>> inames.to_python("=!2C43.1A9F.B6F6.E8E6")
+ Traceback (most recent call last):
+ ...
+ Invalid: "!2C43.1A9F.B6F6.E8E6" is an invalid i-name
+ >>> iname_with_schema = XRI(True, xri_type="i-name")
+ >>> iname_with_schema.to_python("=Richard.Stallman")
+ 'xri://=Richard.Stallman'
+ >>> inames.to_python("=John Smith")
+ Traceback (most recent call last):
+ ...
+ formencode.api.Invalid: "John Smith" is an invalid i-name
+ >>> inumbers = XRI(xri_type="i-number")
+ >>> inumbers.to_python("!!1000!de21.4536.2cb2.8074")
+ '!!1000!de21.4536.2cb2.8074'
+ >>> inumbers.to_python("@!1000.9554.fabd.129c!2847.df3c")
+ '@!1000.9554.fabd.129c!2847.df3c'
+
+ """
+
+ iname_valid_pattern = re.compile(r"""
+ ^
+ [\w]+ # A global alphanumeric i-name
+ (\.[\w]+)* # An i-name with dots
+ (\*[\w]+(\.[\w]+)*)* # A community i-name
+ $
+ """, re.VERBOSE|re.UNICODE)
+
+
+ iname_invalid_start = re.compile(r"^[\d\.-]", re.UNICODE)
+ """@cvar: These characters must not be at the beggining of the i-name"""
+
+ inumber_pattern = re.compile(r"""
+ ^
+ (
+ [=@]! # It's a personal or organization i-number
+ |
+ !! # It's a network i-number
+ )
+ [\dA-F]{1,4}(\.[\dA-F]{1,4}){0,3} # A global i-number
+ (![\dA-F]{1,4}(\.[\dA-F]{1,4}){0,3})* # Zero or more sub i-numbers
+ $
+ """, re.VERBOSE|re.IGNORECASE)
+
+ messages = {
+ 'noType': _("The type of i-name is not defined; it may be either individual or organizational"),
+ 'repeatedChar': _("Dots and dashes may not be repeated consecutively"),
+ 'badIname': _('"%(iname)s" is an invalid i-name'),
+ 'badInameStart': _("i-names may not start with numbers nor punctuation "
+ "marks"),
+ 'badInumber': _('"%(inumber)s" is an invalid i-number'),
+ 'badType': _("The XRI must be a string (not a %(type)s: %(value)r)"),
+ 'badXri': _('"%(xri_type)s" is not a valid type of XRI')
+ }
+
+ def __init__(self, add_xri=False, xri_type="i-name", **kwargs):
+ """Create an XRI validator.
+
+ @param add_xri: Should the schema be added if not present? Officially
+ it's optional.
+ @type add_xri: C{bool}
+ @param xri_type: What type of XRI should be validated? Possible values:
+ C{i-name} or C{i-number}.
+ @type xri_type: C{str}
+
+ """
+ self.add_xri = add_xri
+ assert xri_type in ('i-name', 'i-number'), \
+ ('xri_type must be "i-name" or "i-number"')
+ self.xri_type = xri_type
+ super(XRI, self).__init__(**kwargs)
+
+ def _to_python(self, value, state):
+ """Prepend the 'xri://' schema if necessary and then remove trailing
+ spaces"""
+ value = value.strip()
+ if self.add_xri and not value.startswith("xri://"):
+ value = "xri://" + value
+ return value
+
+ def validate_python(self, value, state=None):
+ """Validate an XRI
+
+ @raise Invalid: If at least one of the following conditions in met:
+ - C{value} is not a string.
+ - The XRI is not a personal, organizational or network one.
+ - The relevant validator (i-name or i-number) considers the XRI
+ is not valid.
+
+ """
+ if not (isinstance(value, str) or isinstance(value, unicode)):
+ raise Invalid(self.message("badType", state, type=str(type(value)),
+ value=value),
+ value, state)
+
+ # Let's remove the schema, if any
+ if value.startswith("xri://"):
+ value = value[6:]
+
+ if not value[0] in ('@', '=') and not (self.xri_type == "i-number" \
+ and value[0] == '!'):
+ raise Invalid(self.message("noType", state), value, state)
+
+ if self.xri_type == "i-name":
+ self._validate_iname(value, state)
+ else:
+ self._validate_inumber(value, state)
+
+ def _validate_iname(self, iname, state):
+ """Validate an i-name"""
+ # The type is not required here:
+ iname = iname[1:]
+ if ".." in iname or "--" in iname:
+ raise Invalid(self.message("repeatedChar", state), iname, state)
+ if self.iname_invalid_start.match(iname):
+ raise Invalid(self.message("badInameStart", state), iname, state)
+ if not self.iname_valid_pattern.match(iname) or "_" in iname:
+ raise Invalid(self.message("badIname", state, iname=iname), iname,
+ state)
+
+ def _validate_inumber(self, inumber, state):
+ """Validate an i-number"""
+ if not self.__class__.inumber_pattern.match(inumber):
+ raise Invalid(self.message("badInumber", state, inumber=inumber,
+ value=inumber),
+ inumber, state)
+
+
+class OpenId(FancyValidator):
+ r"""
+ OpenId validator.
+
+ ::
+ >>> v = OpenId(add_schema=True)
+ >>> v.to_python(' example.net ')
+ 'http://example.net'
+ >>> v.to_python('@TurboGears')
+ 'xri://@TurboGears'
+ >>> w = OpenId(add_schema=False)
+ >>> w.to_python(' example.net ')
+ Traceback (most recent call last):
+ ...
+ Invalid: "example.net" is not a valid OpenId (it is neither an URL nor an XRI)
+ >>> w.to_python('!!1000')
+ '!!1000'
+ >>> w.to_python('lo...@me...')
+ Traceback (most recent call last):
+ ...
+ Invalid: "lo...@me..." is not a valid OpenId (it is neither an URL nor an XRI)
+
+ """
+
+ messages = {
+ 'badId': _('"%(id)s" is not a valid OpenId (it is neither an URL nor an XRI)')
+ }
+
+ def __init__(self, add_schema=False, **kwargs):
+ """Create an OpenId validator.
+
+ @param add_schema: Should the schema be added if not present?
+ @type add_schema: C{bool}
+
+ """
+ self.url_validator = URL(add_http=add_schema)
+ self.iname_validator = XRI(add_schema, xri_type="i-name")
+ self.inumber_validator = XRI(add_schema, xri_type="i-number")
+
+ def _to_python(self, value, state):
+ value = value.strip()
+ try:
+ return self.url_validator.to_python(value, state)
+ except Invalid:
+ try:
+ return self.iname_validator.to_python(value, state)
+ except Invalid:
+ try:
+ return self.inumber_validator.to_python(value, state)
+ except Invalid:
+ pass
+ # It's not an OpenId!
+ raise Invalid(self.message("badId", state, id=value), value, state)
+
+ def validate_python(self, value, state):
+ self._to_python(value, state)
+
+
def StateProvince(*kw, **kwargs):
warnings.warn("please use formencode.national.USStateProvince", DeprecationWarning, stacklevel=2)
from formencode.national import USStateProvince
Modified: FormEncode/trunk/tests/test_validators.py
===================================================================
--- FormEncode/trunk/tests/test_validators.py 2008-09-16 18:53:55 UTC (rev 3589)
+++ FormEncode/trunk/tests/test_validators.py 2008-09-16 19:47:05 UTC (rev 3590)
@@ -1,4 +1,8 @@
-from formencode.validators import String, UnicodeString, Invalid, Int
+# -*- coding: utf-8 -*-
+import unittest
+
+from formencode.validators import String, UnicodeString, Invalid, Int, XRI, \
+ OpenId
from formencode.validators import DateConverter
from formencode.variabledecode import NestedVariables
from formencode.schema import Schema
@@ -127,3 +131,171 @@
else:
raise Exception("Shouldn't be valid data", values, start_values)
+
+
+
+
+class TestXRIValidator(unittest.TestCase):
+ """Generic tests for the XRI validator"""
+
+ def test_creation_valid_params(self):
+ """The creation of an XRI validator with valid parameters must
+ succeed"""
+ XRI()
+ XRI(True, "i-name")
+ XRI(True, "i-number")
+ XRI(False, "i-name")
+ XRI(False, "i-number")
+
+ def test_creation_invalid_xri(self):
+ """Only "i-name" and "i-number" are valid XRIs"""
+ self.assertRaises(AssertionError, XRI, True, 'i-something')
+
+ def test_valid_simple_individual_iname_without_type(self):
+ """XRIs must start with either an equals sign or an at sign"""
+ validator = XRI(True, "i-name")
+ self.assertRaises(Invalid, validator.validate_python, 'Gustavo')
+
+ def test_valid_iname_with_schema(self):
+ """XRIs may have their schema in the beggining"""
+ validator = XRI()
+ self.assertEqual(validator.to_python('xri://=Gustavo'),
+ 'xri://=Gustavo')
+
+ def test_schema_is_added_if_asked(self):
+ """The schema must be added to an XRI if explicitly asked"""
+ validator = XRI(True)
+ self.assertEqual(validator.to_python('=Gustavo'),
+ 'xri://=Gustavo')
+
+ def test_schema_not_added_if_not_asked(self):
+ """The schema must not be added to an XRI unless explicitly asked"""
+ validator = XRI()
+ self.assertEqual(validator.to_python('=Gustavo'), '=Gustavo')
+
+ def test_spaces_are_trimmed(self):
+ """Spaces at the beggining or end of the XRI are removed"""
+ validator = XRI()
+ self.assertEqual(validator.to_python(' =Gustavo '), '=Gustavo')
+
+
+class TestINameValidator(unittest.TestCase):
+ """Tests for the XRI i-names validator"""
+
+ def setUp(self):
+ self.validator = XRI(xri_type="i-name")
+
+ def test_valid_global_individual_iname(self):
+ """Global & valid individual i-names must pass validation"""
+ self.validator.validate_python('=Gustavo')
+
+ def test_valid_global_organizational_iname(self):
+ """Global & valid organizational i-names must pass validation"""
+ self.validator.validate_python('@Canonical')
+
+ def test_invalid_iname(self):
+ """Non-string i-names are rejected"""
+ self.assertRaises(Invalid, self.validator.validate_python, None)
+
+ def test_exclamation_in_inames(self):
+ """Exclamation marks at the beggining of XRIs is something specific
+ to i-numbers and must be rejected in i-names"""
+ self.assertRaises(Invalid, self.validator.validate_python,
+ "!!1000!de21.4536.2cb2.8074")
+
+ def test_repeated_characters(self):
+ """Dots and dashes must not be consecutively repeated in i-names"""
+ self.assertRaises(Invalid, self.validator.validate_python,
+ "=Gustavo--Narea")
+ self.assertRaises(Invalid, self.validator.validate_python,
+ "=Gustavo..Narea")
+
+ def test_punctuation_marks_at_beggining(self):
+ """Punctuation marks at the beggining of i-names are forbidden"""
+ self.assertRaises(Invalid, self.validator.validate_python,
+ "=.Gustavo")
+ self.assertRaises(Invalid, self.validator.validate_python,
+ "=-Gustavo.Narea")
+
+ def test_numerals_at_beggining(self):
+ """Numerals at the beggining of i-names are forbidden"""
+ self.assertRaises(Invalid, self.validator.validate_python,
+ "=1Gustavo")
+
+ def test_non_english_inames(self):
+ """i-names with non-English characters are valid"""
+ self.validator.validate_python(u'=Gustavo.Narea.García')
+ self.validator.validate_python(u'@名前.例')
+
+ def test_inames_plus_paths(self):
+ """i-names with paths are valid but not supported"""
+ self.assertRaises(Invalid, self.validator.validate_python,
+ "=Gustavo/(+email)")
+
+ def test_communities(self):
+ """i-names may have so-called 'communities'"""
+ self.validator.validate_python(u'=María*Yolanda*Liliana*Gustavo')
+ self.validator.validate_python(u'=Gustavo*Andreina')
+ self.validator.validate_python(u'@IBM*Lenovo')
+
+
+class TestINumberValidator(unittest.TestCase):
+ """Tests for the XRI i-number validator"""
+
+ def setUp(self):
+ self.validator = XRI(xri_type="i-number")
+
+ def test_valid_global_personal_inumber(self):
+ """Global & valid personal i-numbers must pass validation"""
+ self.validator.validate_python('=!1000.a1b2.93d2.8c73')
+
+ def test_valid_global_organizational_inumber(self):
+ """Global & valid organizational i-numbers must pass validation"""
+ self.validator.validate_python('@!1000.a1b2.93d2.8c73')
+
+ def test_valid_global_network_inumber(self):
+ """Global & valid network i-numbers must pass validation"""
+ self.validator.validate_python('!!1000')
+
+ def test_valid_community_personal_inumbers(self):
+ """Community & valid personal i-numbers must pass validation"""
+ self.validator.validate_python('=!1000.a1b2.93d2.8c73!3ae2!1490')
+
+ def test_valid_community_organizational_inumber(self):
+ """Community & valid organizational i-numbers must pass validation"""
+ self.validator.validate_python('@!1000.9554.fabd.129c!2847.df3c')
+
+ def test_valid_community_network_inumber(self):
+ """Community & valid network i-numbers must pass validation"""
+ self.validator.validate_python('!!1000!de21.4536.2cb2.8074')
+
+
+class TestOpenIdValidator(unittest.TestCase):
+ """Tests for the OpenId validator"""
+
+ def setUp(self):
+ self.validator = OpenId(add_schema=False)
+
+ def test_url(self):
+ self.assertEqual(self.validator.to_python('http://example.org'),
+ 'http://example.org')
+
+ def test_iname(self):
+ self.assertEqual(self.validator.to_python('=Gustavo'), '=Gustavo')
+
+ def test_inumber(self):
+ self.assertEqual(self.validator.to_python('!!1000'), '!!1000')
+
+ def test_email(self):
+ """Email addresses are not valid OpenIds!"""
+ self.assertRaises(Invalid, self.validator.to_python,
+ "wa...@bu...")
+
+ def test_prepending_schema(self):
+ validator = OpenId(add_schema=True)
+ self.assertEqual(validator.to_python("example.org"),
+ "http://example.org")
+ self.assertEqual(validator.to_python("=Gustavo"),
+ "xri://=Gustavo")
+ self.assertEqual(validator.to_python("!!1000"),
+ "xri://!!1000")
|
|
From: <sub...@co...> - 2008-09-16 18:53:47
|
Author: ianb
Date: 2008-09-16 12:53:55 -0600 (Tue, 16 Sep 2008)
New Revision: 3589
Modified:
FormEncode/trunk/docs/htmlfill.txt
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/htmlfill.py
Log:
Add a new format=ignore for htmlfill error formatting
Modified: FormEncode/trunk/docs/htmlfill.txt
===================================================================
--- FormEncode/trunk/docs/htmlfill.txt 2008-09-16 15:49:05 UTC (rev 3588)
+++ FormEncode/trunk/docs/htmlfill.txt 2008-09-16 18:53:55 UTC (rev 3589)
@@ -66,6 +66,26 @@
In addition to explicit error tags, any leftover errors will be placed
immediately above the associated input field.
+The default formatters available to you:
+
+``default``:
+ HTML-quotes the error and wraps it in ``<span class="error-message">``
+
+``none``:
+ Puts the error message in with no quoting of any kind. This
+ allows you to put HTML in the error message, but might also expose
+ you to cross-site scripting vulnerabilities.
+
+``escape``:
+ HTML-quotes the error, but doesn't wrap it in anything.
+
+``escapenl``:
+ HTML-quotes the error, and translates newlines to ``<br>``
+
+``ignore``:
+ Swallows the error, emitting nothing. You can use this when you
+ never want an error for a field to display.
+
Valid form templates
--------------------
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-09-16 15:49:05 UTC (rev 3588)
+++ FormEncode/trunk/docs/news.txt 2008-09-16 18:53:55 UTC (rev 3589)
@@ -34,6 +34,10 @@
list instance, so if you modified it then it would effect future
``if_missing`` values (reported by Felix Schwarz).
+* Added formatter to :mod:`formencode.htmlfill`, so you can use
+ ``<form:error name="field_name" formatter="ignore" />`` -- this will
+ cause the error to be swallowed, not shown to the user.
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/htmlfill.py
===================================================================
--- FormEncode/trunk/formencode/htmlfill.py 2008-09-16 15:49:05 UTC (rev 3588)
+++ FormEncode/trunk/formencode/htmlfill.py 2008-09-16 18:53:55 UTC (rev 3589)
@@ -128,6 +128,12 @@
error = error.replace('\n', '<br>\n')
return error
+def ignore_formatter(error):
+ """
+ Formatter that emits nothing, regardless of the error.
+ """
+ return ''
+
class FillingParser(RewritingParser):
r"""
Fills HTML with default values, as in a form.
@@ -495,4 +501,6 @@
default_formatter_dict = {'default': default_formatter,
'none': none_formatter,
'escape': escape_formatter,
- 'escapenl': escapenl_formatter}
+ 'escapenl': escapenl_formatter,
+ 'ingore': ignore_formatter,
+ }
|
|
From: <sub...@co...> - 2008-09-10 16:13:40
|
Author: ianb
Date: 2008-09-10 10:13:50 -0600 (Wed, 10 Sep 2008)
New Revision: 3576
Modified:
FormEncode/trunk/docs/news.txt
FormEncode/trunk/formencode/foreach.py
Log:
fix ForEach.if_missing to make it an empty-list factory
Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt 2008-09-10 11:47:48 UTC (rev 3575)
+++ FormEncode/trunk/docs/news.txt 2008-09-10 16:13:50 UTC (rev 3576)
@@ -29,6 +29,11 @@
* :class:`formencode.compound.All` does not handle empty values,
instead relying on sub-validators to check for emptiness.
+* Fixed the ``if_missing`` attribute in
+ :class:`formencode.foreach.ForEach`; previously it would be the same
+ list instance, so if you modified it then it would effect future
+ ``if_missing`` values (reported by Felix Schwarz).
+
1.0.1
-----
Modified: FormEncode/trunk/formencode/foreach.py
===================================================================
--- FormEncode/trunk/formencode/foreach.py 2008-09-10 11:47:48 UTC (rev 3575)
+++ FormEncode/trunk/formencode/foreach.py 2008-09-10 16:13:50 UTC (rev 3576)
@@ -42,7 +42,6 @@
convert_to_list = True
if_empty = NoDefault
- if_missing = []
repeating = True
def attempt_convert(self, value, state, validate):
@@ -112,6 +111,10 @@
def empty_value(self, value):
return []
+ @property
+ def if_missing(self):
+ return []
+
def _convert_to_list(self, value):
if isinstance(value, (str, unicode)):
return [value]
|
|
From: <sub...@co...> - 2008-08-14 14:31:03
|
Author: mark
Date: 2008-08-14 08:31:11 -0600 (Thu, 14 Aug 2008)
New Revision: 3559
Modified:
FormEncode/trunk/formencode/national.py
Log:
tests for PostalCodeInCountryFormat and proper citation of ISO codes
Modified: FormEncode/trunk/formencode/national.py
===================================================================
--- FormEncode/trunk/formencode/national.py 2008-08-13 15:17:18 UTC (rev 3558)
+++ FormEncode/trunk/formencode/national.py 2008-08-14 14:31:11 UTC (rev 3559)
@@ -314,7 +314,7 @@
>>> CountryValidator.to_python('Krakovia')
Traceback (most recent call last):
...
- Invalid: That country is not listed in ISO-3166
+ Invalid: That country is not listed in ISO 3166
>>> CountryValidator.from_python('DE')
'Germany'
>>> CountryValidator.from_python('FI')
@@ -324,7 +324,7 @@
key_ok = True
messages = {
- 'valueNotFound': _("That country is not listed in ISO-3166"),
+ 'valueNotFound': _("That country is not listed in ISO 3166"),
}
def _to_python(self, value, state):
@@ -348,9 +348,29 @@
class PostalCodeInCountryFormat(FancyValidator):
"""
- Makes sure the postal code is in the country's format.
+ Makes sure the postal code is in the country's format by chosing postal
+ code validator by provided country code. Does convert it into the preferred
+ format, too.
+
+ ::
+
+ >>> fs = PostalCodeInCountryFormat('country', 'zip')
+ >>> fs.to_python({'country': 'DE', 'zip': '30167'})
+ {'country': 'DE', 'zip': '30167'}
+ >>> fs.to_python({'country': 'DE', 'zip': '3008'})
+ Traceback (most recent call last):
+ ...
+ Invalid: Given postal code does not match the country's format.
+ >>> fs.to_python({'country': 'PL', 'zip': '34343'})
+ {'country': 'PL', 'zip': '34-343'}
+ >>> fs = PostalCodeInCountryFormat('staat', 'plz')
+ >>> fs.to_python({'staat': 'GB', 'plz': 'l1a 3gr'})
+ {'staat': 'GB', 'plz': 'L1A 3GR'}
"""
+ country_field = 'country'
+ zip_field = 'zip'
+ __unpackargs__ = ('country_field', 'zip_field')
messages = {
'badFormat': _("Given postal code does not match the country's format."),
}
@@ -395,15 +415,15 @@
}
def validate_python(self, fields_dict, state):
- if fields_dict['country'] in self._vd:
+ if fields_dict[self.country_field] in self._vd:
try:
- zip_validator = self._vd[fields_dict['country']]()
- fields_dict['zip'] = zip_validator.to_python(fields_dict['zip'])
+ zip_validator = self._vd[fields_dict[self.country_field]]()
+ fields_dict[self.zip_field] = zip_validator.to_python(fields_dict[self.zip_field])
except Invalid, e:
message = self.message('badFormat', state)
raise Invalid(message, fields_dict, state,
- error_dict = {'zip' : e.message,
- 'country': message})
+ error_dict = {self.zip_field: e.message,
+ self.country_field: message})
class USStateProvince(FancyValidator):
@@ -673,7 +693,7 @@
>>> l.to_python('Klingonian')
Traceback (most recent call last):
...
- Invalid: That language is not listed in ISO-639-2
+ Invalid: That language is not listed in ISO 639
>>> l.from_python('de')
'German'
>>> l.from_python('zh')
@@ -683,7 +703,7 @@
key_ok = True
messages = {
- 'valueNotFound': _("That language is not listed in ISO-639-2"),
+ 'valueNotFound': _("That language is not listed in ISO 639"),
}
def _to_python(self, value, state):
|
|
From: <sub...@co...> - 2008-08-13 15:17:11
|
Author: mark
Date: 2008-08-13 09:17:18 -0600 (Wed, 13 Aug 2008)
New Revision: 3558
Modified:
FormEncode/trunk/formencode/national.py
Log:
validator for languages
Modified: FormEncode/trunk/formencode/national.py
===================================================================
--- FormEncode/trunk/formencode/national.py 2008-08-13 14:28:10 UTC (rev 3557)
+++ FormEncode/trunk/formencode/national.py 2008-08-13 15:17:18 UTC (rev 3558)
@@ -46,11 +46,29 @@
def get_country(code):
return dict(get_countries())[code]
+
+ def get_languages():
+ c1 = tgformat.get_languages('en')
+ c2 = tgformat.get_languages()
+ if len(c1) > len(c2):
+ d = dict(c1)
+ d.update(dict(c2))
+ return d.items()
+ else:
+ return c2
+
+ def get_language(code):
+ try:
+ return tgformat.get_language(code)
+ except KeyError:
+ return tgformat.get_language(code, 'en')
elif has_pycountry:
# @@ mark: interestingly, common gettext notation does not work here
import gettext
gettext.bindtextdomain('iso3166', pycountry.LOCALES_DIR)
_c = lambda t: gettext.dgettext('iso3166', t)
+ gettext.bindtextdomain('iso639', pycountry.LOCALES_DIR)
+ _l = lambda t: gettext.dgettext('iso639', t)
def get_countries():
c1 = set([(e.alpha2, _c(e.name)) for e in pycountry.countries])
@@ -59,9 +77,15 @@
def get_country(code):
return _c(pycountry.countries.get(alpha2=code).name)
+
+ def get_languages():
+ return [(e.alpha2, _l(e.name)) for e in pycountry.languages]
+
+ def get_language(code):
+ return _l(pycountry.languages.get(alpha2=code).name)
else:
from warnings import warn
- warn('Please easy_install pycountry or validators handling country names will not work.', DeprecationWarning)
+ warn('Please easy_install pycountry or validators handling country names and/or languages will not work.', DeprecationWarning)
#endif
############################################################
@@ -620,3 +644,63 @@
if not self._phoneIsSane.search(value):
raise Invalid(self.message('phoneFormat', state), value, state)
return value
+
+############################################################
+## language validators
+############################################################
+
+class LanguageValidator(FancyValidator):
+
+ """
+ Converts a given language into its ISO 639 alpha 2 code, if there is any.
+ Returns the language's full name in the reverse.
+
+ Warning: ISO 639 neither differentiates between languages such as Cantonese
+ and Mandarin nor does it contain all spoken languages. E.g., Lechitic
+ languages are missing.
+ Warning: ISO 639 is a smaller subset of ISO 639-2
+
+ @param key_ok accept the language's code instead of its name for input
+ defaults to True
+
+ ::
+
+ >>> l = LanguageValidator()
+ >>> l.to_python('German')
+ 'de'
+ >>> l.to_python('Chinese')
+ 'zh'
+ >>> l.to_python('Klingonian')
+ Traceback (most recent call last):
+ ...
+ Invalid: That language is not listed in ISO-639-2
+ >>> l.from_python('de')
+ 'German'
+ >>> l.from_python('zh')
+ 'Chinese'
+ """
+
+ key_ok = True
+
+ messages = {
+ 'valueNotFound': _("That language is not listed in ISO-639-2"),
+ }
+
+ def _to_python(self, value, state):
+ upval = value.upper()
+ if self.key_ok:
+ try:
+ c = get_language(value)
+ return value
+ except:
+ pass
+ for k, v in get_languages():
+ if v.upper() == upval:
+ return k
+ raise Invalid(self.message('valueNotFound', state), value, state)
+
+ def _from_python(self, value, state):
+ try:
+ return get_language(value.lower())
+ except KeyError:
+ return value
|