Skip to content

Commit 06c1949

Browse files
authored
Merge pull request #1548 from njgheorghita/type-hints-complete
Type hints complete
2 parents 6bf0d32 + 3724ecd commit 06c1949

39 files changed

+466
-354
lines changed

docs/ethpm.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ A valid content-addressed Github URI *must* conform to the following scheme, as
200200

201201
>>> from ethpm.uri import create_content_addressed_github_uri
202202

203-
>>> owned_github_api_uri = "https://api.github.com/repos/ethpm/py-ethpm/contents/ethpm/assets/owned/1.0.1.json"
204-
>>> content_addressed_uri = "https://api.github.com/repos/ethpm/py-ethpm/git/blobs/a7232a93f1e9e75d606f6c1da18aa16037e03480"
203+
>>> owned_github_api_uri = "https://api.github.com/repos/ethereum/web3.py/contents/ethpm/assets/owned/1.0.1.json"
204+
>>> content_addressed_uri = "https://api.github.com/repos/ethereum/web3.py/git/blobs/a7232a93f1e9e75d606f6c1da18aa16037e03480"
205205

206206
>>> actual_blob_uri = create_content_addressed_github_uri(owned_github_api_uri)
207207
>>> assert actual_blob_uri == content_addressed_uri

ens/main.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from eth_typing import (
1111
Address,
1212
ChecksumAddress,
13-
Hash32,
1413
HexAddress,
1514
HexStr,
1615
)
@@ -19,6 +18,9 @@
1918
is_checksum_address,
2019
to_checksum_address,
2120
)
21+
from hexbytes import (
22+
HexBytes,
23+
)
2224

2325
from ens import abis
2426
from ens.constants import (
@@ -57,9 +59,7 @@
5759
)
5860

5961

60-
ENS_MAINNET_ADDR = ChecksumAddress(
61-
HexAddress(HexStr('0x314159265dD8dbb310642f98f50C066173C1259b'))
62-
)
62+
ENS_MAINNET_ADDR = ChecksumAddress(HexAddress(HexStr('0x314159265dD8dbb310642f98f50C066173C1259b')))
6363

6464

6565
class ENS:
@@ -130,7 +130,7 @@ def setup_address(
130130
name: str,
131131
address: Union[Address, ChecksumAddress, HexAddress]=cast(ChecksumAddress, default),
132132
transact: "TxParams"={}
133-
) -> Hash32:
133+
) -> HexBytes:
134134
"""
135135
Set up the name to point to the supplied address.
136136
The sender of the transaction must own the name, or
@@ -169,7 +169,7 @@ def setup_address(
169169
@dict_copy
170170
def setup_name(
171171
self, name: str, address: ChecksumAddress=None, transact: "TxParams"={}
172-
) -> Hash32:
172+
) -> HexBytes:
173173
"""
174174
Set up the address for reverse lookup, aka "caller ID".
175175
After successful setup, the method :meth:`~ens.main.ENS.name` will return
@@ -354,7 +354,7 @@ def _set_resolver(
354354
@dict_copy
355355
def _setup_reverse(
356356
self, name: str, address: ChecksumAddress, transact: "TxParams"={}
357-
) -> Hash32:
357+
) -> HexBytes:
358358
if name:
359359
name = normalize_name(name)
360360
else:

ethpm/_utils/chains.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@
1717
is_integer,
1818
remove_0x_prefix,
1919
)
20+
from hexbytes import (
21+
HexBytes,
22+
)
2023

2124
from ethpm.constants import (
2225
SUPPORTED_CHAIN_IDS,
2326
)
2427
from web3 import Web3
2528

2629

27-
def get_genesis_block_hash(web3: Web3) -> str:
30+
def get_genesis_block_hash(web3: Web3) -> HexBytes:
2831
return web3.eth.getBlock(BlockNumber(0))["hash"]
2932

3033

ethpm/package.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ def _get_all_contract_instances(
386386
f"{self.contract_types}."
387387
)
388388
contract_instance = self.get_contract_instance(
389-
deployment_data['contract_type'],
389+
ContractName(deployment_data['contract_type']),
390390
deployment_data['address'],
391391
)
392392
yield deployment_name, contract_instance

ethpm/uri.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
CannotHandleURI,
3737
)
3838
from web3 import Web3
39+
from web3.types import (
40+
BlockNumber,
41+
)
3942

4043

4144
def resolve_uri_contents(uri: URI, fingerprint: bool = None) -> bytes:
@@ -101,13 +104,13 @@ def create_latest_block_uri(w3: Web3, from_blocks_ago: int = 3) -> URI:
101104
"""
102105
chain_id = to_hex(get_genesis_block_hash(w3))
103106
latest_block_tx_receipt = w3.eth.getBlock("latest")
104-
target_block_number = latest_block_tx_receipt.number - from_blocks_ago
107+
target_block_number = BlockNumber(latest_block_tx_receipt["number"] - from_blocks_ago)
105108
if target_block_number < 0:
106109
raise Exception(
107-
f"Only {latest_block_tx_receipt.number} blocks avaible on provided w3, "
110+
f"Only {latest_block_tx_receipt['number']} blocks avaible on provided w3, "
108111
f"cannot create latest block uri for {from_blocks_ago} blocks ago."
109112
)
110-
recent_block = to_hex(w3.eth.getBlock(target_block_number).hash)
113+
recent_block = to_hex(w3.eth.getBlock(target_block_number)["hash"])
111114
return create_block_uri(chain_id, recent_block)
112115

113116

tests/ethpm/test_uri.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ def test_is_valid_content_addressed_github_uri(uri, expected):
6161

6262

6363
def test_create_github_uri():
64-
api_uri = "https://api.github.com/repos/ethpm/py-ethpm/contents/ethpm/assets/owned/1.0.1.json"
65-
expected_blob_uri = "https://api.github.com/repos/ethpm/py-ethpm/git/blobs/a7232a93f1e9e75d606f6c1da18aa16037e03480" # noqa: E501
64+
api_uri = "https://api.github.com/repos/ethereum/web3.py/contents/ethpm/assets/owned/1.0.1.json"
65+
expected_blob_uri = "https://api.github.com/repos/ethereum/web3.py/git/blobs/a7232a93f1e9e75d606f6c1da18aa16037e03480" # noqa: E501
6666
actual_blob_uri = create_content_addressed_github_uri(api_uri)
6767
assert actual_blob_uri == expected_blob_uri
6868

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,4 @@ extras=linter
6363
commands=
6464
flake8 {toxinidir}/web3 {toxinidir}/ens {toxinidir}/ethpm {toxinidir}/tests
6565
isort --recursive --check-only --diff {toxinidir}/web3/ {toxinidir}/ens/ {toxinidir}/ethpm/ {toxinidir}/tests/
66-
mypy -p web3._utils -p web3.providers -p web3.main -p web3.contract -p web3.datastructures -p web3.eth -p web3.exceptions -p web3.geth -p web3.iban -p web3.logs -p web3.manager -p web3.module -p web3.net -p web3.parity -p web3.middleware -p web3.method -p web3.pm -p web3.auto -p web3.gas_strategies -p web3.testing -p web3.tools -p web3.version -p ethpm -p ens --config-file {toxinidir}/mypy.ini
66+
mypy -p web3 -p ethpm -p ens --config-file {toxinidir}/mypy.ini

web3/_utils/abi.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,7 @@
8686

8787

8888
def filter_by_type(_type: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
89-
# fix for this just landed, not yet released : https://github.com/python/mypy/pull/7917
90-
# after it's released, update Union[ABIFunction, ABIEvent] -> ABIElement
91-
return [abi for abi in contract_abi if abi['type'] == _type] # type: ignore
89+
return [abi for abi in contract_abi if abi['type'] == _type]
9290

9391

9492
def filter_by_name(name: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
@@ -97,25 +95,24 @@ def filter_by_name(name: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIE
9795
for abi
9896
in contract_abi
9997
if (
100-
# type ignored b/c see line 91
101-
abi['type'] not in ('fallback', 'constructor') and # type: ignore
102-
abi['name'] == name # type: ignore
98+
abi['type'] not in ('fallback', 'constructor') and
99+
abi['name'] == name
103100
)
104101
]
105102

106103

107-
def get_abi_input_types(abi: Union[ABIFunction, ABIEvent]) -> List[str]:
104+
def get_abi_input_types(abi: ABIFunction) -> List[str]:
108105
if 'inputs' not in abi and abi['type'] == 'fallback':
109106
return []
110107
else:
111-
return [collapse_if_tuple(arg) for arg in abi['inputs']]
108+
return [collapse_if_tuple(cast(Dict[str, Any], arg)) for arg in abi['inputs']]
112109

113110

114-
def get_abi_output_types(abi: Union[ABIFunction, ABIEvent]) -> List[str]:
111+
def get_abi_output_types(abi: ABIFunction) -> List[str]:
115112
if abi['type'] == 'fallback':
116113
return []
117114
else:
118-
return [collapse_if_tuple(arg) for arg in abi['outputs']]
115+
return [collapse_if_tuple(cast(Dict[str, Any], arg)) for arg in abi['outputs']]
119116

120117

121118
def get_abi_input_names(abi: Union[ABIFunction, ABIEvent]) -> List[str]:
@@ -128,7 +125,7 @@ def get_abi_input_names(abi: Union[ABIFunction, ABIEvent]) -> List[str]:
128125
def get_fallback_func_abi(contract_abi: ABI) -> ABIFunction:
129126
fallback_abis = filter_by_type('fallback', contract_abi)
130127
if fallback_abis:
131-
return fallback_abis[0]
128+
return cast(ABIFunction, fallback_abis[0])
132129
else:
133130
raise FallbackNotFound("No fallback function was found in the contract ABI.")
134131

@@ -152,8 +149,7 @@ def filter_by_argument_count(
152149
abi
153150
for abi
154151
in contract_abi
155-
# type ignored b/c see line 91
156-
if len(abi['inputs']) == num_arguments # type: ignore
152+
if len(abi['inputs']) == num_arguments
157153
]
158154

159155

@@ -373,10 +369,12 @@ def filter_by_encodability(
373369
abi_codec: codec.ABIEncoder, args: Sequence[Any], kwargs: Dict[str, Any], contract_abi: ABI
374370
) -> List[ABIFunction]:
375371
return [
376-
function_abi
372+
cast(ABIFunction, function_abi)
377373
for function_abi
378374
in contract_abi
379-
if check_if_arguments_can_be_encoded(function_abi, abi_codec, args, kwargs)
375+
if check_if_arguments_can_be_encoded(
376+
cast(ABIFunction, function_abi), abi_codec, args, kwargs
377+
)
380378
]
381379

382380

@@ -516,7 +514,7 @@ def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
516514
new_abi = copy.copy(arg_abi)
517515
new_abi['type'] = tuple_prefix
518516

519-
sub_abis = itertools.repeat(new_abi)
517+
sub_abis = itertools.repeat(new_abi) # type: ignore
520518

521519
if isinstance(arg, abc.Mapping):
522520
# Arg is mapping. Align values according to abi order.
@@ -555,7 +553,9 @@ def get_aligned_abi_inputs(
555553
args = tuple(args[abi['name']] for abi in input_abis)
556554

557555
return (
558-
tuple(collapse_if_tuple(abi) for abi in input_abis),
556+
# typed dict cannot be used w/ a normal Dict
557+
# https://github.com/python/mypy/issues/4976
558+
tuple(collapse_if_tuple(abi) for abi in input_abis), # type: ignore
559559
# too many arguments for Sequence
560560
type(args)( # type: ignore
561561
_align_abi_input(abi, arg)
@@ -566,11 +566,10 @@ def get_aligned_abi_inputs(
566566

567567
def get_constructor_abi(contract_abi: ABI) -> ABIFunction:
568568
candidates = [
569-
# type ignored b/c see line 91
570-
abi for abi in contract_abi if abi['type'] == 'constructor' # type: ignore
569+
abi for abi in contract_abi if abi['type'] == 'constructor'
571570
]
572571
if len(candidates) == 1:
573-
return candidates[0]
572+
return cast(ABIFunction, candidates[0])
574573
elif len(candidates) == 0:
575574
return None
576575
elif len(candidates) > 1:
@@ -725,7 +724,7 @@ def is_probably_enum(abi_type: TypeStr) -> bool:
725724
@to_tuple
726725
def normalize_event_input_types(
727726
abi_args: Collection[Union[ABIFunction, ABIEvent]]
728-
) -> Iterable[Union[TypeStr, Dict[TypeStr, Any]]]:
727+
) -> Iterable[Union[ABIFunction, ABIEvent, Dict[TypeStr, Any]]]:
729728
for arg in abi_args:
730729
if is_recognized_type(arg['type']):
731730
yield arg
@@ -739,8 +738,7 @@ def abi_to_signature(abi: Union[ABIFunction, ABIEvent]) -> str:
739738
function_signature = "{fn_name}({fn_input_types})".format(
740739
fn_name=abi['name'],
741740
fn_input_types=','.join([
742-
# type ignored b/c see line 91
743-
arg['type'] for arg in normalize_event_input_types(abi.get('inputs', [])) # type: ignore # noqa: E501
741+
arg['type'] for arg in normalize_event_input_types(abi.get('inputs', []))
744742
]),
745743
)
746744
return function_signature

web3/_utils/compat/__init__.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import sys
12
# remove once web3 supports python>=3.8
23
# TypedDict was added to typing in 3.8
3-
try:
4-
from typing import Literal, Protocol, TypedDict # type: ignore
5-
except ImportError:
6-
from typing_extensions import Literal, Protocol, TypedDict # type: ignore # noqa: F401
4+
if sys.version_info >= (3, 8):
5+
from typing import Literal, Protocol, TypedDict
6+
else:
7+
from typing_extensions import Literal, Protocol, TypedDict # noqa: F401

web3/_utils/contracts.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
Tuple,
77
Type,
88
Union,
9+
cast,
910
)
1011

1112
from eth_abi.codec import (
@@ -199,7 +200,7 @@ def prepare_transaction(
199200
transaction: TxParams=None,
200201
fn_args: Sequence[Any]=None,
201202
fn_kwargs: Any=None,
202-
) -> HexStr:
203+
) -> TxParams:
203204
"""
204205
:parameter `is_function_abi` is used to distinguish function abi from contract abi
205206
Returns a dictionary of the transaction that could be used to call this
@@ -214,7 +215,7 @@ def prepare_transaction(
214215
if transaction is None:
215216
prepared_transaction: TxParams = {}
216217
else:
217-
prepared_transaction = dict(**transaction)
218+
prepared_transaction = cast(TxParams, dict(**transaction))
218219

219220
if 'data' in prepared_transaction:
220221
raise ValueError("Transaction parameter may not contain a 'data' key")
@@ -280,7 +281,9 @@ def get_function_info(
280281
if fn_abi is None:
281282
fn_abi = find_matching_fn_abi(contract_abi, abi_codec, fn_name, args, kwargs)
282283

283-
fn_selector = encode_hex(function_abi_to_4byte_selector(fn_abi))
284+
# typed dict cannot be used w/ a normal Dict
285+
# https://github.com/python/mypy/issues/4976
286+
fn_selector = encode_hex(function_abi_to_4byte_selector(fn_abi)) # type: ignore
284287

285288
fn_arguments = merge_args_and_kwargs(fn_abi, args, kwargs)
286289

0 commit comments

Comments
 (0)