-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
subtests.test cannot be used inside a generator #66
Comments
Hi @pmeier, Thanks for the detailed report, appreciate it! If you have the time, please consider opening a pull request. 👍 |
I'll send a PR if I figure out how this can be solved. My current understanding is that first the FWIW, import unittest
class TestFoo(unittest.TestCase):
def gen(self, n):
for i in range(n):
with self.subTest(msg=str(i)):
yield i
def test_bar(self):
for i in self.gen(5):
assert i % 2 == 0 $ python -m unittest main.py
Exception ignored in: <generator object TestFoo.gen at 0x7f48747bf150>
RuntimeError: generator ignored GeneratorExit
F
======================================================================
ERROR: test_foo (main.TestFoo) [1]
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/user/main.py", line 33, in gen
yield i
GeneratorExit
======================================================================
FAIL: test_foo (main.TestFoo)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/user/main.py", line 37, in test_foo
assert i % 2 == 0
AssertionError
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1, errors=1)
|
If I'm reading this right
one cannot yield values after the first failure. This of course would completely defeat the purpose of a subtest. |
My best guess is that we are hitting a language limitation here: import contextlib
def gen(n):
for i in range(n):
print(f"Before yield {i}")
with contextlib.suppress(GeneratorExit):
yield i
print(f"After yield {i}")
for i in gen(3):
print(f"Processing {i}")
break
So, after the first |
its certainly a language "limitation", as its a intentionally NOT supported pattern and structurally its absolutely valid, we should go as far as letting subtest special case generator exit and taising a ProgrammingError, as structurally, the generator is intentionally disconnected from exceptions in the outer loop body, outer exception -> generator close @nicoddemus i propose ensuring subtests transfer generator-exits as is + triggering a warning for the subtest/test |
I can send a PR for that. What is the preferred way to warn users from inside a |
Imagine I have similar test case setup for multiple tests and I want to use
subtests
:This gives the following output
As you can see, although the
subtests.test
context manager is in place, the execution stops after the first failure. Since it is aFAILED
instead of aSUBFAILED
, one also misses out on the extra information the sub failure would print.Digging into the code, the problem is
pytest-subtests/pytest_subtests.py
Lines 168 to 171 in 90df760
not handling the
GeneratorExit
.The text was updated successfully, but these errors were encountered: