better validators and comments, thanks Paolo

This commit is contained in:
mdipierro
2018-06-01 13:34:27 -05:00
parent 319490edc1
commit c358d2a851
+43 -40
View File
@@ -21,7 +21,7 @@ import struct
import decimal
import unicodedata
from gluon._compat import StringIO, long, basestring, unicodeT, to_unicode, urllib_unquote, unichr, to_bytes, PY2, \
from gluon._compat import StringIO, integer_types, basestring, unicodeT, urllib_unquote, unichr, to_bytes, PY2, \
to_unicode, to_native, string_types, urlparse
from gluon.utils import simple_hash, web2py_uuid, DIGEST_ALG_BY_SIZE
from pydal.objects import Field, FieldVirtual, FieldMethod
@@ -104,7 +104,7 @@ class Validator(object):
Here is an example of how to require a validator for a table field::
db.define_table('person', SQLField('name'))
db.define_table('person', Field('name'))
db.person.name.requires=IS_NOT_EMPTY()
Validators are always assigned using the requires attribute of a field. A
@@ -633,7 +633,7 @@ class IS_IN_DB(Validator):
if field.type in ('id', 'integer'):
new_values = []
for value in values:
if not (isinstance(value, (int, long)) or value.isdigit()):
if not (isinstance(value, integer_types) or value.isdigit()):
if self.auto_add:
value = str(self.maybe_add(table, self.fieldnames[0], value))
else:
@@ -660,7 +660,7 @@ class IS_IN_DB(Validator):
return (values, None)
else:
if field.type in ('id', 'integer'):
if isinstance(value, (int, long)) or (isinstance(value, string_types) and value.isdigit()):
if isinstance(value, integer_types) or (isinstance(value, string_types) and value.isdigit()):
value = int(value)
elif self.auto_add:
value = self.maybe_add(table, self.fieldnames[0], value)
@@ -757,7 +757,7 @@ def range_error_message(error_message, what_to_enter, minimum, maximum):
error_message += ' greater than or equal to %(min)g'
elif maximum is not None:
error_message += ' less than or equal to %(max)g'
if type(maximum) in [int, long]:
if type(maximum) in integer_types:
maximum -= 1
return translate(error_message) % dict(min=minimum, max=maximum)
@@ -1231,12 +1231,12 @@ class IS_LIST_OF_EMAILS(object):
Example:
Used as::
Field('emails','list:string',
widget=SQLFORM.widgets.text.widget,
requires=IS_LIST_OF_EMAILS(),
represent=lambda v,r: \
SPAN(*[A(x,_href='mailto:'+x) for x in (v or [])])
)
Field('emails', 'list:string',
widget=SQLFORM.widgets.text.widget,
requires=IS_LIST_OF_EMAILS(),
represent=lambda v, r: \
XML(', '.join([A(x, _href='mailto:'+x).xml() for x in (v or [])]))
)
"""
split_emails = re.compile('[^,;\s]+')
@@ -2741,14 +2741,17 @@ class ANY_OF(Validator):
"""
def __init__(self, subs):
def __init__(self, subs, error_message=None):
self.subs = subs
self.error_message = error_message
def __call__(self, value):
for validator in self.subs:
value, error = validator(value)
if error is None:
break
if error is not None and self.error_message is not None:
error = translate(self.error_message)
return value, error
def formatter(self, value):
@@ -3546,14 +3549,14 @@ class IS_IPV4(Validator):
for bottom, top in zip(self.minip, self.maxip):
if self.invert != (bottom <= number <= top):
ok = True
if not (self.is_localhost is None or self.is_localhost ==
(number == self.localhost)):
if ok and self.is_localhost is not None and \
self.is_localhost != (number == self.localhost):
ok = False
if not (self.is_private is None or self.is_private ==
(sum([private_number[0] <= number <= private_number[1]
for private_number in self.private]) > 0)):
if ok and self.is_private is not None and (self.is_private !=
any([private_number[0] <= number <= private_number[1]
for private_number in self.private])):
ok = False
if not (self.is_automatic is None or self.is_automatic ==
if ok and self.is_automatic is not None and (self.is_automatic !=
(self.automatic[0] <= number <= self.automatic[1])):
ok = False
if ok:
@@ -3563,9 +3566,10 @@ class IS_IPV4(Validator):
class IS_IPV6(Validator):
"""
Checks if field's value is an IP version 6 address. First attempts to
use the ipaddress library and falls back to contrib/ipaddr.py from Google
(https://code.google.com/p/ipaddr-py/)
Checks if field's value is an IP version 6 address.
Uses the ipaddress from the Python 3 standard library
and its Python 2 backport (in contrib/ipaddress.py).
Args:
is_private: None (default): indifferent
@@ -3573,7 +3577,7 @@ class IS_IPV6(Validator):
False (forbid): address must NOT be in fc00::/7 range
is_link_local: Same as above but uses fe80::/10 range
is_reserved: Same as above but uses IETF reserved range
is_mulicast: Same as above but uses ff00::/8 range
is_multicast: Same as above but uses ff00::/8 range
is_routeable: Similar to above but enforces not private, link_local,
reserved or multicast
is_6to4: Same as above but uses 2002::/16 range
@@ -3673,27 +3677,26 @@ class IS_IPV6(Validator):
if self.is_routeable:
self.is_private = False
self.is_link_local = False
self.is_reserved = False
self.is_multicast = False
if not (self.is_private is None or self.is_private ==
ip.is_private):
if ok and self.is_private is not None and \
self.is_private != ip.is_private:
ok = False
if not (self.is_link_local is None or self.is_link_local ==
ip.is_link_local):
if ok and self.is_link_local is not None and \
self.is_link_local != ip.is_link_local:
ok = False
if not (self.is_reserved is None or self.is_reserved ==
ip.is_reserved):
if ok and self.is_reserved is not None and \
self.is_reserved != ip.is_reserved:
ok = False
if not (self.is_multicast is None or self.is_multicast ==
ip.is_multicast):
if ok and self.is_multicast is not None and \
self.is_multicast != ip.is_multicast:
ok = False
if not (self.is_6to4 is None or self.is_6to4 ==
ip.is_6to4):
if ok and self.is_6to4 is not None and \
self.is_6to4 != bool(ip.sixtofour):
ok = False
if not (self.is_teredo is None or self.is_teredo ==
ip.is_teredo):
if ok and self.is_teredo is not None and \
self.is_teredo != bool(ip.teredo):
ok = False
if ok:
@@ -3708,8 +3711,8 @@ class IS_IPADDRESS(Validator):
addresses from within a specific range. Checks are done with the correct
IS_IPV4 and IS_IPV6 validators.
Uses ipaddress library if found, falls back to PEP-3144 ipaddr.py from
Google (in contrib).
Uses the ipaddress from the Python 3 standard library
and its Python 2 backport (in contrib/ipaddress.py).
Args:
minip: lowest allowed address; accepts:
@@ -3742,7 +3745,7 @@ class IS_IPADDRESS(Validator):
- is_link_local: Same as above but uses fe80::/10 range
- is_reserved: Same as above but uses IETF reserved range
- is_mulicast: Same as above but uses ff00::/8 range
- is_multicast: Same as above but uses ff00::/8 range
- is_routeable: Similar to above but enforces not private, link_local,
reserved or multicast
- is_6to4: Same as above but uses 2002::/16 range
@@ -3861,7 +3864,7 @@ class IS_IPADDRESS(Validator):
self.is_localhost = is_localhost
self.is_private = is_private
self.is_automatic = is_automatic
self.is_ipv4 = is_ipv4
self.is_ipv4 = is_ipv4 or is_ipv6 is False
self.is_private = is_private
self.is_link_local = is_link_local
self.is_reserved = is_reserved
@@ -3870,7 +3873,7 @@ class IS_IPADDRESS(Validator):
self.is_6to4 = is_6to4
self.is_teredo = is_teredo
self.subnets = subnets
self.is_ipv6 = is_ipv6
self.is_ipv6 = is_ipv6 or is_ipv4 is False
self.error_message = error_message
def __call__(self, value):