diff options
author | INADA Naoki <songofacandy@gmail.com> | 2016-10-09 05:44:47 (GMT) |
---|---|---|
committer | INADA Naoki <songofacandy@gmail.com> | 2016-10-09 05:44:47 (GMT) |
commit | 9e4e38ecd2cb46e0e52d1b23de3dd95dcdf645bf (patch) | |
tree | e32422607ffd7841407b6fad1179cb3bda5118af /Lib/asyncio | |
parent | 518599b24ce015910a364152692d60733c40f88f (diff) | |
download | cpython-9e4e38ecd2cb46e0e52d1b23de3dd95dcdf645bf.zip cpython-9e4e38ecd2cb46e0e52d1b23de3dd95dcdf645bf.tar.gz cpython-9e4e38ecd2cb46e0e52d1b23de3dd95dcdf645bf.tar.bz2 |
Issue #26801: Added C implementation of asyncio.Future.
Original patch by Yury Selivanov.
Diffstat (limited to 'Lib/asyncio')
-rw-r--r-- | Lib/asyncio/futures.py | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index bcd4d16..7c5b1aa 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -120,6 +120,46 @@ def isfuture(obj): return getattr(obj, '_asyncio_future_blocking', None) is not None +def _format_callbacks(cb): + """helper function for Future.__repr__""" + size = len(cb) + if not size: + cb = '' + + def format_cb(callback): + return events._format_callback_source(callback, ()) + + if size == 1: + cb = format_cb(cb[0]) + elif size == 2: + cb = '{}, {}'.format(format_cb(cb[0]), format_cb(cb[1])) + elif size > 2: + cb = '{}, <{} more>, {}'.format(format_cb(cb[0]), + size-2, + format_cb(cb[-1])) + return 'cb=[%s]' % cb + + +def _future_repr_info(future): + # (Future) -> str + """helper function for Future.__repr__""" + info = [future._state.lower()] + if future._state == _FINISHED: + if future._exception is not None: + info.append('exception={!r}'.format(future._exception)) + else: + # use reprlib to limit the length of the output, especially + # for very long strings + result = reprlib.repr(future._result) + info.append('result={}'.format(result)) + if future._callbacks: + info.append(_format_callbacks(future._callbacks)) + if future._source_traceback: + frame = future._source_traceback[-1] + info.append('created at %s:%s' % (frame[0], frame[1])) + return info + + class Future: """This class is *almost* compatible with concurrent.futures.Future. @@ -172,45 +212,10 @@ class Future: if self._loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) - def __format_callbacks(self): - cb = self._callbacks - size = len(cb) - if not size: - cb = '' - - def format_cb(callback): - return events._format_callback_source(callback, ()) - - if size == 1: - cb = format_cb(cb[0]) - elif size == 2: - cb = '{}, {}'.format(format_cb(cb[0]), format_cb(cb[1])) - elif size > 2: - cb = '{}, <{} more>, {}'.format(format_cb(cb[0]), - size-2, - format_cb(cb[-1])) - return 'cb=[%s]' % cb - - def _repr_info(self): - info = [self._state.lower()] - if self._state == _FINISHED: - if self._exception is not None: - info.append('exception={!r}'.format(self._exception)) - else: - # use reprlib to limit the length of the output, especially - # for very long strings - result = reprlib.repr(self._result) - info.append('result={}'.format(result)) - if self._callbacks: - info.append(self.__format_callbacks()) - if self._source_traceback: - frame = self._source_traceback[-1] - info.append('created at %s:%s' % (frame[0], frame[1])) - return info + _repr_info = _future_repr_info def __repr__(self): - info = self._repr_info() - return '<%s %s>' % (self.__class__.__name__, ' '.join(info)) + return '<%s %s>' % (self.__class__.__name__, ' '.join(self._repr_info())) # On Python 3.3 and older, objects with a destructor part of a reference # cycle are never destroyed. It's not more the case on Python 3.4 thanks @@ -426,6 +431,21 @@ def _copy_future_state(source, dest): dest.set_result(result) +try: + import _futures +except ImportError: + pass +else: + _futures._init_module( + traceback.extract_stack, + events.get_event_loop, + _future_repr_info, + InvalidStateError, + CancelledError) + + Future = _futures.Future + + def _chain_future(source, destination): """Chain two futures so that when one completes, so does the other. |