def test_ext_handlers_subclass(self): class Rectangle: def __init__(self, length, width): self.length = length self.width = width def __eq__(self, other): return self.length == other.length and self.width == other.width class Square(Rectangle): def __init__(self, width): Rectangle.__init__(self, width, width) # Test pack (packs base class) packed = umsgpack.packb( Square(5), ext_handlers={ Rectangle: lambda obj: umsgpack.Ext( 0x10, umsgpack.packb([obj.length, obj.width])), }) self.assertEqual(packed, b"\xc7\x03\x10\x92\x05\x05") # Test unpack (unpacks base class) unpacked = umsgpack.unpackb( packed, ext_handlers={ 0x10: lambda ext: Rectangle(*umsgpack.unpackb(ext.data)), }) self.assertEqual(unpacked, Rectangle(5, 5))
def test_unpack_tuple(self): # Use tuple test vector (_, obj, data, obj_tuple) = tuple_test_vectors[0] # Unpack with default options (list) self.assertEqual(umsgpack.unpackb(data), obj) # Unpack with use_tuple=False (list) self.assertEqual(umsgpack.unpackb(data, use_tuple=False), obj) # Unpack with use_tuple=True (tuple) self.assertEqual(umsgpack.unpackb(data, use_tuple=True), obj_tuple)
def test_ext_serializable_subclass(self): @umsgpack.ext_serializable(0x10) class Rectangle: def __init__(self, length, width): self.length = length self.width = width def __eq__(self, other): return self.length == other.length and self.width == other.width def packb(self): return umsgpack.packb([self.length, self.width]) @classmethod def unpackb(cls, data): return cls(*umsgpack.unpackb(data)) class Square(Rectangle): def __init__(self, width): Rectangle.__init__(self, width, width) # Test pack (packs base class) packed = umsgpack.packb(Square(5)) self.assertEqual(packed, b"\xc7\x03\x10\x92\x05\x05") # Test unpack (unpacks base class) unpacked = umsgpack.unpackb(packed) self.assertEqual(unpacked, Rectangle(5, 5)) # Unregister Ext serializable classes to prevent interference with # subsequent tests umsgpack._ext_classes_to_code = {} umsgpack._ext_code_to_classes = {}
def test_unpack_invalid_string(self): # Use last unpack exception test vector (an invalid string) (_, data, _) = unpack_exception_test_vectors[-1] obj = umsgpack.unpackb(data, allow_invalid_utf8=True) self.assertTrue(isinstance(obj, umsgpack.InvalidString)) self.assertEqual(obj, b"\x80")
def test_unpack_ordered_dict(self): # Use last composite test vector (a map) (_, obj, data) = composite_test_vectors[-1] # Unpack with default options (unordered dict) unpacked = umsgpack.unpackb(data) self.assertTrue(isinstance(unpacked, dict)) # Unpack with unordered dict unpacked = umsgpack.unpackb(data, use_ordered_dict=False) self.assertTrue(isinstance(unpacked, dict)) # Unpack with ordered dict unpacked = umsgpack.unpackb(data, use_ordered_dict=True) self.assertTrue(isinstance(unpacked, OrderedDict)) self.assertEqual(unpacked, obj)
def test_unpack_composite(self): for (name, obj, data) in composite_test_vectors: obj_repr = repr(obj) print("\tTesting {:s}: object {:s}".format( name, obj_repr if len(obj_repr) < 24 else obj_repr[0:24] + "...")) self.assertEqual(umsgpack.unpackb(data), obj)
def test_unpack_ext_override(self): # Test overridden unpacking of Ext type -1 (name, obj, data) = override_ext_handlers_test_vectors[1] obj_repr = repr(obj) print("\tTesting {:s}: object {:s}".format( name, obj_repr if len(obj_repr) < 24 else obj_repr[0:24] + "...")) unpacked = umsgpack.unpackb(data, ext_handlers=override_ext_handlers) self.assertEqual(unpacked, obj)
def test_unpack_naive_timestamp(self): for (name, _, data, obj) in naive_timestamp_test_vectors: obj_repr = repr(obj) print("\tTesting {:s}: object {:s}".format( name, obj_repr if len(obj_repr) < 24 else obj_repr[0:24] + "...")) unpacked = umsgpack.unpackb(data) self.assertEqual(unpacked, obj)
def test_unpack_ext_handler(self): for (name, obj, data) in ext_handlers_test_vectors: obj_repr = repr(obj) print("\tTesting {:s}: object {:s}".format( name, obj_repr if len(obj_repr) < 24 else obj_repr[0:24] + "...")) unpacked = umsgpack.unpackb(data, ext_handlers=ext_handlers) self.assertEqual(unpacked, obj)
def test_unpack_compatibility(self): umsgpack.compatibility = True for (name, obj, data) in compatibility_test_vectors: obj_repr = repr(obj) print("\tTesting {:s}: object {:s}".format( name, obj_repr if len(obj_repr) < 24 else obj_repr[0:24] + "...")) unpacked = umsgpack.unpackb(data) # Encoded raw should always unpack to bytes in compatibility mode, # so convert any string obj to bytes before comparison if sys.version_info[0] == 3 and isinstance(obj, str): _obj = obj.encode('utf-8') else: _obj = obj self.assertTrue(isinstance(unpacked, type(_obj))) self.assertEqual(unpacked, _obj) umsgpack.compatibility = False
def test_unpack_single(self): for (name, obj, data) in single_test_vectors: obj_repr = repr(obj) print("\tTesting {:s}: object {:s}".format( name, obj_repr if len(obj_repr) < 24 else obj_repr[0:24] + "...")) unpacked = umsgpack.unpackb(data) # In Python2, we have both int and long integer types, but which # one we end up with depends on the architecture (32-bit/64-bit) if sys.version_info[0] == 2: # Allow both {int,long} -> unpackb -> {int,long} if isinstance(obj, int) or isinstance(obj, long): self.assertTrue( isinstance(unpacked, int) or isinstance(unpacked, long)) else: self.assertTrue(isinstance(unpacked, type(obj))) # In Python3, we only have the int integer type else: self.assertTrue(isinstance(unpacked, type(obj))) self.assertEqual(unpacked, obj)
def unpackb(cls, data): return cls(*umsgpack.unpackb(data))
def test_ext_serializable(self): # Register test class @umsgpack.ext_serializable(0x20) class CustomComplex: def __init__(self, real, imag): self.real = real self.imag = imag def __eq__(self, other): return self.real == other.real and self.imag == other.imag def packb(self): return struct.pack("<II", self.real, self.imag) @classmethod def unpackb(cls, data): return cls(*struct.unpack("<II", data)) obj, data = CustomComplex( 123, 456), b"\xd7\x20\x7b\x00\x00\x00\xc8\x01\x00\x00" # Test pack packed = umsgpack.packb(obj) self.assertEqual(packed, data) # Test unpack unpacked = umsgpack.unpackb(packed) self.assertTrue(isinstance(unpacked, CustomComplex)) self.assertEqual(unpacked, obj) _, obj, data = ext_handlers_test_vectors[0] # Test pack priority of ext_handlers over ext_serializable() packed = umsgpack.packb(obj, ext_handlers=ext_handlers) self.assertEqual(packed, data) # Test unpack priority of ext_handlers over ext_serializable() unpacked = umsgpack.unpackb(data, ext_handlers=ext_handlers) self.assertTrue(isinstance(unpacked, complex)) self.assertEqual(unpacked, obj) # Test registration collision with self.assertRaises(ValueError): @umsgpack.ext_serializable(0x20) class DummyClass: pass # Test out of range Ext type value with self.assertRaises(ValueError): @umsgpack.ext_serializable(-129) class DummyClass2: pass with self.assertRaises(ValueError): @umsgpack.ext_serializable(128) class DummyClass3: pass # Register class with missing packb() and unpackb() @umsgpack.ext_serializable(0x21) class IncompleteClass: pass # Test unimplemented packb() with self.assertRaises(NotImplementedError): umsgpack.packb(IncompleteClass()) # Test unimplemented unpackb() with self.assertRaises(NotImplementedError): umsgpack.unpackb(b"\xd4\x21\x00") # Unregister Ext serializable classes to prevent interference with # subsequent tests umsgpack._ext_classes_to_code = {} umsgpack._ext_code_to_classes = {}
def test_unpack_exceptions(self): for (name, data, exception) in unpack_exception_test_vectors: print("\tTesting {:s}".format(name)) with self.assertRaises(exception): umsgpack.unpackb(data)
[ "96-bit timestamp (naive)", datetime.datetime(3000, 1, 1, 10, 5, 2, 1234, umsgpack._utc_tzinfo), b"\xc7\x0c\xff\x00\x12\xd4\x50\x00\x00\x00\x07\x91\x5f\x59\xce", datetime.datetime(3000, 1, 1, 10, 5, 2, 1234, umsgpack._utc_tzinfo) ], ] CustomType = namedtuple('CustomType', ['x', 'y', 'z']) ext_handlers = { complex: lambda obj: umsgpack.Ext(0x20, struct.pack("<ff", obj.real, obj.imag)), CustomType: lambda obj: umsgpack.Ext(0x30, umsgpack.packb(list(obj))), 0x20: lambda ext: complex(*struct.unpack("<ff", ext.data)), 0x30: lambda ext: CustomType(*umsgpack.unpackb(ext.data)), } ext_handlers_test_vectors = [ ["complex", complex(1, 2), b"\xd7\x20\x00\x00\x80\x3f\x00\x00\x00\x40"], [ "custom type", CustomType(b"abc", 123, True), b"\xd7\x30\x93\xc4\x03\x61\x62\x63\x7b\xc3" ], ] override_ext_handlers = { datetime.datetime: lambda obj: umsgpack.Ext(0x40,