text and bytes attributes now convert values from/to bytes/text when needed (ascii only conversion)

This commit is contained in:
Christophe de Vienne 2012-09-19 23:10:00 +02:00
parent 5258fd3cc5
commit 81ebb79e66
2 changed files with 51 additions and 27 deletions

View File

@ -175,7 +175,7 @@ class TestTypes(unittest.TestCase):
obj = AType()
obj.a = 'v1'
assert obj.a == 'v1'
assert obj.a == 'v1', repr(obj.a)
try:
obj.a = 'v3'
@ -202,6 +202,19 @@ class TestTypes(unittest.TestCase):
self.assertRaises(ValueError, setattr, obj, 'alist', 12)
self.assertRaises(ValueError, setattr, obj, 'alist', [2, 'a'])
def test_text_attribute_conversion(self):
class SType(object):
atext = types.text
abytes = types.bytes
types.register_type(SType)
obj = SType()
obj.atext = six.b('somebytes')
assert obj.atext == six.u('somebytes')
assert isinstance(obj.atext, types.text)
def test_named_attribute(self):
class AType(object):
a_list = types.wsattr([int], name='a.list')

View File

@ -47,8 +47,10 @@ class ArrayType(object):
raise ValueError("Wrong type. Expected '[%s]', got '%s'" % (
self.item_type, type(value)
))
for item in value:
return [
validate_value(self.item_type, item)
for item in value
]
class DictType(object):
@ -76,9 +78,12 @@ class DictType(object):
raise ValueError("Wrong type. Expected '{%s: %s}', got '%s'" % (
self.key_type, self.value_type, type(value)
))
for key, v in value.items():
validate_value(self.key_type, key)
validate_value(self.value_type, v)
return dict((
(
validate_value(self.key_type, key),
validate_value(self.value_type, v)
) for key, v in value.items()
))
class UserType(object):
@ -86,7 +91,7 @@ class UserType(object):
name = None
def validate(self, value):
return
return value
def tobasetype(self, value):
return value
@ -147,6 +152,7 @@ class Enum(UserType):
if value not in self.values:
raise ValueError("Value '%s' is invalid (should be one of: %s)" % (
value, ', '.join(self.values)))
return value
def tobasetype(self, value):
return value
@ -190,28 +196,33 @@ def validate_value(datatype, value):
if hasattr(datatype, 'validate'):
return datatype.validate(value)
else:
if value is Unset:
return True
if value is not None:
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 not isinstance(value, datatype):
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 '%s', got '%s'" % (
datatype, type(value)
"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 not isinstance(value, datatype):
raise ValueError(
"Wrong type. Expected '%s', got '%s'" % (
datatype, type(value)
))
return value
class wsproperty(property):
@ -285,7 +296,7 @@ class wsattr(object):
def __set__(self, instance, value):
try:
validate_value(self.datatype, value)
value = validate_value(self.datatype, value)
except ValueError:
e = sys.exc_info()[1]
raise ValueError("%s: %s" % (self.name, e))