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__, ))
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)
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"}
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))