From 3907e1754acb2dc81892acbff7b21d9ee6ab7be7 Mon Sep 17 00:00:00 2001 From: kclowes Date: Fri, 28 Oct 2022 14:29:14 -0600 Subject: [PATCH 1/2] Support Python 3.11 --- .circleci/config.yml | 109 ++++++++++++++++++ ethpm/_utils/protobuf/ipfs_file_pb2.py | 27 ++--- newsfragments/2699.feature.rst | 1 + setup.py | 12 +- .../middleware/test_eth_tester_middleware.py | 5 +- tests/core/module-class/test_module.py | 1 + tests/ens/test_get_text.py | 8 +- tests/integration/test_ethereum_tester.py | 10 ++ tox.ini | 19 ++- web3/_utils/method_formatters.py | 2 +- web3/providers/eth_tester/defaults.py | 4 +- web3/providers/eth_tester/middleware.py | 4 + 12 files changed, 170 insertions(+), 32 deletions(-) create mode 100644 newsfragments/2699.feature.rst diff --git a/.circleci/config.yml b/.circleci/config.yml index 3897abb3eb..521592be00 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -615,6 +615,103 @@ jobs: environment: TOXENV: py310-wheel-cli + # + # Python 3.11 + # + py311-core: + <<: *common + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-core + + py311-ens: + <<: *common + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-ens + + py311-ethpm: + <<: *ethpm_steps + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-ethpm + # Please don't use this key for any shenanigans + WEB3_INFURA_PROJECT_ID: 7707850c2fb7465ebe6f150d67182e22 + + py311-integration-goethereum-ipc: + <<: *geth_steps + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-integration-goethereum-ipc + GETH_VERSION: v1.10.25 + + py311-integration-goethereum-ipc_flaky: + <<: *geth_steps + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-integration-goethereum-ipc_flaky + GETH_VERSION: v1.10.25 + + py311-integration-goethereum-http: + <<: *geth_steps + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-integration-goethereum-http + GETH_VERSION: v1.10.25 + + py311-integration-goethereum-http_async: + <<: *geth_steps + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-integration-goethereum-http_async + GETH_VERSION: v1.10.25 + + py311-integration-goethereum-http_flaky: + <<: *geth_steps + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-integration-goethereum-http_flaky + GETH_VERSION: v1.10.25 + + py311-integration-goethereum-ws: + <<: *geth_steps + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-integration-goethereum-ws + GETH_VERSION: v1.10.25 + + py311-integration-goethereum-ws_flaky: + <<: *geth_steps + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-integration-goethereum-ws_flaky + GETH_VERSION: v1.10.25 + + py311-integration-ethtester-pyevm: + <<: *common + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-integration-ethtester + ETHEREUM_TESTER_CHAIN_BACKEND: eth_tester.backends.PyEVMBackend + + py311-wheel-cli: + <<: *common + docker: + - image: cimg/python:3.11 + environment: + TOXENV: py311-wheel-cli + benchmark: <<: *geth_steps docker: @@ -632,6 +729,7 @@ workflows: - py38-core - py39-core - py310-core + - py311-core - lint - docs - benchmark @@ -680,3 +778,14 @@ workflows: - py310-integration-goethereum-ws_flaky - py310-integration-ethtester-pyevm - py310-wheel-cli + - py311-ens + - py311-ethpm + - py311-integration-goethereum-ipc + - py311-integration-goethereum-ipc_flaky + - py311-integration-goethereum-http + - py311-integration-goethereum-http_async + - py311-integration-goethereum-http_flaky + - py311-integration-goethereum-ws + - py311-integration-goethereum-ws_flaky + - py311-integration-ethtester-pyevm + - py311-wheel-cli diff --git a/ethpm/_utils/protobuf/ipfs_file_pb2.py b/ethpm/_utils/protobuf/ipfs_file_pb2.py index 0b7f80ae74..bc7659d4db 100644 --- a/ethpm/_utils/protobuf/ipfs_file_pb2.py +++ b/ethpm/_utils/protobuf/ipfs_file_pb2.py @@ -7,26 +7,27 @@ from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import symbol_database as _symbol_database + # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fipfs_file.proto\"\xc1\x01\n\x04\x44\x61ta\x12\x1c\n\x04Type\x18\x01 \x01(\x0e\x32\x0e.Data.DataType\x12\x11\n\x04\x44\x61ta\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x15\n\x08\x66ilesize\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x12\n\nblocksizes\x18\x04 \x03(\x04\"G\n\x08\x44\x61taType\x12\x07\n\x03Raw\x10\x00\x12\r\n\tDirectory\x10\x01\x12\x08\n\x04\x46ile\x10\x02\x12\x0c\n\x08Metadata\x10\x03\x12\x0b\n\x07Symlink\x10\x04\x42\x07\n\x05_DataB\x0b\n\t_filesize\"^\n\x06PBLink\x12\x11\n\x04Hash\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x11\n\x04Name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05Tsize\x18\x03 \x01(\x04H\x02\x88\x01\x01\x42\x07\n\x05_HashB\x07\n\x05_NameB\x08\n\x06_Tsize\"<\n\x06PBNode\x12\x16\n\x05Links\x18\x02 \x03(\x0b\x32\x07.PBLink\x12\x11\n\x04\x44\x61ta\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x07\n\x05_Datab\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x0fipfs_file.proto"\xc1\x01\n\x04\x44\x61ta\x12\x1c\n\x04Type\x18\x01 \x01(\x0e\x32\x0e.Data.DataType\x12\x11\n\x04\x44\x61ta\x18\x02 \x01(\x0cH\x00\x88\x01\x01\x12\x15\n\x08\x66ilesize\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x12\n\nblocksizes\x18\x04 \x03(\x04"G\n\x08\x44\x61taType\x12\x07\n\x03Raw\x10\x00\x12\r\n\tDirectory\x10\x01\x12\x08\n\x04\x46ile\x10\x02\x12\x0c\n\x08Metadata\x10\x03\x12\x0b\n\x07Symlink\x10\x04\x42\x07\n\x05_DataB\x0b\n\t_filesize"^\n\x06PBLink\x12\x11\n\x04Hash\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x12\x11\n\x04Name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x12\n\x05Tsize\x18\x03 \x01(\x04H\x02\x88\x01\x01\x42\x07\n\x05_HashB\x07\n\x05_NameB\x08\n\x06_Tsize"<\n\x06PBNode\x12\x16\n\x05Links\x18\x02 \x03(\x0b\x32\x07.PBLink\x12\x11\n\x04\x44\x61ta\x18\x01 \x01(\x0cH\x00\x88\x01\x01\x42\x07\n\x05_Datab\x06proto3' +) _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'ipfs_file_pb2', globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "ipfs_file_pb2", globals()) if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None - _DATA._serialized_start=20 - _DATA._serialized_end=213 - _DATA_DATATYPE._serialized_start=120 - _DATA_DATATYPE._serialized_end=191 - _PBLINK._serialized_start=215 - _PBLINK._serialized_end=309 - _PBNODE._serialized_start=311 - _PBNODE._serialized_end=371 + DESCRIPTOR._options = None + _DATA._serialized_start = 20 + _DATA._serialized_end = 213 + _DATA_DATATYPE._serialized_start = 120 + _DATA_DATATYPE._serialized_end = 191 + _PBLINK._serialized_start = 215 + _PBLINK._serialized_end = 309 + _PBNODE._serialized_start = 311 + _PBNODE._serialized_end = 371 # @@protoc_insertion_point(module_scope) diff --git a/newsfragments/2699.feature.rst b/newsfragments/2699.feature.rst new file mode 100644 index 0000000000..dd64d49299 --- /dev/null +++ b/newsfragments/2699.feature.rst @@ -0,0 +1 @@ +Support Python 3.11 diff --git a/setup.py b/setup.py index c533df0805..6211ee5685 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ extras_require = { "tester": [ - "eth-tester[py-evm]==v0.7.0-b.1", + "eth-tester[py-evm]==v0.8.0-b.3", "py-geth>=3.10.0", ], "linter": [ @@ -80,11 +80,12 @@ include_package_data=True, install_requires=[ "aiohttp>=3.7.4.post0", - "eth-abi>=3.0.0", - "eth-account>=0.7.0", - "eth-hash[pycryptodome]>=0.2.0", + "eth-abi>=4.0.0-b.2", + "parsimonious==0.9.0", # TODO - fix in eth-abi + "eth-account>=0.8.0", + "eth-hash[pycryptodome]>=0.5.1", "eth-typing>=3.0.0", - "eth-utils>=2.0.0", + "eth-utils>=2.1.0", "hexbytes>=0.1.0", "jsonschema>=4.0.0", "lru-dict>=1.1.6", @@ -114,5 +115,6 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", ], ) diff --git a/tests/core/middleware/test_eth_tester_middleware.py b/tests/core/middleware/test_eth_tester_middleware.py index 44e3e68189..8fd70e8e58 100644 --- a/tests/core/middleware/test_eth_tester_middleware.py +++ b/tests/core/middleware/test_eth_tester_middleware.py @@ -32,8 +32,9 @@ def test_get_block_formatters(w3): latest_block_keys = set(latest_block.keys()) keys_diff = all_block_keys.difference(latest_block_keys) - assert len(keys_diff) == 1 - assert keys_diff.pop() == "mixHash" # mixHash is not implemented in eth-tester + assert len(keys_diff) == 2 + # mixHash and miner not implemented in eth-tester + assert keys_diff == set(["mixHash", "miner"]) @pytest.mark.parametrize( diff --git a/tests/core/module-class/test_module.py b/tests/core/module-class/test_module.py index fa73c66642..cbe9cfb17b 100644 --- a/tests/core/module-class/test_module.py +++ b/tests/core/module-class/test_module.py @@ -86,6 +86,7 @@ def test_attach_methods_with_mungers(web3_with_external_modules): } ) + w3.provider.ethereum_tester.mine_block() assert w3.eth.get_block(0, False)["baseFeePerGas"] == 1000000000 assert w3.eth.get_block(1, False)["baseFeePerGas"] == 875000000 diff --git a/tests/ens/test_get_text.py b/tests/ens/test_get_text.py index 3b7b6b1403..fc81f6a8ec 100644 --- a/tests/ens/test_get_text.py +++ b/tests/ens/test_get_text.py @@ -1,7 +1,7 @@ import pytest -from eth_tester.exceptions import ( - TransactionFailed, +from eth_utils.exceptions import ( + ValidationError, ) from ens.exceptions import ( @@ -29,7 +29,7 @@ def test_set_text_fails_with_bad_address(ens): address = ens.w3.eth.accounts[2] ens.setup_address("tester.eth", address) zero_address = "0x" + "00" * 20 - with pytest.raises(TransactionFailed): + with pytest.raises(ValidationError): ens.set_text( "tester.eth", "url", "http://example.com", transact={"from": zero_address} ) @@ -97,7 +97,7 @@ async def test_async_set_text_fails_with_bad_address(async_ens): address = accounts[2] await async_ens.setup_address("tester.eth", address) zero_address = "0x" + "00" * 20 - with pytest.raises(TransactionFailed): + with pytest.raises(ValidationError): await async_ens.set_text( "tester.eth", "url", "http://example.com", transact={"from": zero_address} ) diff --git a/tests/integration/test_ethereum_tester.py b/tests/integration/test_ethereum_tester.py index d3bd54874e..e22c9e1b4a 100644 --- a/tests/integration/test_ethereum_tester.py +++ b/tests/integration/test_ethereum_tester.py @@ -568,6 +568,16 @@ def test_eth_send_transaction_no_gas(self, eth_tester, w3, unlocked_account): def test_eth_send_transaction_no_max_fee(self, eth_tester, w3, unlocked_account): super().test_eth_send_transaction_no_max_fee(w3, unlocked_account) + def test_eth_getBlockByNumber_safe( + self, w3: "Web3", empty_block: BlockData + ) -> None: + super().test_eth_getBlockByNumber_safe(w3, empty_block) + + def test_eth_getBlockByNumber_finalized( + self, w3: "Web3", empty_block: BlockData + ) -> None: + super().test_eth_getBlockByNumber_finalized(w3, empty_block) + class TestEthereumTesterNetModule(NetModuleTest): pass diff --git a/tox.ini b/tox.ini index 20df6a0b8d..975a6d0f27 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,13 @@ [tox] envlist= - py{37,38,39,310}-ens - py{37,38,39,310}-ethpm - py{37,38,39,310}-core - py{37,38,39,310}-integration-{goethereum,ethtester} + py{37,38,39,310,311}-ens + py{37,38,39,310,311}-ethpm + py{37,38,39,310,311}-core + py{37,38,39,310,311}-integration-{goethereum,ethtester} lint docs benchmark - py{37,38,39,310}-wheel-cli + py{37,38,39,310,311}-wheel-cli [isort] combine_as_imports=True @@ -28,7 +28,7 @@ extend-ignore=E203,W503 [testenv] allowlist_externals=/usr/bin/make -install_command=python -m pip install --no-use-pep517 {opts} {packages} +install_command=python -m pip install {opts} {packages} usedevelop=True commands= core: pytest {posargs:tests/core} @@ -58,6 +58,7 @@ basepython = py38: python3.8 py39: python3.9 py310: python3.10 + py311: python3.11 [testenv:lint] basepython=python @@ -111,6 +112,12 @@ allowlist_externals={[common-wheel-cli]allowlist_externals} commands={[common-wheel-cli]commands} skip_install=true +[testenv:py311-wheel-cli] +deps={[common-wheel-cli]deps} +allowlist_externals={[common-wheel-cli]allowlist_externals} +commands={[common-wheel-cli]commands} +skip_install=true + [common-wheel-cli-windows] deps=wheel allowlist_externals= diff --git a/web3/_utils/method_formatters.py b/web3/_utils/method_formatters.py index 368a9d4f60..9c48a8a416 100644 --- a/web3/_utils/method_formatters.py +++ b/web3/_utils/method_formatters.py @@ -629,7 +629,7 @@ def raise_contract_logic_error_on_revert(response: RPCResponse) -> RPCResponse: if data[:10] == "0x556f1830": parsed_data_as_bytes = to_bytes(hexstr=data[10:]) abi_decoded_data = abi.decode( - OFFCHAIN_LOOKUP_FIELDS.values(), parsed_data_as_bytes + list(OFFCHAIN_LOOKUP_FIELDS.values()), parsed_data_as_bytes ) offchain_lookup_payload = dict( zip(OFFCHAIN_LOOKUP_FIELDS.keys(), abi_decoded_data) diff --git a/web3/providers/eth_tester/defaults.py b/web3/providers/eth_tester/defaults.py index 3a4d9f5598..955b72d1ab 100644 --- a/web3/providers/eth_tester/defaults.py +++ b/web3/providers/eth_tester/defaults.py @@ -89,7 +89,9 @@ def call_eth_tester( data_payload = parsed_data_as_bytes[ 4: ] # everything but the function selector - abi_decoded_data = abi.decode(OFFCHAIN_LOOKUP_FIELDS.values(), data_payload) + abi_decoded_data = abi.decode( + list(OFFCHAIN_LOOKUP_FIELDS.values()), data_payload + ) offchain_lookup_payload = dict( zip(OFFCHAIN_LOOKUP_FIELDS.keys(), abi_decoded_data) ) diff --git a/web3/providers/eth_tester/middleware.py b/web3/providers/eth_tester/middleware.py index 28b5baec9f..c30c22c896 100644 --- a/web3/providers/eth_tester/middleware.py +++ b/web3/providers/eth_tester/middleware.py @@ -186,6 +186,10 @@ def is_hexstr(value: Any) -> bool: "extra_data": "extraData", "gas_used": "gasUsed", "base_fee_per_gas": "baseFeePerGas", + # eth-tester changed the miner key to coinbase since + # there is no longer any mining happening, but the current + # JSON-RPC spec still says miner + "coinbase": "miner", } block_result_remapper = apply_key_map(BLOCK_RESULT_KEY_MAPPING) From 4aac916b543cad9f7fbdfcfb2a187b1ea0624cfa Mon Sep 17 00:00:00 2001 From: kclowes Date: Fri, 16 Dec 2022 14:07:52 -0700 Subject: [PATCH 2/2] Add mix_hash to the BLOCK_RESULTS_KEY_MAPPING from eth-tester --- tests/core/middleware/test_eth_tester_middleware.py | 5 +---- web3/providers/eth_tester/middleware.py | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/core/middleware/test_eth_tester_middleware.py b/tests/core/middleware/test_eth_tester_middleware.py index 8fd70e8e58..508be3a21c 100644 --- a/tests/core/middleware/test_eth_tester_middleware.py +++ b/tests/core/middleware/test_eth_tester_middleware.py @@ -31,10 +31,7 @@ def test_get_block_formatters(w3): all_block_keys = set(BlockData.__annotations__.keys()) latest_block_keys = set(latest_block.keys()) - keys_diff = all_block_keys.difference(latest_block_keys) - assert len(keys_diff) == 2 - # mixHash and miner not implemented in eth-tester - assert keys_diff == set(["mixHash", "miner"]) + assert all_block_keys == latest_block_keys @pytest.mark.parametrize( diff --git a/web3/providers/eth_tester/middleware.py b/web3/providers/eth_tester/middleware.py index c30c22c896..ee21b826f9 100644 --- a/web3/providers/eth_tester/middleware.py +++ b/web3/providers/eth_tester/middleware.py @@ -186,6 +186,7 @@ def is_hexstr(value: Any) -> bool: "extra_data": "extraData", "gas_used": "gasUsed", "base_fee_per_gas": "baseFeePerGas", + "mix_hash": "mixHash", # eth-tester changed the miner key to coinbase since # there is no longer any mining happening, but the current # JSON-RPC spec still says miner