abi-gen/Py: fix incorrect method return types and other small issues (#2345)

* .gitignore gen'd Python staking contract wrappers

* abi-gen/test-cli: check Python type hints in lint

* sra_client.py: Update doc for replicating examples

* abi-gen/Py: fix call() return type incl. tx hash

Previously, generated wrappers for contract methods were including type
hints that suggested that a call() (as opposed to a send_transaction())
might return either the underlying return type or a transaction hash.
This doesn't make sense because a call() will never return a TX hash.
Now, the type hint just has the return type of the underlying method.

* abi-gen: fix test_cli:lint checking wrong code

test_cli:lint is meant to be a rudimentary test of the code generated by
abi-gen.  However, previously, this script was incorporated into `yarn
lint`, and in CircleCI `static-tests` runs independently of `build`.
Consequently, the runs of test_cli:lint were checking the OLD code,
which was previously generated and checked in to git, NOT the code
generated with the version of abi-gen represented by the git repo.  Now,
test_cli:lint happens during `yarn test` rather than `yarn lint`,
because `yarn test` IS dependent on `yarn build`.

* contract_wrappers.py: fix misplaced doc

Previously, the routines `order_to_jsdict()` and `jsdict_to_order()`
were moved from contract_wrappers.exchange.types to
contract_wrappers.order_conversions.  However, the module-level
docstring describing those routines was accidentally left behind in
exchange.types.

* abi-gen/Py: stop documenting return types for TXs

Previously the send_transaction() interface included docstring
documentation for the return types of the contract method, but that
doesn't make any sense because send_transaction() returns a transaction
hash rather than any actual return values.

* abi-gen/Py: stop gen'ing send_tx for const methods

* abi-gen/Py: add build_tx to contract methods

* abi-gen/Py: fix incorrect method return types

Fixes #2298 .

* abi-gen/Py: rm validator arg to no-input methods

* abi-gen: mv Py Handlebars helpers to own module

Move all existing Python-related Handlebars helpers to the newly created
python_handlebars_helpers module.

* abi-gen: refactor internal interface

No functionality is changed.  Sole purpose of this commit is to
facilitate an upcoming commit.

* abi-gen: refactor internal interface

No functionality is changed.  Sole purpose of this commit is to
facilitate an upcoming commit.

* abi-gen/Py: name tuples w/internalType, not hash

Use the new `internalType` field on the `DataItem`s in the contract
artifact to give generated tuple classes a better name than just hashing
their component field names.

* Fix CI errors

* abi-gen/Py/wrapper: make internal member private

* Update CHANGELOGs
This commit is contained in:
F. Eugene Aumson
2019-11-15 18:27:45 -05:00
committed by GitHub
parent 9e3cc379ed
commit df97b20913
31 changed files with 679 additions and 847 deletions

View File

@@ -0,0 +1,11 @@
{{~#if outputs~}}
{{#if outputs.length}}
{{#singleReturnValue}}
{{#returnType outputs.[0]}}{{~/returnType~}}
{{/singleReturnValue}}
{{^singleReturnValue}}
Tuple[{{#each outputs}}{{#returnType this}}{{/returnType}}{{#unless @last}}, {{/unless}}{{/each}}]
{{~/singleReturnValue}}
{{else}}None
{{/if}}
{{else}}None{{/if~}}

View File

@@ -2,10 +2,10 @@
class {{toPythonClassname this.languageSpecificName}}Method(ContractMethod):
"""Various interfaces to the {{this.name}} method."""
def __init__(self, web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction, validator: Validator=None):
def __init__(self, web3_or_provider: Union[Web3, BaseProvider], contract_address: str, contract_function: ContractFunction{{#if inputs}}, validator: Validator=None{{/if}}):
"""Persist instance data."""
super().__init__(web3_or_provider, contract_address, validator)
self.underlying_method = contract_function
super().__init__(web3_or_provider, contract_address{{#if inputs}}, validator{{/if}})
self._underlying_method = contract_function
{{#if inputs}}
def validate_and_normalize_inputs(self, {{> typed_params inputs=inputs}}):
@@ -26,7 +26,7 @@ class {{toPythonClassname this.languageSpecificName}}Method(ContractMethod):
return ({{> params }})
{{/if}}
def call(self, {{#if inputs}}{{> typed_params inputs=inputs}}, {{/if}}tx_params: Optional[TxParams] = None) -> {{> return_type outputs=outputs type='call'~}}:
def call(self, {{#if inputs}}{{> typed_params inputs=inputs}}, {{/if}}tx_params: Optional[TxParams] = None) -> {{> call_return_type outputs=outputs type='call'~}}:
"""Execute underlying contract method via eth_call.
{{sanitizeDevdocDetails this.name this.devdoc.details 8}}{{~#if this.devdoc.params~}}{{#each this.devdoc.params}}
{{makeParameterDocstringRole @key this 8}}{{/each}}{{/if}}
@@ -42,28 +42,37 @@ class {{toPythonClassname this.languageSpecificName}}Method(ContractMethod):
({{> params }}) = self.validate_and_normalize_inputs({{> params}})
{{/if}}
tx_params = super().normalize_tx_params(tx_params)
return self.underlying_method({{> params}}).call(tx_params.as_dict())
{{#hasReturnValue}}returned = {{/hasReturnValue}}self._underlying_method({{> params}}).call(tx_params.as_dict())
{{#hasReturnValue}}
return {{makeOutputsValue 'returned' outputs}}
{{/hasReturnValue}}
{{^if this.constant}}
def send_transaction(self, {{#if inputs}}{{> typed_params inputs=inputs}}, {{/if}}tx_params: Optional[TxParams] = None) -> Union[HexBytes, bytes]:
"""Execute underlying contract method via eth_sendTransaction.
{{sanitizeDevdocDetails this.name this.devdoc.details 8}}{{~#if this.devdoc.params~}}{{#each this.devdoc.params}}
{{makeParameterDocstringRole @key this 8}}{{/each}}{{/if}}
:param tx_params: transaction parameters
{{#if this.constant~}}
{{#if this.devdoc.return}}
{{makeReturnDocstringRole this.devdoc.return 8}}{{/if}}
{{/if}}
"""
{{#if inputs}}
({{> params }}) = self.validate_and_normalize_inputs({{> params}})
{{/if}}
tx_params = super().normalize_tx_params(tx_params)
return self.underlying_method({{> params}}).transact(tx_params.as_dict())
return self._underlying_method({{> params}}).transact(tx_params.as_dict())
def build_transaction(self, {{#if inputs}}{{> typed_params inputs=inputs}}, {{/if}}tx_params: Optional[TxParams] = None) -> dict:
"""Construct calldata to be used as input to the method."""
{{#if inputs}}
({{> params }}) = self.validate_and_normalize_inputs({{> params}})
{{/if}}
tx_params = super().normalize_tx_params(tx_params)
return self._underlying_method({{> params}}).buildTransaction(tx_params.as_dict())
{{/if}}
def estimate_gas(self, {{#if inputs}}{{> typed_params inputs=inputs}}, {{/if}}tx_params: Optional[TxParams] = None) -> int:
"""Estimate gas consumption of method call."""
{{#if inputs}}
({{> params }}) = self.validate_and_normalize_inputs({{> params}})
{{/if}}
tx_params = super().normalize_tx_params(tx_params)
return self.underlying_method({{> params}}).estimateGas(tx_params.as_dict())
return self._underlying_method({{> params}}).estimateGas(tx_params.as_dict())

View File

@@ -4,10 +4,10 @@ Union[
{{~/if~}}
{{#if outputs.length}}
{{#singleReturnValue}}
{{#returnType outputs.0.type outputs.0.components}}{{~/returnType~}}
{{#returnType outputs.[0]}}{{~/returnType~}}
{{/singleReturnValue}}
{{^singleReturnValue}}
Tuple[{{#each outputs}}{{#returnType type components}}{{/returnType}}{{#unless @last}}, {{/unless}}{{/each}}]
Tuple[{{#each outputs}}{{#returnType this}}{{/returnType}}{{#unless @last}}, {{/unless}}{{/each}}]
{{~/singleReturnValue}}
{{else}}None
{{/if}}{{^if this.constant}}, Union[HexBytes, bytes]]{{/if~}}

View File

@@ -1,3 +1,3 @@
{{#each inputs}}
{{toPythonIdentifier name}}: {{#parameterType type components}}{{/parameterType}}{{^if @last}}, {{/if~}}
{{toPythonIdentifier name}}: {{#parameterType this}}{{/parameterType}}{{^if @last}}, {{/if~}}
{{/each~}}