]> granicus.if.org Git - python/commitdiff
DeprecationWarning is now silent by default.
authorBrett Cannon <bcannon@gmail.com>
Sun, 10 Jan 2010 02:56:19 +0000 (02:56 +0000)
committerBrett Cannon <bcannon@gmail.com>
Sun, 10 Jan 2010 02:56:19 +0000 (02:56 +0000)
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.

Doc/library/warnings.rst
Lib/test/test_ascii_formatd.py
Lib/test/test_exceptions.py
Lib/warnings.py
Misc/NEWS
Python/_warnings.c

index b018a338e37cf81ded0a6e4d1d3594b1fc0314e2..e4343e87fad01c1ce45bb028095114dd54a34992 100644 (file)
@@ -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
index 5ee84fa6dfeb68cd3ad6e0acc74ce09d4434b641..77759fe07bcee0b936b42977ccb8d29edb9bc948 100644 (file)
@@ -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')
index a30f42bcd68bea2be447c505013d00610de10ea7..3a2bdf59526d4fd2904b4cb9276e1e0a8c543157 100644 (file)
@@ -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)
index 8d46cd68df6b8a5ba84e0865503b4692041ddaa7..a88e7ba52bca8fcfeb1ce978750faca5f639be50 100644 (file)
@@ -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"
index c0f23b5aa2d1c78f0e2e62c2cdd97dc709c94131..979ac8b6cb5188983cdbe7b7015203f75539e87e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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
index 18fcdac7957ca227148a30f9bd38a464f347fe25..96bb0493c99ca6b8f206c5a21b24bfe4fa4b2d75 100644 (file)
@@ -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;
     }