From 313a9809043ed2ed1ad25282af7169e08cdc92a3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 29 Jul 2014 12:58:23 +0200 Subject: asyncio: sync with Tulip * _WaitHandleFuture.cancel() now notify IocpProactor through the overlapped object that the wait was cancelled. * Optimize IocpProactor.wait_for_handle() gets the result if the wait is signaled immediatly. * Enhance representation of Future and Future subclasses - Add "created at filename:lineno" in the representation - Add Future._repr_info() method which can be more easily overriden than Future.__repr__(). It should now be more easy to enhance Future representation without having to modify each subclass. For example, _OverlappedFuture and _WaitHandleFuture get the new "created at" information. - Use reprlib to format Future result, and function arguments when formatting a callback, to limit the length of the representation. * Fix repr(_WaitHandleFuture) * _WaitHandleFuture and _OverlappedFuture: hide frames of internal calls in the source traceback. * Cleanup ProactorIocp._poll(): set the timeout to 0 after the first call to GetQueuedCompletionStatus() * test_locks: close the temporary event loop and check the condition lock * Remove workaround in test_futures, no more needed --- Lib/asyncio/futures.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'Lib/asyncio/futures.py') diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 022fef76ef..7998fbbcfb 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -7,6 +7,7 @@ __all__ = ['CancelledError', 'TimeoutError', import concurrent.futures._base import logging +import reprlib import sys import traceback @@ -175,20 +176,25 @@ class Future: format_cb(cb[-1])) return 'cb=[%s]' % cb - def _format_result(self): - if self._state != _FINISHED: - return None - elif self._exception is not None: - return 'exception={!r}'.format(self._exception) - else: - return 'result={!r}'.format(self._result) - - def __repr__(self): + def _repr_info(self): info = [self._state.lower()] if self._state == _FINISHED: - info.append(self._format_result()) + 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 + + def __repr__(self): + info = self._repr_info() return '<%s %s>' % (self.__class__.__name__, ' '.join(info)) # On Python 3.3 or older, objects with a destructor part of a reference -- cgit v1.2.1