FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

use Contextmanagers to handle StopIteration in generators by RonnyPfannschmidt · Pull Request #12934 · pytest-dev/pytest · GitHub

use Contextmanagers to handle StopIteration in generators - #12934

Merged
graingert merged 13 commits into
pytest-dev:mainfrom
RonnyPfannschmidt:bug-stopiteration-hook
May 31, 2025
Merged

use Contextmanagers to handle StopIteration in generators#12934
graingert merged 13 commits into
pytest-dev:mainfrom
RonnyPfannschmidt:bug-stopiteration-hook

Conversation

Copy link
Copy Markdown
Member
  • prepare example test for stopiteration passover issue
  • WIP: use contextmanagers instead of yield from

yield from is a generator boundary that transfers StopIteration into a RuntimeError

closes #12929

RonnyPfannschmidt added this to the 8.4 milestone Nov 12, 2024

graingert commented Dec 9, 2024
edited
Loading

Copy link
Copy Markdown
Member

src/_pytest/threadexception.py and src/_pytest/unraisableexception.py both use regular trylast hooks instead of generators, so the conflicts can be resolved by checking them out from main

Copy link
Copy Markdown
Member

this won't pass without a new Pluggy release

Copy link
Copy Markdown
Member

@RonnyPfannschmidt what is the status here? Do you plan to make a pluggy release yourself?

Copy link
Copy Markdown
Member Author

Indeed

I intend to give this priority by the end of the month

as it turns out, StopIteration is not transparent on the boundaries of generators

# Conflicts:
#	src/_pytest/threadexception.py
#	src/_pytest/unraisableexception.py

Copy link
Copy Markdown
Member

@RonnyPfannschmidt I wrote some test cases for this, I hope you find them useful:

def test_stop_iteration_from_collect(pytester: Pytester) -> None:
    pytester.makepyfile(test_it="raise StopIteration('hello')")
    result = pytester.runpytest()
    assert result.ret == ExitCode.INTERRUPTED
    result.assert_outcomes(failed=0, passed=0, errors=1)
    result.stdout.fnmatch_lines(
        [
            "=========================== short test summary info ============================",
            "ERROR test_it.py - StopIteration: hello",
            "!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!",
            "=============================== 1 error in * ===============================",
        ]
    )


def test_stop_iteration_runtest_protocol(pytester: Pytester) -> None:
    pytester.makepyfile(
        test_it="""
        import pytest
        @pytest.fixture
        def fail_setup():
            raise StopIteration(1)
        def test_fail_setup(fail_setup):
            pass
        def test_fail_teardown(request):
            def stop_iteration():
                raise StopIteration(2)
            request.addfinalizer(stop_iteration)
        def test_fail_call():
            raise StopIteration(3)
        """
    )
    result = pytester.runpytest()
    assert result.ret == ExitCode.TESTS_FAILED
    result.assert_outcomes(failed=1, passed=1, errors=2)
    result.stdout.fnmatch_lines(
        [
            "=========================== short test summary info ============================",
            "FAILED test_it.py::test_fail_call - StopIteration: 3",
            "ERROR test_it.py::test_fail_setup - StopIteration: 1",
            "ERROR test_it.py::test_fail_teardown - StopIteration: 2",
            "==================== 1 failed, 1 passed, 2 errors in * =====================",
        ]
    )

Copy link
Copy Markdown
Member

note this is still currently blocked by a release of pytest-dev/pluggy#545

Copy link
Copy Markdown
Member Author

i intend to land pytest-dev/pluggy#546 as before the next release of pluggy

psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label May 31, 2025
graingert marked this pull request as ready for review May 31, 2025 18:27
graingert requested review from jakkdl and nicoddemus May 31, 2025 18:27

Copy link
Copy Markdown
Member Author

im ok with squashing

graingert merged commit 075c5ef into pytest-dev:main May 31, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tests raising StopIteration break pytest/pluggy

4 participants


Back | FazBrowse Home | New Git URL