Example #1
0
def generate_cache_key(value):
    """
    Generates a cache key for the *args and **kwargs
    """
    if is_bytes(value):
        return hashlib.md5(value).hexdigest()
    elif is_text(value):
        return generate_cache_key(to_bytes(text=value))
    elif is_boolean(value) or is_null(value) or is_number(value):
        return generate_cache_key(repr(value))
    elif is_dict(value):
        return generate_cache_key((
            (key, value[key])
            for key
            in sorted(value.keys())
        ))
    elif is_list_like(value) or isinstance(value, Generator):
        return generate_cache_key("".join((
            generate_cache_key(item)
            for item
            in value
        )))
    else:
        raise TypeError("Cannot generate cache key for value {0} of type {1}".format(
            value,
            type(value),
        ))
 def validate_value(cls, value):
     if not is_text(value):
         raise EncodingTypeError(
             "Value of type {} cannot be encoded by {}".format(
                 type(value),
                 cls.__name__,
             ))
Example #3
0
def find_matching_fn_abi(abi, fn_identifier=None, args=None, kwargs=None):
    args = args or tuple()
    kwargs = kwargs or dict()
    filters = []
    num_arguments = len(args) + len(kwargs)

    if fn_identifier is FallbackFn:
        return get_fallback_func_abi(abi)

    if not is_text(fn_identifier):
        raise TypeError("Unsupported function identifier")

    name_filter = functools.partial(filter_by_name, fn_identifier)
    arg_count_filter = functools.partial(filter_by_argument_count,
                                         num_arguments)
    encoding_filter = functools.partial(filter_by_encodability, args, kwargs)
    filters.extend([
        name_filter,
        arg_count_filter,
        encoding_filter,
    ])
    function_candidates = pipe(abi, *filters)
    if len(function_candidates) == 1:
        return function_candidates[0]
    else:
        matching_identifiers = name_filter(abi)
        matching_function_signatures = [
            abi_to_signature(func) for func in matching_identifiers
        ]
        arg_count_matches = len(arg_count_filter(matching_identifiers))
        encoding_matches = len(encoding_filter(matching_identifiers))
        if arg_count_matches == 0:
            diagnosis = "\nFunction invocation failed due to improper number of arguments."
        elif encoding_matches == 0:
            diagnosis = "\nFunction invocation failed due to no matching argument types."
        elif encoding_matches > 1:
            diagnosis = (
                "\nAmbiguous argument encoding. "
                "Provided arguments can be encoded to multiple functions matching this call."
            )
        message = (
            "\nCould not identify the intended function with name `{name}`, "
            "positional argument(s) of type `{arg_types}` and "
            "keyword argument(s) of type `{kwarg_types}`."
            "\nFound {num_candidates} function(s) with the name `{name}`: {candidates}"
            "{diagnosis}").format(
                name=fn_identifier,
                arg_types=tuple(map(type, args)),
                kwarg_types=valmap(type, kwargs),
                num_candidates=len(matching_identifiers),
                candidates=matching_function_signatures,
                diagnosis=diagnosis,
            )
        raise ValidationError(message)
Example #4
0
def is_predefined_block_number(value):
    if is_text(value):
        value_text = value
    elif is_bytes(value):
        # `value` could either be random bytes or the utf-8 encoding of
        # one of the words in: {"latest", "pending", "earliest"}
        # We cannot decode the bytes as utf8, because random bytes likely won't be valid.
        # So we speculatively decode as 'latin-1', which cannot fail.
        value_text = value.decode('latin-1')
    elif is_integer(value):
        return False
    else:
        raise TypeError("unrecognized block reference: %r" % value)

    return value_text in {"latest", "pending", "earliest"}
Example #5
0
def encode_transaction_data(web3,
                            fn_identifier,
                            contract_abi=None,
                            fn_abi=None,
                            vmtype=None,
                            args=None,
                            kwargs=None):
    if fn_identifier is FallbackFn:
        fn_abi, fn_selector, fn_arguments = get_fallback_function_info(
            contract_abi, fn_abi)
    elif is_text(fn_identifier):
        fn_abi, fn_selector, fn_arguments = get_function_info(
            fn_identifier,
            contract_abi,
            fn_abi,
            args,
            kwargs,
        )
    else:
        raise TypeError("Unsupported function identifier")

    return add_0x_prefix(
        encode_abi(web3, fn_abi, fn_arguments, vmtype, fn_selector,
                   contract_abi))