diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5403b0f47..fd12096b9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,11 +43,14 @@ repos: - id: mdformat additional_dependencies: - mdformat-gfm -- repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.5.1 +- repo: local hooks: - - id: mypy - files: eth/ + - id: mypy-local + name: run mypy with all dev dependencies present + entry: python -m mypy -p eth + language: system + always_run: true + pass_filenames: false - repo: https://github.com/PrincetonUniversity/blocklint rev: v0.2.5 hooks: diff --git a/.readthedocs.yaml b/.readthedocs.yaml index e72927c2a..73d5ae7d4 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -15,6 +15,7 @@ python: path: . extra_requirements: - docs + - test # Build all formats for RTD Downloads - htmlzip, pdf, epub formats: all diff --git a/eth/consensus/clique/_utils.py b/eth/consensus/clique/_utils.py index 0947784d4..269e857f5 100644 --- a/eth/consensus/clique/_utils.py +++ b/eth/consensus/clique/_utils.py @@ -1,5 +1,6 @@ from typing import ( Iterable, + cast, ) from eth_keys import ( @@ -91,9 +92,12 @@ def get_block_signer(header: BlockHeaderAPI) -> Address: signature = keys.Signature(signature_bytes=signature_bytes) - return signature.recover_public_key_from_msg_hash( - signature_hash - ).to_canonical_address() + return cast( + Address, + signature.recover_public_key_from_msg_hash( + signature_hash + ).to_canonical_address(), + ) def is_in_turn(signer: Address, snapshot: Snapshot, header: BlockHeaderAPI) -> bool: diff --git a/eth/consensus/clique/snapshot_manager.py b/eth/consensus/clique/snapshot_manager.py index 2ed5aa11d..b80233a14 100644 --- a/eth/consensus/clique/snapshot_manager.py +++ b/eth/consensus/clique/snapshot_manager.py @@ -48,7 +48,7 @@ def make_snapshot_lookup_key(block_hash: Hash32) -> bytes: - return f"block-hash-to-snapshot:{block_hash}".encode() + return f"block-hash-to-snapshot:{block_hash!r}".encode() class SnapshotManager: @@ -123,11 +123,11 @@ def apply(self, current_snapshot: Snapshot, header: BlockHeaderAPI) -> Snapshot: if tally.votes > len(snapshot.signers) / 2: if tally.action is VoteAction.NOMINATE: snapshot.signers.append(header.coinbase) - self.logger.debug(f"New signer added: {header.coinbase}") + self.logger.debug(f"New signer added: {header.coinbase!r}") else: if header.coinbase in snapshot.signers: snapshot.signers.remove(header.coinbase) - self.logger.debug(f"Signer removed: {header.coinbase}") + self.logger.debug(f"Signer removed: {header.coinbase!r}") for vote in snapshot.votes.copy(): # Discard any pending votes *from* the added or removed member diff --git a/eth/db/chain.py b/eth/db/chain.py index 0b70984fd..0636e36f8 100644 --- a/eth/db/chain.py +++ b/eth/db/chain.py @@ -290,8 +290,8 @@ def _persist_block( uncles_hash = EMPTY_UNCLE_HASH if uncles_hash != block.header.uncles_hash: raise ValidationError( - f"Block's uncles_hash ({block.header.uncles_hash}) does not match " - f"actual uncles' hash ({uncles_hash})" + f"Block's uncles_hash ({block.header.uncles_hash!r}) does not match " + f"actual uncles' hash ({uncles_hash!r})" ) new_canonical_hashes = tuple(header.hash for header in new_canonical_headers) old_canonical_hashes = tuple(header.hash for header in old_canonical_headers) diff --git a/eth/db/schema.py b/eth/db/schema.py index 78c550597..3d2e01319 100644 --- a/eth/db/schema.py +++ b/eth/db/schema.py @@ -20,7 +20,7 @@ def make_block_number_to_hash_lookup_key(block_number: BlockNumber) -> bytes: @staticmethod def make_block_hash_to_score_lookup_key(block_hash: Hash32) -> bytes: - return f"block-hash-to-score:{block_hash}".encode() + return f"block-hash-to-score:{block_hash!r}".encode() @staticmethod def make_header_chain_gaps_lookup_key() -> bytes: @@ -39,8 +39,8 @@ def make_checkpoint_headers_key() -> bytes: @staticmethod def make_transaction_hash_to_block_lookup_key(transaction_hash: Hash32) -> bytes: - return f"transaction-hash-to-block:{transaction_hash}".encode() + return f"transaction-hash-to-block:{transaction_hash!r}".encode() @staticmethod def make_withdrawal_hash_to_block_lookup_key(withdrawal_hash: Hash32) -> bytes: - return f"withdrawal-hash-to-block:{withdrawal_hash}".encode() + return f"withdrawal-hash-to-block:{withdrawal_hash!r}".encode() diff --git a/eth/precompiles/point_evaluation.py b/eth/precompiles/point_evaluation.py index 234b414a1..92c3b7003 100644 --- a/eth/precompiles/point_evaluation.py +++ b/eth/precompiles/point_evaluation.py @@ -1,5 +1,8 @@ import hashlib import os +from typing import ( + cast, +) from ckzg import ( load_trusted_setup, @@ -29,7 +32,9 @@ def kzg_to_versioned_hash(commitment: bytes) -> Hash32: - return VERSIONED_HASH_VERSION_KZG + hashlib.sha256(commitment).digest()[1:] + return cast( + Hash32, VERSIONED_HASH_VERSION_KZG + hashlib.sha256(commitment).digest()[1:] + ) def point_evaluation_precompile(computation: ComputationAPI) -> ComputationAPI: diff --git a/eth/rlp/blocks.py b/eth/rlp/blocks.py index c106ae223..4ade9d797 100644 --- a/eth/rlp/blocks.py +++ b/eth/rlp/blocks.py @@ -1,4 +1,5 @@ from typing import ( + Sequence, Type, ) @@ -12,13 +13,39 @@ ) from eth.abc import ( BlockAPI, + BlockHeaderAPI, + SignedTransactionAPI, TransactionBuilderAPI, + WithdrawalAPI, ) class BaseBlock(Configurable, rlp.Serializable, BlockAPI): transaction_builder: Type[TransactionBuilderAPI] = None + def __init__( + self, + header: BlockHeaderAPI, + transactions: Sequence[SignedTransactionAPI] = None, + uncles: Sequence[BlockHeaderAPI] = None, + withdrawals: Sequence[WithdrawalAPI] = None, + ) -> None: + if withdrawals is not None: + rlp.Serializable.__init__( + self, + header=header, + transactions=transactions, + uncles=uncles, + withdrawals=withdrawals, + ) + else: + rlp.Serializable.__init__( + self, + header=header, + transactions=transactions, + uncles=uncles, + ) + @classmethod def get_transaction_builder(cls) -> Type[TransactionBuilderAPI]: if cls.transaction_builder is None: diff --git a/eth/tools/fixtures/loading.py b/eth/tools/fixtures/loading.py index ca13bec47..8d9639106 100644 --- a/eth/tools/fixtures/loading.py +++ b/eth/tools/fixtures/loading.py @@ -1,12 +1,18 @@ +from pytest import ( + Mark, + MarkDecorator, +) import functools import json import os from typing import ( Any, Callable, + Collection, Dict, Iterable, Tuple, + Union, ) from eth_utils import ( @@ -81,7 +87,9 @@ def load_fixture( def filter_fixtures( all_fixtures: Iterable[Any], fixtures_base_dir: str, - mark_fn: Callable[[str, str], bool] = None, + mark_fn: Callable[ + [str, str], Union[MarkDecorator, Collection[Union[MarkDecorator, Mark]], None] + ] = None, ignore_fn: Callable[..., bool] = None, ) -> Any: """ diff --git a/eth/tools/mining.py b/eth/tools/mining.py index f2b86c55d..470fb52bb 100644 --- a/eth/tools/mining.py +++ b/eth/tools/mining.py @@ -15,7 +15,9 @@ class POWMiningMixin(VirtualMachineAPI): """ def finalize_block(self, block: BlockAPI) -> BlockAndMetaWitness: - block_result = super().finalize_block(block) + # type ignored because as a mixin, we expect to only use this with another + # class that properly implements finalize_block + block_result = super().finalize_block(block) # type: ignore[safe-super] block = block_result.block nonce, mix_hash = pow.mine_pow_nonce( diff --git a/eth/vm/forks/berlin/transactions.py b/eth/vm/forks/berlin/transactions.py index 623ead7f5..415b37675 100644 --- a/eth/vm/forks/berlin/transactions.py +++ b/eth/vm/forks/berlin/transactions.py @@ -282,7 +282,7 @@ def max_fee_per_blob_gas(self) -> int: ) @property - def blob_versioned_hashes(self) -> Hash32: + def blob_versioned_hashes(self) -> Sequence[Hash32]: raise NotImplementedError( "blob_versioned_hashes is not implemented until Cancun." ) @@ -376,7 +376,7 @@ def max_fee_per_blob_gas(self) -> int: ) @property - def blob_versioned_hashes(self) -> Hash32: + def blob_versioned_hashes(self) -> Sequence[Hash32]: raise NotImplementedError( "blob_versioned_hashes is not implemented until Cancun." ) diff --git a/eth/vm/forks/cancun/constants.py b/eth/vm/forks/cancun/constants.py index 8bcf4049c..7381dd3ae 100644 --- a/eth/vm/forks/cancun/constants.py +++ b/eth/vm/forks/cancun/constants.py @@ -1,5 +1,9 @@ +from eth_typing import ( + Address, +) + HISTORY_BUFFER_LENGTH = 8191 -BEACON_ROOTS_ADDRESS = ( +BEACON_ROOTS_ADDRESS = Address( b'\x00\x0f=\xf6\xd72\x80~\xf11\x9f\xb7\xb8\xbb\x85"\xd0\xbe\xac\x02' ) BEACON_ROOTS_CONTRACT_CODE = b"3s\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\x14`MW` 6\x14`$W__\xfd[_5\x80\x15`IWb\x00\x1f\xff\x81\x06\x90\x81T\x14` int: ) @property - def blob_versioned_hashes(self) -> Hash32: + def blob_versioned_hashes(self) -> Sequence[Hash32]: raise NotImplementedError( "blob_versioned_hashes is not implemented until Cancun." ) diff --git a/newsfragments/2197.breaking.rst b/newsfragments/2197.breaking.rst new file mode 100644 index 000000000..2b9bfb39e --- /dev/null +++ b/newsfragments/2197.breaking.rst @@ -0,0 +1 @@ +Adds running ``mypy`` locally with all deps installed, then updating typing as needed. Moves ``eth/tools/factories`` into ``tests`` as it is only ever used there. diff --git a/scripts/benchmark/checks/deploy_dos.py b/scripts/benchmark/checks/deploy_dos.py index 8bff29f27..18587d3db 100644 --- a/scripts/benchmark/checks/deploy_dos.py +++ b/scripts/benchmark/checks/deploy_dos.py @@ -24,9 +24,6 @@ from eth.rlp.blocks import ( BaseBlock, ) -from eth.tools.factories.transaction import ( - new_transaction, -) from scripts.benchmark._utils.chain_plumbing import ( FUNDED_ADDRESS, FUNDED_ADDRESS_PRIVATE_KEY, @@ -38,6 +35,9 @@ from scripts.benchmark._utils.reporting import ( DefaultStat, ) +from tests.tools.factories.transaction import ( + new_transaction, +) from .base_benchmark import ( BaseBenchmark, diff --git a/scripts/benchmark/checks/erc20_interact.py b/scripts/benchmark/checks/erc20_interact.py index d64e9418b..ab62d303d 100644 --- a/scripts/benchmark/checks/erc20_interact.py +++ b/scripts/benchmark/checks/erc20_interact.py @@ -23,9 +23,6 @@ from eth.rlp.blocks import ( BaseBlock, ) -from eth.tools.factories.transaction import ( - new_transaction, -) from scripts.benchmark._utils.chain_plumbing import ( FUNDED_ADDRESS, FUNDED_ADDRESS_PRIVATE_KEY, @@ -39,6 +36,9 @@ from scripts.benchmark._utils.reporting import ( DefaultStat, ) +from tests.tools.factories.transaction import ( + new_transaction, +) from .base_benchmark import ( BaseBenchmark, diff --git a/scripts/benchmark/checks/simple_value_transfers.py b/scripts/benchmark/checks/simple_value_transfers.py index 10dfa097b..5d712740c 100644 --- a/scripts/benchmark/checks/simple_value_transfers.py +++ b/scripts/benchmark/checks/simple_value_transfers.py @@ -14,9 +14,6 @@ from eth.rlp.blocks import ( BaseBlock, ) -from eth.tools.factories.transaction import ( - new_transaction, -) from scripts.benchmark._utils.address import ( generate_random_address, ) @@ -32,6 +29,9 @@ from scripts.benchmark._utils.shellart import ( bold_yellow, ) +from tests.tools.factories.transaction import ( + new_transaction, +) from .base_benchmark import ( BaseBenchmark, diff --git a/setup.py b/setup.py index 05d9461a1..905d3fe70 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,7 @@ "build>=0.9.0", "bump_my_version>=0.19.0", "ipython", + "mypy==1.10.0", "pre-commit>=3.4.0", "tox>=4.0.0", "twine", diff --git a/tests/core/builder-tools/test_chain_builder.py b/tests/core/builder-tools/test_chain_builder.py index 57e8c0d55..496d6196f 100644 --- a/tests/core/builder-tools/test_chain_builder.py +++ b/tests/core/builder-tools/test_chain_builder.py @@ -25,7 +25,7 @@ mine_block, mine_blocks, ) -from eth.tools.factories.transaction import ( +from tests.tools.factories.transaction import ( new_transaction, ) diff --git a/tests/core/chain-object/test_build_block_incrementally.py b/tests/core/chain-object/test_build_block_incrementally.py index bcde7ce3e..e2a225a1f 100644 --- a/tests/core/chain-object/test_build_block_incrementally.py +++ b/tests/core/chain-object/test_build_block_incrementally.py @@ -6,7 +6,7 @@ from eth.chains.base import ( MiningChain, ) -from eth.tools.factories.transaction import ( +from tests.tools.factories.transaction import ( new_transaction, ) diff --git a/tests/core/chain-object/test_chain.py b/tests/core/chain-object/test_chain.py index 5a8f0526e..f0a0f6034 100644 --- a/tests/core/chain-object/test_chain.py +++ b/tests/core/chain-object/test_chain.py @@ -30,15 +30,15 @@ from eth.exceptions import ( TransactionNotFound, ) -from eth.tools.factories.transaction import ( - new_transaction, -) from eth.vm.forks.frontier.blocks import ( FrontierBlock, ) from tests.core.fixtures import ( valid_block_rlp, ) +from tests.tools.factories.transaction import ( + new_transaction, +) @pytest.fixture diff --git a/tests/core/chain-object/test_contract_call.py b/tests/core/chain-object/test_contract_call.py index 465b3bbb4..e4f59b44c 100644 --- a/tests/core/chain-object/test_contract_call.py +++ b/tests/core/chain-object/test_contract_call.py @@ -14,9 +14,6 @@ OutOfGas, Revert, ) -from eth.tools.factories.transaction import ( - new_transaction, -) from eth.vm.forks import ( ArrowGlacierVM, BerlinVM, @@ -32,6 +29,9 @@ SpuriousDragonVM, TangerineWhistleVM, ) +from tests.tools.factories.transaction import ( + new_transaction, +) @pytest.fixture diff --git a/tests/core/chain-object/test_gas_estimation.py b/tests/core/chain-object/test_gas_estimation.py index 43d2a1ec3..b407d29c8 100644 --- a/tests/core/chain-object/test_gas_estimation.py +++ b/tests/core/chain-object/test_gas_estimation.py @@ -6,9 +6,6 @@ from eth.estimators.gas import ( binary_gas_search_1000_tolerance, ) -from eth.tools.factories.transaction import ( - new_transaction, -) from eth.vm.forks import ( ArrowGlacierVM, BerlinVM, @@ -26,6 +23,9 @@ from tests.core.helpers import ( fill_block, ) +from tests.tools.factories.transaction import ( + new_transaction, +) ADDRESS_2 = b"\0" * 19 + b"\x02" diff --git a/tests/core/consensus/test_clique_consensus.py b/tests/core/consensus/test_clique_consensus.py index 64687a27e..6cb77ee04 100644 --- a/tests/core/consensus/test_clique_consensus.py +++ b/tests/core/consensus/test_clique_consensus.py @@ -37,18 +37,18 @@ from eth.rlp.headers import ( BlockHeader, ) -from eth.tools.factories.keys import ( - PublicKeyFactory, -) -from eth.tools.factories.transaction import ( - new_transaction, -) from eth.vm.forks.istanbul import ( IstanbulVM, ) from eth.vm.forks.petersburg import ( PetersburgVM, ) +from tests.tools.factories.keys import ( + PublicKeyFactory, +) +from tests.tools.factories.transaction import ( + new_transaction, +) ALICE_PK = keys.PrivateKey( decode_hex("0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8") diff --git a/tests/core/helpers.py b/tests/core/helpers.py index 58864d749..dc9906d60 100644 --- a/tests/core/helpers.py +++ b/tests/core/helpers.py @@ -8,7 +8,7 @@ from eth.chains.base import ( MiningChain, ) -from eth.tools.factories.transaction import ( +from tests.tools.factories.transaction import ( new_transaction, ) diff --git a/tests/core/vm/test_contract_code_size_limit.py b/tests/core/vm/test_contract_code_size_limit.py index 268b2a929..a651c3b1f 100644 --- a/tests/core/vm/test_contract_code_size_limit.py +++ b/tests/core/vm/test_contract_code_size_limit.py @@ -15,9 +15,6 @@ from eth.exceptions import ( OutOfGas, ) -from eth.tools.factories.transaction import ( - new_transaction, -) from eth.vm import ( opcode_values, ) @@ -30,6 +27,9 @@ from eth.vm.message import ( Message, ) +from tests.tools.factories.transaction import ( + new_transaction, +) def assemble(*codes): diff --git a/tests/core/vm/test_london.py b/tests/core/vm/test_london.py index 84f072cf2..964280a49 100644 --- a/tests/core/vm/test_london.py +++ b/tests/core/vm/test_london.py @@ -22,13 +22,13 @@ from eth.exceptions import ( InvalidInstruction, ) -from eth.tools.factories.transaction import ( - new_dynamic_fee_transaction, - new_transaction, -) from eth.vm.forks import ( BerlinVM, ) +from tests.tools.factories.transaction import ( + new_dynamic_fee_transaction, + new_transaction, +) FOUR_TXN_GAS_LIMIT = 21000 * 4 diff --git a/tests/core/vm/test_rewards.py b/tests/core/vm/test_rewards.py index 436cbfc67..05c943241 100644 --- a/tests/core/vm/test_rewards.py +++ b/tests/core/vm/test_rewards.py @@ -25,7 +25,7 @@ spurious_dragon_at, tangerine_whistle_at, ) -from eth.tools.factories.transaction import ( +from tests.tools.factories.transaction import ( new_dynamic_fee_transaction, ) diff --git a/tests/core/vm/test_validate_transaction.py b/tests/core/vm/test_validate_transaction.py index f97a0e68a..c6352bc9b 100644 --- a/tests/core/vm/test_validate_transaction.py +++ b/tests/core/vm/test_validate_transaction.py @@ -13,12 +13,12 @@ from eth.constants import ( GAS_TX, ) -from eth.tools.factories.transaction import ( - new_dynamic_fee_transaction, -) from eth.vm.forks import ( LondonVM, ) +from tests.tools.factories.transaction import ( + new_dynamic_fee_transaction, +) @pytest.fixture diff --git a/tests/core/vm/test_vm.py b/tests/core/vm/test_vm.py index e3fb8d974..167949d3f 100644 --- a/tests/core/vm/test_vm.py +++ b/tests/core/vm/test_vm.py @@ -19,7 +19,7 @@ from eth.tools.builder.chain import ( api, ) -from eth.tools.factories.transaction import ( +from tests.tools.factories.transaction import ( new_transaction, ) diff --git a/tests/core/vm/test_vm_state.py b/tests/core/vm/test_vm_state.py index 5d4093ed2..be770f194 100644 --- a/tests/core/vm/test_vm_state.py +++ b/tests/core/vm/test_vm_state.py @@ -4,12 +4,12 @@ ValidationError, ) -from eth.tools.factories.transaction import ( - new_transaction, -) from eth.vm.interrupt import ( MissingAccountTrieNode, ) +from tests.tools.factories.transaction import ( + new_transaction, +) ADDRESS = b"\xaa" * 20 OTHER_ADDRESS = b"\xbb" * 20 diff --git a/tests/database/test_eth1_chaindb.py b/tests/database/test_eth1_chaindb.py index 4707f9083..80a363f99 100644 --- a/tests/database/test_eth1_chaindb.py +++ b/tests/database/test_eth1_chaindb.py @@ -46,10 +46,6 @@ from eth.tools.builder.chain import ( api, ) -from eth.tools.factories.transaction import ( - new_access_list_transaction, - new_transaction, -) from eth.tools.rlp import ( assert_headers_eq, ) @@ -63,6 +59,10 @@ from eth.vm.forks.homestead.blocks import ( HomesteadBlock, ) +from tests.tools.factories.transaction import ( + new_access_list_transaction, + new_transaction, +) A_ADDRESS = b"\xaa" * 20 B_ADDRESS = b"\xbb" * 20 diff --git a/eth/tools/factories/keys.py b/tests/tools/factories/keys.py similarity index 80% rename from eth/tools/factories/keys.py rename to tests/tools/factories/keys.py index b7262bdf7..3d04c5a2f 100644 --- a/eth/tools/factories/keys.py +++ b/tests/tools/factories/keys.py @@ -6,13 +6,7 @@ from eth_utils import ( int_to_big_endian, ) - -try: - import factory -except ImportError: - raise ImportError( - "The p2p.tools.factories module requires the `factory_boy` library." - ) +import factory def _mk_private_key_bytes() -> bytes: diff --git a/eth/tools/factories/transaction.py b/tests/tools/factories/transaction.py similarity index 100% rename from eth/tools/factories/transaction.py rename to tests/tools/factories/transaction.py diff --git a/tox.ini b/tox.ini index 3c02dc054..62ecbe374 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,7 @@ envlist= py{38,39,310,311,312,313}-wheel windows-wheel docs - py312-native-blockchain-{ \ + py313-native-blockchain-{ \ metropolis, transition, frontier, homestead, tangerine_whistle, \ spurious_dragon, byzantium, constantinople, petersburg, istanbul, \ berlin, london, paris, shanghai, cancun \ @@ -65,6 +65,7 @@ allowlist_externals=make,pre-commit [testenv:py{38,39,310,311,312,313}-lint] deps=pre-commit +extras=dev commands= pre-commit install pre-commit run --all-files --show-diff-on-failure