asyncio: __del__() keep reference to warnings.warn (GH-11491)

* asyncio: __del__() keep reference to warnings.warn

The __del__() methods of asyncio classes now keep a strong reference
to the warnings.warn() to be able to display the ResourceWarning
warning in more cases. Ensure that the function remains available if
instances are destroyed late during Python shutdown (while module
symbols are cleared).

* Rename warn parameter to _warn

"_warn" name is a hint that it's not the regular warnings.warn()
function.
This commit is contained in:
Victor Stinner 2019-01-10 11:24:40 +01:00 committed by GitHub
parent 9b07681c09
commit fb2c3465f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 16 additions and 24 deletions

View File

@ -622,10 +622,9 @@ class BaseEventLoop(events.AbstractEventLoop):
"""Returns True if the event loop was closed."""
return self._closed
def __del__(self):
def __del__(self, _warn=warnings.warn):
if not self.is_closed():
warnings.warn(f"unclosed event loop {self!r}", ResourceWarning,
source=self)
_warn(f"unclosed event loop {self!r}", ResourceWarning, source=self)
if not self.is_running():
self.close()

View File

@ -120,10 +120,9 @@ class BaseSubprocessTransport(transports.SubprocessTransport):
# Don't clear the _proc reference yet: _post_init() may still run
def __del__(self):
def __del__(self, _warn=warnings.warn):
if not self._closed:
warnings.warn(f"unclosed transport {self!r}", ResourceWarning,
source=self)
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
self.close()
def get_pid(self):

View File

@ -89,10 +89,9 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin,
self._read_fut.cancel()
self._read_fut = None
def __del__(self):
def __del__(self, _warn=warnings.warn):
if self._sock is not None:
warnings.warn(f"unclosed transport {self!r}", ResourceWarning,
source=self)
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
self.close()
def _fatal_error(self, exc, message='Fatal error on pipe transport'):

View File

@ -658,10 +658,9 @@ class _SelectorTransport(transports._FlowControlMixin,
self._loop._remove_writer(self._sock_fd)
self._loop.call_soon(self._call_connection_lost, None)
def __del__(self):
def __del__(self, _warn=warnings.warn):
if self._sock is not None:
warnings.warn(f"unclosed transport {self!r}", ResourceWarning,
source=self)
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
self._sock.close()
def _fatal_error(self, exc, message='Fatal error on transport'):

View File

@ -316,10 +316,9 @@ class _SSLProtocolTransport(transports._FlowControlMixin,
self._closed = True
self._ssl_protocol._start_shutdown()
def __del__(self):
def __del__(self, _warn=warnings.warn):
if not self._closed:
warnings.warn(f"unclosed transport {self!r}", ResourceWarning,
source=self)
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
self.close()
def is_reading(self):

View File

@ -511,10 +511,9 @@ class _UnixReadPipeTransport(transports.ReadTransport):
if not self._closing:
self._close(None)
def __del__(self):
def __del__(self, _warn=warnings.warn):
if self._pipe is not None:
warnings.warn(f"unclosed transport {self!r}", ResourceWarning,
source=self)
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
self._pipe.close()
def _fatal_error(self, exc, message='Fatal error on pipe transport'):
@ -707,10 +706,9 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
# write_eof is all what we needed to close the write pipe
self.write_eof()
def __del__(self):
def __del__(self, _warn=warnings.warn):
if self._pipe is not None:
warnings.warn(f"unclosed transport {self!r}", ResourceWarning,
source=self)
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
self._pipe.close()
def abort(self):

View File

@ -107,10 +107,9 @@ class PipeHandle:
CloseHandle(self._handle)
self._handle = None
def __del__(self):
def __del__(self, _warn=warnings.warn):
if self._handle is not None:
warnings.warn(f"unclosed {self!r}", ResourceWarning,
source=self)
_warn(f"unclosed {self!r}", ResourceWarning, source=self)
self.close()
def __enter__(self):