]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
asyncio: __del__() keep reference to warnings.warn (GH-11491)
authorVictor Stinner <vstinner@redhat.com>
Thu, 10 Jan 2019 10:24:40 +0000 (11:24 +0100)
committerGitHub <noreply@github.com>
Thu, 10 Jan 2019 10:24:40 +0000 (11:24 +0100)
* 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.

Lib/asyncio/base_events.py
Lib/asyncio/base_subprocess.py
Lib/asyncio/proactor_events.py
Lib/asyncio/selector_events.py
Lib/asyncio/sslproto.py
Lib/asyncio/unix_events.py
Lib/asyncio/windows_utils.py

index 60a189bdfb7ec9c609fb0577de8e13ac0990fbc3..cec47ce67f38243b6bcfd4fb6127421a9587b4f4 100644 (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()
 
index b547c444ad5d1c24e282da99aeb46d8c3b22a9eb..f503f78fdda349b4e56bed1a5a09a44d0dd17a07 100644 (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):
index da204c69d45e32a44059ec2178b8d6f447e51082..3a1826e2c0d22884a61f0c737731632d62a186af 100644 (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'):
index 112c4b15b8d8cf38efe9081bb94a6291dc51a8d2..93b6889509436c7d384beb6b434fe1d7a138e376 100644 (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'):
index 12fdb0d1c5ec1008844a07cd682678d96cce6e3d..42785609dcd2c0591bd56c9b73cbf7de902445ee 100644 (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):
index 1a62db4f59bcfef8227dcdc889e5f59057e7bc21..73d4bda7c2341b7c90fb071b5b8ecdef4c6a3dac 100644 (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):
index 9e22f6e0740e0c1e92bbf3a19406763d75296212..ef277fac3e291c307d5e26ada8ef5e28c47434f1 100644 (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):