Commit 3c7d4fb9 authored by Jason Madden's avatar Jason Madden

Unwrap a FileObjectThread before printing errors to it in the hub

Fixes #825.
parent d3e7ad56
...@@ -114,6 +114,9 @@ Other Changes ...@@ -114,6 +114,9 @@ Other Changes
- :class:`gevent.hub.signal` (aka :func:`gevent.signal`) now verifies - :class:`gevent.hub.signal` (aka :func:`gevent.signal`) now verifies
that its `handler` argument is callable, raising a :exc:`TypeError` that its `handler` argument is callable, raising a :exc:`TypeError`
if it isn't. Reported in :issue:`818` by Peter Renström. if it isn't. Reported in :issue:`818` by Peter Renström.
- If ``sys.stderr`` has been monkey-patched (not recommended),
exceptions that the hub reports aren't lost and can still be caught.
Reported in :issue:`825` by Jelle Smet.
1.1.1 (Apr 4, 2016) 1.1.1 (Apr 4, 2016)
=================== ===================
......
...@@ -582,8 +582,13 @@ class Hub(RawGreenlet): ...@@ -582,8 +582,13 @@ class Hub(RawGreenlet):
.. versionadded:: 1.2a1 .. versionadded:: 1.2a1
""" """
# Unwrap any FileObjectThread we have thrown around sys.stderr
return sys.stderr # (because it can't be used in the hub). Tricky because we are
# called in error situations when it's not safe to import.
stderr = sys.stderr
if type(stderr).__name__ == 'FileObjectThread':
stderr = stderr.io
return stderr
def print_exception(self, context, type, value, tb): def print_exception(self, context, type, value, tb):
# Python 3 does not gracefully handle None value or tb in # Python 3 does not gracefully handle None value or tb in
......
...@@ -12,9 +12,15 @@ MSG = 'should be re-raised and caught' ...@@ -12,9 +12,15 @@ MSG = 'should be re-raised and caught'
class Test(greentest.TestCase): class Test(greentest.TestCase):
x = None
error_fatal = False error_fatal = False
def start(self, *args):
raise NotImplementedError
def setUp(self):
self.x = None
def test_sys_exit(self): def test_sys_exit(self):
self.start(sys.exit, MSG) self.start(sys.exit, MSG)
...@@ -35,6 +41,19 @@ class Test(greentest.TestCase): ...@@ -35,6 +41,19 @@ class Test(greentest.TestCase):
else: else:
raise AssertionError('must raise KeyboardInterrupt') raise AssertionError('must raise KeyboardInterrupt')
def test_keyboard_interrupt_stderr_patched(self):
from gevent import monkey
monkey.patch_sys(stdin=False, stdout=False, stderr=True)
try:
try:
self.start(raise_, KeyboardInterrupt)
while True:
gevent.sleep(0.1)
except KeyboardInterrupt:
pass # expected
finally:
sys.stderr = monkey.get_original('sys', 'stderr')
def test_system_error(self): def test_system_error(self):
self.start(raise_, SystemError(MSG)) self.start(raise_, SystemError(MSG))
...@@ -53,6 +72,7 @@ class Test(greentest.TestCase): ...@@ -53,6 +72,7 @@ class Test(greentest.TestCase):
class TestCallback(Test): class TestCallback(Test):
def tearDown(self): def tearDown(self):
if self.x is not None:
assert not self.x.pending, self.x assert not self.x.pending, self.x
def start(self, *args): def start(self, *args):
...@@ -63,6 +83,7 @@ class TestSpawn(Test): ...@@ -63,6 +83,7 @@ class TestSpawn(Test):
def tearDown(self): def tearDown(self):
gevent.sleep(0.0001) gevent.sleep(0.0001)
if self.x is not None:
assert self.x.dead, self.x assert self.x.dead, self.x
def start(self, *args): def start(self, *args):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment