'AttributeError: 'NoneType' object has no attribute '_with_attr' - Python running tests with pytest

My environment is : Python 3.9.9 Pytest 6.2.5 Brownie 1.17.1

I'm working on the test_fund_me.py from Patrick Collins' Smart Contract tutorial on Youtube; at this stage, I'm supposed to run tests and include an exception through Pytest so that only the owner of the contract can call the function. I added the pytest.raises(exceptions.VirtualMachineError) method, but it still returns a failed test and raises the error mentioned in the title.

Here is my code:

from scripts.helpful_scripts import get_account, LOCAL_BLOCKCHAIN_ENVIRONMENTS
from scripts.deploy import deploy_fund_me
from brownie import network, accounts, exceptions
import pytest


def test_can_fund_and_withdraw():
    account = get_account()
    fund_me = deploy_fund_me()
    entrance_fee = fund_me.getEntranceFee() + 100
    tx = fund_me.fund({"from": account, "value": entrance_fee})
    tx.wait(1)
    assert fund_me.addressToAmountFunded(account.address) == entrance_fee
    tx2 = fund_me.withdraw({"from": account})
    tx2.wait(1)
    assert fund_me.addressToAmountFunded(account.address) == 0


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})

and here is the error message:

PS C:\Users\chret\Documents\demo\brownie_fund_me> brownie test -k test_only_owner_can_withdraw
INFO: Could not find files for the given pattern(s).
Brownie v1.17.1 - Python development framework for Ethereum

=============================================================================== test session starts ================================================================================
platform win32 -- Python 3.9.9, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: C:\Users\chret\Documents\demo\brownie_fund_me
plugins: eth-brownie-1.17.1, hypothesis-6.24.0, forked-1.3.0, xdist-1.34.0, web3-5.24.0
collected 2 items / 1 deselected / 1 selected                                                                                                                                       

Launching 'ganache-cli.cmd --accounts 10 --hardfork istanbul --gasLimit 12000000 --mnemonic brownie --port 8545'...

tests\test_fund_me.py F                                                                                                                                                       [100%]

===================================================================================== FAILURES =====================================================================================
___________________________________________________________________________ test_only_owner_can_withdraw ___________________________________________________________________________

    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})

tests\test_fund_me.py:25:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\..\AppData\Local\Programs\Python\Python39\lib\site-packages\brownie\network\contract.py:1625: in __call__
    return self.transact(*args)
..\..\..\AppData\Local\Programs\Python\Python39\lib\site-packages\brownie\network\contract.py:1498: in transact
    return tx["from"].transfer(
..\..\..\AppData\Local\Programs\Python\Python39\lib\site-packages\brownie\network\account.py:690: in transfer
    receipt._raise_if_reverted(exc)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <Transaction '0xb66de8420866ddd8efba108a2b401d80a64cbdeb780ea09ef75a73185809bbca'>, exc = None

    def _raise_if_reverted(self, exc: Any) -> None:
        if self.status or CONFIG.mode == "console":
            return
        if not web3.supports_traces:
            # if traces are not available, do not attempt to determine the revert reason
            raise exc or ValueError("Execution reverted")

        if self._dev_revert_msg is None:
            # no revert message and unable to check dev string - have to get trace
            self._expand_trace()
        if self.contract_address:
            source = ""
        elif CONFIG.argv["revert"]:
            source = self._traceback_string()
        else:
            source = self._error_string(1)
            contract = state._find_contract(self.receiver)
            if contract:
                marker = "//" if contract._build["language"] == "Solidity" else "#"
                line = self._traceback_string().split("\n")[-1]
                if marker + " dev: " in line:
                    self._dev_revert_msg = line[line.index(marker) + len(marker) : -5].strip()

>       raise exc._with_attr(
            source=source, revert_msg=self._revert_msg, dev_revert_msg=self._dev_revert_msg
        )
E       AttributeError: 'NoneType' object has no attribute '_with_attr'

..\..\..\AppData\Local\Programs\Python\Python39\lib\site-packages\brownie\network\transaction.py:446: AttributeError
------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------
The active network is development
Deploying Mocks...
Mocks Deployed!
Contract deployed to 0x602C71e4DAC47a042Ee7f46E0aee17F94A3bA0B6
mnemonic: 'veteran company dinosaur actual jump club quit horn walk gym jar melody'
============================================================================= short test summary info ==============================================================================
FAILED tests/test_fund_me.py::test_only_owner_can_withdraw - AttributeError: 'NoneType' object has no attribute '_with_attr'
========================================================================= 1 failed, 1 deselected in 4.70s ==========================================================================
Terminating local RPC client...
PS C:\Users\chret\Documents\demo\brownie_fund_me>

I've looked up what this "NoneType" error is, and from what I understood, it could be coming from the bad_actor call for an account, it looks like bad_actor = account.add() return a type of None. But I'm not sure, and neither am I understanding how to fix this.

I saw someone opening an issue on the same thing a few days ago and by closing the terminal, the issue went away. That's not my case, I even rebooted my computer, the issue remains.

Any help appreciated :)



Solution 1:[1]

I had the same issue and was able to get it to work if I changed what I passed to pytest.raises() I used:

with pytest.raises(AttributeError):

Solution 2:[2]

It's a bug, fixed with brownie v1.18.1. Upgrade brownie with this command:

pipx upgrade eth-brownie

Works on my environment with Python 3.9.11

Ref: https://github.com/eth-brownie/brownie/issues/1434#issue-1129651456

Solution 3:[3]

Try Fetching the latest FundMe from brownie

from brownie import FundMe, network
from scripts.helpful_scripts import get_account, LOCAL_BLOCKCHAIN_ENVIRONMENTS
from scripts.deploy import deploy_fund_me
from brownie import network, accounts, exceptions
import pytest


def test_can_fund_and_withdraw():
    account = get_account()
    deploy_fund_me()
    fund_me = FundMe[-1]
    entrance_fee = fund_me.getEntranceFee()
    tx = fund_me.fund({"from": account, "value": entrance_fee})
    tx.wait(1)
    assert fund_me.addressToAmountFunded(account.address) == entrance_fee
    tx2 = fund_me.withdraw({"from": account})
    tx2.wait(1)
    assert fund_me.addressToAmountFunded(account.address) == 0


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

Solution 4:[4]

I ran into the same issue. I stumbled upon a "solution" - launching a Ganache GUI. The puzzling thing is that the first test "test_can_fund_and_withdraw" cleared even without the Ganache GUI running.

Solution 5:[5]

Add return fund_me in the end of deploy_fund_me() method (deploy.py file). You can refer the code at https://github.com/PatrickAlphaC/brownie_fund_me/blob/main/scripts/deploy.py (author: Patrick Collins - He is really awesome!)

If that does not work. Upgrade Brownie version to 1.18.1 (mentioned like this answer: https://stackoverflow.com/a/71551313/304751). ou can upgrade to latest version (currently 1.18.1). One of solutions to upgrade is following steps:

  1. Run pip uninstall eth-brownie

  2. Clone Brownie source from https://github.com/eth-brownie/brownie.git

  3. Go to cloned folder, run $python setup.py install

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Duderino
Solution 2 Riccardo Biffi
Solution 3 ATAKPU IKHIDE
Solution 4 Jim B
Solution 5