| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- import functools
- from .grammar import (
- BasicType,
- TupleType,
- normalize,
- parse,
- )
- def parse_type_str(expected_base=None, with_arrlist=False):
- """
- Used by BaseCoder subclasses as a convenience for implementing the
- ``from_type_str`` method required by ``ABIRegistry``. Useful if normalizing
- then parsing a type string with an (optional) expected base is required in
- that method.
- """
- def decorator(old_from_type_str):
- @functools.wraps(old_from_type_str)
- def new_from_type_str(cls, type_str, registry):
- normalized_type_str = normalize(type_str)
- abi_type = parse(normalized_type_str)
- type_str_repr = repr(type_str)
- if type_str != normalized_type_str:
- type_str_repr = "{} (normalized to {})".format(
- type_str_repr,
- repr(normalized_type_str),
- )
- if expected_base is not None:
- if not isinstance(abi_type, BasicType):
- raise ValueError(
- "Cannot create {} for non-basic type {}".format(
- cls.__name__,
- type_str_repr,
- )
- )
- if abi_type.base != expected_base:
- raise ValueError(
- "Cannot create {} for type {}: expected type with "
- "base '{}'".format(
- cls.__name__,
- type_str_repr,
- expected_base,
- )
- )
- if not with_arrlist and abi_type.arrlist is not None:
- raise ValueError(
- "Cannot create {} for type {}: expected type with "
- "no array dimension list".format(
- cls.__name__,
- type_str_repr,
- )
- )
- if with_arrlist and abi_type.arrlist is None:
- raise ValueError(
- "Cannot create {} for type {}: expected type with "
- "array dimension list".format(
- cls.__name__,
- type_str_repr,
- )
- )
- # Perform general validation of default solidity types
- abi_type.validate()
- return old_from_type_str(cls, abi_type, registry)
- return classmethod(new_from_type_str)
- return decorator
- def parse_tuple_type_str(old_from_type_str):
- """
- Used by BaseCoder subclasses as a convenience for implementing the
- ``from_type_str`` method required by ``ABIRegistry``. Useful if normalizing
- then parsing a tuple type string is required in that method.
- """
- @functools.wraps(old_from_type_str)
- def new_from_type_str(cls, type_str, registry):
- normalized_type_str = normalize(type_str)
- abi_type = parse(normalized_type_str)
- type_str_repr = repr(type_str)
- if type_str != normalized_type_str:
- type_str_repr = "{} (normalized to {})".format(
- type_str_repr,
- repr(normalized_type_str),
- )
- if not isinstance(abi_type, TupleType):
- raise ValueError(
- "Cannot create {} for non-tuple type {}".format(
- cls.__name__,
- type_str_repr,
- )
- )
- abi_type.validate()
- return old_from_type_str(cls, abi_type, registry)
- return classmethod(new_from_type_str)
- class BaseCoder:
- """
- Base class for all encoder and decoder classes.
- """
- is_dynamic = False
- def __init__(self, **kwargs):
- cls = type(self)
- # Ensure no unrecognized kwargs were given
- for key, value in kwargs.items():
- if not hasattr(cls, key):
- raise AttributeError(
- "Property {key} not found on {cls_name} class. "
- "`{cls_name}.__init__` only accepts keyword arguments which are "
- "present on the {cls_name} class.".format(
- key=key,
- cls_name=cls.__name__,
- )
- )
- setattr(self, key, value)
- # Validate given combination of kwargs
- self.validate()
- def validate(self):
- pass
- @classmethod
- def from_type_str(cls, type_str, registry): # pragma: no cover
- """
- Used by :any:`ABIRegistry` to get an appropriate encoder or decoder
- instance for the given type string and type registry.
- """
- raise NotImplementedError("Must implement `from_type_str`")
|