diff --git a/eventlet/timeout.py b/eventlet/timeout.py index 135545b..573f4ab 100644 --- a/eventlet/timeout.py +++ b/eventlet/timeout.py @@ -57,7 +57,7 @@ class Timeout(BaseException): '%r is already started; to restart it, cancel it first' % self if self.seconds is None: # "fake" timeout (never expires) self.timer = None - elif self.exception is None or self.exception is False: # timeout that raises self + elif self.exception is None or isinstance(self.exception, bool): # timeout that raises self self.timer = get_hub().schedule_call_global( self.seconds, greenlet.getcurrent().throw, self) else: # regular timeout with user-provided exception @@ -112,7 +112,7 @@ class Timeout(BaseException): suffix = '' else: suffix = 's' - if self.exception is None: + if self.exception is None or self.exception is True: return '%s second%s' % (self.seconds, suffix) elif self.exception is False: return '%s second%s (silent)' % (self.seconds, suffix) diff --git a/examples/producer_consumer.py b/examples/producer_consumer.py index b335f7d..6f6c82f 100644 --- a/examples/producer_consumer.py +++ b/examples/producer_consumer.py @@ -2,7 +2,7 @@ it doesn't respect robots.txt and it is pretty brutal about how quickly it fetches pages. -This is a kind of "producer/consumer" example; the producer function produces +This is a kind of "producer/consumer" example; the fetch function produces jobs, and the GreenPool itself is the consumer, farming out work concurrently. It's easier to write it this way rather than writing a standard consumer loop; GreenPool handles any exceptions raised and arranges so that there's a set @@ -43,10 +43,10 @@ def producer(start_url): # limit requests to eventlet.net so we don't crash all over the internet if url not in seen and 'eventlet.net' in url: seen.add(url) - pool.spawn(fetch, url, q) + pool.spawn_n(fetch, url, q) return seen seen = producer("http://eventlet.net") print "I saw these urls:" -print "\n".join(seen) \ No newline at end of file +print "\n".join(seen) diff --git a/tests/timeout_test_with_statement.py b/tests/timeout_test_with_statement.py index 48fe0b5..21779ce 100644 --- a/tests/timeout_test_with_statement.py +++ b/tests/timeout_test_with_statement.py @@ -15,7 +15,7 @@ class Error(Exception): pass class Test(LimitedTestCase): - def test_api(self): + def test_cancellation(self): # Nothing happens if with-block finishes before the timeout expires t = Timeout(DELAY*2) sleep(0) # make it pending @@ -27,6 +27,7 @@ class Test(LimitedTestCase): assert not t.pending, repr(t) sleep(DELAY*2) + def test_raising_self(self): # An exception will be raised if it's not try: with Timeout(DELAY) as t: @@ -36,6 +37,17 @@ class Test(LimitedTestCase): else: raise AssertionError('must raise Timeout') + def test_raising_self_true(self): + # specifying True as the exception raises self as well + try: + with Timeout(DELAY, True) as t: + sleep(DELAY*2) + except Timeout, ex: + assert ex is t, (ex, t) + else: + raise AssertionError('must raise Timeout') + + def test_raising_custom_exception(self): # You can customize the exception raised: try: with Timeout(DELAY, IOError("Operation takes way too long")): @@ -43,6 +55,7 @@ class Test(LimitedTestCase): except IOError, ex: assert str(ex)=="Operation takes way too long", repr(ex) + def test_raising_exception_class(self): # Providing classes instead of values should be possible too: try: with Timeout(DELAY, ValueError): @@ -50,6 +63,7 @@ class Test(LimitedTestCase): except ValueError: pass + def test_raising_exc_tuple(self): try: 1//0 except: @@ -63,12 +77,16 @@ class Test(LimitedTestCase): else: raise AssertionError('should not get there') + def test_cancel_timer_inside_block(self): # It's possible to cancel the timer inside the block: with Timeout(DELAY) as timer: timer.cancel() sleep(DELAY*2) - # To silent the exception before exiting the block, pass False as second parameter. + + def test_silent_block(self): + # To silence the exception before exiting the block, pass + # False as second parameter. XDELAY=0.1 start = time.time() with Timeout(XDELAY, False): @@ -76,6 +94,8 @@ class Test(LimitedTestCase): delta = (time.time()-start) assert delta