diff options
Diffstat (limited to 'Lib/asyncio')
-rw-r--r-- | Lib/asyncio/base_events.py | 6 | ||||
-rw-r--r-- | Lib/asyncio/base_subprocess.py | 3 | ||||
-rw-r--r-- | Lib/asyncio/futures.py | 95 | ||||
-rw-r--r-- | Lib/asyncio/proactor_events.py | 3 | ||||
-rw-r--r-- | Lib/asyncio/selector_events.py | 3 | ||||
-rw-r--r-- | Lib/asyncio/sslproto.py | 3 | ||||
-rw-r--r-- | Lib/asyncio/test_utils.py | 8 | ||||
-rw-r--r-- | Lib/asyncio/unix_events.py | 6 | ||||
-rw-r--r-- | Lib/asyncio/windows_events.py | 9 | ||||
-rw-r--r-- | Lib/asyncio/windows_utils.py | 3 |
10 files changed, 84 insertions, 55 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index b3e318e1b1..58800617d9 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -348,6 +348,9 @@ class BaseEventLoop(events.AbstractEventLoop): self._asyncgens.discard(agen) if not self.is_closed(): self.create_task(agen.aclose()) + # Wake up the loop if the finalizer was called from + # a different thread. + self._write_to_self() def _asyncgen_firstiter_hook(self, agen): if self._asyncgens_shutdown_called: @@ -485,7 +488,8 @@ class BaseEventLoop(events.AbstractEventLoop): if compat.PY34: def __del__(self): if not self.is_closed(): - warnings.warn("unclosed event loop %r" % self, ResourceWarning) + warnings.warn("unclosed event loop %r" % self, ResourceWarning, + source=self) if not self.is_running(): self.close() diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py index 23742a169a..a00d9d5732 100644 --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -127,7 +127,8 @@ class BaseSubprocessTransport(transports.SubprocessTransport): if compat.PY34: def __del__(self): if not self._closed: - warnings.warn("unclosed transport %r" % self, ResourceWarning) + warnings.warn("unclosed transport %r" % self, ResourceWarning, + source=self) self.close() def get_pid(self): diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index bcd4d16b9d..e45d6aa387 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 @@ -242,10 +247,10 @@ class Future: if self._state != _PENDING: return False self._state = _CANCELLED - self._schedule_callbacks() + self.__schedule_callbacks() return True - def _schedule_callbacks(self): + def __schedule_callbacks(self): """Internal: Ask the event loop to call all callbacks. The callbacks are scheduled to be called as soon as possible. Also @@ -347,7 +352,7 @@ class Future: raise InvalidStateError('{}: {!r}'.format(self._state, self)) self._result = result self._state = _FINISHED - self._schedule_callbacks() + self.__schedule_callbacks() def set_exception(self, exception): """Mark the future done and set an exception. @@ -364,7 +369,7 @@ class Future: "and cannot be raised into a Future") self._exception = exception self._state = _FINISHED - self._schedule_callbacks() + self.__schedule_callbacks() if compat.PY34: self._log_traceback = True else: @@ -476,3 +481,11 @@ def wrap_future(future, *, loop=None): new_future = loop.create_future() _chain_future(future, new_future) return new_future + + +try: + import _asyncio +except ImportError: + pass +else: + Future = _asyncio.Future diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index fef3205877..ff12877fae 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -92,7 +92,8 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, if compat.PY34: def __del__(self): if self._sock is not None: - warnings.warn("unclosed transport %r" % self, ResourceWarning) + warnings.warn("unclosed transport %r" % self, ResourceWarning, + source=self) self.close() def _fatal_error(self, exc, message='Fatal error on pipe transport'): diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 12d357b560..9dbe550b01 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -627,7 +627,8 @@ class _SelectorTransport(transports._FlowControlMixin, if compat.PY34: def __del__(self): if self._sock is not None: - warnings.warn("unclosed transport %r" % self, ResourceWarning) + warnings.warn("unclosed transport %r" % self, ResourceWarning, + source=self) self._sock.close() def _fatal_error(self, exc, message='Fatal error on transport'): diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 804c5c30f1..991c77b482 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -331,7 +331,8 @@ class _SSLProtocolTransport(transports._FlowControlMixin, if compat.PY34: def __del__(self): if not self._closed: - warnings.warn("unclosed transport %r" % self, ResourceWarning) + warnings.warn("unclosed transport %r" % self, ResourceWarning, + source=self) self.close() def pause_reading(self): diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py index 307fffccc6..fdd3ba0e41 100644 --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -119,10 +119,10 @@ class SSLWSGIServerMixin: 'test', 'test_asyncio') keyfile = os.path.join(here, 'ssl_key.pem') certfile = os.path.join(here, 'ssl_cert.pem') - ssock = ssl.wrap_socket(request, - keyfile=keyfile, - certfile=certfile, - server_side=True) + context = ssl.SSLContext() + context.load_cert_chain(certfile, keyfile) + + ssock = context.wrap_socket(request, server_side=True) try: self.RequestHandlerClass(ssock, client_address, self) ssock.close() diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 65b61db66a..2843678bba 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -411,7 +411,8 @@ class _UnixReadPipeTransport(transports.ReadTransport): if compat.PY34: def __del__(self): if self._pipe is not None: - warnings.warn("unclosed transport %r" % self, ResourceWarning) + warnings.warn("unclosed transport %r" % self, ResourceWarning, + source=self) self._pipe.close() def _fatal_error(self, exc, message='Fatal error on pipe transport'): @@ -611,7 +612,8 @@ class _UnixWritePipeTransport(transports._FlowControlMixin, if compat.PY34: def __del__(self): if self._pipe is not None: - warnings.warn("unclosed transport %r" % self, ResourceWarning) + warnings.warn("unclosed transport %r" % self, ResourceWarning, + source=self) self._pipe.close() def abort(self): diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index 668fe1451b..b777dd065a 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -171,8 +171,13 @@ class _WaitCancelFuture(_BaseWaitHandleFuture): def cancel(self): raise RuntimeError("_WaitCancelFuture must not be cancelled") - def _schedule_callbacks(self): - super(_WaitCancelFuture, self)._schedule_callbacks() + def set_result(self, result): + super().set_result(result) + if self._done_callback is not None: + self._done_callback(self) + + def set_exception(self, exception): + super().set_exception(exception) if self._done_callback is not None: self._done_callback(self) diff --git a/Lib/asyncio/windows_utils.py b/Lib/asyncio/windows_utils.py index 870cd13abe..7c63fb904b 100644 --- a/Lib/asyncio/windows_utils.py +++ b/Lib/asyncio/windows_utils.py @@ -159,7 +159,8 @@ class PipeHandle: def __del__(self): if self._handle is not None: - warnings.warn("unclosed %r" % self, ResourceWarning) + warnings.warn("unclosed %r" % self, ResourceWarning, + source=self) self.close() def __enter__(self): |