[Python-checkins] cpython: Add a source parameter to warnings.warn()

victor.stinner python-checkins at python.org
Tue Mar 22 19:38:36 EDT 2016


https://hg.python.org/cpython/rev/3a57ced47459
changeset: 100669:3a57ced47459
user: Victor Stinner <victor.stinner at gmail.com>
date: Wed Mar 23 00:28:08 2016 +0100
summary:
 Add a source parameter to warnings.warn()
Issue #26604:
* Add a new optional source parameter to _warnings.warn() and warnings.warn()
* Modify asyncore, asyncio and _pyio modules to set the source parameter when
 logging a ResourceWarning warning
files:
 Doc/library/warnings.rst | 8 +++++++-
 Lib/_pyio.py | 2 +-
 Lib/asyncio/base_events.py | 3 ++-
 Lib/asyncio/base_subprocess.py | 3 ++-
 Lib/asyncio/proactor_events.py | 3 ++-
 Lib/asyncio/selector_events.py | 3 ++-
 Lib/asyncio/sslproto.py | 3 ++-
 Lib/asyncio/unix_events.py | 6 ++++--
 Lib/asyncio/windows_utils.py | 3 ++-
 Lib/asyncore.py | 3 ++-
 Lib/tempfile.py | 1 -
 Lib/warnings.py | 4 ++--
 Python/_warnings.c | 11 ++++++-----
 13 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst
--- a/Doc/library/warnings.rst
+++ b/Doc/library/warnings.rst
@@ -300,7 +300,7 @@
 -------------------
 
 
-.. function:: warn(message, category=None, stacklevel=1)
+.. function:: warn(message, category=None, stacklevel=1, source=None)
 
 Issue a warning, or maybe ignore it or raise an exception. The *category*
 argument, if given, must be a warning category class (see above); it defaults to
@@ -318,6 +318,12 @@
 source of :func:`deprecation` itself (since the latter would defeat the purpose
 of the warning message).
 
+ *source*, if supplied, is the destroyed object which emitted a
+ :exc:`ResourceWarning`.
+
+ .. versionchanged:: 3.6
+ Added *source* parameter.
+
 
 .. function:: warn_explicit(message, category, filename, lineno, module=None, registry=None, module_globals=None, source=None)
 
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -1514,7 +1514,7 @@
 if self._fd >= 0 and self._closefd and not self.closed:
 import warnings
 warnings.warn('unclosed file %r' % (self,), ResourceWarning,
- stacklevel=2)
+ stacklevel=2, source=self)
 self.close()
 
 def __getstate__(self):
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -412,7 +412,8 @@
 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
--- a/Lib/asyncio/base_subprocess.py
+++ b/Lib/asyncio/base_subprocess.py
@@ -122,7 +122,8 @@
 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/proactor_events.py b/Lib/asyncio/proactor_events.py
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -86,7 +86,8 @@
 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
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -573,7 +573,8 @@
 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
--- a/Lib/asyncio/sslproto.py
+++ b/Lib/asyncio/sslproto.py
@@ -324,7 +324,8 @@
 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/unix_events.py b/Lib/asyncio/unix_events.py
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -378,7 +378,8 @@
 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'):
@@ -567,7 +568,8 @@
 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_utils.py b/Lib/asyncio/windows_utils.py
--- a/Lib/asyncio/windows_utils.py
+++ b/Lib/asyncio/windows_utils.py
@@ -159,7 +159,8 @@
 
 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):
diff --git a/Lib/asyncore.py b/Lib/asyncore.py
--- a/Lib/asyncore.py
+++ b/Lib/asyncore.py
@@ -595,7 +595,8 @@
 
 def __del__(self):
 if self.fd >= 0:
- warnings.warn("unclosed file %r" % self, ResourceWarning)
+ warnings.warn("unclosed file %r" % self, ResourceWarning,
+ source=self)
 self.close()
 
 def recv(self, *args):
diff --git a/Lib/tempfile.py b/Lib/tempfile.py
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -797,7 +797,6 @@
 _shutil.rmtree(name)
 _warnings.warn(warn_message, ResourceWarning)
 
-
 def __repr__(self):
 return "<{} {!r}>".format(self.__class__.__name__, self.name)
 
diff --git a/Lib/warnings.py b/Lib/warnings.py
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -233,7 +233,7 @@
 
 
 # Code typically replaced by _warnings
-def warn(message, category=None, stacklevel=1):
+def warn(message, category=None, stacklevel=1, source=None):
 """Issue a warning, or maybe ignore it or raise an exception."""
 # Check if message is already a Warning object
 if isinstance(message, Warning):
@@ -283,7 +283,7 @@
 filename = module
 registry = globals.setdefault("__warningregistry__", {})
 warn_explicit(message, category, filename, lineno, module, registry,
- globals)
+ globals, source)
 
 def warn_explicit(message, category, filename, lineno,
 module=None, registry=None, module_globals=None,
diff --git a/Python/_warnings.c b/Python/_warnings.c
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -787,18 +787,19 @@
 static PyObject *
 warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
 {
- static char *kw_list[] = { "message", "category", "stacklevel", 0 };
- PyObject *message, *category = NULL;
+ static char *kw_list[] = {"message", "category", "stacklevel",
+ "source", NULL};
+ PyObject *message, *category = NULL, *source = NULL;
 Py_ssize_t stack_level = 1;
 
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
- &message, &category, &stack_level))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OnO:warn", kw_list,
+ &message, &category, &stack_level, &source))
 return NULL;
 
 category = get_category(message, category);
 if (category == NULL)
 return NULL;
- return do_warn(message, category, stack_level, NULL);
+ return do_warn(message, category, stack_level, source);
 }
 
 static PyObject *
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /