-
Notifications
You must be signed in to change notification settings - Fork 24
Unhandled exception somewhere within use of gatherResults causes test to hang #61
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
Comments
Your example does hang for me as well. So does this. import pytest
import pytest_twisted
from twisted.internet.defer import inlineCallbacks, Deferred, gatherResults
@inlineCallbacks
def thingy():
d1 = Deferred()
d2 = Deferred()
yield d1
yield d2
@pytest_twisted.inlineCallbacks
def test_thingy():
result = yield thingy() Wouldn't you need to import pytest_twisted
from twisted.internet.defer import inlineCallbacks, Deferred, gatherResults
@inlineCallbacks
def thingy():
d1 = Deferred()
d2 = Deferred()
d1.callback(1)
d2.callback(2)
result = yield gatherResults([d1, d2], consumeErrors=True)
return result
@pytest_twisted.inlineCallbacks
def test_thingy():
result = yield thingy()
assert result == [1, 2] The fixture just makes a 'best effort' to fail tests when you leave an errback unhandled. Such as below. import gc
import pytest
import twisted.internet.defer
import twisted.logger
class Observer:
def __init__(self):
self.failures = []
def __call__(self, event_dict):
is_error = event_dict.get('isError')
s = 'Unhandled error in Deferred'.casefold()
is_unhandled = s in event_dict.get('log_format', '').casefold()
if is_error and is_unhandled:
self.failures.append(event_dict)
def assert_empty(self):
assert [] == self.failures
@pytest.fixture
def assert_no_unhandled_errbacks():
observer = Observer()
twisted.logger.globalLogPublisher.addObserver(observer)
yield
gc.collect()
twisted.logger.globalLogPublisher.removeObserver(observer)
observer.assert_empty()
def test_thingy(assert_no_unhandled_errbacks):
d = twisted.internet.defer.Deferred()
d.errback(2) I'm guessing there's another example behind this that is closer to a 'real' problem? Or, maybe I missed something here. Cheers, |
@altendky Well, that is odd: in the production code, when I commented out the gatherResults and yielded in sequence on the deferreds, the test ran fine. But it looks like I do see the same problem on the small example like you said.
That's the point of gatherResults, right? To fire their callbacks and return when all deferreds are fired? I think passing gatherResults already-fired callbacks makes gatherResults a no-op. |
Sure, manually calling https://twistedmatrix.com/documents/current/api/twisted.internet.defer.gatherResults.html
Neither |
OK, that makes sense. I need to mock out the resolution of those deferreds. Honestly I wouldn't have posted this if my serial evaluation had failed in the original context >:( Since that one succeeded I thought I was onto something at the time. I'll have to think here a bit about what to patch... |
If you want to share more I can take a look and see if I can help. Here or on IRC in |
@altendky I wound up setting the return_value on the mock'd functions to a fired deferred, and everything works now. Perhaps not the most elegant, but it makes sense now! Thanks for your help. |
Please try this:
This hangs indefinitely for me when I run
pytest
against it. I was having the problem with python=3.7, pytest=4.3.0 and pytest-twisted=1.9, although I initially encountered it in a context where I was running python=2.7, pytest=3.1.2, pytest-twisted=1.5.It does not appear to make a difference what consumerErrors is set to. Of course, yielding on the deferreds sequentially and not using gatherResults works fine.
The test hangs until you CTRL-C, where you see something like this:
I learned that this error message probably stemmed from an unhandled exception at this post: #4
I tried the fixture suggested recently at that post, but it did not change the problem I was having.
The text was updated successfully, but these errors were encountered: