F. Eugene Aumson 5ac7ff7084
Generate wrappers for all contracts (#2010)
* abi-gen/Py: fix return type for multi-val returns

Methods that return multiple values were broken in two ways.  One: a
spurious newline was being injected between the return type and the
colon ending the Python method prototype.  Two: the return type was
being generated as just `[TypeA, TypeB]`, whereas it should be
`Tuple[TypeA, TypeB]`.

* abi-gen/Py: fix support for arrays of structs

* abi-gen/Py: FAILING test case nested unrefd struct

When a struct contains another struct, and the inner struct is not
directly referenced by any method interface, wrapper generation is
failing to render a class to represent the inner struct.

This won't fail in CI because at this time CI doesn't run any native
Python tooling to analyze the generated code.  Running mypy locally on
the files in this commit produces the following output:

test-cli/output/python/abi_gen_dummy/__init__.py:76: error: Name 'Tuple0x246f9407' is not defined

This problem affects the generation of wrappers for the DutchAuction
contract.

* abi-gen/Py: fix nested unref'd struct failure

* abi-gen/Py: introduce newlines to quiet linter

When generating contracts with long names (eg
CoordinatorRegistryValidator), the `black` reformatter was introducing
these newlines for us, and it was moving the `# type: ignore` comment in
there such that it no longer was on the line it needed to be on.
Introducing these newlines manually (instead of letting black inject
them) allows the linter directive to stay where it needs to be.

* abi-gen/Py: declare tuples in dependency order

* abi-gen/Py: fix support for overloaded methods

* contract_wrappers.py: pylint: permit 2-char args

By default pylint says that 2 characters is too short for an argument
name, but we have some contract methods with 2-character argument names
(eg `to` in `AssetProxyOwner.getTransactionIds()`), so we want to permit
them.

* contract_wrappers.py: include all contracts

* Update CHANGELOGs

* abi-gen: rename variable

* abi-gen: refine comments

* abi-gen/Py: reword tuple class docstring
2019-08-07 12:44:16 -04:00

95 lines
2.9 KiB
Handlebars

"""Generated wrapper for {{contractName}} Solidity contract."""
# pylint: disable=too-many-arguments
import json
from typing import ( # pylint: disable=unused-import
Any,
List,
Optional,
Tuple,
Union,
)
from eth_utils import to_checksum_address
from mypy_extensions import TypedDict # pylint: disable=unused-import
from hexbytes import HexBytes
from web3 import Web3
from web3.contract import ContractFunction
from web3.datastructures import AttributeDict
from web3.providers.base import BaseProvider
from zero_ex.contract_wrappers.bases import ContractMethod, Validator
from zero_ex.contract_wrappers.tx_params import TxParams
# Try to import a custom validator class definition; if there isn't one,
# declare one that we can instantiate for the default argument to the
# constructor for {{contractName}} below.
try:
# both mypy and pylint complain about what we're doing here, but this
# works just fine, so their messages have been disabled here.
from . import ( # type: ignore # pylint: disable=import-self
{{contractName}}Validator,
)
except ImportError:
class {{contractName}}Validator( # type: ignore
Validator
):
"""No-op input validator."""
{{tupleDefinitions ABIString}}
{{#each methods}}
{{> method_class contractName=../contractName}}
{{/each}}
# pylint: disable=too-many-public-methods,too-many-instance-attributes
class {{contractName}}:
"""Wrapper class for {{contractName}} Solidity contract.{{docBytesIfNecessary ABIString}}"""
{{#each methods}}
{{toPythonIdentifier this.languageSpecificName}}: {{toPythonClassname this.languageSpecificName}}Method
{{/each}}
def __init__(
self,
provider: BaseProvider,
contract_address: str,
validator: {{contractName}}Validator = None,
):
"""Get an instance of wrapper for smart contract.
:param provider: instance of :class:`web3.providers.base.BaseProvider`
:param contract_address: where the contract has been deployed
:param validator: for validation of method inputs.
"""
self.contract_address = contract_address
if not validator:
validator = {{contractName}}Validator(provider, contract_address)
self._web3_eth = Web3( # type: ignore # pylint: disable=no-member
provider
).eth
functions = self._web3_eth.contract(address=to_checksum_address(contract_address), abi={{contractName}}.abi()).functions
{{#each methods}}
self.{{toPythonIdentifier this.languageSpecificName}} = {{toPythonClassname this.languageSpecificName}}Method(provider, contract_address, functions.{{this.name}}, validator)
{{/each}}
{{#each events}}
{{> event contractName=../contractName}}
{{/each}}
@staticmethod
def abi():
"""Return the ABI to the underlying contract."""
return json.loads(
'{{{ABIString}}}' # noqa: E501 (line-too-long)
)
# pylint: disable=too-many-lines