DeprecationWarning is now silent by default.
This was originally suggested by Guido, discussed on the stdlib-sig mailing list, and given the OK by Guido directly to me. What this change essentially means is that Python has taken a policy of silencing warnings that are only of interest to developers by default. This should prevent users from seeing warnings which are triggered by an application being run against a new interpreter before the app developer has a chance to update their code. Closes issue #7319. Thanks to Antoine Pitrou, Ezio Melotti, and Brian Curtin for helping with the issue.
This commit is contained in:
parent
3ad57e2625
commit
6fdd3dcb6a
|
@ -59,7 +59,7 @@ following warnings category classes are currently defined:
|
|||
| :exc:`UserWarning` | The default category for :func:`warn`. |
|
||||
+----------------------------------+-----------------------------------------------+
|
||||
| :exc:`DeprecationWarning` | Base category for warnings about deprecated |
|
||||
| | features. |
|
||||
| | features (ignored by default). |
|
||||
+----------------------------------+-----------------------------------------------+
|
||||
| :exc:`SyntaxWarning` | Base category for warnings about dubious |
|
||||
| | syntactic features. |
|
||||
|
@ -89,6 +89,9 @@ User code can define additional warning categories by subclassing one of the
|
|||
standard warning categories. A warning category must always be a subclass of
|
||||
the :exc:`Warning` class.
|
||||
|
||||
.. versionchanged:: 2.7
|
||||
:exc:`DeprecationWarning` is ignored by default.
|
||||
|
||||
|
||||
.. _warning-filter:
|
||||
|
||||
|
@ -148,14 +151,6 @@ interpreter command line. The interpreter saves the arguments for all
|
|||
:mod:`warnings` module parses these when it is first imported (invalid options
|
||||
are ignored, after printing a message to ``sys.stderr``).
|
||||
|
||||
The warnings that are ignored by default may be enabled by passing :option:`-Wd`
|
||||
to the interpreter. This enables default handling for all warnings, including
|
||||
those that are normally ignored by default. This is particular useful for
|
||||
enabling ImportWarning when debugging problems importing a developed package.
|
||||
ImportWarning can also be enabled explicitly in Python code using::
|
||||
|
||||
warnings.simplefilter('default', ImportWarning)
|
||||
|
||||
|
||||
.. _warning-suppress:
|
||||
|
||||
|
@ -226,6 +221,37 @@ continues to increase after each operation, or else delete the previous
|
|||
entries from the warnings list before each new operation).
|
||||
|
||||
|
||||
Updating Code For New Versions of Python
|
||||
----------------------------------------
|
||||
|
||||
Warnings that are only of interest to the developer are ignored by default. As
|
||||
such you should make sure to test your code with typically ignored warnings
|
||||
made visible. You can do this from the command-line by passing :option:`-Wd`
|
||||
to the interpreter (this is shorthand for :option:`-W default`). This enables
|
||||
default handling for all warnings, including those that are ignored by default.
|
||||
To change what action is taken for encountered warnings you simply change what
|
||||
argument is passed to :option:`-W`, e.g. :option:`-W error`. See the
|
||||
:option:`-W` flag for more details on what is possible.
|
||||
|
||||
To programmatically do the same as :option:`-Wd`, use::
|
||||
|
||||
warnings.simplefilter('default')
|
||||
|
||||
Make sure to execute this code as soon as possible. This prevents the
|
||||
registering of what warnings have been raised from unexpectedly influencing how
|
||||
future warnings are treated.
|
||||
|
||||
Having certain warnings ignored by default is done to prevent a user from
|
||||
seeing warnings that are only of interest to the developer. As you do not
|
||||
necessarily have control over what interpreter a user uses to run their code,
|
||||
it is possible that a new version of Python will be released between your
|
||||
release cycles. The new interpreter release could trigger new warnings in your
|
||||
code that were not there in an older interpreter, e.g.
|
||||
:exc:`DeprecationWarning` for a module that you are using. While you as a
|
||||
developer want to be notified that your code is using a deprecated module, to a
|
||||
user this information is essentially noise and provides no benefit to them.
|
||||
|
||||
|
||||
.. _warning-functions:
|
||||
|
||||
Available Functions
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import unittest
|
||||
from test_support import check_warnings, run_unittest, cpython_only
|
||||
import warnings
|
||||
|
||||
|
||||
class FormatDeprecationTests(unittest.TestCase):
|
||||
|
@ -17,6 +18,7 @@ class FormatDeprecationTests(unittest.TestCase):
|
|||
buf = create_string_buffer(' ' * 100)
|
||||
|
||||
with check_warnings() as w:
|
||||
warnings.simplefilter('default')
|
||||
PyOS_ascii_formatd(byref(buf), sizeof(buf), '%+.10f',
|
||||
c_double(10.0))
|
||||
self.assertEqual(buf.value, '+10.0000000000')
|
||||
|
|
|
@ -309,6 +309,7 @@ class ExceptionTests(unittest.TestCase):
|
|||
# BaseException.__init__ triggers a deprecation warning.
|
||||
exc = BaseException("foo")
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter('default')
|
||||
self.assertEquals(exc.message, "foo")
|
||||
self.assertEquals(len(w), 1)
|
||||
self.assertEquals(w[0].category, DeprecationWarning)
|
||||
|
|
|
@ -383,8 +383,8 @@ except ImportError:
|
|||
# Module initialization
|
||||
_processoptions(sys.warnoptions)
|
||||
if not _warnings_defaults:
|
||||
simplefilter("ignore", category=PendingDeprecationWarning, append=1)
|
||||
simplefilter("ignore", category=ImportWarning, append=1)
|
||||
for cls in (DeprecationWarning, PendingDeprecationWarning, ImportWarning):
|
||||
simplefilter("ignore", category=cls, append=True)
|
||||
bytes_warning = sys.flags.bytes_warning
|
||||
if bytes_warning > 1:
|
||||
bytes_action = "error"
|
||||
|
|
|
@ -12,6 +12,8 @@ What's New in Python 2.7 alpha 3?
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #7319: Silence DeprecationWarning by default.
|
||||
|
||||
- Issue #2335: Backport set literals syntax from Python 3.x.
|
||||
|
||||
Library
|
||||
|
|
|
@ -85,10 +85,10 @@ get_default_action(void)
|
|||
|
||||
default_action = get_warnings_attr("defaultaction");
|
||||
if (default_action == NULL) {
|
||||
if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
return _default_action;
|
||||
if (PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
return _default_action;
|
||||
}
|
||||
|
||||
Py_DECREF(_default_action);
|
||||
|
@ -202,12 +202,12 @@ normalize_module(PyObject *filename)
|
|||
|
||||
mod_str = PyString_AsString(filename);
|
||||
if (mod_str == NULL)
|
||||
return NULL;
|
||||
return NULL;
|
||||
len = PyString_Size(filename);
|
||||
if (len < 0)
|
||||
return NULL;
|
||||
if (len >= 3 &&
|
||||
strncmp(mod_str + (len - 3), ".py", 3) == 0) {
|
||||
strncmp(mod_str + (len - 3), ".py", 3) == 0) {
|
||||
module = PyString_FromStringAndSize(mod_str, len-3);
|
||||
}
|
||||
else {
|
||||
|
@ -251,7 +251,7 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
|
|||
|
||||
name = PyObject_GetAttrString(category, "__name__");
|
||||
if (name == NULL) /* XXX Can an object lack a '__name__' attribute? */
|
||||
return;
|
||||
return;
|
||||
|
||||
f_stderr = PySys_GetObject("stderr");
|
||||
if (f_stderr == NULL) {
|
||||
|
@ -341,7 +341,7 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
rc = already_warned(registry, key, 0);
|
||||
if (rc == -1)
|
||||
goto cleanup;
|
||||
else if (rc == 1)
|
||||
else if (rc == 1)
|
||||
goto return_none;
|
||||
/* Else this warning hasn't been generated before. */
|
||||
}
|
||||
|
@ -492,9 +492,9 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
|
|||
/* Setup filename. */
|
||||
*filename = PyDict_GetItemString(globals, "__file__");
|
||||
if (*filename != NULL) {
|
||||
Py_ssize_t len = PyString_Size(*filename);
|
||||
Py_ssize_t len = PyString_Size(*filename);
|
||||
const char *file_str = PyString_AsString(*filename);
|
||||
if (file_str == NULL || (len < 0 && PyErr_Occurred()))
|
||||
if (file_str == NULL || (len < 0 && PyErr_Occurred()))
|
||||
goto handle_error;
|
||||
|
||||
/* if filename.lower().endswith((".pyc", ".pyo")): */
|
||||
|
@ -506,10 +506,10 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
|
|||
tolower(file_str[len-1]) == 'o'))
|
||||
{
|
||||
*filename = PyString_FromStringAndSize(file_str, len-1);
|
||||
if (*filename == NULL)
|
||||
goto handle_error;
|
||||
}
|
||||
else
|
||||
if (*filename == NULL)
|
||||
goto handle_error;
|
||||
}
|
||||
else
|
||||
Py_INCREF(*filename);
|
||||
}
|
||||
else {
|
||||
|
@ -536,8 +536,8 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
|
|||
else {
|
||||
/* embedded interpreters don't have sys.argv, see bug #839151 */
|
||||
*filename = PyString_FromString("__main__");
|
||||
if (*filename == NULL)
|
||||
goto handle_error;
|
||||
if (*filename == NULL)
|
||||
goto handle_error;
|
||||
}
|
||||
}
|
||||
if (*filename == NULL) {
|
||||
|
@ -839,26 +839,29 @@ create_filter(PyObject *category, const char *action)
|
|||
static PyObject *
|
||||
init_filters(void)
|
||||
{
|
||||
PyObject *filters = PyList_New(3);
|
||||
PyObject *filters = PyList_New(4);
|
||||
const char *bytes_action;
|
||||
if (filters == NULL)
|
||||
return NULL;
|
||||
|
||||
PyList_SET_ITEM(filters, 0,
|
||||
create_filter(PyExc_DeprecationWarning, "ignore"));
|
||||
PyList_SET_ITEM(filters, 1,
|
||||
create_filter(PyExc_PendingDeprecationWarning, "ignore"));
|
||||
PyList_SET_ITEM(filters, 1, create_filter(PyExc_ImportWarning, "ignore"));
|
||||
PyList_SET_ITEM(filters, 2, create_filter(PyExc_ImportWarning, "ignore"));
|
||||
if (Py_BytesWarningFlag > 1)
|
||||
bytes_action = "error";
|
||||
else if (Py_BytesWarningFlag)
|
||||
bytes_action = "default";
|
||||
else
|
||||
bytes_action = "ignore";
|
||||
PyList_SET_ITEM(filters, 2, create_filter(PyExc_BytesWarning,
|
||||
PyList_SET_ITEM(filters, 3, create_filter(PyExc_BytesWarning,
|
||||
bytes_action));
|
||||
|
||||
if (PyList_GET_ITEM(filters, 0) == NULL ||
|
||||
PyList_GET_ITEM(filters, 1) == NULL ||
|
||||
PyList_GET_ITEM(filters, 2) == NULL) {
|
||||
PyList_GET_ITEM(filters, 2) == NULL ||
|
||||
PyList_GET_ITEM(filters, 3) == NULL) {
|
||||
Py_DECREF(filters);
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue