mirror of https://github.com/python/cpython
Require implementations for warnings.showwarning() support the 'line' argument.
Was a DeprecationWarning for not supporting it since Python 2.6. Closes issue #3652.
This commit is contained in:
parent
8f19598f78
commit
6c4cff0f32
|
@ -291,9 +291,8 @@ Available Functions
|
|||
message; if *line* is not supplied, :func:`showwarning` will
|
||||
try to read the line specified by *filename* and *lineno*.
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
Added the *line* argument. Implementations that lack the new argument
|
||||
will trigger a :exc:`DeprecationWarning`.
|
||||
.. versionchanged:: 2.7
|
||||
The *line* argument is required to be supported.
|
||||
|
||||
|
||||
.. function:: formatwarning(message, category, filename, lineno[, line])
|
||||
|
|
|
@ -605,41 +605,6 @@ class PyCatchWarningTests(CatchWarningTests):
|
|||
module = py_warnings
|
||||
|
||||
|
||||
class ShowwarningDeprecationTests(BaseTest):
|
||||
|
||||
"""Test the deprecation of the old warnings.showwarning() API works."""
|
||||
|
||||
@staticmethod
|
||||
def bad_showwarning(message, category, filename, lineno, file=None):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def ok_showwarning(*args):
|
||||
pass
|
||||
|
||||
def test_deprecation(self):
|
||||
# message, category, filename, lineno[, file[, line]]
|
||||
args = ("message", UserWarning, "file name", 42)
|
||||
with original_warnings.catch_warnings(module=self.module):
|
||||
self.module.filterwarnings("error", category=DeprecationWarning)
|
||||
self.module.showwarning = self.bad_showwarning
|
||||
self.assertRaises(DeprecationWarning, self.module.warn_explicit,
|
||||
*args)
|
||||
self.module.showwarning = self.ok_showwarning
|
||||
try:
|
||||
self.module.warn_explicit(*args)
|
||||
except DeprecationWarning as exc:
|
||||
self.fail('showwarning(*args) should not trigger a '
|
||||
'DeprecationWarning')
|
||||
|
||||
class CShowwarningDeprecationTests(ShowwarningDeprecationTests):
|
||||
module = c_warnings
|
||||
|
||||
|
||||
class PyShowwarningDeprecationTests(ShowwarningDeprecationTests):
|
||||
module = py_warnings
|
||||
|
||||
|
||||
def test_main():
|
||||
py_warnings.onceregistry.clear()
|
||||
c_warnings.onceregistry.clear()
|
||||
|
@ -649,8 +614,6 @@ def test_main():
|
|||
_WarningsTests,
|
||||
CWarningsDisplayTests, PyWarningsDisplayTests,
|
||||
CCatchWarningTests, PyCatchWarningTests,
|
||||
CShowwarningDeprecationTests,
|
||||
PyShowwarningDeprecationTests,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -262,24 +262,6 @@ def warn_explicit(message, category, filename, lineno,
|
|||
raise RuntimeError(
|
||||
"Unrecognized action (%r) in warnings.filters:\n %s" %
|
||||
(action, item))
|
||||
# Warn if showwarning() does not support the 'line' argument.
|
||||
# Don't use 'inspect' as it relies on an extension module, which break the
|
||||
# build thanks to 'warnings' being imported by setup.py.
|
||||
fxn_code = None
|
||||
if hasattr(showwarning, 'func_code'):
|
||||
fxn_code = showwarning.func_code
|
||||
elif hasattr(showwarning, '__func__'):
|
||||
fxn_code = showwarning.__func__.func_code
|
||||
if fxn_code:
|
||||
args = fxn_code.co_varnames[:fxn_code.co_argcount]
|
||||
CO_VARARGS = 0x4
|
||||
if 'line' not in args and not fxn_code.co_flags & CO_VARARGS:
|
||||
showwarning_msg = ("functions overriding warnings.showwarning() "
|
||||
"must support the 'line' argument")
|
||||
if message == showwarning_msg:
|
||||
_show_warning(message, category, filename, lineno)
|
||||
else:
|
||||
warn(showwarning_msg, DeprecationWarning)
|
||||
# Print message and context
|
||||
showwarning(message, category, filename, lineno)
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 1
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #3652: Make the 'line' argument for warnings.showwarning() a
|
||||
requirement. Means the DeprecationWarning from Python 2.6 can go away.
|
||||
|
||||
- Issue #5247: Improve error message when unknown format codes are
|
||||
used when using str.format() with str, unicode, long, int, and
|
||||
float arguments.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "Python.h"
|
||||
#include "code.h" /* For DeprecationWarning about adding 'line'. */
|
||||
#include "frameobject.h"
|
||||
|
||||
#define MODULE_NAME "_warnings"
|
||||
|
@ -387,54 +386,23 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
show_warning(filename, lineno, text, category, sourceline);
|
||||
}
|
||||
else {
|
||||
const char *msg = "functions overriding warnings.showwarning() "
|
||||
"must support the 'line' argument";
|
||||
const char *text_char = PyString_AS_STRING(text);
|
||||
PyObject *res;
|
||||
|
||||
if (strcmp(msg, text_char) == 0) {
|
||||
/* Prevent infinite recursion by using built-in implementation
|
||||
of showwarning(). */
|
||||
show_warning(filename, lineno, text, category, sourceline);
|
||||
}
|
||||
else {
|
||||
PyObject *check_fxn;
|
||||
PyObject *defaults;
|
||||
PyObject *res;
|
||||
if (!PyMethod_Check(show_fxn) && !PyFunction_Check(show_fxn)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"warnings.showwarning() must be set to a "
|
||||
"function or method");
|
||||
Py_DECREF(show_fxn);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (PyMethod_Check(show_fxn))
|
||||
check_fxn = PyMethod_Function(show_fxn);
|
||||
else if (PyFunction_Check(show_fxn))
|
||||
check_fxn = show_fxn;
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"warnings.showwarning() must be set to a "
|
||||
"function or method");
|
||||
Py_DECREF(show_fxn);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
defaults = PyFunction_GetDefaults(check_fxn);
|
||||
/* A proper implementation of warnings.showwarning() should
|
||||
have at least two default arguments. */
|
||||
if ((defaults == NULL) || (PyTuple_Size(defaults) < 2)) {
|
||||
PyCodeObject *code = (PyCodeObject *)
|
||||
PyFunction_GetCode(check_fxn);
|
||||
if (!(code->co_flags & CO_VARARGS)) {
|
||||
if (PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1) <
|
||||
0) {
|
||||
Py_DECREF(show_fxn);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
|
||||
filename, lineno_obj,
|
||||
NULL);
|
||||
Py_DECREF(show_fxn);
|
||||
Py_XDECREF(res);
|
||||
if (res == NULL)
|
||||
goto cleanup;
|
||||
}
|
||||
res = PyObject_CallFunctionObjArgs(show_fxn, message, category,
|
||||
filename, lineno_obj,
|
||||
NULL);
|
||||
Py_DECREF(show_fxn);
|
||||
Py_XDECREF(res);
|
||||
if (res == NULL)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else /* if (rc == -1) */
|
||||
|
|
Loading…
Reference in New Issue