support: do not clear sys.exc_info if can be preserved (greenlet >= 0.3.2)
This commit is contained in:

committed by
Sergey Shepelev

parent
2adaeb6159
commit
0195326cbe
@@ -1,4 +1,8 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from eventlet.support import greenlets
|
||||||
|
|
||||||
|
|
||||||
def get_errno(exc):
|
def get_errno(exc):
|
||||||
""" Get the error code out of socket.error objects.
|
""" Get the error code out of socket.error objects.
|
||||||
socket.error in <2.5 does not have errno attribute
|
socket.error in <2.5 does not have errno attribute
|
||||||
@@ -18,7 +22,7 @@ def get_errno(exc):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if sys.version_info[0]<3:
|
if sys.version_info[0]<3 and not greenlets.preserves_excinfo:
|
||||||
from sys import exc_clear as clear_sys_exc_info
|
from sys import exc_clear as clear_sys_exc_info
|
||||||
else:
|
else:
|
||||||
def clear_sys_exc_info():
|
def clear_sys_exc_info():
|
||||||
|
@@ -1,7 +1,11 @@
|
|||||||
|
import distutils.version
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import greenlet
|
import greenlet
|
||||||
getcurrent = greenlet.greenlet.getcurrent
|
getcurrent = greenlet.greenlet.getcurrent
|
||||||
GreenletExit = greenlet.greenlet.GreenletExit
|
GreenletExit = greenlet.greenlet.GreenletExit
|
||||||
|
preserves_excinfo = (distutils.version.LooseVersion(greenlet.__version__)
|
||||||
|
>= distutils.version.LooseVersion('0.3.2'))
|
||||||
greenlet = greenlet.greenlet
|
greenlet = greenlet.greenlet
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
raise
|
raise
|
||||||
@@ -9,14 +13,17 @@ except ImportError, e:
|
|||||||
from py.magic import greenlet
|
from py.magic import greenlet
|
||||||
getcurrent = greenlet.getcurrent
|
getcurrent = greenlet.getcurrent
|
||||||
GreenletExit = greenlet.GreenletExit
|
GreenletExit = greenlet.GreenletExit
|
||||||
|
preserves_excinfo = False
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from stackless import greenlet
|
from stackless import greenlet
|
||||||
getcurrent = greenlet.getcurrent
|
getcurrent = greenlet.getcurrent
|
||||||
GreenletExit = greenlet.GreenletExit
|
GreenletExit = greenlet.GreenletExit
|
||||||
|
preserves_excinfo = False
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
from support.stacklesss import greenlet, getcurrent, GreenletExit
|
from support.stacklesss import greenlet, getcurrent, GreenletExit
|
||||||
|
preserves_excinfo = False
|
||||||
(greenlet, getcurrent, GreenletExit) # silence pyflakes
|
(greenlet, getcurrent, GreenletExit) # silence pyflakes
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
raise ImportError("Unable to find an implementation of greenlet.")
|
raise ImportError("Unable to find an implementation of greenlet.")
|
||||||
|
@@ -1,10 +1,14 @@
|
|||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
|
import sys
|
||||||
|
|
||||||
from tests import LimitedTestCase, main, skip_with_pyevent, skip_if_no_itimer
|
from tests import LimitedTestCase, main, skip_with_pyevent, skip_if_no_itimer, skip_unless
|
||||||
import time
|
import time
|
||||||
import eventlet
|
import eventlet
|
||||||
from eventlet import hubs
|
from eventlet import hubs
|
||||||
from eventlet.green import socket
|
from eventlet.green import socket
|
||||||
|
from eventlet.event import Event
|
||||||
|
from eventlet.semaphore import Semaphore
|
||||||
|
from eventlet.support import greenlets
|
||||||
|
|
||||||
DELAY = 0.001
|
DELAY = 0.001
|
||||||
def noop():
|
def noop():
|
||||||
@@ -132,6 +136,62 @@ class TestExceptionInMainloop(LimitedTestCase):
|
|||||||
assert delay >= DELAY*0.9, 'sleep returned after %s seconds (was scheduled for %s)' % (delay, DELAY)
|
assert delay >= DELAY*0.9, 'sleep returned after %s seconds (was scheduled for %s)' % (delay, DELAY)
|
||||||
|
|
||||||
|
|
||||||
|
class TestExceptionInGreenthread(LimitedTestCase):
|
||||||
|
@skip_unless(greenlets.preserves_excinfo)
|
||||||
|
def test_exceptionpreservation(self):
|
||||||
|
# events for controlling execution order
|
||||||
|
gt1event = Event()
|
||||||
|
gt2event = Event()
|
||||||
|
|
||||||
|
def test_gt1():
|
||||||
|
try:
|
||||||
|
raise KeyError()
|
||||||
|
except KeyError:
|
||||||
|
gt1event.send('exception')
|
||||||
|
gt2event.wait()
|
||||||
|
assert sys.exc_info()[0] is KeyError
|
||||||
|
gt1event.send('test passed')
|
||||||
|
|
||||||
|
def test_gt2():
|
||||||
|
gt1event.wait()
|
||||||
|
gt1event.reset()
|
||||||
|
assert sys.exc_info()[0] is None
|
||||||
|
try:
|
||||||
|
raise ValueError()
|
||||||
|
except ValueError:
|
||||||
|
gt2event.send('exception')
|
||||||
|
gt1event.wait()
|
||||||
|
assert sys.exc_info()[0] is ValueError
|
||||||
|
|
||||||
|
g1 = eventlet.spawn(test_gt1)
|
||||||
|
g2 = eventlet.spawn(test_gt2)
|
||||||
|
try:
|
||||||
|
g1.wait()
|
||||||
|
g2.wait()
|
||||||
|
finally:
|
||||||
|
g1.kill()
|
||||||
|
g2.kill()
|
||||||
|
|
||||||
|
def test_exceptionleaks(self):
|
||||||
|
# tests expected behaviour with all versions of greenlet
|
||||||
|
def test_gt(sem):
|
||||||
|
try:
|
||||||
|
raise KeyError()
|
||||||
|
except KeyError:
|
||||||
|
sem.release()
|
||||||
|
hubs.get_hub().switch()
|
||||||
|
|
||||||
|
# semaphores for controlling execution order
|
||||||
|
sem = Semaphore()
|
||||||
|
sem.acquire()
|
||||||
|
g = eventlet.spawn(test_gt, sem)
|
||||||
|
try:
|
||||||
|
sem.acquire()
|
||||||
|
assert sys.exc_info()[0] is None
|
||||||
|
finally:
|
||||||
|
g.kill()
|
||||||
|
|
||||||
|
|
||||||
class TestHubSelection(LimitedTestCase):
|
class TestHubSelection(LimitedTestCase):
|
||||||
def test_explicit_hub(self):
|
def test_explicit_hub(self):
|
||||||
if getattr(hubs.get_hub(), 'uses_twisted_reactor', None):
|
if getattr(hubs.get_hub(), 'uses_twisted_reactor', None):
|
||||||
|
Reference in New Issue
Block a user