diff --git a/web3/_utils/method_formatters.py b/web3/_utils/method_formatters.py index d66852ed9d..d42017b923 100644 --- a/web3/_utils/method_formatters.py +++ b/web3/_utils/method_formatters.py @@ -120,6 +120,8 @@ TValue = TypeVar("TValue") +CachedFormatters = Dict[RPCEndpoint, Callable[[RPCResponse], Any]] + def bytes_to_ascii(value: bytes) -> str: return codecs.decode(value, "ascii") @@ -1258,17 +1260,30 @@ def get_result_formatters( return compose(*partial_formatters, *formatters) +_error_formatters: CachedFormatters = {} + + def get_error_formatters(method_name: RPCEndpoint) -> Callable[[RPCResponse], Any]: # Note error formatters work on the full response dict - error_formatter_maps = (ERROR_FORMATTERS,) - formatters = combine_formatters(error_formatter_maps, method_name) + try: + return _error_formatters[method_name] + except KeyError: + formatters = _error_formatters[method_name] = compose( + *combine_formatters((ERROR_FORMATTERS,), method_name) + ) + return formatters - return compose(*formatters) + +_null_result_formatters: CachedFormatters = {} def get_null_result_formatters( method_name: RPCEndpoint, ) -> Callable[[RPCResponse], Any]: - formatters = combine_formatters((NULL_RESULT_FORMATTERS,), method_name) - - return compose(*formatters) + try: + return _null_result_formatters[method_name] + except KeyError: + formatters = _null_result_formatters[method_name] = compose( + *combine_formatters((NULL_RESULT_FORMATTERS,), method_name) + ) + return formatters