You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

学习Solidity课程运行pytest遇TypeError:int()无法转换非字符串类型

Brownie测试报错:TypeError: int() can't convert non-string with explicit base

问题场景

我正在学习Patrick的Solidity课程,复制了课程中的测试代码:

def test_only_owner_can_withdraw():
    if network.show_active() not in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
        pytest.skip("only for local testing")
    fund_me = deploy_fund_me()
    bad_actor = accounts.add()
    with pytest.raises(exceptions.VirtualMachineError):
        fund_me.withdraw({"from": bad_actor})

其他pytest测试均可正常运行,但执行该测试时出现错误:pytest: TypeError: int() can't convert non-string with explicit base,错误发生在brownie库的_get_trace方法中,具体代码位置及上下文如下:

def _get_trace(self) -> None:
    """Retrieves the stack trace via debug_traceTransaction and finds the
    return value, revert message and event logs in the trace.
    """

    # check if trace has already been retrieved, or the tx warrants it
    if self._raw_trace is not None:
        return
    self._raw_trace = []
    if self.input == "0x" and self.gas_used == 21000:
        self._modified_state = False
        self._trace = []
        return

    if not web3.supports_traces:
        raise RPCRequestError("Node client does not support `debug_traceTransaction`")
    try:
        trace = web3.provider.make_request(  # type: ignore
            "debug_traceTransaction", (self.txid, {"disableStorage": CONFIG.mode != "console"})
        )
    except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
        msg = f"Encountered a {type(e).__name__} while requesting "
        msg += "`debug_traceTransaction`. The local RPC client has likely crashed."
        if CONFIG.argv["coverage"]:
            msg += " If the error persists, add the `skip_coverage` marker to this test."
        raise RPCRequestError(msg) from None

    if "error" in trace:
        self._modified_state = None
        self._trace_exc = RPCRequestError(trace["error"]["message"])
        raise self._trace_exc

    self._raw_trace = trace = trace["result"]["structLogs"]
    if not trace:
        self._modified_state = False
        return

    # different nodes return slightly different formats. its really fun to handle
    # geth/nethermind returns unprefixed and with 0-padding for stack and memory
    # erigon returns 0x-prefixed and without padding (but their memory values are like geth)
    fix_stack = False
    for step in trace:
        if not step["stack"]:
            continue
        check = step["stack"][0]
        if not isinstance(check, str):
            break
        if check.startswith("0x"):
            fix_stack = True

> c:\users\xxxx\appdata\local\programs\python\python310\lib\site-packages\brownie\network\transaction.py(678)_get_trace()
-> step["pc"] = int(step["pc"], 16)
(Pdb)

错误原因

这个错误的核心是:Brownie在处理debug_traceTransaction返回的交易追踪数据时,尝试将step["pc"](程序计数器)以16进制转换为整数,但step["pc"]本身已经是整数类型,不是字符串,导致int()函数触发类型错误。

出现该问题的常见诱因是你使用的本地节点(如Ganache、Hardhat节点)返回的structLogs中,pc字段是数字而非字符串,而旧版本Brownie未兼容这种格式差异。

解决方案

方案1:升级Brownie到最新版本

新版本Brownie已修复不同节点返回格式的兼容问题,执行升级命令:

pip install --upgrade eth-brownie

方案2:临时修改Brownie源码(应急用,不推荐)

若暂时无法升级,找到报错的transaction.py文件(路径示例:c:\users\xxxx\appdata\local\programs\python\python310\lib\site-packages\brownie\network\transaction.py),修改第678行代码:
将原代码:

step["pc"] = int(step["pc"], 16)

替换为:

if isinstance(step["pc"], str):
    step["pc"] = int(step["pc"], 16)
else:
    step["pc"] = int(step["pc"])

这样可兼容字符串和数字类型的pc值。

方案3:切换本地节点类型

若升级Brownie后问题仍存在,尝试切换本地节点(如从Ganache换成Hardhat节点,或反之)。不同节点返回的追踪数据格式可能不同,部分节点返回的pc是字符串,可被旧版本Brownie正确处理。

内容的提问来源于stack exchange,提问作者MrPotatoHeadDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:20:29