summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYury Selivanov <yury@magic.io>2016-06-08 13:57:03 -0400
committerYury Selivanov <yury@magic.io>2016-06-08 13:57:03 -0400
commite4502c9fc0ed27304466f421455805f507928cb0 (patch)
tree614f8a4e4ccb7ade2ffe402a8487133f9eb22cf5
parentc77db5a6008a43c7873b2929c65eb7fd44fb9818 (diff)
downloadcpython-e4502c9fc0ed27304466f421455805f507928cb0.tar.gz
asyncio: Remove asyncio.timeout() context manager.
It will probably be added back in Python 3.6, once its compatibility issues are resolved; see [1] for more details. [1] https://mail.python.org/pipermail/async-sig/2016-June/000045.html
-rw-r--r--Doc/library/asyncio-task.rst16
-rw-r--r--Doc/whatsnew/3.5.rst4
-rw-r--r--Lib/asyncio/tasks.py53
-rw-r--r--Lib/test/test_asyncio/test_tasks.py187
4 files changed, 0 insertions, 260 deletions
diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst
index a1b69c8a66..de6ee58e92 100644
--- a/Doc/library/asyncio-task.rst
+++ b/Doc/library/asyncio-task.rst
@@ -662,22 +662,6 @@ Task functions
except CancelledError:
res = None
-.. function:: timeout(timeout, \*, loop=None)
-
- Return a context manager that cancels a block on *timeout* expiring::
-
- with timeout(1.5):
- yield from inner()
-
- 1. If ``inner()`` is executed faster than in ``1.5`` seconds
- nothing happens.
- 2. Otherwise ``inner()`` is cancelled internally but
- :exc:`asyncio.TimeoutError` is raised outside of
- context manager scope.
-
- Passing ``None`` as *timeout* argument disables the manager logic.
-
- .. versionadded:: 3.5.2
.. coroutinefunction:: wait(futures, \*, loop=None, timeout=None,\
return_when=ALL_COMPLETED)
diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst
index e3e73e4825..83d5ce694c 100644
--- a/Doc/whatsnew/3.5.rst
+++ b/Doc/whatsnew/3.5.rst
@@ -835,10 +835,6 @@ Updates in 3.5.2:
method to get the current exception handler.
(Contributed by Yury Selivanov.)
-* New :func:`~asyncio.timeout` context manager to simplify timeouts
- handling code.
- (Contributed by Andrew Svetlov.)
-
* New :meth:`StreamReader.readuntil() <asyncio.StreamReader.readuntil>`
method to read data from the stream until a separator bytes
sequence appears.
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index 81510ba8d4..0cca8e36a5 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -4,7 +4,6 @@ __all__ = ['Task',
'FIRST_COMPLETED', 'FIRST_EXCEPTION', 'ALL_COMPLETED',
'wait', 'wait_for', 'as_completed', 'sleep', 'async',
'gather', 'shield', 'ensure_future', 'run_coroutine_threadsafe',
- 'timeout',
]
import concurrent.futures
@@ -737,55 +736,3 @@ def run_coroutine_threadsafe(coro, loop):
loop.call_soon_threadsafe(callback)
return future
-
-
-def timeout(timeout, *, loop=None):
- """A factory which produce a context manager with timeout.
-
- Useful in cases when you want to apply timeout logic around block
- of code or in cases when asyncio.wait_for is not suitable.
-
- For example:
-
- >>> with asyncio.timeout(0.001):
- ... yield from coro()
-
-
- timeout: timeout value in seconds or None to disable timeout logic
- loop: asyncio compatible event loop
- """
- if loop is None:
- loop = events.get_event_loop()
- return _Timeout(timeout, loop=loop)
-
-
-class _Timeout:
- def __init__(self, timeout, *, loop):
- self._timeout = timeout
- self._loop = loop
- self._task = None
- self._cancelled = False
- self._cancel_handler = None
-
- def __enter__(self):
- self._task = Task.current_task(loop=self._loop)
- if self._task is None:
- raise RuntimeError('Timeout context manager should be used '
- 'inside a task')
- if self._timeout is not None:
- self._cancel_handler = self._loop.call_later(
- self._timeout, self._cancel_task)
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- if exc_type is futures.CancelledError and self._cancelled:
- self._cancel_handler = None
- self._task = None
- raise futures.TimeoutError
- if self._timeout is not None:
- self._cancel_handler.cancel()
- self._cancel_handler = None
- self._task = None
-
- def _cancel_task(self):
- self._cancelled = self._task.cancel()
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index 128b7ce9e5..e7fb774fca 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -2260,192 +2260,5 @@ class SleepTests(test_utils.TestCase):
self.assertEqual(result, 11)
-class TimeoutTests(test_utils.TestCase):
- def setUp(self):
- self.loop = asyncio.new_event_loop()
- asyncio.set_event_loop(None)
-
- def tearDown(self):
- self.loop.close()
- self.loop = None
-
- def test_timeout(self):
- canceled_raised = [False]
-
- @asyncio.coroutine
- def long_running_task():
- try:
- yield from asyncio.sleep(10, loop=self.loop)
- except asyncio.CancelledError:
- canceled_raised[0] = True
- raise
-
- @asyncio.coroutine
- def go():
- with self.assertRaises(asyncio.TimeoutError):
- with asyncio.timeout(0.01, loop=self.loop) as t:
- yield from long_running_task()
- self.assertIs(t._loop, self.loop)
-
- self.loop.run_until_complete(go())
- self.assertTrue(canceled_raised[0], 'CancelledError was not raised')
-
- def test_timeout_finish_in_time(self):
- @asyncio.coroutine
- def long_running_task():
- yield from asyncio.sleep(0.01, loop=self.loop)
- return 'done'
-
- @asyncio.coroutine
- def go():
- with asyncio.timeout(0.1, loop=self.loop):
- resp = yield from long_running_task()
- self.assertEqual(resp, 'done')
-
- self.loop.run_until_complete(go())
-
- def test_timeout_gloabal_loop(self):
- asyncio.set_event_loop(self.loop)
-
- @asyncio.coroutine
- def run():
- with asyncio.timeout(0.1) as t:
- yield from asyncio.sleep(0.01)
- self.assertIs(t._loop, self.loop)
-
- self.loop.run_until_complete(run())
-
- def test_timeout_not_relevant_exception(self):
- @asyncio.coroutine
- def go():
- yield from asyncio.sleep(0, loop=self.loop)
- with self.assertRaises(KeyError):
- with asyncio.timeout(0.1, loop=self.loop):
- raise KeyError
-
- self.loop.run_until_complete(go())
-
- def test_timeout_canceled_error_is_converted_to_timeout(self):
- @asyncio.coroutine
- def go():
- yield from asyncio.sleep(0, loop=self.loop)
- with self.assertRaises(asyncio.CancelledError):
- with asyncio.timeout(0.001, loop=self.loop):
- raise asyncio.CancelledError
-
- self.loop.run_until_complete(go())
-
- def test_timeout_blocking_loop(self):
- @asyncio.coroutine
- def long_running_task():
- time.sleep(0.05)
- return 'done'
-
- @asyncio.coroutine
- def go():
- with asyncio.timeout(0.01, loop=self.loop):
- result = yield from long_running_task()
- self.assertEqual(result, 'done')
-
- self.loop.run_until_complete(go())
-
- def test_for_race_conditions(self):
- fut = asyncio.Future(loop=self.loop)
- self.loop.call_later(0.1, fut.set_result('done'))
-
- @asyncio.coroutine
- def go():
- with asyncio.timeout(0.2, loop=self.loop):
- resp = yield from fut
- self.assertEqual(resp, 'done')
-
- self.loop.run_until_complete(go())
-
- def test_timeout_time(self):
- @asyncio.coroutine
- def go():
- foo_running = None
-
- start = self.loop.time()
- with self.assertRaises(asyncio.TimeoutError):
- with asyncio.timeout(0.1, loop=self.loop):
- foo_running = True
- try:
- yield from asyncio.sleep(0.2, loop=self.loop)
- finally:
- foo_running = False
-
- dt = self.loop.time() - start
- # tolerate a small delta for slow delta or unstable clocks
- self.assertTrue(0.09 < dt < 0.12, dt)
- self.assertFalse(foo_running)
-
- self.loop.run_until_complete(go())
-
- def test_timeout_disable(self):
- @asyncio.coroutine
- def long_running_task():
- yield from asyncio.sleep(0.1, loop=self.loop)
- return 'done'
-
- @asyncio.coroutine
- def go():
- t0 = self.loop.time()
- with asyncio.timeout(None, loop=self.loop):
- resp = yield from long_running_task()
- self.assertEqual(resp, 'done')
- dt = self.loop.time() - t0
- # tolerate a time delta for clocks with bad resolution
- # and slow buildbots
- self.assertTrue(0.09 < dt < 0.15, dt)
- self.loop.run_until_complete(go())
-
- def test_raise_runtimeerror_if_no_task(self):
- with self.assertRaises(RuntimeError):
- with asyncio.timeout(0.1, loop=self.loop):
- pass
-
- def test_outer_coro_is_not_cancelled(self):
-
- has_timeout = [False]
-
- @asyncio.coroutine
- def outer():
- try:
- with asyncio.timeout(0.001, loop=self.loop):
- yield from asyncio.sleep(1, loop=self.loop)
- except asyncio.TimeoutError:
- has_timeout[0] = True
-
- @asyncio.coroutine
- def go():
- task = asyncio.ensure_future(outer(), loop=self.loop)
- yield from task
- self.assertTrue(has_timeout[0])
- self.assertFalse(task.cancelled())
- self.assertTrue(task.done())
-
- self.loop.run_until_complete(go())
-
- def test_cancel_outer_coro(self):
- fut = asyncio.Future(loop=self.loop)
-
- @asyncio.coroutine
- def outer():
- fut.set_result(None)
- yield from asyncio.sleep(1, loop=self.loop)
-
- @asyncio.coroutine
- def go():
- task = asyncio.ensure_future(outer(), loop=self.loop)
- yield from fut
- task.cancel()
- with self.assertRaises(asyncio.CancelledError):
- yield from task
- self.assertTrue(task.cancelled())
- self.assertTrue(task.done())
-
- self.loop.run_until_complete(go())
-
if __name__ == '__main__':
unittest.main()