PageRenderTime 29ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/test/test_asyncio/test_tasks.py

https://bitbucket.org/jaraco/cpython-issue13540
Python | 1962 lines | 1536 code | 356 blank | 70 comment | 81 complexity | 1a8530048c0bc18f9dd943ed31a7f7d0 MD5 | raw file
Possible License(s): BSD-3-Clause, 0BSD
  1. """Tests for tasks.py."""
  2. import re
  3. import sys
  4. import types
  5. import unittest
  6. import weakref
  7. from test import support
  8. from test.script_helper import assert_python_ok
  9. from unittest import mock
  10. import asyncio
  11. from asyncio import coroutines
  12. from asyncio import test_utils
  13. PY34 = (sys.version_info >= (3, 4))
  14. PY35 = (sys.version_info >= (3, 5))
  15. @asyncio.coroutine
  16. def coroutine_function():
  17. pass
  18. def format_coroutine(qualname, state, src, source_traceback, generator=False):
  19. if generator:
  20. state = '%s' % state
  21. else:
  22. state = '%s, defined' % state
  23. if source_traceback is not None:
  24. frame = source_traceback[-1]
  25. return ('coro=<%s() %s at %s> created at %s:%s'
  26. % (qualname, state, src, frame[0], frame[1]))
  27. else:
  28. return 'coro=<%s() %s at %s>' % (qualname, state, src)
  29. class Dummy:
  30. def __repr__(self):
  31. return '<Dummy>'
  32. def __call__(self, *args):
  33. pass
  34. class TaskTests(test_utils.TestCase):
  35. def setUp(self):
  36. self.loop = self.new_test_loop()
  37. def test_task_class(self):
  38. @asyncio.coroutine
  39. def notmuch():
  40. return 'ok'
  41. t = asyncio.Task(notmuch(), loop=self.loop)
  42. self.loop.run_until_complete(t)
  43. self.assertTrue(t.done())
  44. self.assertEqual(t.result(), 'ok')
  45. self.assertIs(t._loop, self.loop)
  46. loop = asyncio.new_event_loop()
  47. self.set_event_loop(loop)
  48. t = asyncio.Task(notmuch(), loop=loop)
  49. self.assertIs(t._loop, loop)
  50. loop.run_until_complete(t)
  51. loop.close()
  52. def test_async_coroutine(self):
  53. @asyncio.coroutine
  54. def notmuch():
  55. return 'ok'
  56. t = asyncio.async(notmuch(), loop=self.loop)
  57. self.loop.run_until_complete(t)
  58. self.assertTrue(t.done())
  59. self.assertEqual(t.result(), 'ok')
  60. self.assertIs(t._loop, self.loop)
  61. loop = asyncio.new_event_loop()
  62. self.set_event_loop(loop)
  63. t = asyncio.async(notmuch(), loop=loop)
  64. self.assertIs(t._loop, loop)
  65. loop.run_until_complete(t)
  66. loop.close()
  67. def test_async_future(self):
  68. f_orig = asyncio.Future(loop=self.loop)
  69. f_orig.set_result('ko')
  70. f = asyncio.async(f_orig)
  71. self.loop.run_until_complete(f)
  72. self.assertTrue(f.done())
  73. self.assertEqual(f.result(), 'ko')
  74. self.assertIs(f, f_orig)
  75. loop = asyncio.new_event_loop()
  76. self.set_event_loop(loop)
  77. with self.assertRaises(ValueError):
  78. f = asyncio.async(f_orig, loop=loop)
  79. loop.close()
  80. f = asyncio.async(f_orig, loop=self.loop)
  81. self.assertIs(f, f_orig)
  82. def test_async_task(self):
  83. @asyncio.coroutine
  84. def notmuch():
  85. return 'ok'
  86. t_orig = asyncio.Task(notmuch(), loop=self.loop)
  87. t = asyncio.async(t_orig)
  88. self.loop.run_until_complete(t)
  89. self.assertTrue(t.done())
  90. self.assertEqual(t.result(), 'ok')
  91. self.assertIs(t, t_orig)
  92. loop = asyncio.new_event_loop()
  93. self.set_event_loop(loop)
  94. with self.assertRaises(ValueError):
  95. t = asyncio.async(t_orig, loop=loop)
  96. loop.close()
  97. t = asyncio.async(t_orig, loop=self.loop)
  98. self.assertIs(t, t_orig)
  99. def test_async_neither(self):
  100. with self.assertRaises(TypeError):
  101. asyncio.async('ok')
  102. def test_task_repr(self):
  103. self.loop.set_debug(False)
  104. @asyncio.coroutine
  105. def notmuch():
  106. yield from []
  107. return 'abc'
  108. # test coroutine function
  109. self.assertEqual(notmuch.__name__, 'notmuch')
  110. if PY35:
  111. self.assertEqual(notmuch.__qualname__,
  112. 'TaskTests.test_task_repr.<locals>.notmuch')
  113. self.assertEqual(notmuch.__module__, __name__)
  114. filename, lineno = test_utils.get_function_source(notmuch)
  115. src = "%s:%s" % (filename, lineno)
  116. # test coroutine object
  117. gen = notmuch()
  118. if coroutines._DEBUG or PY35:
  119. coro_qualname = 'TaskTests.test_task_repr.<locals>.notmuch'
  120. else:
  121. coro_qualname = 'notmuch'
  122. self.assertEqual(gen.__name__, 'notmuch')
  123. if PY35:
  124. self.assertEqual(gen.__qualname__,
  125. coro_qualname)
  126. # test pending Task
  127. t = asyncio.Task(gen, loop=self.loop)
  128. t.add_done_callback(Dummy())
  129. coro = format_coroutine(coro_qualname, 'running', src,
  130. t._source_traceback, generator=True)
  131. self.assertEqual(repr(t),
  132. '<Task pending %s cb=[<Dummy>()]>' % coro)
  133. # test cancelling Task
  134. t.cancel() # Does not take immediate effect!
  135. self.assertEqual(repr(t),
  136. '<Task cancelling %s cb=[<Dummy>()]>' % coro)
  137. # test cancelled Task
  138. self.assertRaises(asyncio.CancelledError,
  139. self.loop.run_until_complete, t)
  140. coro = format_coroutine(coro_qualname, 'done', src,
  141. t._source_traceback)
  142. self.assertEqual(repr(t),
  143. '<Task cancelled %s>' % coro)
  144. # test finished Task
  145. t = asyncio.Task(notmuch(), loop=self.loop)
  146. self.loop.run_until_complete(t)
  147. coro = format_coroutine(coro_qualname, 'done', src,
  148. t._source_traceback)
  149. self.assertEqual(repr(t),
  150. "<Task finished %s result='abc'>" % coro)
  151. def test_task_repr_coro_decorator(self):
  152. self.loop.set_debug(False)
  153. @asyncio.coroutine
  154. def notmuch():
  155. # notmuch() function doesn't use yield from: it will be wrapped by
  156. # @coroutine decorator
  157. return 123
  158. # test coroutine function
  159. self.assertEqual(notmuch.__name__, 'notmuch')
  160. if PY35:
  161. self.assertEqual(notmuch.__qualname__,
  162. 'TaskTests.test_task_repr_coro_decorator.<locals>.notmuch')
  163. self.assertEqual(notmuch.__module__, __name__)
  164. # test coroutine object
  165. gen = notmuch()
  166. if coroutines._DEBUG or PY35:
  167. # On Python >= 3.5, generators now inherit the name of the
  168. # function, as expected, and have a qualified name (__qualname__
  169. # attribute).
  170. coro_name = 'notmuch'
  171. coro_qualname = 'TaskTests.test_task_repr_coro_decorator.<locals>.notmuch'
  172. else:
  173. # On Python < 3.5, generators inherit the name of the code, not of
  174. # the function. See: http://bugs.python.org/issue21205
  175. coro_name = coro_qualname = 'coro'
  176. self.assertEqual(gen.__name__, coro_name)
  177. if PY35:
  178. self.assertEqual(gen.__qualname__, coro_qualname)
  179. # test repr(CoroWrapper)
  180. if coroutines._DEBUG:
  181. # format the coroutine object
  182. if coroutines._DEBUG:
  183. filename, lineno = test_utils.get_function_source(notmuch)
  184. frame = gen._source_traceback[-1]
  185. coro = ('%s() running, defined at %s:%s, created at %s:%s'
  186. % (coro_qualname, filename, lineno,
  187. frame[0], frame[1]))
  188. else:
  189. code = gen.gi_code
  190. coro = ('%s() running at %s:%s'
  191. % (coro_qualname, code.co_filename, code.co_firstlineno))
  192. self.assertEqual(repr(gen), '<CoroWrapper %s>' % coro)
  193. # test pending Task
  194. t = asyncio.Task(gen, loop=self.loop)
  195. t.add_done_callback(Dummy())
  196. # format the coroutine object
  197. if coroutines._DEBUG:
  198. src = '%s:%s' % test_utils.get_function_source(notmuch)
  199. else:
  200. code = gen.gi_code
  201. src = '%s:%s' % (code.co_filename, code.co_firstlineno)
  202. coro = format_coroutine(coro_qualname, 'running', src,
  203. t._source_traceback,
  204. generator=not coroutines._DEBUG)
  205. self.assertEqual(repr(t),
  206. '<Task pending %s cb=[<Dummy>()]>' % coro)
  207. self.loop.run_until_complete(t)
  208. def test_task_repr_wait_for(self):
  209. self.loop.set_debug(False)
  210. @asyncio.coroutine
  211. def wait_for(fut):
  212. return (yield from fut)
  213. fut = asyncio.Future(loop=self.loop)
  214. task = asyncio.Task(wait_for(fut), loop=self.loop)
  215. test_utils.run_briefly(self.loop)
  216. self.assertRegex(repr(task),
  217. '<Task .* wait_for=%s>' % re.escape(repr(fut)))
  218. fut.set_result(None)
  219. self.loop.run_until_complete(task)
  220. def test_task_basics(self):
  221. @asyncio.coroutine
  222. def outer():
  223. a = yield from inner1()
  224. b = yield from inner2()
  225. return a+b
  226. @asyncio.coroutine
  227. def inner1():
  228. return 42
  229. @asyncio.coroutine
  230. def inner2():
  231. return 1000
  232. t = outer()
  233. self.assertEqual(self.loop.run_until_complete(t), 1042)
  234. def test_cancel(self):
  235. def gen():
  236. when = yield
  237. self.assertAlmostEqual(10.0, when)
  238. yield 0
  239. loop = self.new_test_loop(gen)
  240. @asyncio.coroutine
  241. def task():
  242. yield from asyncio.sleep(10.0, loop=loop)
  243. return 12
  244. t = asyncio.Task(task(), loop=loop)
  245. loop.call_soon(t.cancel)
  246. with self.assertRaises(asyncio.CancelledError):
  247. loop.run_until_complete(t)
  248. self.assertTrue(t.done())
  249. self.assertTrue(t.cancelled())
  250. self.assertFalse(t.cancel())
  251. def test_cancel_yield(self):
  252. @asyncio.coroutine
  253. def task():
  254. yield
  255. yield
  256. return 12
  257. t = asyncio.Task(task(), loop=self.loop)
  258. test_utils.run_briefly(self.loop) # start coro
  259. t.cancel()
  260. self.assertRaises(
  261. asyncio.CancelledError, self.loop.run_until_complete, t)
  262. self.assertTrue(t.done())
  263. self.assertTrue(t.cancelled())
  264. self.assertFalse(t.cancel())
  265. def test_cancel_inner_future(self):
  266. f = asyncio.Future(loop=self.loop)
  267. @asyncio.coroutine
  268. def task():
  269. yield from f
  270. return 12
  271. t = asyncio.Task(task(), loop=self.loop)
  272. test_utils.run_briefly(self.loop) # start task
  273. f.cancel()
  274. with self.assertRaises(asyncio.CancelledError):
  275. self.loop.run_until_complete(t)
  276. self.assertTrue(f.cancelled())
  277. self.assertTrue(t.cancelled())
  278. def test_cancel_both_task_and_inner_future(self):
  279. f = asyncio.Future(loop=self.loop)
  280. @asyncio.coroutine
  281. def task():
  282. yield from f
  283. return 12
  284. t = asyncio.Task(task(), loop=self.loop)
  285. test_utils.run_briefly(self.loop)
  286. f.cancel()
  287. t.cancel()
  288. with self.assertRaises(asyncio.CancelledError):
  289. self.loop.run_until_complete(t)
  290. self.assertTrue(t.done())
  291. self.assertTrue(f.cancelled())
  292. self.assertTrue(t.cancelled())
  293. def test_cancel_task_catching(self):
  294. fut1 = asyncio.Future(loop=self.loop)
  295. fut2 = asyncio.Future(loop=self.loop)
  296. @asyncio.coroutine
  297. def task():
  298. yield from fut1
  299. try:
  300. yield from fut2
  301. except asyncio.CancelledError:
  302. return 42
  303. t = asyncio.Task(task(), loop=self.loop)
  304. test_utils.run_briefly(self.loop)
  305. self.assertIs(t._fut_waiter, fut1) # White-box test.
  306. fut1.set_result(None)
  307. test_utils.run_briefly(self.loop)
  308. self.assertIs(t._fut_waiter, fut2) # White-box test.
  309. t.cancel()
  310. self.assertTrue(fut2.cancelled())
  311. res = self.loop.run_until_complete(t)
  312. self.assertEqual(res, 42)
  313. self.assertFalse(t.cancelled())
  314. def test_cancel_task_ignoring(self):
  315. fut1 = asyncio.Future(loop=self.loop)
  316. fut2 = asyncio.Future(loop=self.loop)
  317. fut3 = asyncio.Future(loop=self.loop)
  318. @asyncio.coroutine
  319. def task():
  320. yield from fut1
  321. try:
  322. yield from fut2
  323. except asyncio.CancelledError:
  324. pass
  325. res = yield from fut3
  326. return res
  327. t = asyncio.Task(task(), loop=self.loop)
  328. test_utils.run_briefly(self.loop)
  329. self.assertIs(t._fut_waiter, fut1) # White-box test.
  330. fut1.set_result(None)
  331. test_utils.run_briefly(self.loop)
  332. self.assertIs(t._fut_waiter, fut2) # White-box test.
  333. t.cancel()
  334. self.assertTrue(fut2.cancelled())
  335. test_utils.run_briefly(self.loop)
  336. self.assertIs(t._fut_waiter, fut3) # White-box test.
  337. fut3.set_result(42)
  338. res = self.loop.run_until_complete(t)
  339. self.assertEqual(res, 42)
  340. self.assertFalse(fut3.cancelled())
  341. self.assertFalse(t.cancelled())
  342. def test_cancel_current_task(self):
  343. loop = asyncio.new_event_loop()
  344. self.set_event_loop(loop)
  345. @asyncio.coroutine
  346. def task():
  347. t.cancel()
  348. self.assertTrue(t._must_cancel) # White-box test.
  349. # The sleep should be cancelled immediately.
  350. yield from asyncio.sleep(100, loop=loop)
  351. return 12
  352. t = asyncio.Task(task(), loop=loop)
  353. self.assertRaises(
  354. asyncio.CancelledError, loop.run_until_complete, t)
  355. self.assertTrue(t.done())
  356. self.assertFalse(t._must_cancel) # White-box test.
  357. self.assertFalse(t.cancel())
  358. def test_stop_while_run_in_complete(self):
  359. def gen():
  360. when = yield
  361. self.assertAlmostEqual(0.1, when)
  362. when = yield 0.1
  363. self.assertAlmostEqual(0.2, when)
  364. when = yield 0.1
  365. self.assertAlmostEqual(0.3, when)
  366. yield 0.1
  367. loop = self.new_test_loop(gen)
  368. x = 0
  369. waiters = []
  370. @asyncio.coroutine
  371. def task():
  372. nonlocal x
  373. while x < 10:
  374. waiters.append(asyncio.sleep(0.1, loop=loop))
  375. yield from waiters[-1]
  376. x += 1
  377. if x == 2:
  378. loop.stop()
  379. t = asyncio.Task(task(), loop=loop)
  380. with self.assertRaises(RuntimeError) as cm:
  381. loop.run_until_complete(t)
  382. self.assertEqual(str(cm.exception),
  383. 'Event loop stopped before Future completed.')
  384. self.assertFalse(t.done())
  385. self.assertEqual(x, 2)
  386. self.assertAlmostEqual(0.3, loop.time())
  387. # close generators
  388. for w in waiters:
  389. w.close()
  390. t.cancel()
  391. self.assertRaises(asyncio.CancelledError, loop.run_until_complete, t)
  392. def test_wait_for(self):
  393. def gen():
  394. when = yield
  395. self.assertAlmostEqual(0.2, when)
  396. when = yield 0
  397. self.assertAlmostEqual(0.1, when)
  398. when = yield 0.1
  399. loop = self.new_test_loop(gen)
  400. foo_running = None
  401. @asyncio.coroutine
  402. def foo():
  403. nonlocal foo_running
  404. foo_running = True
  405. try:
  406. yield from asyncio.sleep(0.2, loop=loop)
  407. finally:
  408. foo_running = False
  409. return 'done'
  410. fut = asyncio.Task(foo(), loop=loop)
  411. with self.assertRaises(asyncio.TimeoutError):
  412. loop.run_until_complete(asyncio.wait_for(fut, 0.1, loop=loop))
  413. self.assertTrue(fut.done())
  414. # it should have been cancelled due to the timeout
  415. self.assertTrue(fut.cancelled())
  416. self.assertAlmostEqual(0.1, loop.time())
  417. self.assertEqual(foo_running, False)
  418. def test_wait_for_blocking(self):
  419. loop = self.new_test_loop()
  420. @asyncio.coroutine
  421. def coro():
  422. return 'done'
  423. res = loop.run_until_complete(asyncio.wait_for(coro(),
  424. timeout=None,
  425. loop=loop))
  426. self.assertEqual(res, 'done')
  427. def test_wait_for_with_global_loop(self):
  428. def gen():
  429. when = yield
  430. self.assertAlmostEqual(0.2, when)
  431. when = yield 0
  432. self.assertAlmostEqual(0.01, when)
  433. yield 0.01
  434. loop = self.new_test_loop(gen)
  435. @asyncio.coroutine
  436. def foo():
  437. yield from asyncio.sleep(0.2, loop=loop)
  438. return 'done'
  439. asyncio.set_event_loop(loop)
  440. try:
  441. fut = asyncio.Task(foo(), loop=loop)
  442. with self.assertRaises(asyncio.TimeoutError):
  443. loop.run_until_complete(asyncio.wait_for(fut, 0.01))
  444. finally:
  445. asyncio.set_event_loop(None)
  446. self.assertAlmostEqual(0.01, loop.time())
  447. self.assertTrue(fut.done())
  448. self.assertTrue(fut.cancelled())
  449. def test_wait(self):
  450. def gen():
  451. when = yield
  452. self.assertAlmostEqual(0.1, when)
  453. when = yield 0
  454. self.assertAlmostEqual(0.15, when)
  455. yield 0.15
  456. loop = self.new_test_loop(gen)
  457. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  458. b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
  459. @asyncio.coroutine
  460. def foo():
  461. done, pending = yield from asyncio.wait([b, a], loop=loop)
  462. self.assertEqual(done, set([a, b]))
  463. self.assertEqual(pending, set())
  464. return 42
  465. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  466. self.assertEqual(res, 42)
  467. self.assertAlmostEqual(0.15, loop.time())
  468. # Doing it again should take no time and exercise a different path.
  469. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  470. self.assertAlmostEqual(0.15, loop.time())
  471. self.assertEqual(res, 42)
  472. def test_wait_with_global_loop(self):
  473. def gen():
  474. when = yield
  475. self.assertAlmostEqual(0.01, when)
  476. when = yield 0
  477. self.assertAlmostEqual(0.015, when)
  478. yield 0.015
  479. loop = self.new_test_loop(gen)
  480. a = asyncio.Task(asyncio.sleep(0.01, loop=loop), loop=loop)
  481. b = asyncio.Task(asyncio.sleep(0.015, loop=loop), loop=loop)
  482. @asyncio.coroutine
  483. def foo():
  484. done, pending = yield from asyncio.wait([b, a])
  485. self.assertEqual(done, set([a, b]))
  486. self.assertEqual(pending, set())
  487. return 42
  488. asyncio.set_event_loop(loop)
  489. res = loop.run_until_complete(
  490. asyncio.Task(foo(), loop=loop))
  491. self.assertEqual(res, 42)
  492. def test_wait_duplicate_coroutines(self):
  493. @asyncio.coroutine
  494. def coro(s):
  495. return s
  496. c = coro('test')
  497. task = asyncio.Task(
  498. asyncio.wait([c, c, coro('spam')], loop=self.loop),
  499. loop=self.loop)
  500. done, pending = self.loop.run_until_complete(task)
  501. self.assertFalse(pending)
  502. self.assertEqual(set(f.result() for f in done), {'test', 'spam'})
  503. def test_wait_errors(self):
  504. self.assertRaises(
  505. ValueError, self.loop.run_until_complete,
  506. asyncio.wait(set(), loop=self.loop))
  507. # -1 is an invalid return_when value
  508. sleep_coro = asyncio.sleep(10.0, loop=self.loop)
  509. wait_coro = asyncio.wait([sleep_coro], return_when=-1, loop=self.loop)
  510. self.assertRaises(ValueError,
  511. self.loop.run_until_complete, wait_coro)
  512. sleep_coro.close()
  513. def test_wait_first_completed(self):
  514. def gen():
  515. when = yield
  516. self.assertAlmostEqual(10.0, when)
  517. when = yield 0
  518. self.assertAlmostEqual(0.1, when)
  519. yield 0.1
  520. loop = self.new_test_loop(gen)
  521. a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
  522. b = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  523. task = asyncio.Task(
  524. asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED,
  525. loop=loop),
  526. loop=loop)
  527. done, pending = loop.run_until_complete(task)
  528. self.assertEqual({b}, done)
  529. self.assertEqual({a}, pending)
  530. self.assertFalse(a.done())
  531. self.assertTrue(b.done())
  532. self.assertIsNone(b.result())
  533. self.assertAlmostEqual(0.1, loop.time())
  534. # move forward to close generator
  535. loop.advance_time(10)
  536. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  537. def test_wait_really_done(self):
  538. # there is possibility that some tasks in the pending list
  539. # became done but their callbacks haven't all been called yet
  540. @asyncio.coroutine
  541. def coro1():
  542. yield
  543. @asyncio.coroutine
  544. def coro2():
  545. yield
  546. yield
  547. a = asyncio.Task(coro1(), loop=self.loop)
  548. b = asyncio.Task(coro2(), loop=self.loop)
  549. task = asyncio.Task(
  550. asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED,
  551. loop=self.loop),
  552. loop=self.loop)
  553. done, pending = self.loop.run_until_complete(task)
  554. self.assertEqual({a, b}, done)
  555. self.assertTrue(a.done())
  556. self.assertIsNone(a.result())
  557. self.assertTrue(b.done())
  558. self.assertIsNone(b.result())
  559. def test_wait_first_exception(self):
  560. def gen():
  561. when = yield
  562. self.assertAlmostEqual(10.0, when)
  563. yield 0
  564. loop = self.new_test_loop(gen)
  565. # first_exception, task already has exception
  566. a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
  567. @asyncio.coroutine
  568. def exc():
  569. raise ZeroDivisionError('err')
  570. b = asyncio.Task(exc(), loop=loop)
  571. task = asyncio.Task(
  572. asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION,
  573. loop=loop),
  574. loop=loop)
  575. done, pending = loop.run_until_complete(task)
  576. self.assertEqual({b}, done)
  577. self.assertEqual({a}, pending)
  578. self.assertAlmostEqual(0, loop.time())
  579. # move forward to close generator
  580. loop.advance_time(10)
  581. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  582. def test_wait_first_exception_in_wait(self):
  583. def gen():
  584. when = yield
  585. self.assertAlmostEqual(10.0, when)
  586. when = yield 0
  587. self.assertAlmostEqual(0.01, when)
  588. yield 0.01
  589. loop = self.new_test_loop(gen)
  590. # first_exception, exception during waiting
  591. a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop)
  592. @asyncio.coroutine
  593. def exc():
  594. yield from asyncio.sleep(0.01, loop=loop)
  595. raise ZeroDivisionError('err')
  596. b = asyncio.Task(exc(), loop=loop)
  597. task = asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION,
  598. loop=loop)
  599. done, pending = loop.run_until_complete(task)
  600. self.assertEqual({b}, done)
  601. self.assertEqual({a}, pending)
  602. self.assertAlmostEqual(0.01, loop.time())
  603. # move forward to close generator
  604. loop.advance_time(10)
  605. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  606. def test_wait_with_exception(self):
  607. def gen():
  608. when = yield
  609. self.assertAlmostEqual(0.1, when)
  610. when = yield 0
  611. self.assertAlmostEqual(0.15, when)
  612. yield 0.15
  613. loop = self.new_test_loop(gen)
  614. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  615. @asyncio.coroutine
  616. def sleeper():
  617. yield from asyncio.sleep(0.15, loop=loop)
  618. raise ZeroDivisionError('really')
  619. b = asyncio.Task(sleeper(), loop=loop)
  620. @asyncio.coroutine
  621. def foo():
  622. done, pending = yield from asyncio.wait([b, a], loop=loop)
  623. self.assertEqual(len(done), 2)
  624. self.assertEqual(pending, set())
  625. errors = set(f for f in done if f.exception() is not None)
  626. self.assertEqual(len(errors), 1)
  627. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  628. self.assertAlmostEqual(0.15, loop.time())
  629. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  630. self.assertAlmostEqual(0.15, loop.time())
  631. def test_wait_with_timeout(self):
  632. def gen():
  633. when = yield
  634. self.assertAlmostEqual(0.1, when)
  635. when = yield 0
  636. self.assertAlmostEqual(0.15, when)
  637. when = yield 0
  638. self.assertAlmostEqual(0.11, when)
  639. yield 0.11
  640. loop = self.new_test_loop(gen)
  641. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  642. b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
  643. @asyncio.coroutine
  644. def foo():
  645. done, pending = yield from asyncio.wait([b, a], timeout=0.11,
  646. loop=loop)
  647. self.assertEqual(done, set([a]))
  648. self.assertEqual(pending, set([b]))
  649. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  650. self.assertAlmostEqual(0.11, loop.time())
  651. # move forward to close generator
  652. loop.advance_time(10)
  653. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  654. def test_wait_concurrent_complete(self):
  655. def gen():
  656. when = yield
  657. self.assertAlmostEqual(0.1, when)
  658. when = yield 0
  659. self.assertAlmostEqual(0.15, when)
  660. when = yield 0
  661. self.assertAlmostEqual(0.1, when)
  662. yield 0.1
  663. loop = self.new_test_loop(gen)
  664. a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop)
  665. b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop)
  666. done, pending = loop.run_until_complete(
  667. asyncio.wait([b, a], timeout=0.1, loop=loop))
  668. self.assertEqual(done, set([a]))
  669. self.assertEqual(pending, set([b]))
  670. self.assertAlmostEqual(0.1, loop.time())
  671. # move forward to close generator
  672. loop.advance_time(10)
  673. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  674. def test_as_completed(self):
  675. def gen():
  676. yield 0
  677. yield 0
  678. yield 0.01
  679. yield 0
  680. loop = self.new_test_loop(gen)
  681. # disable "slow callback" warning
  682. loop.slow_callback_duration = 1.0
  683. completed = set()
  684. time_shifted = False
  685. @asyncio.coroutine
  686. def sleeper(dt, x):
  687. nonlocal time_shifted
  688. yield from asyncio.sleep(dt, loop=loop)
  689. completed.add(x)
  690. if not time_shifted and 'a' in completed and 'b' in completed:
  691. time_shifted = True
  692. loop.advance_time(0.14)
  693. return x
  694. a = sleeper(0.01, 'a')
  695. b = sleeper(0.01, 'b')
  696. c = sleeper(0.15, 'c')
  697. @asyncio.coroutine
  698. def foo():
  699. values = []
  700. for f in asyncio.as_completed([b, c, a], loop=loop):
  701. values.append((yield from f))
  702. return values
  703. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  704. self.assertAlmostEqual(0.15, loop.time())
  705. self.assertTrue('a' in res[:2])
  706. self.assertTrue('b' in res[:2])
  707. self.assertEqual(res[2], 'c')
  708. # Doing it again should take no time and exercise a different path.
  709. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  710. self.assertAlmostEqual(0.15, loop.time())
  711. def test_as_completed_with_timeout(self):
  712. def gen():
  713. yield
  714. yield 0
  715. yield 0
  716. yield 0.1
  717. loop = self.new_test_loop(gen)
  718. a = asyncio.sleep(0.1, 'a', loop=loop)
  719. b = asyncio.sleep(0.15, 'b', loop=loop)
  720. @asyncio.coroutine
  721. def foo():
  722. values = []
  723. for f in asyncio.as_completed([a, b], timeout=0.12, loop=loop):
  724. if values:
  725. loop.advance_time(0.02)
  726. try:
  727. v = yield from f
  728. values.append((1, v))
  729. except asyncio.TimeoutError as exc:
  730. values.append((2, exc))
  731. return values
  732. res = loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  733. self.assertEqual(len(res), 2, res)
  734. self.assertEqual(res[0], (1, 'a'))
  735. self.assertEqual(res[1][0], 2)
  736. self.assertIsInstance(res[1][1], asyncio.TimeoutError)
  737. self.assertAlmostEqual(0.12, loop.time())
  738. # move forward to close generator
  739. loop.advance_time(10)
  740. loop.run_until_complete(asyncio.wait([a, b], loop=loop))
  741. def test_as_completed_with_unused_timeout(self):
  742. def gen():
  743. yield
  744. yield 0
  745. yield 0.01
  746. loop = self.new_test_loop(gen)
  747. a = asyncio.sleep(0.01, 'a', loop=loop)
  748. @asyncio.coroutine
  749. def foo():
  750. for f in asyncio.as_completed([a], timeout=1, loop=loop):
  751. v = yield from f
  752. self.assertEqual(v, 'a')
  753. loop.run_until_complete(asyncio.Task(foo(), loop=loop))
  754. def test_as_completed_reverse_wait(self):
  755. def gen():
  756. yield 0
  757. yield 0.05
  758. yield 0
  759. loop = self.new_test_loop(gen)
  760. a = asyncio.sleep(0.05, 'a', loop=loop)
  761. b = asyncio.sleep(0.10, 'b', loop=loop)
  762. fs = {a, b}
  763. futs = list(asyncio.as_completed(fs, loop=loop))
  764. self.assertEqual(len(futs), 2)
  765. x = loop.run_until_complete(futs[1])
  766. self.assertEqual(x, 'a')
  767. self.assertAlmostEqual(0.05, loop.time())
  768. loop.advance_time(0.05)
  769. y = loop.run_until_complete(futs[0])
  770. self.assertEqual(y, 'b')
  771. self.assertAlmostEqual(0.10, loop.time())
  772. def test_as_completed_concurrent(self):
  773. def gen():
  774. when = yield
  775. self.assertAlmostEqual(0.05, when)
  776. when = yield 0
  777. self.assertAlmostEqual(0.05, when)
  778. yield 0.05
  779. loop = self.new_test_loop(gen)
  780. a = asyncio.sleep(0.05, 'a', loop=loop)
  781. b = asyncio.sleep(0.05, 'b', loop=loop)
  782. fs = {a, b}
  783. futs = list(asyncio.as_completed(fs, loop=loop))
  784. self.assertEqual(len(futs), 2)
  785. waiter = asyncio.wait(futs, loop=loop)
  786. done, pending = loop.run_until_complete(waiter)
  787. self.assertEqual(set(f.result() for f in done), {'a', 'b'})
  788. def test_as_completed_duplicate_coroutines(self):
  789. @asyncio.coroutine
  790. def coro(s):
  791. return s
  792. @asyncio.coroutine
  793. def runner():
  794. result = []
  795. c = coro('ham')
  796. for f in asyncio.as_completed([c, c, coro('spam')],
  797. loop=self.loop):
  798. result.append((yield from f))
  799. return result
  800. fut = asyncio.Task(runner(), loop=self.loop)
  801. self.loop.run_until_complete(fut)
  802. result = fut.result()
  803. self.assertEqual(set(result), {'ham', 'spam'})
  804. self.assertEqual(len(result), 2)
  805. def test_sleep(self):
  806. def gen():
  807. when = yield
  808. self.assertAlmostEqual(0.05, when)
  809. when = yield 0.05
  810. self.assertAlmostEqual(0.1, when)
  811. yield 0.05
  812. loop = self.new_test_loop(gen)
  813. @asyncio.coroutine
  814. def sleeper(dt, arg):
  815. yield from asyncio.sleep(dt/2, loop=loop)
  816. res = yield from asyncio.sleep(dt/2, arg, loop=loop)
  817. return res
  818. t = asyncio.Task(sleeper(0.1, 'yeah'), loop=loop)
  819. loop.run_until_complete(t)
  820. self.assertTrue(t.done())
  821. self.assertEqual(t.result(), 'yeah')
  822. self.assertAlmostEqual(0.1, loop.time())
  823. def test_sleep_cancel(self):
  824. def gen():
  825. when = yield
  826. self.assertAlmostEqual(10.0, when)
  827. yield 0
  828. loop = self.new_test_loop(gen)
  829. t = asyncio.Task(asyncio.sleep(10.0, 'yeah', loop=loop),
  830. loop=loop)
  831. handle = None
  832. orig_call_later = loop.call_later
  833. def call_later(delay, callback, *args):
  834. nonlocal handle
  835. handle = orig_call_later(delay, callback, *args)
  836. return handle
  837. loop.call_later = call_later
  838. test_utils.run_briefly(loop)
  839. self.assertFalse(handle._cancelled)
  840. t.cancel()
  841. test_utils.run_briefly(loop)
  842. self.assertTrue(handle._cancelled)
  843. def test_task_cancel_sleeping_task(self):
  844. def gen():
  845. when = yield
  846. self.assertAlmostEqual(0.1, when)
  847. when = yield 0
  848. self.assertAlmostEqual(5000, when)
  849. yield 0.1
  850. loop = self.new_test_loop(gen)
  851. @asyncio.coroutine
  852. def sleep(dt):
  853. yield from asyncio.sleep(dt, loop=loop)
  854. @asyncio.coroutine
  855. def doit():
  856. sleeper = asyncio.Task(sleep(5000), loop=loop)
  857. loop.call_later(0.1, sleeper.cancel)
  858. try:
  859. yield from sleeper
  860. except asyncio.CancelledError:
  861. return 'cancelled'
  862. else:
  863. return 'slept in'
  864. doer = doit()
  865. self.assertEqual(loop.run_until_complete(doer), 'cancelled')
  866. self.assertAlmostEqual(0.1, loop.time())
  867. def test_task_cancel_waiter_future(self):
  868. fut = asyncio.Future(loop=self.loop)
  869. @asyncio.coroutine
  870. def coro():
  871. yield from fut
  872. task = asyncio.Task(coro(), loop=self.loop)
  873. test_utils.run_briefly(self.loop)
  874. self.assertIs(task._fut_waiter, fut)
  875. task.cancel()
  876. test_utils.run_briefly(self.loop)
  877. self.assertRaises(
  878. asyncio.CancelledError, self.loop.run_until_complete, task)
  879. self.assertIsNone(task._fut_waiter)
  880. self.assertTrue(fut.cancelled())
  881. def test_step_in_completed_task(self):
  882. @asyncio.coroutine
  883. def notmuch():
  884. return 'ko'
  885. gen = notmuch()
  886. task = asyncio.Task(gen, loop=self.loop)
  887. task.set_result('ok')
  888. self.assertRaises(AssertionError, task._step)
  889. gen.close()
  890. def test_step_result(self):
  891. @asyncio.coroutine
  892. def notmuch():
  893. yield None
  894. yield 1
  895. return 'ko'
  896. self.assertRaises(
  897. RuntimeError, self.loop.run_until_complete, notmuch())
  898. def test_step_result_future(self):
  899. # If coroutine returns future, task waits on this future.
  900. class Fut(asyncio.Future):
  901. def __init__(self, *args, **kwds):
  902. self.cb_added = False
  903. super().__init__(*args, **kwds)
  904. def add_done_callback(self, fn):
  905. self.cb_added = True
  906. super().add_done_callback(fn)
  907. fut = Fut(loop=self.loop)
  908. result = None
  909. @asyncio.coroutine
  910. def wait_for_future():
  911. nonlocal result
  912. result = yield from fut
  913. t = asyncio.Task(wait_for_future(), loop=self.loop)
  914. test_utils.run_briefly(self.loop)
  915. self.assertTrue(fut.cb_added)
  916. res = object()
  917. fut.set_result(res)
  918. test_utils.run_briefly(self.loop)
  919. self.assertIs(res, result)
  920. self.assertTrue(t.done())
  921. self.assertIsNone(t.result())
  922. def test_step_with_baseexception(self):
  923. @asyncio.coroutine
  924. def notmutch():
  925. raise BaseException()
  926. task = asyncio.Task(notmutch(), loop=self.loop)
  927. self.assertRaises(BaseException, task._step)
  928. self.assertTrue(task.done())
  929. self.assertIsInstance(task.exception(), BaseException)
  930. def test_baseexception_during_cancel(self):
  931. def gen():
  932. when = yield
  933. self.assertAlmostEqual(10.0, when)
  934. yield 0
  935. loop = self.new_test_loop(gen)
  936. @asyncio.coroutine
  937. def sleeper():
  938. yield from asyncio.sleep(10, loop=loop)
  939. base_exc = BaseException()
  940. @asyncio.coroutine
  941. def notmutch():
  942. try:
  943. yield from sleeper()
  944. except asyncio.CancelledError:
  945. raise base_exc
  946. task = asyncio.Task(notmutch(), loop=loop)
  947. test_utils.run_briefly(loop)
  948. task.cancel()
  949. self.assertFalse(task.done())
  950. self.assertRaises(BaseException, test_utils.run_briefly, loop)
  951. self.assertTrue(task.done())
  952. self.assertFalse(task.cancelled())
  953. self.assertIs(task.exception(), base_exc)
  954. def test_iscoroutinefunction(self):
  955. def fn():
  956. pass
  957. self.assertFalse(asyncio.iscoroutinefunction(fn))
  958. def fn1():
  959. yield
  960. self.assertFalse(asyncio.iscoroutinefunction(fn1))
  961. @asyncio.coroutine
  962. def fn2():
  963. yield
  964. self.assertTrue(asyncio.iscoroutinefunction(fn2))
  965. def test_yield_vs_yield_from(self):
  966. fut = asyncio.Future(loop=self.loop)
  967. @asyncio.coroutine
  968. def wait_for_future():
  969. yield fut
  970. task = wait_for_future()
  971. with self.assertRaises(RuntimeError):
  972. self.loop.run_until_complete(task)
  973. self.assertFalse(fut.done())
  974. def test_yield_vs_yield_from_generator(self):
  975. @asyncio.coroutine
  976. def coro():
  977. yield
  978. @asyncio.coroutine
  979. def wait_for_future():
  980. gen = coro()
  981. try:
  982. yield gen
  983. finally:
  984. gen.close()
  985. task = wait_for_future()
  986. self.assertRaises(
  987. RuntimeError,
  988. self.loop.run_until_complete, task)
  989. def test_coroutine_non_gen_function(self):
  990. @asyncio.coroutine
  991. def func():
  992. return 'test'
  993. self.assertTrue(asyncio.iscoroutinefunction(func))
  994. coro = func()
  995. self.assertTrue(asyncio.iscoroutine(coro))
  996. res = self.loop.run_until_complete(coro)
  997. self.assertEqual(res, 'test')
  998. def test_coroutine_non_gen_function_return_future(self):
  999. fut = asyncio.Future(loop=self.loop)
  1000. @asyncio.coroutine
  1001. def func():
  1002. return fut
  1003. @asyncio.coroutine
  1004. def coro():
  1005. fut.set_result('test')
  1006. t1 = asyncio.Task(func(), loop=self.loop)
  1007. t2 = asyncio.Task(coro(), loop=self.loop)
  1008. res = self.loop.run_until_complete(t1)
  1009. self.assertEqual(res, 'test')
  1010. self.assertIsNone(t2.result())
  1011. def test_current_task(self):
  1012. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  1013. @asyncio.coroutine
  1014. def coro(loop):
  1015. self.assertTrue(asyncio.Task.current_task(loop=loop) is task)
  1016. task = asyncio.Task(coro(self.loop), loop=self.loop)
  1017. self.loop.run_until_complete(task)
  1018. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  1019. def test_current_task_with_interleaving_tasks(self):
  1020. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  1021. fut1 = asyncio.Future(loop=self.loop)
  1022. fut2 = asyncio.Future(loop=self.loop)
  1023. @asyncio.coroutine
  1024. def coro1(loop):
  1025. self.assertTrue(asyncio.Task.current_task(loop=loop) is task1)
  1026. yield from fut1
  1027. self.assertTrue(asyncio.Task.current_task(loop=loop) is task1)
  1028. fut2.set_result(True)
  1029. @asyncio.coroutine
  1030. def coro2(loop):
  1031. self.assertTrue(asyncio.Task.current_task(loop=loop) is task2)
  1032. fut1.set_result(True)
  1033. yield from fut2
  1034. self.assertTrue(asyncio.Task.current_task(loop=loop) is task2)
  1035. task1 = asyncio.Task(coro1(self.loop), loop=self.loop)
  1036. task2 = asyncio.Task(coro2(self.loop), loop=self.loop)
  1037. self.loop.run_until_complete(asyncio.wait((task1, task2),
  1038. loop=self.loop))
  1039. self.assertIsNone(asyncio.Task.current_task(loop=self.loop))
  1040. # Some thorough tests for cancellation propagation through
  1041. # coroutines, tasks and wait().
  1042. def test_yield_future_passes_cancel(self):
  1043. # Cancelling outer() cancels inner() cancels waiter.
  1044. proof = 0
  1045. waiter = asyncio.Future(loop=self.loop)
  1046. @asyncio.coroutine
  1047. def inner():
  1048. nonlocal proof
  1049. try:
  1050. yield from waiter
  1051. except asyncio.CancelledError:
  1052. proof += 1
  1053. raise
  1054. else:
  1055. self.fail('got past sleep() in inner()')
  1056. @asyncio.coroutine
  1057. def outer():
  1058. nonlocal proof
  1059. try:
  1060. yield from inner()
  1061. except asyncio.CancelledError:
  1062. proof += 100 # Expect this path.
  1063. else:
  1064. proof += 10
  1065. f = asyncio.async(outer(), loop=self.loop)
  1066. test_utils.run_briefly(self.loop)
  1067. f.cancel()
  1068. self.loop.run_until_complete(f)
  1069. self.assertEqual(proof, 101)
  1070. self.assertTrue(waiter.cancelled())
  1071. def test_yield_wait_does_not_shield_cancel(self):
  1072. # Cancelling outer() makes wait() return early, leaves inner()
  1073. # running.
  1074. proof = 0
  1075. waiter = asyncio.Future(loop=self.loop)
  1076. @asyncio.coroutine
  1077. def inner():
  1078. nonlocal proof
  1079. yield from waiter
  1080. proof += 1
  1081. @asyncio.coroutine
  1082. def outer():
  1083. nonlocal proof
  1084. d, p = yield from asyncio.wait([inner()], loop=self.loop)
  1085. proof += 100
  1086. f = asyncio.async(outer(), loop=self.loop)
  1087. test_utils.run_briefly(self.loop)
  1088. f.cancel()
  1089. self.assertRaises(
  1090. asyncio.CancelledError, self.loop.run_until_complete, f)
  1091. waiter.set_result(None)
  1092. test_utils.run_briefly(self.loop)
  1093. self.assertEqual(proof, 1)
  1094. def test_shield_result(self):
  1095. inner = asyncio.Future(loop=self.loop)
  1096. outer = asyncio.shield(inner)
  1097. inner.set_result(42)
  1098. res = self.loop.run_until_complete(outer)
  1099. self.assertEqual(res, 42)
  1100. def test_shield_exception(self):
  1101. inner = asyncio.Future(loop=self.loop)
  1102. outer = asyncio.shield(inner)
  1103. test_utils.run_briefly(self.loop)
  1104. exc = RuntimeError('expected')
  1105. inner.set_exception(exc)
  1106. test_utils.run_briefly(self.loop)
  1107. self.assertIs(outer.exception(), exc)
  1108. def test_shield_cancel(self):
  1109. inner = asyncio.Future(loop=self.loop)
  1110. outer = asyncio.shield(inner)
  1111. test_utils.run_briefly(self.loop)
  1112. inner.cancel()
  1113. test_utils.run_briefly(self.loop)
  1114. self.assertTrue(outer.cancelled())
  1115. def test_shield_shortcut(self):
  1116. fut = asyncio.Future(loop=self.loop)
  1117. fut.set_result(42)
  1118. res = self.loop.run_until_complete(asyncio.shield(fut))
  1119. self.assertEqual(res, 42)
  1120. def test_shield_effect(self):
  1121. # Cancelling outer() does not affect inner().
  1122. proof = 0
  1123. waiter = asyncio.Future(loop=self.loop)
  1124. @asyncio.coroutine
  1125. def inner():
  1126. nonlocal proof
  1127. yield from waiter
  1128. proof += 1
  1129. @asyncio.coroutine
  1130. def outer():
  1131. nonlocal proof
  1132. yield from asyncio.shield(inner(), loop=self.loop)
  1133. proof += 100
  1134. f = asyncio.async(outer(), loop=self.loop)
  1135. test_utils.run_briefly(self.loop)
  1136. f.cancel()
  1137. with self.assertRaises(asyncio.CancelledError):
  1138. self.loop.run_until_complete(f)
  1139. waiter.set_result(None)
  1140. test_utils.run_briefly(self.loop)
  1141. self.assertEqual(proof, 1)
  1142. def test_shield_gather(self):
  1143. child1 = asyncio.Future(loop=self.loop)
  1144. child2 = asyncio.Future(loop=self.loop)
  1145. parent = asyncio.gather(child1, child2, loop=self.loop)
  1146. outer = asyncio.shield(parent, loop=self.loop)
  1147. test_utils.run_briefly(self.loop)
  1148. outer.cancel()
  1149. test_utils.run_briefly(self.loop)
  1150. self.assertTrue(outer.cancelled())
  1151. child1.set_result(1)
  1152. child2.set_result(2)
  1153. test_utils.run_briefly(self.loop)
  1154. self.assertEqual(parent.result(), [1, 2])
  1155. def test_gather_shield(self):
  1156. child1 = asyncio.Future(loop=self.loop)
  1157. child2 = asyncio.Future(loop=self.loop)
  1158. inner1 = asyncio.shield(child1, loop=self.loop)
  1159. inner2 = asyncio.shield(child2, loop=self.loop)
  1160. parent = asyncio.gather(inner1, inner2, loop=self.loop)
  1161. test_utils.run_briefly(self.loop)
  1162. parent.cancel()
  1163. # This should cancel inner1 and inner2 but bot child1 and child2.
  1164. test_utils.run_briefly(self.loop)
  1165. self.assertIsInstance(parent.exception(), asyncio.CancelledError)
  1166. self.assertTrue(inner1.cancelled())
  1167. self.assertTrue(inner2.cancelled())
  1168. child1.set_result(1)
  1169. child2.set_result(2)
  1170. test_utils.run_briefly(self.loop)
  1171. def test_as_completed_invalid_args(self):
  1172. fut = asyncio.Future(loop=self.loop)
  1173. # as_completed() expects a list of futures, not a future instance
  1174. self.assertRaises(TypeError, self.loop.run_until_complete,
  1175. asyncio.as_completed(fut, loop=self.loop))
  1176. coro = coroutine_function()
  1177. self.assertRaises(TypeError, self.loop.run_until_complete,
  1178. asyncio.as_completed(coro, loop=self.loop))
  1179. coro.close()
  1180. def test_wait_invalid_args(self):
  1181. fut = asyncio.Future(loop=self.loop)
  1182. # wait() expects a list of futures, not a future instance
  1183. self.assertRaises(TypeError, self.loop.run_until_complete,
  1184. asyncio.wait(fut, loop=self.loop))
  1185. coro = coroutine_function()
  1186. self.assertRaises(TypeError, self.loop.run_until_complete,
  1187. asyncio.wait(coro, loop=self.loop))
  1188. coro.close()
  1189. # wait() expects at least a future
  1190. self.assertRaises(ValueError, self.loop.run_until_complete,
  1191. asyncio.wait([], loop=self.loop))
  1192. def test_corowrapper_mocks_generator(self):
  1193. def check():
  1194. # A function that asserts various things.
  1195. # Called twice, with different debug flag values.
  1196. @asyncio.coroutine
  1197. def coro():
  1198. # The actual coroutine.
  1199. self.assertTrue(gen.gi_running)
  1200. yield from fut
  1201. # A completed Future used to run the coroutine.
  1202. fut = asyncio.Future(loop=self.loop)
  1203. fut.set_result(None)
  1204. # Call the coroutine.
  1205. gen = coro()
  1206. # Check some properties.
  1207. self.assertTrue(asyncio.iscoroutine(gen))
  1208. self.assertIsInstance(gen.gi_frame, types.FrameType)
  1209. self.assertFalse(gen.gi_running)
  1210. self.assertIsInstance(gen.gi_code, types.CodeType)
  1211. # Run it.
  1212. self.loop.run_until_complete(gen)
  1213. # The frame should have changed.
  1214. self.assertIsNone(gen.gi_frame)
  1215. # Save debug flag.
  1216. old_debug = asyncio.coroutines._DEBUG
  1217. try:
  1218. # Test with debug flag cleared.
  1219. asyncio.coroutines._DEBUG = False
  1220. check()
  1221. # Test with debug flag set.
  1222. asyncio.coroutines._DEBUG = True
  1223. check()
  1224. finally:
  1225. # Restore original debug flag.
  1226. asyncio.coroutines._DEBUG = old_debug
  1227. def test_yield_from_corowrapper(self):
  1228. old_debug = asyncio.coroutines._DEBUG
  1229. asyncio.coroutines._DEBUG = True
  1230. try:
  1231. @asyncio.coroutine
  1232. def t1():
  1233. return (yield from t2())
  1234. @asyncio.coroutine
  1235. def t2():
  1236. f = asyncio.Future(loop=self.loop)
  1237. asyncio.Task(t3(f), loop=self.loop)
  1238. return (yield from f)
  1239. @asyncio.coroutine
  1240. def t3(f):
  1241. f.set_result((1, 2, 3))
  1242. task = asyncio.Task(t1(), loop=self.loop)
  1243. val = self.loop.run_until_complete(task)
  1244. self.assertEqual(val, (1, 2, 3))
  1245. finally:
  1246. asyncio.coroutines._DEBUG = old_debug
  1247. def test_yield_from_corowrapper_send(self):
  1248. def foo():
  1249. a = yield
  1250. return a
  1251. def call(arg):
  1252. cw = asyncio.coroutines.CoroWrapper(foo(), foo)
  1253. cw.send(None)
  1254. try:
  1255. cw.send(arg)
  1256. except StopIteration as ex:
  1257. return ex.args[0]
  1258. else:
  1259. raise AssertionError('StopIteration was expected')
  1260. self.assertEqual(call((1, 2)), (1, 2))
  1261. self.assertEqual(call('spam'), 'spam')
  1262. def test_corowrapper_weakref(self):
  1263. wd = weakref.WeakValueDictionary()
  1264. def foo(): yield from []
  1265. cw = asyncio.coroutines.CoroWrapper(foo(), foo)
  1266. wd['cw'] = cw # Would fail without __weakref__ slot.
  1267. cw.gen = None # Suppress warning from __del__.
  1268. @unittest.skipUnless(PY34,
  1269. 'need python 3.4 or later')
  1270. def test_log_destroyed_pending_task(self):
  1271. @asyncio.coroutine
  1272. def kill_me(loop):
  1273. future = asyncio.Future(loop=loop)
  1274. yield from future
  1275. # at this point, the only reference to kill_me() task is
  1276. # the Task._wakeup() method in future._callbacks
  1277. raise Exception("code never reached")
  1278. mock_handler = mock.Mock()
  1279. self.loop.set_debug(True)
  1280. self.loop.set_exception_handler(mock_handler)
  1281. # schedule the task
  1282. coro = kill_me(self.loop)
  1283. task = asyncio.async(coro, loop=self.loop)
  1284. self.assertEqual(asyncio.Task.all_tasks(loop=self.loop), {task})
  1285. # execute the task so it waits for future
  1286. self.loop._run_once()
  1287. self.assertEqual(len(self.loop._ready), 0)
  1288. # remove the future used in kill_me(), and references to the task
  1289. del coro.gi_frame.f_locals['future']
  1290. coro = None
  1291. source_traceback = task._source_traceback
  1292. task = None
  1293. # no more reference to kill_me() task: the task is destroyed by the GC
  1294. support.gc_collect()
  1295. self.assertEqual(asyncio.Task.all_tasks(loop=self.loop), set())
  1296. mock_handler.assert_called_with(self.loop, {
  1297. 'message': 'Task was destroyed but it is pending!',
  1298. 'task': mock.ANY,
  1299. 'source_traceback': source_traceback,
  1300. })
  1301. mock_handler.reset_mock()
  1302. @mock.patch('asyncio.coroutines.logger')
  1303. def test_coroutine_never_yielded(self, m_log):
  1304. debug = asyncio.coroutines._DEBUG
  1305. try:
  1306. asyncio.coroutines._DEBUG = True
  1307. @asyncio.coroutine
  1308. def coro_noop():
  1309. pass
  1310. finally:
  1311. asyncio.coroutines._DEBUG = debug
  1312. tb_filename = __file__
  1313. tb_lineno = sys._getframe().f_lineno + 2
  1314. # create a coroutine object but don't use it
  1315. coro_noop()
  1316. support.gc_collect()
  1317. self.assertTrue(m_log.error.called)
  1318. message = m_log.error.call_args[0][0]
  1319. func_filename, func_lineno = test_utils.get_function_source(coro_noop)
  1320. regex = (r'^<CoroWrapper %s\(\) .* at %s:%s, .*> was never yielded from\n'
  1321. r'Coroutine object created at \(most recent call last\):\n'
  1322. r'.*\n'
  1323. r' File "%s", line %s, in test_coroutine_never_yielded\n'
  1324. r' coro_noop\(\)$'
  1325. % (re.escape(coro_noop.__qualname__),
  1326. re.escape(func_filename), func_lineno,
  1327. re.escape(tb_filename), tb_lineno))
  1328. self.assertRegex(message, re.compile(regex, re.DOTALL))
  1329. def test_task_source_traceback(self):
  1330. self.loop.set_debug(True)
  1331. task = asyncio.Task(coroutine_function(), loop=self.loop)
  1332. lineno = sys._getframe().f_lineno - 1
  1333. self.assertIsInstance(task._source_traceback, list)
  1334. self.assertEqual(task._source_traceback[-1][:3],
  1335. (__file__,
  1336. lineno,
  1337. 'test_task_source_traceback'))
  1338. self.loop.run_until_complete(task)
  1339. class GatherTestsBase:
  1340. def setUp(self):
  1341. self.one_loop = self.new_test_loop()
  1342. self.other_loop = self.new_test_loop()
  1343. self.set_event_loop(self.one_loop, cleanup=False)
  1344. def _run_loop(self, loop):
  1345. while loop._ready:
  1346. test_utils.run_briefly(loop)
  1347. def _check_success(self, **kwargs):
  1348. a, b, c = [asyncio.Future(loop=self.one_loop) for i in range(3)]
  1349. fut = asyncio.gather(*self.wrap_futures(a, b, c), **kwargs)
  1350. cb = test_utils.MockCallback()
  1351. fut.add_done_callback(cb)
  1352. b.set_result(1)
  1353. a.set_result(2)
  1354. self._run_loop(self.one_loop)
  1355. self.assertEqual(cb.called, False)
  1356. self.assertFalse(fut.done())
  1357. c.set_result(3)
  1358. self._run_loop(self.one_loop)
  1359. cb.assert_called_once_with(fut)
  1360. self.assertEqual(fut.result(), [2, 1, 3])
  1361. def test_success(self):
  1362. self._check_success()
  1363. self._check_success(return_exceptions=False)
  1364. def test_result_exception_success(self):
  1365. self._check_success(return_exceptions=True)
  1366. def test_one_exception(self):
  1367. a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)]
  1368. fut = asyncio.gather(*self.wrap_futures(a, b, c, d, e))
  1369. cb = test_utils.MockCallback()
  1370. fut.add_done_callback(cb)
  1371. exc = ZeroDivisionError()
  1372. a.set_result(1)
  1373. b.set_exception(exc)
  1374. self._run_loop(self.one_loop)
  1375. self.assertTrue(fut.done())
  1376. cb.assert_called_once_with(fut)
  1377. self.assertIs(fut.exception(), exc)
  1378. # Does nothing
  1379. c.set_result(3)
  1380. d.cancel()
  1381. e.set_exception(RuntimeError())
  1382. e.exception()
  1383. def test_return_exceptions(self):
  1384. a, b, c, d = [asyncio.Future(loop=self.one_loop) for i in range(4)]
  1385. fut = asyncio.gather(*self.wrap_futures(a, b, c, d),
  1386. return_exceptions=True)
  1387. cb = test_utils.MockCallback()
  1388. fut.add_done_callback(cb)
  1389. exc = ZeroDivisionError()
  1390. exc2 = RuntimeError()
  1391. b.set_result(1)
  1392. c.set_exception(exc)
  1393. a.set_result(3)
  1394. self._run_loop(self.one_loop)
  1395. self.assertFalse(fut.done())
  1396. d.set_exception(exc2)
  1397. self._run_loop(self.one_loop)
  1398. self.assertTrue(fut.done())
  1399. cb.assert_called_once_with(fut)
  1400. self.assertEqual(fut.result(), [3, 1, exc, exc2])
  1401. def test_env_var_debug(self):
  1402. code = '\n'.join((
  1403. 'import asyncio.coroutines',
  1404. 'print(asyncio.coroutines._DEBUG)'))
  1405. # Test with -E to not fail if the unit test was run with
  1406. # PYTHONASYNCIODEBUG set to a non-empty string
  1407. sts, stdout, stderr = assert_python_ok('-E', '-c', code)
  1408. self.assertEqual(stdout.rstrip(), b'False')
  1409. sts, stdout, stderr = assert_python_ok('-c', code,
  1410. PYTHONASYNCIODEBUG='')
  1411. self.assertEqual(stdout.rstrip(), b'False')
  1412. sts, stdout, stderr = assert_python_ok('-c', code,
  1413. PYTHONASYNCIODEBUG='1')
  1414. self.assertEqual(stdout.rstrip(), b'True')
  1415. sts, stdout, stderr = assert_python_ok('-E', '-c', code,
  1416. PYTHONASYNCIODEBUG='1')
  1417. self.assertEqual(stdout.rstrip(), b'False')
  1418. class FutureGatherTests(GatherTestsBase, test_utils.TestCase):
  1419. def wrap_futures(self, *futures):
  1420. return futures
  1421. def _check_empty_sequence(self, seq_or_iter):
  1422. asyncio.set_event_loop(self.one_loop)
  1423. self.addCleanup(asyncio.set_event_loop, None)
  1424. fut = asyncio.gather(*seq_or_iter)
  1425. self.assertIsInstance(fut, asyncio.Future)
  1426. self.assertIs(fut._loop, self.one_loop)
  1427. self._run_loop(self.one_loop)
  1428. self.assertTrue(fut.done())
  1429. self.assertEqual(fut.result(), [])
  1430. fut = asyncio.gather(*seq_or_iter, loop=self.other_loop)
  1431. self.assertIs(fut._loop, self.other_loop)
  1432. def test_constructor_empty_sequence(self):
  1433. self._check_empty_sequence([])
  1434. self._check_empty_sequence(())
  1435. self._check_empty_sequence(set())
  1436. self._check_empty_sequence(iter(""))
  1437. def test_constructor_heterogenous_futures(self):
  1438. fut1 = asyncio.Future(loop=self.one_loop)
  1439. fut2 = asyncio.Future(loop=self.other_loop)
  1440. with self.assertRaises(ValueError):
  1441. asyncio.gather(fut1, fut2)
  1442. with self.assertRaises(ValueError):
  1443. asyncio.gather(fut1, loop=self.other_loop)
  1444. def test_constructor_homogenous_futures(self):
  1445. children = [asyncio.Future(loop=self.other_loop) for i in range(3)]
  1446. fut = asyncio.gather(*children)
  1447. self.assertIs(fut._loop, self.other_loop)
  1448. self._run_loop(self.other_loop)
  1449. self.assertFalse(fut.done())
  1450. fut = asyncio.gather(*children, loop=self.other_loop)
  1451. self.assertIs(fut._loop, self.other_loop)
  1452. self._run_loop(self.other_loop)
  1453. self.assertFalse(fut.done())
  1454. def test_one_cancellation(self):
  1455. a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)]
  1456. fut = asyncio.gather(a, b, c, d, e)
  1457. cb = test_utils.MockCallback()
  1458. fut.add_done_callback(cb)
  1459. a.set_result(1)
  1460. b.cancel()
  1461. self._run_loop(self.one_loop)
  1462. self.assertTrue(fut.done())
  1463. cb.assert_called_once_with(fut)
  1464. self.assertFalse(fut.cancelled())
  1465. self.assertIsInstance(fut.exception(), asyncio.CancelledError)
  1466. # Does nothing
  1467. c.set_result(3)
  1468. d.cancel()
  1469. e.set_exception(RuntimeError())
  1470. e.exception()
  1471. def test_result_exception_one_cancellation(self):
  1472. a, b, c, d, e, f = [asyncio.Future(loop=self.one_loop)
  1473. for i in range(6)]
  1474. fut = asyncio.gather(a, b, c, d, e, f, return_exceptions=True)
  1475. cb = test_utils.MockCallback()
  1476. fut.add_done_callback(cb)
  1477. a.set_result(1)
  1478. zde = ZeroDivisionError()
  1479. b.set_exception(zde)
  1480. c.cancel()
  1481. self._run_loop(self.one_loop)
  1482. self.assertFalse(fut.done())
  1483. d.set_result(3)
  1484. e.cancel()
  1485. rte = RuntimeError()
  1486. f.set_exception(rte)
  1487. res = self.one_loop.run_until_complete(fut)
  1488. self.assertIsInstance(res[2], asyncio.CancelledError)
  1489. self.assertIsInstance(res[4], asyncio.CancelledError)
  1490. res[2] = res[4] = None
  1491. self.assertEqual(res, [1, zde, None, 3, None, rte])
  1492. cb.assert_called_once_with(fut)
  1493. class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
  1494. def setUp(self):
  1495. super().setUp()
  1496. asyncio.set_event_loop(self.one_loop)
  1497. def wrap_futures(self, *futures):
  1498. coros = []
  1499. for fut in futures:
  1500. @asyncio.coroutine
  1501. def coro(fut=fut):
  1502. return (yield from fut)
  1503. coros.append(coro())
  1504. return coros
  1505. def test_constructor_loop_selection(self):
  1506. @asyncio.coroutine
  1507. def coro():
  1508. return 'abc'
  1509. gen1 = coro()
  1510. gen2 = coro()
  1511. fut = asyncio.gather(gen1, gen2)
  1512. self.assertIs(fut._loop, self.one_loop)
  1513. self.one_loop.run_until_complete(fut)
  1514. self.set_event_loop(self.other_loop, cleanup=False)
  1515. gen3 = coro()
  1516. gen4 = coro()
  1517. fut2 = asyncio.gather(gen3, gen4, loop=self.other_loop)
  1518. self.assertIs(fut2._loop, self.other_loop)
  1519. self.other_loop.run_until_complete(fut2)
  1520. def test_duplicate_coroutines(self):
  1521. @asyncio.coroutine
  1522. def coro(s):
  1523. return s
  1524. c = coro('abc')
  1525. fut = asyncio.gather(c, c, coro('def'), c, loop=self.one_loop)
  1526. self._run_loop(self.one_loop)
  1527. self.assertEqual(fut.result(), ['abc', 'abc', 'def', 'abc'])
  1528. def test_cancellation_broadcast(self):
  1529. # Cancelling outer() cancels all children.
  1530. proof = 0
  1531. waiter = asyncio.Future(loop=self.one_loop)
  1532. @asyncio.coroutine
  1533. def inner():
  1534. nonlocal proof
  1535. yield from waiter
  1536. proof += 1
  1537. child1 = asyncio.async(inner(), loop=self.one_loop)
  1538. child2 = asyncio.async(inner(), loop=self.one_loop)
  1539. gatherer = None
  1540. @asyncio.coroutine
  1541. def outer():
  1542. nonlocal proof, gatherer
  1543. gatherer = asyncio.gather(child1, child2, loop=self.one_loop)
  1544. yield from gatherer
  1545. proof += 100
  1546. f = asyncio.async(outer(), loop=self.one_loop)
  1547. test_utils.run_briefly(self.one_loop)
  1548. self.assertTrue(f.cancel())
  1549. with self.assertRaises(asyncio.CancelledError):
  1550. self.one_loop.run_until_complete(f)
  1551. self.assertFalse(gatherer.cancel())
  1552. self.assertTrue(waiter.cancelled())
  1553. self.assertTrue(child1.cancelled())
  1554. self.assertTrue(child2.cancelled())
  1555. test_utils.run_briefly(self.one_loop)
  1556. self.assertEqual(proof, 0)
  1557. def test_exception_marking(self):
  1558. # Test for the first line marked "Mark exception retrieved."
  1559. @asyncio.coroutine
  1560. def inner(f):
  1561. yield from f
  1562. raise RuntimeError('should not be ignored')
  1563. a = asyncio.Future(loop=self.one_loop)
  1564. b = asyncio.Future(loop=self.one_loop)
  1565. @asyncio.coroutine
  1566. def outer():
  1567. yield from asyncio.gather(inner(a), inner(b), loop=self.one_loop)
  1568. f = asyncio.async(outer(), loop=self.one_loop)
  1569. test_utils.run_briefly(self.one_loop)
  1570. a.set_result(None)
  1571. test_utils.run_briefly(self.one_loop)
  1572. b.set_result(None)
  1573. test_utils.run_briefly(self.one_loop)
  1574. self.assertIsInstance(f.exception(), RuntimeError)
  1575. if __name__ == '__main__':
  1576. unittest.main()