PageRenderTime 25ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/msf/core/modules/external/python/async_timeout/__init__.py

https://github.com/rapid7/metasploit-framework
Python | 101 lines | 87 code | 5 blank | 9 comment | 0 complexity | b2846ed3be1f6e432ea72153c03236ce MD5 | raw file
  1. # Vendored from https://github.com/aio-libs/async-timeout
  2. # Copyright: 2016-2017 Andrew Svetlov
  3. # License: Apache 2.0
  4. import asyncio
  5. __version__ = '2.0.0'
  6. class timeout:
  7. """timeout context manager.
  8. Useful in cases when you want to apply timeout logic around block
  9. of code or in cases when asyncio.wait_for is not suitable. For example:
  10. >>> async with timeout(0.001):
  11. ... async with aiohttp.get('https://github.com') as r:
  12. ... await r.text()
  13. timeout - value in seconds or None to disable timeout logic
  14. loop - asyncio compatible event loop
  15. """
  16. def __init__(self, timeout, *, loop=None):
  17. self._timeout = timeout
  18. if loop is None:
  19. loop = asyncio.get_event_loop()
  20. self._loop = loop
  21. self._task = None
  22. self._cancelled = False
  23. self._cancel_handler = None
  24. self._cancel_at = None
  25. def __enter__(self):
  26. return self._do_enter()
  27. def __exit__(self, exc_type, exc_val, exc_tb):
  28. self._do_exit(exc_type)
  29. @asyncio.coroutine
  30. def __aenter__(self):
  31. return self._do_enter()
  32. @asyncio.coroutine
  33. def __aexit__(self, exc_type, exc_val, exc_tb):
  34. self._do_exit(exc_type)
  35. @property
  36. def expired(self):
  37. return self._cancelled
  38. @property
  39. def remaining(self):
  40. if self._cancel_at is not None:
  41. return max(self._cancel_at - self._loop.time(), 0.0)
  42. else:
  43. return None
  44. def _do_enter(self):
  45. # Support Tornado 5- without timeout
  46. # Details: https://github.com/python/asyncio/issues/392
  47. if self._timeout is None:
  48. return self
  49. self._task = current_task(self._loop)
  50. if self._task is None:
  51. raise RuntimeError('Timeout context manager should be used '
  52. 'inside a task')
  53. if self._timeout <= 0:
  54. self._loop.call_soon(self._cancel_task)
  55. return self
  56. self._cancel_at = self._loop.time() + self._timeout
  57. self._cancel_handler = self._loop.call_at(
  58. self._cancel_at, self._cancel_task)
  59. return self
  60. def _do_exit(self, exc_type):
  61. if exc_type is asyncio.CancelledError and self._cancelled:
  62. self._cancel_handler = None
  63. self._task = None
  64. raise asyncio.TimeoutError
  65. if self._timeout is not None and self._cancel_handler is not None:
  66. self._cancel_handler.cancel()
  67. self._cancel_handler = None
  68. self._task = None
  69. def _cancel_task(self):
  70. self._task.cancel()
  71. self._cancelled = True
  72. def current_task(loop):
  73. task = asyncio.Task.current_task(loop=loop)
  74. if task is None:
  75. if hasattr(loop, 'current_task'):
  76. task = loop.current_task()
  77. return task