support: do not clear sys.exc_info if can be preserved (greenlet >= 0.3.2)

This commit is contained in:
Edward George
2012-12-12 22:25:22 +00:00
committed by Sergey Shepelev
parent 2adaeb6159
commit 0195326cbe
3 changed files with 73 additions and 2 deletions

View File

@@ -1,4 +1,8 @@
import sys
from eventlet.support import greenlets
def get_errno(exc):
""" Get the error code out of socket.error objects.
socket.error in <2.5 does not have errno attribute
@@ -18,7 +22,7 @@ def get_errno(exc):
except IndexError:
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
else:
def clear_sys_exc_info():

View File

@@ -1,7 +1,11 @@
import distutils.version
try:
import greenlet
getcurrent = greenlet.greenlet.getcurrent
GreenletExit = greenlet.greenlet.GreenletExit
preserves_excinfo = (distutils.version.LooseVersion(greenlet.__version__)
>= distutils.version.LooseVersion('0.3.2'))
greenlet = greenlet.greenlet
except ImportError, e:
raise
@@ -9,14 +13,17 @@ except ImportError, e:
from py.magic import greenlet
getcurrent = greenlet.getcurrent
GreenletExit = greenlet.GreenletExit
preserves_excinfo = False
except ImportError:
try:
from stackless import greenlet
getcurrent = greenlet.getcurrent
GreenletExit = greenlet.GreenletExit
preserves_excinfo = False
except ImportError:
try:
from support.stacklesss import greenlet, getcurrent, GreenletExit
preserves_excinfo = False
(greenlet, getcurrent, GreenletExit) # silence pyflakes
except ImportError, e:
raise ImportError("Unable to find an implementation of greenlet.")

View File

@@ -1,10 +1,14 @@
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 eventlet
from eventlet import hubs
from eventlet.green import socket
from eventlet.event import Event
from eventlet.semaphore import Semaphore
from eventlet.support import greenlets
DELAY = 0.001
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)
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):
def test_explicit_hub(self):
if getattr(hubs.get_hub(), 'uses_twisted_reactor', None):