Merged in dhellmann/wsme-validate (pull request #2)
This commit is contained in:
commit
dbd435a2fe
@ -6,7 +6,8 @@ syntax: glob
|
||||
*.swp
|
||||
*.orig
|
||||
~*
|
||||
.coverage
|
||||
*~
|
||||
.coverage*
|
||||
coverage.xml
|
||||
.noseids
|
||||
.tox
|
||||
|
@ -249,7 +249,7 @@ class TestTypes(unittest.TestCase):
|
||||
assert value.a is types.Unset
|
||||
|
||||
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:
|
||||
types.validate_value({int: str}, [])
|
||||
@ -257,11 +257,7 @@ class TestTypes(unittest.TestCase):
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
try:
|
||||
types.validate_value({int: str}, {'1': '1', 5: '5'})
|
||||
assert False, "No ValueError raised"
|
||||
except ValueError:
|
||||
pass
|
||||
assert types.validate_value({int: str}, {'1': '1', 5: '5'})
|
||||
|
||||
try:
|
||||
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), 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):
|
||||
self.assertRaises(ValueError, types.register_type, [])
|
||||
|
@ -178,6 +178,8 @@ pod_types = six.integer_types + (
|
||||
dt_types = (datetime.date, datetime.time, datetime.datetime)
|
||||
extra_types = (binary, decimal.Decimal)
|
||||
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):
|
||||
@ -194,38 +196,49 @@ def isdict(datatype):
|
||||
|
||||
|
||||
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'):
|
||||
return datatype.validate(value)
|
||||
else:
|
||||
if value in (Unset, None):
|
||||
return value
|
||||
|
||||
if isinstance(datatype, list):
|
||||
datatype = ArrayType(datatype[0])
|
||||
if isinstance(datatype, dict):
|
||||
datatype = DictType(*list(datatype.items())[0])
|
||||
if isarray(datatype):
|
||||
datatype.validate(value)
|
||||
elif isdict(datatype):
|
||||
datatype.validate(value)
|
||||
elif datatype in six.integer_types:
|
||||
if not isinstance(value, six.integer_types):
|
||||
raise ValueError(
|
||||
"Wrong type. Expected an integer, got '%s'" % (
|
||||
type(value)
|
||||
))
|
||||
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):
|
||||
# Do type promotion/conversion and data validation for builtin
|
||||
# types.
|
||||
v_type = type(value)
|
||||
if datatype in six.integer_types:
|
||||
if v_type in _promotable_types:
|
||||
try:
|
||||
# Try to turn the value into an int
|
||||
value = datatype(value)
|
||||
except ValueError:
|
||||
# An error is raised at the end of the function
|
||||
# when the types don't match.
|
||||
pass
|
||||
elif datatype is float and v_type in _promotable_types:
|
||||
try:
|
||||
value = float(value)
|
||||
elif not isinstance(value, datatype):
|
||||
raise ValueError(
|
||||
"Wrong type. Expected '%s', got '%s'" % (
|
||||
datatype, type(value)
|
||||
))
|
||||
return value
|
||||
except ValueError:
|
||||
# An error is raised at the end of the function
|
||||
# when the types don't match.
|
||||
pass
|
||||
elif datatype is text and isinstance(value, bytes):
|
||||
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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user