Merged in dhellmann/wsme-validate (pull request #2)

This commit is contained in:
Christophe de Vienne 2012-12-05 22:33:36 +01:00
commit dbd435a2fe
3 changed files with 60 additions and 35 deletions

View File

@ -6,7 +6,8 @@ syntax: glob
*.swp *.swp
*.orig *.orig
~* ~*
.coverage *~
.coverage*
coverage.xml coverage.xml
.noseids .noseids
.tox .tox

View File

@ -249,7 +249,7 @@ class TestTypes(unittest.TestCase):
assert value.a is types.Unset assert value.a is types.Unset
def test_validate_dict(self): def test_validate_dict(self):
types.validate_value({int: str}, {1: '1', 5: '5'}) assert types.validate_value({int: str}, {1: '1', 5: '5'})
try: try:
types.validate_value({int: str}, []) types.validate_value({int: str}, [])
@ -257,11 +257,7 @@ class TestTypes(unittest.TestCase):
except ValueError: except ValueError:
pass pass
try: assert types.validate_value({int: str}, {'1': '1', 5: '5'})
types.validate_value({int: str}, {'1': '1', 5: '5'})
assert False, "No ValueError raised"
except ValueError:
pass
try: try:
types.validate_value({int: str}, {1: 1, 5: '5'}) types.validate_value({int: str}, {1: 1, 5: '5'})
@ -273,6 +269,21 @@ class TestTypes(unittest.TestCase):
self.assertEqual(types.validate_value(float, 1), 1.0) self.assertEqual(types.validate_value(float, 1), 1.0)
self.assertEqual(types.validate_value(float, '1'), 1.0) self.assertEqual(types.validate_value(float, '1'), 1.0)
self.assertEqual(types.validate_value(float, 1.1), 1.1) self.assertEqual(types.validate_value(float, 1.1), 1.1)
try:
types.validate_value(float, [])
assert False, "No ValueError raised"
except ValueError:
pass
def test_validate_int(self):
self.assertEqual(types.validate_value(int, 1), 1)
self.assertEqual(types.validate_value(int, '1'), 1)
self.assertEqual(types.validate_value(int, six.u('1')), 1)
try:
types.validate_value(int, 1.1)
assert False, "No ValueError raised"
except ValueError:
pass
def test_register_invalid_array(self): def test_register_invalid_array(self):
self.assertRaises(ValueError, types.register_type, []) self.assertRaises(ValueError, types.register_type, [])

View File

@ -178,6 +178,8 @@ pod_types = six.integer_types + (
dt_types = (datetime.date, datetime.time, datetime.datetime) dt_types = (datetime.date, datetime.time, datetime.datetime)
extra_types = (binary, decimal.Decimal) extra_types = (binary, decimal.Decimal)
native_types = pod_types + dt_types + extra_types native_types = pod_types + dt_types + extra_types
# The types for which we allow promotion to certain numbers.
_promotable_types = six.integer_types + (text, bytes)
def iscomplex(datatype): def iscomplex(datatype):
@ -194,38 +196,49 @@ def isdict(datatype):
def validate_value(datatype, value): def validate_value(datatype, value):
if value in (Unset, None):
return value
# Try to promote the data type to one of our complex types.
if isinstance(datatype, list):
datatype = ArrayType(datatype[0])
elif isinstance(datatype, dict):
datatype = DictType(*list(datatype.items())[0])
# If the datatype has its own validator, use that.
if hasattr(datatype, 'validate'): if hasattr(datatype, 'validate'):
return datatype.validate(value) return datatype.validate(value)
else:
if value in (Unset, None):
return value
if isinstance(datatype, list): # Do type promotion/conversion and data validation for builtin
datatype = ArrayType(datatype[0]) # types.
if isinstance(datatype, dict): v_type = type(value)
datatype = DictType(*list(datatype.items())[0]) if datatype in six.integer_types:
if isarray(datatype): if v_type in _promotable_types:
datatype.validate(value) try:
elif isdict(datatype): # Try to turn the value into an int
datatype.validate(value) value = datatype(value)
elif datatype in six.integer_types: except ValueError:
if not isinstance(value, six.integer_types): # An error is raised at the end of the function
raise ValueError( # when the types don't match.
"Wrong type. Expected an integer, got '%s'" % ( pass
type(value) elif datatype is float and v_type in _promotable_types:
)) try:
elif datatype is text and isinstance(value, bytes):
value = value.decode()
elif datatype is bytes and isinstance(value, text):
value = value.encode()
elif datatype is float and not isinstance(value, float):
value = float(value) value = float(value)
elif not isinstance(value, datatype): except ValueError:
raise ValueError( # An error is raised at the end of the function
"Wrong type. Expected '%s', got '%s'" % ( # when the types don't match.
datatype, type(value) pass
)) elif datatype is text and isinstance(value, bytes):
return value value = value.decode()
elif datatype is bytes and isinstance(value, text):
value = value.encode()
if not isinstance(value, datatype):
raise ValueError(
"Wrong type. Expected '%s', got '%s'" % (
datatype, v_type
))
return value
class wsproperty(property): class wsproperty(property):