Skip to content

Commit

Permalink
Merge branch 'main' into fix/currency-value-comparable-on-model
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Aug 21, 2024
2 parents a1a9b84 + 04934de commit d4a6ddc
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/ape/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def __init__(
contract_address: Optional["AddressType"] = None,
source_traceback: _SOURCE_TRACEBACK_ARG = None,
project: Optional["ProjectManager"] = None,
set_ape_traceback: bool = False, # Overriden in ContractLogicError
set_ape_traceback: bool = False, # Overridden in ContractLogicError
):
message = message or (str(base_err) if base_err else self.DEFAULT_MESSAGE)
self.message = message
Expand Down
1 change: 0 additions & 1 deletion src/ape_ethereum/ecosystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,6 @@ def _enrich_returndata(self, call: dict, method_abi: MethodABI, **kwargs) -> dic
default_return_value = "<?>"
returndata = call.get("returndata", "")
is_hexstr = isinstance(returndata, str) and is_0x_prefixed(returndata)
return_value_bytes = None

# Check if return is only a revert string.
call = self._enrich_revert_message(call)
Expand Down
25 changes: 18 additions & 7 deletions src/ape_ethereum/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,21 @@ def return_value(self) -> Any:
return self._return_value_from_enriched_calltree

elif abi := self.root_method_abi:
return_data = self._return_data_from_trace_frames
if return_data is not None:
try:
return self._ecosystem.decode_returndata(abi, return_data)
except Exception as err:
logger.debug(f"Failed decoding return data from trace frames. Error: {err}")
# Use enrichment method. It is slow but it'll at least work.
if self.call_trace_approach is TraceApproach.GETH_STRUCT_LOG_PARSE:
return_data = self._return_data_from_trace_frames
if return_data is not None:
try:
return self._ecosystem.decode_returndata(abi, return_data)
except Exception as err:
logger.debug(f"Failed decoding return data from trace frames. Error: {err}")
# Use enrichment method. It is slow but it'll at least work.

else:
# Barely enrich a calltree for performance reasons
# (likely not a need to enrich the whole thing).
calltree = self.get_raw_calltree()
enriched_calltree = self._ecosystem._enrich_returndata(calltree, abi)
return self._get_return_value_from_calltree(enriched_calltree)

return self._return_value_from_enriched_calltree

Expand All @@ -244,6 +252,9 @@ def _return_value_from_enriched_calltree(self) -> Any:
if "return_value" in self.__dict__:
return self.__dict__["return_value"]

return self._get_return_value_from_calltree(calltree)

def _get_return_value_from_calltree(self, calltree: dict) -> Any:
# If enriching too much, Ethereum places regular values in a key
# named "unenriched_return_values".
if "unenriched_return_values" in calltree:
Expand Down
15 changes: 13 additions & 2 deletions tests/functional/geth/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,13 @@ def test_call_trace_supports_debug_trace_call(geth_contract, geth_account):


@geth_process_test
def test_return_value(geth_contract, geth_account):
receipt = geth_contract.getFilledArray.transact(sender=geth_account)
def test_return_value(benchmark, geth_contract, geth_account):
receipt = benchmark.pedantic(
geth_contract.getFilledArray.transact,
kwargs={"sender": geth_account},
rounds=5,
warmup_rounds=1,
)
trace = receipt.trace
expected = [1, 2, 3] # Hardcoded in contract
assert receipt.return_value == expected
Expand All @@ -324,3 +329,9 @@ def test_return_value(geth_contract, geth_account):
# NOTE: This is very important from a performance perspective!
# (VERY IMPORTANT). We shouldn't need to enrich anything.
assert trace._enriched_calltree is None

# Seeing 0.14.
# Before https://github.com/ApeWorX/ape/pull/2225, was seeing 0.17.
# In CI, can see up to 0.4 though.
avg = benchmark.stats["mean"]
assert avg < 0.6
34 changes: 18 additions & 16 deletions tests/integration/cli/test_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,21 @@ def setup(project):
test_files = {}
if tests_path.is_dir():
for file_path in tests_path.iterdir():
if file_path.name.startswith("test_") and file_path.suffix == ".py":
content = file_path.read_text()
test_files[file_path.name] = content
num_passes += len(
[
x
for x in content.splitlines()
if x.startswith("def test_") and not x.startswith("def test_fail_")
]
)
num_failed += len(
[x for x in content.splitlines() if x.startswith("def test_fail_")]
)
if not file_path.name.startswith("test_") or file_path.suffix != ".py":
continue

content = file_path.read_text(encoding="utf8")
test_files[file_path.name] = content
num_passes += len(
[
x
for x in content.splitlines()
if x.startswith("def test_") and not x.startswith("def test_fail_")
]
)
num_failed += len(
[x for x in content.splitlines() if x.startswith("def test_fail_")]
)

pytester.makepyfile(**test_files)

Expand All @@ -111,16 +113,16 @@ def _make_all_files(base: Path, prefix: Optional[Path] = None):
return

for file in base.iterdir():
if file.is_dir() and not file.name == "tests":
if file.is_dir() and file.name != "tests":
_make_all_files(file, prefix=Path(file.name))
elif file.is_file():
elif file.is_file() and file.suffix not in (".sol", ".vy"):
name = (prefix / file.name).as_posix() if prefix else file.name

if name == "ape-config.yaml":
# Hack in in-memory overrides for testing purposes.
text = str(project.config)
else:
text = file.read_text()
text = file.read_text(encoding="utf8")

src = {name: text.splitlines()}
pytester.makefile(file.suffix, **src)
Expand Down

0 comments on commit d4a6ddc

Please sign in to comment.