From ed8a05811105b856a1abf844b06c3453d73740f8 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Thu, 28 Sep 2023 14:09:39 -0400 Subject: [PATCH] fix: metadata output interaction with natspec enabling the `-f metadata` output has an interaction with other outputs because the metadata output format mutates some internal data structures in-place. this is because `vars()` returns a reference to the object's `__dict__` as opposed to a copy of it. the behavior can be seen by trying to call the compiler with `-f metadata,devdoc,userdoc`. this commit fixes the issue by constructing a copy of the object during metadata output formatting. it also modifies the test suite to include more output formats, to test the interactions between these different output formats. in doing so, it was also found that some examples have invalid natspec, which has also been fixed. --- examples/tokens/ERC1155ownable.vy | 2 -- tests/base_conftest.py | 4 ++-- vyper/compiler/output.py | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/tokens/ERC1155ownable.vy b/examples/tokens/ERC1155ownable.vy index 8094225f18..f1070b8f89 100644 --- a/examples/tokens/ERC1155ownable.vy +++ b/examples/tokens/ERC1155ownable.vy @@ -214,7 +214,6 @@ def mint(receiver: address, id: uint256, amount:uint256): @param receiver the account that will receive the minted token @param id the ID of the token @param amount of tokens for this ID - @param data the data associated with this mint. Usually stays empty """ assert not self.paused, "The contract has been paused" assert self.owner == msg.sender, "Only the contract owner can mint" @@ -232,7 +231,6 @@ def mintBatch(receiver: address, ids: DynArray[uint256, BATCH_SIZE], amounts: Dy @param receiver the account that will receive the minted token @param ids array of ids for the tokens @param amounts amounts of tokens for each ID in the ids array - @param data the data associated with this mint. Usually stays empty """ assert not self.paused, "The contract has been paused" assert self.owner == msg.sender, "Only the contract owner can mint" diff --git a/tests/base_conftest.py b/tests/base_conftest.py index 81e8dedc36..1c7c6f3aed 100644 --- a/tests/base_conftest.py +++ b/tests/base_conftest.py @@ -118,8 +118,8 @@ def _get_contract(w3, source_code, optimize, *args, override_opt_level=None, **k settings.optimize = override_opt_level or optimize out = compiler.compile_code( source_code, - # test that metadata gets generated - ["abi", "bytecode", "metadata"], + # test that metadata and natspecs get generated + ["abi", "bytecode", "metadata", "userdoc", "devdoc"], settings=settings, interface_codes=kwargs.pop("interface_codes", None), show_gas_estimates=True, # Enable gas estimates for testing diff --git a/vyper/compiler/output.py b/vyper/compiler/output.py index 9ef492c3e2..9df7262882 100644 --- a/vyper/compiler/output.py +++ b/vyper/compiler/output.py @@ -117,7 +117,7 @@ def _var_rec_dict(variable_record): return ret def _to_dict(func_t): - ret = vars(func_t) + ret = vars(func_t).copy() ret["return_type"] = str(ret["return_type"]) ret["_ir_identifier"] = func_t._ir_info.ir_identifier