From a7ee6f108ef5dbde7efc05d7b807ee067946f986 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 4 Jun 2019 17:42:21 +0800 Subject: [PATCH] Refactor --- test_libs/pyspec/eth2spec/debug/decode.py | 3 +- test_libs/pyspec/eth2spec/debug/encode.py | 3 +- .../pyspec/eth2spec/debug/random_value.py | 44 ++++----- .../pyspec/eth2spec/utils/ssz/ssz_typing.py | 89 +++++++++++-------- 4 files changed, 80 insertions(+), 59 deletions(-) diff --git a/test_libs/pyspec/eth2spec/debug/decode.py b/test_libs/pyspec/eth2spec/debug/decode.py index 86716c5f4..5ce116025 100644 --- a/test_libs/pyspec/eth2spec/debug/decode.py +++ b/test_libs/pyspec/eth2spec/debug/decode.py @@ -36,5 +36,4 @@ def decode(data, typ): hash_tree_root(ret, typ).hex()) return ret else: - print(data, typ) - raise Exception("Type not recognized") + raise Exception(f"Type not recognized: data={data}, typ={typ}") diff --git a/test_libs/pyspec/eth2spec/debug/encode.py b/test_libs/pyspec/eth2spec/debug/encode.py index 8be567f17..61dd87928 100644 --- a/test_libs/pyspec/eth2spec/debug/encode.py +++ b/test_libs/pyspec/eth2spec/debug/encode.py @@ -33,5 +33,4 @@ def encode(value, typ, include_hash_tree_roots=False): ret["hash_tree_root"] = '0x' + hash_tree_root(value, typ).hex() return ret else: - print(value, typ) - raise Exception("Type not recognized") + raise Exception(f"Type not recognized: value={value}, typ={typ}") diff --git a/test_libs/pyspec/eth2spec/debug/random_value.py b/test_libs/pyspec/eth2spec/debug/random_value.py index 43c3de349..189c1268a 100644 --- a/test_libs/pyspec/eth2spec/debug/random_value.py +++ b/test_libs/pyspec/eth2spec/debug/random_value.py @@ -56,65 +56,69 @@ def get_random_ssz_object(rng: Random, """ if chaos: mode = rng.choice(list(RandomizationMode)) - # Bytes array if is_bytes_type(typ): + # Bytes array if mode == RandomizationMode.mode_nil_count: return b'' - if mode == RandomizationMode.mode_max_count: + elif mode == RandomizationMode.mode_max_count: return get_random_bytes_list(rng, max_bytes_length) - if mode == RandomizationMode.mode_one_count: + elif mode == RandomizationMode.mode_one_count: return get_random_bytes_list(rng, 1) - if mode == RandomizationMode.mode_zero: + elif mode == RandomizationMode.mode_zero: return b'\x00' - if mode == RandomizationMode.mode_max: + elif mode == RandomizationMode.mode_max: return b'\xff' - return get_random_bytes_list(rng, rng.randint(0, max_bytes_length)) + else: + return get_random_bytes_list(rng, rng.randint(0, max_bytes_length)) elif is_bytesn_type(typ): + # BytesN length = typ.length # Sanity, don't generate absurdly big random values # If a client is aiming to performance-test, they should create a benchmark suite. assert length <= max_bytes_length if mode == RandomizationMode.mode_zero: return b'\x00' * length - if mode == RandomizationMode.mode_max: + elif mode == RandomizationMode.mode_max: return b'\xff' * length - return get_random_bytes_list(rng, length) - # Basic types + else: + return get_random_bytes_list(rng, length) elif is_basic_type(typ): + # Basic types if mode == RandomizationMode.mode_zero: return get_min_basic_value(typ) - if mode == RandomizationMode.mode_max: + elif mode == RandomizationMode.mode_max: return get_max_basic_value(typ) - return get_random_basic_value(rng, typ) - # Vector: + else: + return get_random_basic_value(rng, typ) elif is_vector_type(typ): + # Vector elem_typ = read_vector_elem_type(typ) return [ get_random_ssz_object(rng, elem_typ, max_bytes_length, max_list_length, mode, chaos) for _ in range(typ.length) ] - # List: elif is_list_type(typ): + # List elem_typ = read_list_elem_type(typ) length = rng.randint(0, max_list_length) if mode == RandomizationMode.mode_one_count: length = 1 - if mode == RandomizationMode.mode_max_count: + elif mode == RandomizationMode.mode_max_count: length = max_list_length + return [ get_random_ssz_object(rng, elem_typ, max_bytes_length, max_list_length, mode, chaos) for _ in range(length) ] - # Container: elif is_container_type(typ): + # Container return typ(**{ field: get_random_ssz_object(rng, subtype, max_bytes_length, max_list_length, mode, chaos) for field, subtype in typ.get_fields() }) else: - print(typ) - raise Exception("Type not recognized") + raise Exception(f"Type not recognized: typ={typ}") def get_random_bytes_list(rng: Random, length: int) -> bytes: @@ -129,7 +133,7 @@ def get_random_basic_value(rng: Random, typ) -> Any: assert size in UINT_SIZES return rng.randint(0, 256**size - 1) else: - raise ValueError("Not a basic type") + raise ValueError(f"Not a basic type: typ={typ}") def get_min_basic_value(typ) -> Any: @@ -140,7 +144,7 @@ def get_min_basic_value(typ) -> Any: assert size in UINT_SIZES return 0 else: - raise ValueError("Not a basic type") + raise ValueError(f"Not a basic type: typ={typ}") def get_max_basic_value(typ) -> Any: @@ -151,4 +155,4 @@ def get_max_basic_value(typ) -> Any: assert size in UINT_SIZES return 256**size - 1 else: - raise ValueError("Not a basic type") + raise ValueError(f"Not a basic type: typ={typ}") diff --git a/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py b/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py index 7f20284a8..fcc3fab82 100644 --- a/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py +++ b/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py @@ -83,13 +83,15 @@ def is_uint_type(typ): def uint_byte_size(typ): if hasattr(typ, '__supertype__'): typ = typ.__supertype__ + if isinstance(typ, type): if issubclass(typ, uint): return typ.byte_len elif issubclass(typ, int): # Default to uint64 return 8 - raise TypeError("Type %s is not an uint (or int-default uint64) type" % typ) + else: + raise TypeError("Type %s is not an uint (or int-default uint64) type" % typ) # SSZ Container base class @@ -167,32 +169,34 @@ def _is_vector_instance_of(a, b): # Other must not be a BytesN if issubclass(b, bytes): return False - if not hasattr(b, 'elem_type') or not hasattr(b, 'length'): + elif not hasattr(b, 'elem_type') or not hasattr(b, 'length'): # Vector (b) is not an instance of Vector[X, Y] (a) return False - if not hasattr(a, 'elem_type') or not hasattr(a, 'length'): + elif not hasattr(a, 'elem_type') or not hasattr(a, 'length'): # Vector[X, Y] (b) is an instance of Vector (a) return True - - # Vector[X, Y] (a) is an instance of Vector[X, Y] (b) - return a.elem_type == b.elem_type and a.length == b.length + else: + # Vector[X, Y] (a) is an instance of Vector[X, Y] (b) + return a.elem_type == b.elem_type and a.length == b.length def _is_equal_vector_type(a, b): # Other must not be a BytesN if issubclass(b, bytes): return False - if not hasattr(a, 'elem_type') or not hasattr(a, 'length'): + elif not hasattr(a, 'elem_type') or not hasattr(a, 'length'): if not hasattr(b, 'elem_type') or not hasattr(b, 'length'): # Vector == Vector return True - # Vector != Vector[X, Y] - return False - if not hasattr(b, 'elem_type') or not hasattr(b, 'length'): + else: + # Vector != Vector[X, Y] + return False + elif not hasattr(b, 'elem_type') or not hasattr(b, 'length'): # Vector[X, Y] != Vector return False - # Vector[X, Y] == Vector[X, Y] - return a.elem_type == b.elem_type and a.length == b.length + else: + # Vector[X, Y] == Vector[X, Y] + return a.elem_type == b.elem_type and a.length == b.length class VectorMeta(type): @@ -233,7 +237,7 @@ class Vector(metaclass=VectorMeta): cls = self.__class__ if not hasattr(cls, 'elem_type'): raise TypeError("Type Vector without elem_type data cannot be instantiated") - if not hasattr(cls, 'length'): + elif not hasattr(cls, 'length'): raise TypeError("Type Vector without length data cannot be instantiated") if len(args) != cls.length: @@ -282,32 +286,34 @@ def _is_bytes_n_instance_of(a, b): # Other has to be a Bytes derivative class to be a BytesN if not issubclass(b, bytes): return False - if not hasattr(b, 'length'): + elif not hasattr(b, 'length'): # BytesN (b) is not an instance of BytesN[X] (a) return False - if not hasattr(a, 'length'): + elif not hasattr(a, 'length'): # BytesN[X] (b) is an instance of BytesN (a) return True - - # BytesN[X] (a) is an instance of BytesN[X] (b) - return a.length == b.length + else: + # BytesN[X] (a) is an instance of BytesN[X] (b) + return a.length == b.length def _is_equal_bytes_n_type(a, b): # Other has to be a Bytes derivative class to be a BytesN if not issubclass(b, bytes): return False - if not hasattr(a, 'length'): + elif not hasattr(a, 'length'): if not hasattr(b, 'length'): # BytesN == BytesN return True - # BytesN != BytesN[X] - return False - if not hasattr(b, 'length'): + else: + # BytesN != BytesN[X] + return False + elif not hasattr(b, 'length'): # BytesN[X] != BytesN return False - # BytesN[X] == BytesN[X] - return a.length == b.length + else: + # BytesN[X] == BytesN[X] + return a.length == b.length class BytesNMeta(type): @@ -341,14 +347,15 @@ class BytesNMeta(type): def parse_bytes(val): if val is None: return None - if isinstance(val, str): + elif isinstance(val, str): # TODO: import from eth-utils instead, and do: hexstr_if_str(to_bytes, val) return None - if isinstance(val, bytes): + elif isinstance(val, bytes): return val - if isinstance(val, int): + elif isinstance(val, int): return bytes([val]) - return None + else: + return None class BytesN(bytes, metaclass=BytesNMeta): @@ -433,6 +440,9 @@ def infer_input_type(fn): def is_bool_type(typ): + """ + Checks if the given type is a bool. + """ if hasattr(typ, '__supertype__'): typ = typ.__supertype__ return isinstance(typ, type) and issubclass(typ, bool) @@ -446,36 +456,45 @@ def is_list_type(typ): def is_bytes_type(typ): + """ + Check if the given type is a ``bytes``. + """ # Do not accept subclasses of bytes here, to avoid confusion with BytesN return typ == bytes +def is_bytesn_type(typ): + """ + Check if the given type is a BytesN. + """ + return isinstance(typ, type) and issubclass(typ, BytesN) + + def is_list_kind(typ): """ - Checks if the given type is a kind of list. Can be bytes. + Check if the given type is a kind of list. Can be bytes. """ return is_list_type(typ) or is_bytes_type(typ) def is_vector_type(typ): """ - Checks if the given type is a vector. + Check if the given type is a vector. """ return isinstance(typ, type) and issubclass(typ, Vector) -def is_bytesn_type(typ): - return isinstance(typ, type) and issubclass(typ, BytesN) - - def is_vector_kind(typ): """ - Checks if the given type is a kind of vector. Can be BytesN. + Check if the given type is a kind of vector. Can be BytesN. """ return is_vector_type(typ) or is_bytesn_type(typ) def is_container_type(typ): + """ + Check if the given type is a container. + """ return isinstance(typ, type) and issubclass(typ, Container)