'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:
Run
pip uninstall eth-brownie
Clone Brownie source from
https://github.com/eth-brownie/brownie.git
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 |