diff --git a/src/ape/pytest/fixtures.py b/src/ape/pytest/fixtures.py index 0f9ede3b70..25b01c54a6 100644 --- a/src/ape/pytest/fixtures.py +++ b/src/ape/pytest/fixtures.py @@ -94,12 +94,16 @@ def _isolation(self) -> Iterator[None]: snapshot_id = None if self._track_transactions: + did_yield = False try: with self.receipt_capture: yield + did_yield = True except BlockNotFoundError: - yield + if not did_yield: + # Prevent double yielding. + yield else: yield diff --git a/tests/functional/test_fixtures.py b/tests/functional/test_fixtures.py new file mode 100644 index 0000000000..dd9ee8919b --- /dev/null +++ b/tests/functional/test_fixtures.py @@ -0,0 +1,31 @@ +import pytest + +from ape.exceptions import BlockNotFoundError +from ape.pytest.fixtures import PytestApeFixtures + + +@pytest.fixture +def receipt_capture(mocker): + return mocker.MagicMock() + + +@pytest.fixture +def fixtures(mocker, receipt_capture): + return PytestApeFixtures(mocker.MagicMock(), receipt_capture) + + +@pytest.fixture +def isolation(fixtures): + return fixtures._isolation() + + +def test_isolation(isolation, receipt_capture): + # Set up receipt capture to fail on __exit__ + # AFTER the yield statement. There was a bug + # where we got a double-yield in this situation. + + receipt_capture.__exit__.side_effect = BlockNotFoundError(0) + + assert next(isolation) is None + with pytest.raises(StopIteration): + next(isolation)