summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-01-10 11:24:40 +0100
committerGitHub <noreply@github.com>2019-01-10 11:24:40 +0100
commitfb2c3465f09e1f720cdae7eca87d62125a327fd9 (patch)
treea1cfdcf7ea81295f3a955bcdec2275b8e8967965
parent9b07681c09182d4b9d23cd52566a4992b8afecbb (diff)
downloadcpython-git-fb2c3465f09e1f720cdae7eca87d62125a327fd9.tar.gz
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.
-rw-r--r--Lib/asyncio/base_events.py5
-rw-r--r--Lib/asyncio/base_subprocess.py5
-rw-r--r--Lib/asyncio/proactor_events.py5
-rw-r--r--Lib/asyncio/selector_events.py5
-rw-r--r--Lib/asyncio/sslproto.py5
-rw-r--r--Lib/asyncio/unix_events.py10
-rw-r--r--Lib/asyncio/windows_utils.py5
7 files changed, 16 insertions, 24 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 60a189bdfb..cec47ce67f 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -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()
diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py
index b547c444ad..f503f78fdd 100644
--- a/Lib/asyncio/base_subprocess.py
+++ b/Lib/asyncio/base_subprocess.py
@@ -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):
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
index da204c69d4..3a1826e2c0 100644
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -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'):
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index 112c4b15b8..93b6889509 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -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'):
diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py
index 12fdb0d1c5..42785609dc 100644
--- a/Lib/asyncio/sslproto.py
+++ b/Lib/asyncio/sslproto.py
@@ -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):
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 1a62db4f59..73d4bda7c2 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -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):
diff --git a/Lib/asyncio/windows_utils.py b/Lib/asyncio/windows_utils.py
index 9e22f6e074..ef277fac3e 100644
--- a/Lib/asyncio/windows_utils.py
+++ b/Lib/asyncio/windows_utils.py
@@ -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):