def find_matching_fn_abi(abi, abi_codec, fn_identifier=None, args=None, kwargs=None): args = args or tuple() kwargs = kwargs or dict() 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, abi_codec, args, kwargs) function_candidates = pipe(abi, name_filter, arg_count_filter, encoding_filter) 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 get_fallback_function_info( contract_abi: ABI=None, fn_abi: ABIFunction=None ) -> Tuple[ABIFunction, HexStr, Sequence[Any]]: if fn_abi is None: fn_abi = get_fallback_func_abi(contract_abi) fn_selector = encode_hex(b'') fn_arguments: Sequence[Any] = tuple() return fn_abi, fn_selector, fn_arguments
def find_matching_fn_abi( abi: ABI, abi_codec: ABICodec, fn_identifier: Optional[Union[str, Type[FallbackFn], Type[ReceiveFn]]] = None, args: Optional[Sequence[Any]] = None, kwargs: Optional[Any] = None, ) -> ABIFunction: args = args or tuple() kwargs = kwargs or dict() num_arguments = len(args) + len(kwargs) if fn_identifier is FallbackFn: return get_fallback_func_abi(abi) if fn_identifier is ReceiveFn: return get_receive_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, abi_codec, args, kwargs) function_candidates = pipe(abi, name_filter, arg_count_filter, encoding_filter) 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 = ( f"\nCould not identify the intended function with name `{fn_identifier}`, positional " f"argument(s) of type `{tuple(map(type, args))}` and keyword argument(s) of type " f"`{valmap(type, kwargs)}`.\nFound {len(matching_identifiers)} function(s) with " f"the name `{fn_identifier}`: {matching_function_signatures}{diagnosis}" ) raise ValidationError(message)
def get_fallback_function_info( contract_abi: Optional[ABI] = None, fn_abi: Optional[ABIFunction] = None ) -> Tuple[ABIFunction, HexStr, Tuple[Any, ...]]: if fn_abi is None: fn_abi = get_fallback_func_abi(contract_abi) fn_selector = encode_hex(b'') fn_arguments: Tuple[Any, ...] = tuple() return fn_abi, fn_selector, fn_arguments
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 get_fallback_function_info(contract_abi=None, fn_abi=None): if fn_abi is None: fn_abi = get_fallback_func_abi(contract_abi) fn_selector = encode_hex(b'') fn_arguments = tuple() return fn_abi, fn_selector, fn_arguments