Skip to content

Commit c76fa2c

Browse files
committed
Vendor async_timeout
1 parent 9648101 commit c76fa2c

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

LICENSE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ Files: lib/metasm.rb lib/metasm/* data/cpuinfo/*
7575
Copyright: 2006-2010 Yoann GUILLOT
7676
License: LGPL-2.1
7777

78+
Files: lib/msf/core/modules/external/python/async_timeout/*
79+
Copyright: 2016-2017 Andrew Svetlov
80+
License: Apache 2.0
81+
7882
Files: lib/net/dns.rb lib/net/dns/*
7983
Copyright: 2006 Marco Ceresa
8084
License: Ruby
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Vendored from https://github.com/aio-libs/async-timeout
2+
# Copyright: 2016-2017 Andrew Svetlov
3+
# License: Apache 2.0
4+
5+
import asyncio
6+
7+
8+
__version__ = '2.0.0'
9+
10+
11+
class timeout:
12+
"""timeout context manager.
13+
14+
Useful in cases when you want to apply timeout logic around block
15+
of code or in cases when asyncio.wait_for is not suitable. For example:
16+
17+
>>> async with timeout(0.001):
18+
... async with aiohttp.get('https://github.com') as r:
19+
... await r.text()
20+
21+
22+
timeout - value in seconds or None to disable timeout logic
23+
loop - asyncio compatible event loop
24+
"""
25+
def __init__(self, timeout, *, loop=None):
26+
self._timeout = timeout
27+
if loop is None:
28+
loop = asyncio.get_event_loop()
29+
self._loop = loop
30+
self._task = None
31+
self._cancelled = False
32+
self._cancel_handler = None
33+
self._cancel_at = None
34+
35+
def __enter__(self):
36+
return self._do_enter()
37+
38+
def __exit__(self, exc_type, exc_val, exc_tb):
39+
self._do_exit(exc_type)
40+
41+
@asyncio.coroutine
42+
def __aenter__(self):
43+
return self._do_enter()
44+
45+
@asyncio.coroutine
46+
def __aexit__(self, exc_type, exc_val, exc_tb):
47+
self._do_exit(exc_type)
48+
49+
@property
50+
def expired(self):
51+
return self._cancelled
52+
53+
@property
54+
def remaining(self):
55+
if self._cancel_at is not None:
56+
return max(self._cancel_at - self._loop.time(), 0.0)
57+
else:
58+
return None
59+
60+
def _do_enter(self):
61+
# Support Tornado 5- without timeout
62+
# Details: https://github.com/python/asyncio/issues/392
63+
if self._timeout is None:
64+
return self
65+
66+
self._task = current_task(self._loop)
67+
if self._task is None:
68+
raise RuntimeError('Timeout context manager should be used '
69+
'inside a task')
70+
71+
if self._timeout <= 0:
72+
self._loop.call_soon(self._cancel_task)
73+
return self
74+
75+
self._cancel_at = self._loop.time() + self._timeout
76+
self._cancel_handler = self._loop.call_at(
77+
self._cancel_at, self._cancel_task)
78+
return self
79+
80+
def _do_exit(self, exc_type):
81+
if exc_type is asyncio.CancelledError and self._cancelled:
82+
self._cancel_handler = None
83+
self._task = None
84+
raise asyncio.TimeoutError
85+
if self._timeout is not None and self._cancel_handler is not None:
86+
self._cancel_handler.cancel()
87+
self._cancel_handler = None
88+
self._task = None
89+
90+
def _cancel_task(self):
91+
self._task.cancel()
92+
self._cancelled = True
93+
94+
95+
def current_task(loop):
96+
task = asyncio.Task.current_task(loop=loop)
97+
if task is None:
98+
if hasattr(loop, 'current_task'):
99+
task = loop.current_task()
100+
101+
return task

0 commit comments

Comments
 (0)