mirror of
https://github.com/python/cpython.git
synced 2025-09-18 22:50:26 +00:00
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
This commit is contained in:
parent
060f9bb602
commit
e19558af1b
13 changed files with 34 additions and 19 deletions
|
@ -300,7 +300,7 @@ Available Functions
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|
||||||
.. 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*
|
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
|
argument, if given, must be a warning category class (see above); it defaults to
|
||||||
|
@ -318,6 +318,12 @@ Available Functions
|
||||||
source of :func:`deprecation` itself (since the latter would defeat the purpose
|
source of :func:`deprecation` itself (since the latter would defeat the purpose
|
||||||
of the warning message).
|
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)
|
.. function:: warn_explicit(message, category, filename, lineno, module=None, registry=None, module_globals=None, source=None)
|
||||||
|
|
||||||
|
|
|
@ -1514,7 +1514,7 @@ class FileIO(RawIOBase):
|
||||||
if self._fd >= 0 and self._closefd and not self.closed:
|
if self._fd >= 0 and self._closefd and not self.closed:
|
||||||
import warnings
|
import warnings
|
||||||
warnings.warn('unclosed file %r' % (self,), ResourceWarning,
|
warnings.warn('unclosed file %r' % (self,), ResourceWarning,
|
||||||
stacklevel=2)
|
stacklevel=2, source=self)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
|
|
|
@ -412,7 +412,8 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
if compat.PY34:
|
if compat.PY34:
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if not self.is_closed():
|
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():
|
if not self.is_running():
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,8 @@ class BaseSubprocessTransport(transports.SubprocessTransport):
|
||||||
if compat.PY34:
|
if compat.PY34:
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if not self._closed:
|
if not self._closed:
|
||||||
warnings.warn("unclosed transport %r" % self, ResourceWarning)
|
warnings.warn("unclosed transport %r" % self, ResourceWarning,
|
||||||
|
source=self)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def get_pid(self):
|
def get_pid(self):
|
||||||
|
|
|
@ -86,7 +86,8 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin,
|
||||||
if compat.PY34:
|
if compat.PY34:
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self._sock is not None:
|
if self._sock is not None:
|
||||||
warnings.warn("unclosed transport %r" % self, ResourceWarning)
|
warnings.warn("unclosed transport %r" % self, ResourceWarning,
|
||||||
|
source=self)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def _fatal_error(self, exc, message='Fatal error on pipe transport'):
|
def _fatal_error(self, exc, message='Fatal error on pipe transport'):
|
||||||
|
|
|
@ -573,7 +573,8 @@ class _SelectorTransport(transports._FlowControlMixin,
|
||||||
if compat.PY34:
|
if compat.PY34:
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self._sock is not None:
|
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()
|
self._sock.close()
|
||||||
|
|
||||||
def _fatal_error(self, exc, message='Fatal error on transport'):
|
def _fatal_error(self, exc, message='Fatal error on transport'):
|
||||||
|
|
|
@ -324,7 +324,8 @@ class _SSLProtocolTransport(transports._FlowControlMixin,
|
||||||
if compat.PY34:
|
if compat.PY34:
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if not self._closed:
|
if not self._closed:
|
||||||
warnings.warn("unclosed transport %r" % self, ResourceWarning)
|
warnings.warn("unclosed transport %r" % self, ResourceWarning,
|
||||||
|
source=self)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def pause_reading(self):
|
def pause_reading(self):
|
||||||
|
|
|
@ -378,7 +378,8 @@ class _UnixReadPipeTransport(transports.ReadTransport):
|
||||||
if compat.PY34:
|
if compat.PY34:
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self._pipe is not None:
|
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()
|
self._pipe.close()
|
||||||
|
|
||||||
def _fatal_error(self, exc, message='Fatal error on pipe transport'):
|
def _fatal_error(self, exc, message='Fatal error on pipe transport'):
|
||||||
|
@ -567,7 +568,8 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
|
||||||
if compat.PY34:
|
if compat.PY34:
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self._pipe is not None:
|
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()
|
self._pipe.close()
|
||||||
|
|
||||||
def abort(self):
|
def abort(self):
|
||||||
|
|
|
@ -159,7 +159,8 @@ class PipeHandle:
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self._handle is not None:
|
if self._handle is not None:
|
||||||
warnings.warn("unclosed %r" % self, ResourceWarning)
|
warnings.warn("unclosed %r" % self, ResourceWarning,
|
||||||
|
source=self)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
|
|
|
@ -595,7 +595,8 @@ if os.name == 'posix':
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self.fd >= 0:
|
if self.fd >= 0:
|
||||||
warnings.warn("unclosed file %r" % self, ResourceWarning)
|
warnings.warn("unclosed file %r" % self, ResourceWarning,
|
||||||
|
source=self)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def recv(self, *args):
|
def recv(self, *args):
|
||||||
|
|
|
@ -797,7 +797,6 @@ class TemporaryDirectory(object):
|
||||||
_shutil.rmtree(name)
|
_shutil.rmtree(name)
|
||||||
_warnings.warn(warn_message, ResourceWarning)
|
_warnings.warn(warn_message, ResourceWarning)
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<{} {!r}>".format(self.__class__.__name__, self.name)
|
return "<{} {!r}>".format(self.__class__.__name__, self.name)
|
||||||
|
|
||||||
|
|
|
@ -233,7 +233,7 @@ def _next_external_frame(frame):
|
||||||
|
|
||||||
|
|
||||||
# Code typically replaced by _warnings
|
# 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."""
|
"""Issue a warning, or maybe ignore it or raise an exception."""
|
||||||
# Check if message is already a Warning object
|
# Check if message is already a Warning object
|
||||||
if isinstance(message, Warning):
|
if isinstance(message, Warning):
|
||||||
|
@ -283,7 +283,7 @@ def warn(message, category=None, stacklevel=1):
|
||||||
filename = module
|
filename = module
|
||||||
registry = globals.setdefault("__warningregistry__", {})
|
registry = globals.setdefault("__warningregistry__", {})
|
||||||
warn_explicit(message, category, filename, lineno, module, registry,
|
warn_explicit(message, category, filename, lineno, module, registry,
|
||||||
globals)
|
globals, source)
|
||||||
|
|
||||||
def warn_explicit(message, category, filename, lineno,
|
def warn_explicit(message, category, filename, lineno,
|
||||||
module=None, registry=None, module_globals=None,
|
module=None, registry=None, module_globals=None,
|
||||||
|
|
|
@ -787,18 +787,19 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level,
|
||||||
static PyObject *
|
static PyObject *
|
||||||
warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
|
warnings_warn(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
static char *kw_list[] = { "message", "category", "stacklevel", 0 };
|
static char *kw_list[] = {"message", "category", "stacklevel",
|
||||||
PyObject *message, *category = NULL;
|
"source", NULL};
|
||||||
|
PyObject *message, *category = NULL, *source = NULL;
|
||||||
Py_ssize_t stack_level = 1;
|
Py_ssize_t stack_level = 1;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|On:warn", kw_list,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OnO:warn", kw_list,
|
||||||
&message, &category, &stack_level))
|
&message, &category, &stack_level, &source))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
category = get_category(message, category);
|
category = get_category(message, category);
|
||||||
if (category == NULL)
|
if (category == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return do_warn(message, category, stack_level, NULL);
|
return do_warn(message, category, stack_level, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue