Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode tuples per abi #2799

Merged
merged 35 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
feb002b
tuple contract tests and fixtures added
Jan 27, 2023
63c1184
add abi utils and tests, start typing
Jan 27, 2023
86bd159
finished typing
Jan 27, 2023
bd43a73
add _utils/contracts.py
Jan 27, 2023
7643135
add decode_tuples flag to base_contract
Jan 27, 2023
528ee01
all contract changes added
Jan 27, 2023
053ae6e
remove change to decode_function_input to a separate pr
Jan 27, 2023
9e94690
work on typing
Jan 27, 2023
6a0fafa
wip
Jan 31, 2023
fa49d6c
catch mismatched abi data and test for namedtuple rename
pacrob Jan 31, 2023
8b09a3f
remove todo note
pacrob Jan 31, 2023
2b735fc
first draft docs update
pacrob Feb 1, 2023
dce816f
change decode_tuples default from None to False, fix docs typos
Feb 2, 2023
dd8212c
typing fix
Feb 6, 2023
a323c0d
refactor creation of abidecodednamedtuple
Feb 6, 2023
90e06da
fix test
Feb 6, 2023
6dd9a32
cherry-pick original commit
banteg May 13, 2019
1016e8a
cherry-pick original commits
banteg May 15, 2019
2dc9208
improve contract_call_interface tests
Feb 6, 2023
3565f7d
move tuple contract fixtures up to conftest
Feb 7, 2023
48987c4
wip
Feb 8, 2023
c6800e6
contract caller tests added and passing
pacrob Feb 8, 2023
3ce29f8
correct ContractFunction call args
pacrob Feb 8, 2023
ee8fd8e
call and caller tests passing
pacrob Feb 9, 2023
6548f7e
remove some unused params
Feb 9, 2023
77748f5
dedup test params
Feb 9, 2023
623a230
add newsfragment
Feb 9, 2023
0f24eb8
wip
Feb 10, 2023
6286941
abi decoding tests pass
Feb 10, 2023
757f4c3
typing and linting
Feb 10, 2023
a34923e
test updates
Feb 10, 2023
8a443af
typing
Feb 10, 2023
b01cd33
clean up typing per comments
Feb 11, 2023
d664e6c
typing in abi.py
Feb 13, 2023
f555e68
lowercase web3 please
Feb 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/web3.contract.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,29 @@ Each Contract Factory exposes the following properties.
The runtime part of the contract bytecode string. May be ``None`` if not
provided during factory creation.


.. py:attribute:: Contract.decode_tuples

If a Tuple/Struct is returned by a contract function, this flag defines whether
to apply the field names from the ABI to the returned data.
If False, the returned value will be a normal Python `Tuple`. If True, the returned
value will be a Python `NamedTuple` of the class `ABIDecodedNamedTuple`.

NamedTuples have some restrictions regarding field names.
web3.py sets `NamedTuple`'s `rename=True`, so disallowed field names may be
different than expected. See the [Python docs](https://docs.python.org/3/library/collections.html#collections.namedtuple)
for more information.

Defaults to ``False`` if not provided during factory creation.


.. py:attribute:: Contract.functions

This provides access to contract functions as attributes. For example:
``myContract.functions.MyMethod()``. The exposed contract functions are classes of the
type :py:class:`ContractFunction`.


.. py:attribute:: Contract.events

This provides access to contract events as attributes. For example:
Expand Down
1 change: 1 addition & 0 deletions docs/web3.eth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,7 @@ Contracts
- ``bytecode_runtime``
- ``clone_bin``
- ``dev_doc``
- ``decode_tuples``
- ``interface``
- ``metadata``
- ``opcodes``
Expand Down
1 change: 1 addition & 0 deletions newsfragments/2799.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add decode_tuples option to contract instantiation
82 changes: 82 additions & 0 deletions tests/core/contracts/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
from web3._utils.contract_sources.contract_data.string_contract import (
STRING_CONTRACT_DATA,
)
from web3._utils.contract_sources.contract_data.tuple_contracts import (
NESTED_TUPLE_CONTRACT_DATA,
TUPLE_CONTRACT_DATA,
)


@pytest.fixture(scope="session")
Expand Down Expand Up @@ -340,6 +344,44 @@ def revert_contract(w3, address_conversion_func):
return deploy(w3, revert_contract_factory, address_conversion_func)


@pytest.fixture
def tuple_contract(w3, address_conversion_func):
tuple_contract_factory = w3.eth.contract(**TUPLE_CONTRACT_DATA)
return deploy(w3, tuple_contract_factory, address_conversion_func)


@pytest.fixture
def nested_tuple_contract(w3, address_conversion_func):
nested_tuple_contract_factory = w3.eth.contract(**NESTED_TUPLE_CONTRACT_DATA)
return deploy(w3, nested_tuple_contract_factory, address_conversion_func)


TUPLE_CONTRACT_DATA_DECODE_TUPLES = {
**TUPLE_CONTRACT_DATA,
"decode_tuples": True,
}


NESTED_TUPLE_CONTRACT_DATA_DECODE_TUPLES = {
**NESTED_TUPLE_CONTRACT_DATA,
"decode_tuples": True,
}


@pytest.fixture
def tuple_contract_with_decode_tuples(w3, address_conversion_func):
tuple_contract_factory = w3.eth.contract(**TUPLE_CONTRACT_DATA_DECODE_TUPLES)
return deploy(w3, tuple_contract_factory, address_conversion_func)


@pytest.fixture
def nested_tuple_contract_with_decode_tuples(w3, address_conversion_func):
nested_tuple_contract_factory = w3.eth.contract(
**NESTED_TUPLE_CONTRACT_DATA_DECODE_TUPLES
)
return deploy(w3, nested_tuple_contract_factory, address_conversion_func)


@pytest.fixture
def some_address(address_conversion_func):
return address_conversion_func("0x5B2063246F2191f18F2675ceDB8b28102e957458")
Expand Down Expand Up @@ -563,6 +605,46 @@ async def async_revert_contract(async_w3, address_conversion_func):
)


@pytest_asyncio.fixture
async def async_tuple_contract(async_w3, address_conversion_func):
async_tuple_contract_factory = async_w3.eth.contract(**TUPLE_CONTRACT_DATA)
return await async_deploy(
async_w3, async_tuple_contract_factory, address_conversion_func
)


@pytest_asyncio.fixture
async def async_nested_tuple_contract(async_w3, address_conversion_func):
async_nested_tuple_contract_factory = async_w3.eth.contract(
**NESTED_TUPLE_CONTRACT_DATA
)
return await async_deploy(
async_w3, async_nested_tuple_contract_factory, address_conversion_func
)


@pytest_asyncio.fixture
async def async_tuple_contract_with_decode_tuples(async_w3, address_conversion_func):
async_tuple_contract_factory = async_w3.eth.contract(
**TUPLE_CONTRACT_DATA_DECODE_TUPLES
)
return await async_deploy(
async_w3, async_tuple_contract_factory, address_conversion_func
)


@pytest_asyncio.fixture
async def async_nested_tuple_contract_with_decode_tuples(
async_w3, address_conversion_func
):
async_nested_tuple_contract_factory = async_w3.eth.contract(
**NESTED_TUPLE_CONTRACT_DATA_DECODE_TUPLES
)
return await async_deploy(
async_w3, async_nested_tuple_contract_factory, address_conversion_func
)


async def async_invoke_contract(
api_call_desig="call",
contract=None,
Expand Down
Loading