From 6c4cff0f32c574454114d4cff6bd5f6d2870c04d Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 11 Mar 2009 04:51:06 +0000 Subject: [PATCH] Require implementations for warnings.showwarning() support the 'line' argument. Was a DeprecationWarning for not supporting it since Python 2.6. Closes issue #3652. --- Doc/library/warnings.rst | 5 ++-- Lib/test/test_warnings.py | 37 ----------------------- Lib/warnings.py | 18 ------------ Misc/NEWS | 3 ++ Python/_warnings.c | 62 ++++++++++----------------------------- 5 files changed, 20 insertions(+), 105 deletions(-) diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index 81e74528305..091327f3c8a 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -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]) diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py index b37cdf7788e..e90a2c2636b 100644 --- a/Lib/test/test_warnings.py +++ b/Lib/test/test_warnings.py @@ -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, ) diff --git a/Lib/warnings.py b/Lib/warnings.py index 59011caa46d..14466d3ba01 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -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) diff --git a/Misc/NEWS b/Misc/NEWS index 760badf6018..5af7df7da0c 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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. diff --git a/Python/_warnings.c b/Python/_warnings.c index 6a970bbb2bb..8ddfc8821a8 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -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) */