From 6add4a51d78b9f2487f5db8f5638519bb5dc5580 Mon Sep 17 00:00:00 2001 From: Richard Hartmann Date: Fri, 30 Sep 2016 22:36:59 +0200 Subject: [PATCH] cleanup to increase codecov --- binfootprint/binfootprint.py | 41 +++++++----------- tests/test_binfootprint.py | 84 +++++++++++++++++++++++++++++++----- 2 files changed, 88 insertions(+), 37 deletions(-) diff --git a/binfootprint/binfootprint.py b/binfootprint/binfootprint.py index 3fc430f..c644725 100644 --- a/binfootprint/binfootprint.py +++ b/binfootprint/binfootprint.py @@ -46,7 +46,7 @@ _INT_32 = 0x01 _FLOAT = 0x02 _COMPLEX = 0x03 _STR = 0x04 -_BYTES = 0x05 +_BYTES = 0x05 # only for python3, as bytes and str are equivalent in python2 _INT = 0x06 _TUPLE = 0x07 _NAMEDTUPLE = 0x08 @@ -55,7 +55,6 @@ _LIST = 0x0a _GETSTATE = 0x0b _DICT = 0x0c _INT_NEG = 0x0d -_BFSTATE = 0x0e _VERS = 0x80 def getVersion(): @@ -157,7 +156,7 @@ def _load_spec(b): elif b[1] == char_to_byte('N'): return None, 2 else: - raise BFLoadError("unknown code for 'special' {}".format(b[1])) + raise BFLoadError("internal error (unknown code for 'special' {})".format(b[1])) def _dump_int_32(ob): b = init_BYTES([_INT_32]) @@ -188,7 +187,7 @@ def _load_int(b): elif comp_id(b[0], _INT_NEG): m = -1 else: - assert False + raise BFLoadError("internal error (unknown int id {})".format(b[0])) num_bytes = struct.unpack('>I', b[1:5])[0] i = m*bytes_to_int(b[5:5+num_bytes]) return i, num_bytes + 5 @@ -233,10 +232,7 @@ def _dump_bytes(ob): b = init_BYTES([_BYTES]) num_bytes = len(ob) b += struct.pack('>I', num_bytes) - if isinstance(b, str): - b += str(ob) - else: - b += ob + b += ob return b def _load_bytes(b): @@ -339,14 +335,6 @@ def _dump_getstate(ob): return b -# def _dump_bfstate(ob): -# b = init_BYTES([_BFSTATE]) -# state = ob.__bfstate__() -# obj_type = ob.__class__.__name__ -# b += _dump(str(obj_type)) -# b += _dump(state) -# return b - def _load_getstate(b, classes): assert comp_id(b[0], _GETSTATE) obj_type, l_obj_type = _load_str(b[1:]) @@ -407,11 +395,9 @@ def _dump(ob): elif isinstance(ob, dict): return _dump_dict(ob) elif hasattr(ob, '__getstate__'): - return _dump_getstate(ob) - elif hasattr(ob, '__bfstate__'): - return _dump_bfstate(ob) + return _dump_getstate(ob) else: - raise RuntimeError("unsupported type for dump '{}'".format(type(ob))) + raise TypeError("unsupported type for dump '{}'".format(type(ob))) def _load(b, classes): identifier = b[0] @@ -443,17 +429,15 @@ def _load(b, classes): return _load_dict(b, classes) elif identifier == _GETSTATE: return _load_getstate(b, classes) - elif identifier == _BFSTATE: - raise BFLoadError("BFSTATE objects can not be loaded") else: - raise BFLoadError("unknown identifier '{}'".format(hex(identifier))) + raise BFLoadError("internal error (unknown identifier '{}')".format(hex(identifier))) def dump(ob, vers=_VERS): """ returns the binary footprint of the object 'ob' as bytes """ - global _dump - if vers == _VERS: + global _dump # allows to temporally overwrite the global _dump + if vers == _VERS: # to dump using different version return init_BYTES([_VERS]) + _dump(ob) elif vers < 0x80: __dump_tmp = _dump @@ -485,7 +469,7 @@ def load(b, classes={}): return res else: - raise RuntimeError("unknown version tag found!") + raise BFLoadError("internal error (unknown version tag {})".format(vers)) ################################################################## @@ -498,6 +482,11 @@ def load(b, classes={}): # to be < 128 = 0x80 def _load_namedtuple_00(b, classes): + """ + need to explicitly know the named tuple class for reconstruction + + later version creates its own named tuple + """ assert comp_id(b[0], _NAMEDTUPLE) size = struct.unpack('>I', b[1:5])[0] class_name, len_ob = _load_str(b[5:]) diff --git a/tests/test_binfootprint.py b/tests/test_binfootprint.py index d1f33b3..1bac29c 100644 --- a/tests/test_binfootprint.py +++ b/tests/test_binfootprint.py @@ -11,6 +11,7 @@ import binfootprint as bfp import numpy as np from collections import namedtuple +import pytest import warnings warnings.filterwarnings('error') @@ -21,8 +22,9 @@ def test_version_tag(): assert bfp.byte_to_ord(binob[0]) == bfp.getVersion() def test_atom(): - atoms = [12345678, 3.141, 'hallo Welt', 'öäüß', True, False, None, 2**65, -3**65, b'\xff\fe\03'] - + atoms = [12345678, 3.141, 'hallo Welt', 'öäüß', True, False, None, 2**65, -3**65, b'\xff\fe\03', bytes(range(256))] + + # new version for atom in atoms: bin_atom = bfp.dump(atom) atom_prime = bfp.load(bin_atom) @@ -30,6 +32,15 @@ def test_atom(): assert bin_atom == bin_ob_prime hash(bin_atom) + + # old version + for atom in atoms: + bin_atom = bfp.dump(atom, vers=0) + atom_prime = bfp.load(bin_atom) + bin_ob_prime = bfp.dump(atom_prime, vers=0) + assert bin_atom == bin_ob_prime + + hash(bin_atom) def test_tuple(): t = (12345678, 3.141, 'hallo Welt', 'öäüß', True, False, None, (3, tuple(), (4,5,None), 'test')) @@ -39,6 +50,12 @@ def test_tuple(): assert t == t_prime bin_ob_prime = bfp.dump(t_prime) assert bin_tuple == bin_ob_prime + + # old version + bin_tuple_00 = bfp.dump(t, vers=0) + assert type(bin_tuple_00) is bfp.BIN_TYPE + t_prime_00 = bfp.load(bin_tuple_00) + assert t == t_prime_00 def test_nparray(): ob = np.random.randn(3,53,2) @@ -56,7 +73,14 @@ def test_nparray(): assert np.all(ob[0] == ob_prime[0]) assert np.all(ob[1] == ob_prime[1]) bin_ob_prime = bfp.dump(ob_prime) - assert bin_ob == bin_ob_prime + assert bin_ob == bin_ob_prime + + # old version + ob = np.random.randn(3,53,2) + bin_ob_00 = bfp.dump(ob, vers=0) + assert type(bin_ob_00) is bfp.BIN_TYPE + ob_prime_00 = bfp.load(bin_ob_00) + assert np.all(ob == ob_prime_00) def test_list(): ob = [1,2,3] @@ -65,7 +89,7 @@ def test_list(): ob_prime = bfp.load(bin_ob) assert np.all(ob == ob_prime) bin_ob_prime = bfp.dump(ob_prime) - assert bin_ob == bin_ob_prime + assert bin_ob == bin_ob_prime ob = [1, (2,3), np.array([2j,3j])] bin_ob = bfp.dump(ob) @@ -75,7 +99,14 @@ def test_list(): assert np.all(ob[0] == ob_prime[0]) assert np.all(ob[1] == ob_prime[1]) - assert np.all(ob[2] == ob_prime[2]) + assert np.all(ob[2] == ob_prime[2]) + + # old version + ob = [1,2,3] + bin_ob_00 = bfp.dump(ob, vers=0) + assert type(bin_ob_00) is bfp.BIN_TYPE + ob_prime_00 = bfp.load(bin_ob_00) + assert np.all(ob == ob_prime_00) def test_getstate(): class T(object): @@ -105,7 +136,13 @@ def test_getstate(): pass else: assert False, "binfootprint.BFUnkownClassError should have been raised" - + + # old version + bin_ob_00 = bfp.dump(ob, vers=0) + assert type(bin_ob_00) is bfp.BIN_TYPE + ob_prime_00 = bfp.load(bin_ob_00, classes) + assert np.all(ob.a == ob_prime_00.a) + def test_named_tuple(): obj_type = namedtuple('obj_type', ['a','b','c']) @@ -125,7 +162,13 @@ def test_complex(): bf = bfp.dump(z) assert type(bf) is bfp.BIN_TYPE zr = bfp.load(bf) - assert zr == z + assert zr == z + + # old version + bf_00 = bfp.dump(z, vers=0) + assert type(bf_00) is bfp.BIN_TYPE + zr_00 = bfp.load(bf_00) + assert zr_00 == z def test_dict(): a = {'a':1, 5:5, 3+4j:'l', False: b'ab4+#'} @@ -135,6 +178,13 @@ def test_dict(): for k in a: assert a[k] == a_restored[k] + # old version + bf_00 = bfp.dump(a, vers=0) + assert type(bf_00) is bfp.BIN_TYPE + a_restored_00 = bfp.load(bf_00) + for k in a: + assert a[k] == a_restored_00[k] + def test_versions(): nt = namedtuple('nt', ['x', 'y']) n = nt(4,5) @@ -142,19 +192,30 @@ def test_versions(): ob = [3, n, n2] binob = bfp.dump(ob, vers = 0) + # version 00 needs to explicitly know the namedtuple class + ob_prime = bfp.load(binob, classes={'nt': nt}) + assert ob_prime == ob + try: + # if the namedtuple class is not passed raises BFUnknownClassError bfp.load(binob) except bfp.BFUnkownClassError: pass else: assert False, "binfootprint.BFUnkownClassError should have been raised" - - rest_ob = bfp.load(binob, {'nt': nt}) - assert rest_ob == ob - + + # thats how it works in the new version binob = bfp.dump(ob, vers = 0x80) rest_ob = bfp.load(binob) assert rest_ob == ob + +def test_unsopportedtype(): + obj = bytearray([4,5,6]) + try: + bfp.dump(obj) + except TypeError: + pass + if __name__ == "__main__": @@ -168,5 +229,6 @@ if __name__ == "__main__": test_complex() test_dict() test_versions() + test_unsopportedtype()