From: Ben Darnell Date: Sat, 10 Jun 2017 22:08:49 +0000 (-0400) Subject: ioloop,gen: Unify TimeoutErrors X-Git-Tag: v5.0.0~72^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edf1232c3502a3755c8e87e6fa63c7c63adf9b0f;p=thirdparty%2Ftornado.git ioloop,gen: Unify TimeoutErrors Fixes #1929 --- diff --git a/docs/gen.rst b/docs/gen.rst index 52c7f55d9..cf42269fb 100644 --- a/docs/gen.rst +++ b/docs/gen.rst @@ -21,7 +21,6 @@ .. autoexception:: Return .. autofunction:: with_timeout - .. autoexception:: TimeoutError .. autofunction:: sleep diff --git a/docs/releases/v4.2.0.rst b/docs/releases/v4.2.0.rst index d94843796..93493ee11 100644 --- a/docs/releases/v4.2.0.rst +++ b/docs/releases/v4.2.0.rst @@ -49,7 +49,7 @@ be unlocked *without* acquiring it. This encouraged unorthodox patterns; in Tornado, just use `~.Semaphore.acquire`. Toro's ``Event.wait`` raised a ``Timeout`` exception after a timeout. In -Tornado, `.Event.wait` raises `tornado.gen.TimeoutError`. +Tornado, `.Event.wait` raises ``tornado.gen.TimeoutError``. Toro's ``Condition.wait`` also raised ``Timeout``, but in Tornado, the `.Future` returned by `.Condition.wait` resolves to False after a timeout:: diff --git a/tornado/gen.py b/tornado/gen.py index 2e9e9a6a8..5558f986f 100644 --- a/tornado/gen.py +++ b/tornado/gen.py @@ -89,7 +89,7 @@ from tornado.concurrent import Future, TracebackFuture, is_future, chain_future from tornado.ioloop import IOLoop from tornado.log import app_log from tornado import stack_context -from tornado.util import PY3, raise_exc_info +from tornado.util import PY3, raise_exc_info, TimeoutError try: try: @@ -154,10 +154,6 @@ class ReturnValueIgnoredError(Exception): pass -class TimeoutError(Exception): - """Exception raised by ``with_timeout``.""" - - def _value_from_stopiteration(e): try: # StopIteration has a value attribute beginning in py33. @@ -871,10 +867,10 @@ def maybe_future(x): def with_timeout(timeout, future, quiet_exceptions=()): """Wraps a `.Future` (or other yieldable object) in a timeout. - Raises `TimeoutError` if the input future does not complete before - ``timeout``, which may be specified in any form allowed by - `.IOLoop.add_timeout` (i.e. a `datetime.timedelta` or an absolute time - relative to `.IOLoop.time`) + Raises `tornado.util.TimeoutError` if the input future does not + complete before ``timeout``, which may be specified in any form + allowed by `.IOLoop.add_timeout` (i.e. a `datetime.timedelta` or + an absolute time relative to `.IOLoop.time`) If the wrapped `.Future` fails after it has timed out, the exception will be logged unless it is of a type contained in ``quiet_exceptions`` diff --git a/tornado/ioloop.py b/tornado/ioloop.py index 0527e9222..73d0cbdb7 100644 --- a/tornado/ioloop.py +++ b/tornado/ioloop.py @@ -48,7 +48,7 @@ from tornado.concurrent import TracebackFuture, is_future from tornado.log import app_log, gen_log from tornado.platform.auto import set_close_exec, Waker from tornado import stack_context -from tornado.util import PY3, Configurable, errno_from_exception, timedelta_to_seconds +from tornado.util import PY3, Configurable, errno_from_exception, timedelta_to_seconds, TimeoutError try: import signal @@ -70,10 +70,6 @@ except ImportError: _POLL_TIMEOUT = 3600.0 -class TimeoutError(Exception): - pass - - class IOLoop(Configurable): """A level-triggered I/O loop. @@ -457,7 +453,7 @@ class IOLoop(Configurable): The keyword-only argument ``timeout`` may be used to set a maximum duration for the function. If the timeout expires, - a `TimeoutError` is raised. + a `tornado.util.TimeoutError` is raised. This method is useful in conjunction with `tornado.gen.coroutine` to allow asynchronous calls in a ``main()`` function:: diff --git a/tornado/locks.py b/tornado/locks.py index 4f9ecf6df..c883aa234 100644 --- a/tornado/locks.py +++ b/tornado/locks.py @@ -99,7 +99,7 @@ class Condition(_TimeoutGarbageCollector): # Wait up to 1 second. yield condition.wait(timeout=datetime.timedelta(seconds=1)) - The method raises `tornado.gen.TimeoutError` if there's no notification + The method raises `tornado.util.TimeoutError` if there's no notification before the deadline. """ @@ -220,7 +220,7 @@ class Event(object): def wait(self, timeout=None): """Block until the internal flag is true. - Returns a Future, which raises `tornado.gen.TimeoutError` after a + Returns a Future, which raises `tornado.util.TimeoutError` after a timeout. """ if timeout is None: @@ -480,7 +480,7 @@ class Lock(object): def acquire(self, timeout=None): """Attempt to lock. Returns a Future. - Returns a Future, which raises `tornado.gen.TimeoutError` after a + Returns a Future, which raises `tornado.util.TimeoutError` after a timeout. """ return self._block.acquire(timeout) diff --git a/tornado/queues.py b/tornado/queues.py index 00fa4e22c..735896116 100644 --- a/tornado/queues.py +++ b/tornado/queues.py @@ -166,7 +166,7 @@ class Queue(object): def put(self, item, timeout=None): """Put an item into the queue, perhaps waiting until there is room. - Returns a Future, which raises `tornado.gen.TimeoutError` after a + Returns a Future, which raises `tornado.util.TimeoutError` after a timeout. ``timeout`` may be a number denoting a time (on the same @@ -204,7 +204,7 @@ class Queue(object): """Remove and return an item from the queue. Returns a Future which resolves once an item is available, or raises - `tornado.gen.TimeoutError` after a timeout. + `tornado.util.TimeoutError` after a timeout. ``timeout`` may be a number denoting a time (on the same scale as `tornado.ioloop.IOLoop.time`, normally `time.time`), or a @@ -258,7 +258,7 @@ class Queue(object): def join(self, timeout=None): """Block until all items in the queue are processed. - Returns a Future, which raises `tornado.gen.TimeoutError` after a + Returns a Future, which raises `tornado.util.TimeoutError` after a timeout. """ return self._finished.wait(timeout) diff --git a/tornado/test/import_test.py b/tornado/test/import_test.py index 88d02e027..d8cf14a55 100644 --- a/tornado/test/import_test.py +++ b/tornado/test/import_test.py @@ -45,3 +45,9 @@ class ImportTest(unittest.TestCase): pass else: import tornado.curl_httpclient + + def test_import_aliases(self): + # Ensure we don't delete formerly-documented aliases accidentally. + import tornado.ioloop, tornado.gen, tornado.util + self.assertIs(tornado.ioloop.TimeoutError, tornado.util.TimeoutError) + self.assertIs(tornado.gen.TimeoutError, tornado.util.TimeoutError) diff --git a/tornado/util.py b/tornado/util.py index bfd80beb6..aee718aee 100644 --- a/tornado/util.py +++ b/tornado/util.py @@ -84,6 +84,16 @@ except ImportError: is_finalizing = _get_emulated_is_finalizing() +class TimeoutError(Exception): + """Exception raised by `.with_timeout` and `.IOLoop.run_sync`. + + .. versionchanged:: 5.0: + Unified ``tornado.gen.TimeoutError`` and + ``tornado.ioloop.TimeoutError`` as ``tornado.util.TimeoutError``. + Both former names remain as aliases. + """ + + class ObjectDict(_ObjectDictBase): """Makes a dictionary behave like an object, with attribute-style access. """