Skip to content

Commit

Permalink
Add type hints to web3.main
Browse files Browse the repository at this point in the history
  • Loading branch information
njgheorghita committed Nov 1, 2019
1 parent 8754a15 commit 1068f8e
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 20 deletions.
13 changes: 13 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[mypy]
warn_unused_ignores = True
ignore_missing_imports = True
strict_optional = False
check_untyped_defs = True
disallow_incomplete_defs = True
disallow_untyped_defs = True
disallow_any_generics = True
; todo: disallow untyped calls after entire web3 codebase has type hints
; disallow_untyped_calls = True
warn_redundant_casts = True
warn_unused_configs = True
strict_equality = True
1 change: 1 addition & 0 deletions newsfragments/1488.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Start adding type hints to web3, beginning with web3.main
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
'linter': [
"flake8==3.4.1",
"isort>=4.2.15,<4.3.5",
"mypy==0.730",
],
'docs': [
"mock",
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,4 @@ extras=linter
commands=
flake8 {toxinidir}/web3 {toxinidir}/ens {toxinidir}/ethpm {toxinidir}/tests
isort --recursive --check-only --diff {toxinidir}/web3/ {toxinidir}/ens/ {toxinidir}/ethpm/ {toxinidir}/tests/
mypy -p web3.main --config-file {toxinidir}/mypy.ini
61 changes: 41 additions & 20 deletions web3/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
from hexbytes import (
HexBytes,
)
from typing import Any, Dict, Iterable, List, TYPE_CHECKING, Union

from eth_typing import HexStr, Primitives
from eth_typing.abi import TypeStr

from ens import ENS
from web3._utils.abi import (
Expand All @@ -28,6 +32,7 @@
)
from web3._utils.empty import (
empty,
Empty,
)
from web3._utils.encoding import (
hex_encode_abi_type,
Expand All @@ -43,6 +48,9 @@
from web3._utils.normalizers import (
abi_ens_resolver,
)
from web3.datastructures import (
NamedElementOnion,
)
from web3.eth import (
Eth,
)
Expand All @@ -68,6 +76,9 @@
ParityPersonal,
ParityShh,
)
from web3.providers import (
BaseProvider,
)
from web3.providers.eth_tester import (
EthereumTesterProvider,
)
Expand All @@ -87,8 +98,11 @@
Version,
)

if TYPE_CHECKING:
from web3.pm import PM # noqa: F401


def get_default_modules():
def get_default_modules() -> Dict[str, Iterable[Any]]:
return {
"eth": (Eth,),
"net": (Net,),
Expand Down Expand Up @@ -137,7 +151,13 @@ class Web3:
isChecksumAddress = staticmethod(is_checksum_address)
toChecksumAddress = staticmethod(to_checksum_address)

def __init__(self, provider=None, middlewares=None, modules=None, ens=empty):
def __init__(
self,
provider: BaseProvider=None,
middlewares: List[Any]=None,
modules: Dict[str, Iterable[Any]]=None,
ens: Union[ENS, Empty]=empty
) -> None:
self.manager = self.RequestManager(self, provider, middlewares)

if modules is None:
Expand All @@ -150,35 +170,35 @@ def __init__(self, provider=None, middlewares=None, modules=None, ens=empty):
self.ens = ens

@property
def middleware_onion(self):
def middleware_onion(self) -> NamedElementOnion:
return self.manager.middleware_onion

@property
def provider(self):
def provider(self) -> BaseProvider:
return self.manager.provider

@provider.setter
def provider(self, provider):
def provider(self, provider: BaseProvider) -> None:
self.manager.provider = provider

@property
def clientVersion(self):
def clientVersion(self) -> int:
return self.manager.request_blocking("web3_clientVersion", [])

@property
def api(self):
def api(self) -> str:
from web3 import __version__
return __version__

@staticmethod
@deprecated_for("keccak")
@apply_to_return_value(HexBytes)
def sha3(primitive=None, text=None, hexstr=None):
def sha3(primitive: Primitives=None, text: str=None, hexstr: HexStr=None) -> bytes:
return Web3.keccak(primitive, text, hexstr)

@staticmethod
@apply_to_return_value(HexBytes)
def keccak(primitive=None, text=None, hexstr=None):
def keccak(primitive: Primitives=None, text: str=None, hexstr: HexStr=None) -> bytes:
if isinstance(primitive, (bytes, int, type(None))):
input_bytes = to_bytes(primitive, hexstr=hexstr, text=text)
return eth_utils_keccak(input_bytes)
Expand All @@ -194,11 +214,11 @@ def keccak(primitive=None, text=None, hexstr=None):

@combomethod
@deprecated_for("solidityKeccak")
def soliditySha3(cls, abi_types, values):
def soliditySha3(cls, abi_types: List[TypeStr], values: List[Any]) -> bytes:
return cls.solidityKeccak(abi_types, values)

@combomethod
def solidityKeccak(cls, abi_types, values):
def solidityKeccak(cls, abi_types: List[TypeStr], values: List[Any]) -> bytes:
"""
Executes keccak256 exactly as Solidity does.
Takes list of abi_types as inputs -- `[uint24, int8[], bool]`
Expand All @@ -223,38 +243,39 @@ def solidityKeccak(cls, abi_types, values):
))
return cls.keccak(hexstr=hex_string)

def isConnected(self):
def isConnected(self) -> bool:
return self.provider.isConnected()

def is_encodable(self, _type, value):
def is_encodable(self, _type: TypeStr, value: Any) -> bool:
return self.codec.is_encodable(_type, value)

@property
def ens(self):
def ens(self) -> Union[ENS, Empty]:
if self._ens is empty:
return ENS.fromWeb3(self)
else:
return self._ens

@ens.setter
def ens(self, new_ens):
def ens(self, new_ens: Union[ENS, Empty]) -> None:
self._ens = new_ens

@property
def pm(self):
def pm(self) -> "PM":
if hasattr(self, '_pm'):
return self._pm
# ignored b/c property is dynamically set via enable_unstable_package_management_api
return self._pm # type: ignore
else:
raise AttributeError(
"The Package Management feature is disabled by default until "
"its API stabilizes. To use these features, please enable them by running "
"`w3.enable_unstable_package_management_api()` and try again."
)

def enable_unstable_package_management_api(self):
from web3.pm import PM
def enable_unstable_package_management_api(self) -> None:
from web3.pm import PM # noqa: F811
if not hasattr(self, '_pm'):
PM.attach(self, '_pm')

def enable_strict_bytes_type_checking(self):
def enable_strict_bytes_type_checking(self) -> None:
self.codec = ABICodec(build_strict_registry())

0 comments on commit 1068f8e

Please sign in to comment.