Skip to content

Commit

Permalink
Cleanup, update documentation (#1461)
Browse files Browse the repository at this point in the history
  • Loading branch information
kclowes committed Nov 13, 2019
1 parent cea24ed commit 71ba5f1
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 71 deletions.
1 change: 1 addition & 0 deletions newsfragments/1461.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Pull formatting methods out of middleware
62 changes: 42 additions & 20 deletions tests/core/method-class/test_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_method_accepts_callable_for_selector():

def test_method_selector_fn_accepts_str():
method = Method(
mungers=[],
mungers=None,
json_rpc_method='eth_method',
)
assert method.method_selector_fn() == 'eth_method'
Expand Down Expand Up @@ -68,8 +68,8 @@ def test_get_formatters_non_falsy_config_retrieval():
method_name = method.method_selector_fn()
first_formatter = (method.request_formatters(method_name).first,)
all_other_formatters = method.request_formatters(method_name).funcs
# eth_getBalance goes through an ABI formatter and a pythonic formatter
assert len(first_formatter + all_other_formatters) == 2
# assert method.request_formatters('eth_nonmatching') == 'nonmatch'


def test_input_munger_parameter_passthrough_matching_arity():
Expand Down Expand Up @@ -107,15 +107,16 @@ def test_default_input_munger_with_input_parameters_exception():


@pytest.mark.parametrize(
"method_config,args,kwargs,expected_result",
"method_config,args,kwargs,expected_request_result,expected_result_formatters_len",
(
(
{
'mungers': [],
},
[],
{},
ValueError
ValueError,
2
),
(
{
Expand All @@ -124,7 +125,8 @@ def test_default_input_munger_with_input_parameters_exception():
},
['unexpected_argument'],
{},
TypeError
TypeError,
2
),
(
{
Expand All @@ -133,7 +135,8 @@ def test_default_input_munger_with_input_parameters_exception():
},
['0x0000000000000000000000000000000000000000', 3],
{},
('eth_getBalance', (('0x' + '00' * 20), "0x3"))
('eth_getBalance', (('0x' + '00' * 20), "0x3")),
2
),
(
{
Expand All @@ -142,7 +145,8 @@ def test_default_input_munger_with_input_parameters_exception():
},
['0x0000000000000000000000000000000000000000', 3],
{},
('eth_getBalance', (('0x' + '00' * 20), "0x3"))
('eth_getBalance', (('0x' + '00' * 20), "0x3")),
2
),
(
{
Expand All @@ -154,7 +158,8 @@ def test_default_input_munger_with_input_parameters_exception():
},
[1, 2, 3, ('0x' + '00' * 20)],
{},
('eth_getBalance', (('0x' + '00' * 20), "1"))
('eth_getBalance', (('0x' + '00' * 20), "1")),
2,
),
(
{
Expand All @@ -167,6 +172,7 @@ def test_default_input_munger_with_input_parameters_exception():
[1, 2, 3, 4],
{},
TypeError,
2,
),
(
{
Expand All @@ -175,7 +181,8 @@ def test_default_input_munger_with_input_parameters_exception():
},
('0x0000000000000000000000000000000000000000', 3),
{},
('eth_getBalance', ('0x0000000000000000000000000000000000000000', '0x3'))
('eth_getBalance', ('0x0000000000000000000000000000000000000000', '0x3')),
2,
),
(
{
Expand All @@ -187,7 +194,18 @@ def test_default_input_munger_with_input_parameters_exception():
},
[('0x' + '00' * 20), 1, 2, 3],
{},
('eth_getBalance', (('0x' + '00' * 20), '1'))
('eth_getBalance', (('0x' + '00' * 20), '1')),
2,
),
(
{
'mungers': None,
'json_rpc_method': 'eth_chainId',
},
[],
{},
('eth_chainId', ()),
2,
)
),
ids=[
Expand All @@ -199,22 +217,27 @@ def test_default_input_munger_with_input_parameters_exception():
'test-munger-wrong-length-arg',
'test-request-formatters',
'test-mungers-and-request-formatters',
'test-response-formatters',
]
)
def test_process_params(
method_config,
args,
kwargs,
expected_result,):
expected_request_result,
expected_result_formatters_len):

if isclass(expected_result) and issubclass(expected_result, Exception):
with pytest.raises(expected_result):
if isclass(expected_request_result) and issubclass(expected_request_result, Exception):
with pytest.raises(expected_request_result):
method = Method(**method_config)
req_params, output_formatter = method.process_params(object(), *args, **kwargs)
request_params, output_formatter = method.process_params(object(), *args, **kwargs)
else:
method = Method(**method_config)
req_params, output_formatter = method.process_params(object(), *args, **kwargs)
assert req_params == expected_result
request_params, output_formatter = method.process_params(object(), *args, **kwargs)
assert request_params == expected_request_result
first_formatter = (output_formatter[0].first,)
all_other_formatters = output_formatter[0].funcs
assert len(first_formatter + all_other_formatters) == expected_result_formatters_len


def keywords(module, keyword_one, keyword_two):
Expand All @@ -233,7 +256,7 @@ def formatter(params):

class FakeModule(ModuleV2):
method = Method(
'eth_getBalance',
'eth_method',
mungers=[keywords],
request_formatters=return_exception_raising_formatter)

Expand All @@ -252,8 +275,7 @@ def test_munger_class_method_access_raises_friendly_error():


def test_munger_arguments_by_keyword(dummy_w3):
addr = '0x' + '00' * 20
with pytest.raises(Success):
dummy_w3.fake.method(addr, keyword_two='latest')
dummy_w3.fake.method(keyword_one=1, keyword_two='latest')
with pytest.raises(Success):
dummy_w3.fake.method(addr, 'latest')
dummy_w3.fake.method(1, keyword_two=2)
2 changes: 1 addition & 1 deletion tests/core/version-module/test_version_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ async def test_async_blocking_version(async_w3, blocking_w3):
assert async_w3.async_version.api == blocking_w3.api

assert await async_w3.async_version.node == blocking_w3.clientVersion
assert await async_w3.async_version.ethereum == int(blocking_w3.eth.protocolVersion)
assert await async_w3.async_version.ethereum == blocking_w3.eth.protocolVersion
76 changes: 40 additions & 36 deletions web3/_utils/method_formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
import operator

from eth_utils.curried import (
apply_formatter_at_index,
apply_formatter_if,
apply_formatter_to_array,
apply_formatters_to_dict,
apply_formatters_to_sequence,
apply_one_of_formatters,
is_address,
is_bytes,
is_dict,
Expand All @@ -12,6 +17,7 @@
remove_0x_prefix,
text_if_str,
to_checksum_address,
to_list,
to_tuple,
)
from eth_utils.toolz import (
Expand All @@ -33,11 +39,6 @@
to_hex,
)
from web3._utils.formatters import (
apply_formatter_at_index,
apply_formatter_if,
apply_formatter_to_array,
apply_formatters_to_dict,
apply_one_of_formatters,
hex_to_integer,
integer_to_hex,
is_array_of_dicts,
Expand Down Expand Up @@ -137,14 +138,18 @@ def is_attrdict(val):
whisper_log_formatter = apply_formatters_to_dict(WHISPER_LOG_FORMATTERS)


def apply_list_to_array_formatter(formatter):
return to_list(apply_formatter_to_array(formatter))


LOG_ENTRY_FORMATTERS = {
'blockHash': apply_formatter_if(is_not_null, to_hexbytes(32)),
'blockNumber': apply_formatter_if(is_not_null, to_integer_if_hex),
'transactionIndex': apply_formatter_if(is_not_null, to_integer_if_hex),
'transactionHash': apply_formatter_if(is_not_null, to_hexbytes(32)),
'logIndex': to_integer_if_hex,
'address': to_checksum_address,
'topics': apply_formatter_to_array(to_hexbytes(32)),
'topics': apply_list_to_array_formatter(to_hexbytes(32)),
'data': to_ascii_if_bytes,
}

Expand All @@ -161,7 +166,7 @@ def is_attrdict(val):
'status': to_integer_if_hex,
'gasUsed': to_integer_if_hex,
'contractAddress': apply_formatter_if(is_not_null, to_checksum_address),
'logs': apply_formatter_to_array(log_entry_formatter),
'logs': apply_list_to_array_formatter(log_entry_formatter),
'logsBloom': to_hexbytes(256),
}

Expand All @@ -182,14 +187,14 @@ def is_attrdict(val):
'number': apply_formatter_if(is_not_null, to_integer_if_hex),
'parentHash': apply_formatter_if(is_not_null, to_hexbytes(32)),
'sha3Uncles': apply_formatter_if(is_not_null, to_hexbytes(32)),
'uncles': apply_formatter_to_array(to_hexbytes(32)),
'uncles': apply_list_to_array_formatter(to_hexbytes(32)),
'difficulty': to_integer_if_hex,
'receiptsRoot': to_hexbytes(32),
'stateRoot': to_hexbytes(32),
'totalDifficulty': to_integer_if_hex,
'transactions': apply_one_of_formatters((
(apply_formatter_to_array(transaction_formatter), is_array_of_dicts),
(apply_formatter_to_array(to_hexbytes(32)), is_array_of_strings),
(is_array_of_dicts, apply_list_to_array_formatter(transaction_formatter)),
(is_array_of_strings, apply_list_to_array_formatter(to_hexbytes(32))),
)),
'transactionsRoot': to_hexbytes(32),
}
Expand Down Expand Up @@ -240,17 +245,19 @@ def is_attrdict(val):
STORAGE_PROOF_FORMATTERS = {
'key': HexBytes,
'value': HexBytes,
'proof': apply_formatter_to_array(HexBytes),
'proof': apply_list_to_array_formatter(HexBytes),
}

ACCOUNT_PROOF_FORMATTERS = {
'address': to_checksum_address,
'accountProof': apply_formatter_to_array(HexBytes),
'accountProof': apply_list_to_array_formatter(HexBytes),
'balance': to_integer_if_hex,
'codeHash': to_hexbytes(32),
'nonce': to_integer_if_hex,
'storageHash': to_hexbytes(32),
'storageProof': apply_formatter_to_array(apply_formatters_to_dict(STORAGE_PROOF_FORMATTERS))
'storageProof': apply_list_to_array_formatter(
apply_formatters_to_dict(STORAGE_PROOF_FORMATTERS)
)
}

proof_formatter = apply_formatters_to_dict(ACCOUNT_PROOF_FORMATTERS)
Expand All @@ -265,8 +272,8 @@ def is_attrdict(val):


filter_result_formatter = apply_one_of_formatters((
(apply_formatter_to_array(log_entry_formatter), is_array_of_dicts),
(apply_formatter_to_array(to_hexbytes(32)), is_array_of_strings),
(is_array_of_dicts, apply_list_to_array_formatter(log_entry_formatter)),
(is_array_of_strings, apply_list_to_array_formatter(to_hexbytes(32))),
))


Expand All @@ -289,7 +296,8 @@ def is_attrdict(val):
signed_tx_formatter = apply_formatters_to_dict(SIGNED_TX_FORMATTER)

FILTER_PARAM_NORMALIZERS = apply_formatters_to_dict({
'address': apply_formatter_if(is_string, lambda x: [x])})
'address': apply_formatter_if(is_string, lambda x: [x])
})

PYTHONIC_REQUEST_FORMATTERS = {
# Eth
Expand All @@ -312,21 +320,15 @@ def is_attrdict(val):
apply_formatter_at_index(integer_to_hex, 1),
),
'eth_getUncleByBlockHashAndIndex': apply_formatter_at_index(integer_to_hex, 1),
'eth_newFilter': compose(
apply_formatter_at_index(FILTER_PARAM_NORMALIZERS, 0),
apply_formatter_at_index(filter_params_formatter, 0),
),
'eth_getLogs': compose(
apply_formatter_at_index(FILTER_PARAM_NORMALIZERS, 0),
apply_formatter_at_index(filter_params_formatter, 0),
),
'eth_newFilter': apply_formatter_at_index(filter_params_formatter, 0),
'eth_getLogs': apply_formatter_at_index(filter_params_formatter, 0),
'eth_call': apply_formatters_to_sequence([
transaction_param_formatter,
block_number_formatter,
]),
'eth_estimateGas': apply_one_of_formatters((
(estimate_gas_without_block_id, is_length(1)),
(estimate_gas_with_block_id, is_length(2)),
(is_length(1), estimate_gas_without_block_id),
(is_length(2), estimate_gas_with_block_id),
)),
'eth_sendTransaction': apply_formatter_at_index(transaction_param_formatter, 0),
'eth_getProof': apply_formatter_at_index(block_number_formatter, 2),
Expand All @@ -351,7 +353,7 @@ def is_attrdict(val):

PYTHONIC_RESULT_FORMATTERS = {
# Eth
'eth_accounts': apply_formatter_to_array(to_checksum_address),
'eth_accounts': apply_list_to_array_formatter(to_checksum_address),
'eth_blockNumber': to_integer_if_hex,
'eth_chainId': to_integer_if_hex,
'eth_coinbase': to_checksum_address,
Expand Down Expand Up @@ -397,12 +399,12 @@ def is_attrdict(val):
'eth_syncing': apply_formatter_if(is_not_false, syncing_formatter),
# personal
'personal_importRawKey': to_checksum_address,
'personal_listAccounts': apply_formatter_to_array(to_checksum_address),
'personal_listAccounts': apply_list_to_array_formatter(to_checksum_address),
'personal_newAccount': to_checksum_address,
'personal_sendTransaction': to_hexbytes(32),
'personal_signTypedData': HexBytes,
# SHH
'shh_getFilterMessages': apply_formatter_to_array(whisper_log_formatter),
'shh_getFilterMessages': apply_list_to_array_formatter(whisper_log_formatter),
# Transaction Pool
'txpool_content': transaction_pool_content_formatter,
'txpool_inspect': transaction_pool_inspect_formatter,
Expand Down Expand Up @@ -441,24 +443,26 @@ def combine_formatters(formatter_maps, method_name):


def get_request_formatters(method_name):
# TODO - test if this needs to be reversed
# ex: compose(reverse(*formatters))
request_formatter_maps = (PYTHONIC_REQUEST_FORMATTERS, ABI_REQUEST_FORMATTERS)
request_formatter_maps = (
METHOD_NORMALIZERS,
PYTHONIC_REQUEST_FORMATTERS,
ABI_REQUEST_FORMATTERS
)
formatters = combine_formatters(request_formatter_maps, method_name)
return compose(*formatters)


def get_result_formatters(method_name):
formatters = combine_formatters((PYTHONIC_RESULT_FORMATTERS,), method_name)
formatters = combine_formatters(
(PYTHONIC_RESULT_FORMATTERS,),
method_name
)
attrdict_formatter = apply_formatter_if(is_dict and not_attrdict, AttributeDict.recursive)

return compose(*formatters, attrdict_formatter)


def get_error_formatters(method_name):
# Note error formatters work on the full response dict
# TODO - test this function
error_formatter_maps = ()
formatters = combine_formatters(error_formatter_maps, method_name)

return compose(*formatters)
Loading

0 comments on commit 71ba5f1

Please sign in to comment.