summaryrefslogtreecommitdiffstats
path: root/Python/_warnings.c
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2018-01-08 02:45:02 (GMT)
committerGitHub <noreply@github.com>2018-01-08 02:45:02 (GMT)
commit9b99747386b690007027c3be2a5d7cfe3d3634f5 (patch)
treeba319d02ddc0e437bd0f90d520a4409efa7af6e2 /Python/_warnings.c
parentd13889214a4c81b78fa8683d35bdbd17ff22f4fe (diff)
downloadcpython-9b99747386b690007027c3be2a5d7cfe3d3634f5.zip
cpython-9b99747386b690007027c3be2a5d7cfe3d3634f5.tar.gz
cpython-9b99747386b690007027c3be2a5d7cfe3d3634f5.tar.bz2
bpo-31975 (PEP 565): Show DeprecationWarning in __main__ (GH-4458)
- primary change is to add a new default filter entry for 'default::DeprecationWarning:__main__' - secondary change is an internal one to cope with plain strings in the warning module's internal filter list (this avoids the need to create a compiled regex object early on during interpreter startup) - assorted documentation updates, including many more examples of configuring the warnings settings - additional tests to ensure that both the pure Python and the C accelerated warnings modules have the expected default configuration
Diffstat (limited to 'Python/_warnings.c')
-rw-r--r--Python/_warnings.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/Python/_warnings.c b/Python/_warnings.c
index be8370da..c286364 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -12,6 +12,7 @@ MODULE_NAME " provides basic warning filtering support.\n"
_Py_IDENTIFIER(argv);
_Py_IDENTIFIER(stderr);
#ifndef Py_DEBUG
+_Py_IDENTIFIER(default);
_Py_IDENTIFIER(ignore);
#endif
@@ -22,8 +23,20 @@ check_matched(PyObject *obj, PyObject *arg)
_Py_IDENTIFIER(match);
int rc;
+ /* A 'None' filter always matches */
if (obj == Py_None)
return 1;
+
+ /* An internal plain text default filter must match exactly */
+ if (PyUnicode_CheckExact(obj)) {
+ int cmp_result = PyUnicode_Compare(obj, arg);
+ if (cmp_result == -1 && PyErr_Occurred()) {
+ return -1;
+ }
+ return !cmp_result;
+ }
+
+ /* Otherwise assume a regex filter and call its match() method */
result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL);
if (result == NULL)
return -1;
@@ -1158,16 +1171,27 @@ static PyMethodDef warnings_functions[] = {
#ifndef Py_DEBUG
static PyObject *
-create_filter(PyObject *category, _Py_Identifier *id)
+create_filter(PyObject *category, _Py_Identifier *id, const char *modname)
{
+ PyObject *modname_obj = NULL;
PyObject *action_str = _PyUnicode_FromId(id);
if (action_str == NULL) {
return NULL;
}
+ /* Default to "no module name" for initial filter set */
+ if (modname != NULL) {
+ modname_obj = PyUnicode_InternFromString(modname);
+ if (modname_obj == NULL) {
+ return NULL;
+ }
+ } else {
+ modname_obj = Py_None;
+ }
+
/* This assumes the line number is zero for now. */
return PyTuple_Pack(5, action_str, Py_None,
- category, Py_None, _PyLong_Zero);
+ category, modname_obj, _PyLong_Zero);
}
#endif
@@ -1180,20 +1204,22 @@ init_filters(void)
return PyList_New(0);
#else
/* Other builds ignore a number of warning categories by default */
- PyObject *filters = PyList_New(4);
+ PyObject *filters = PyList_New(5);
if (filters == NULL) {
return NULL;
}
size_t pos = 0; /* Post-incremented in each use. */
PyList_SET_ITEM(filters, pos++,
- create_filter(PyExc_DeprecationWarning, &PyId_ignore));
+ create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__"));
+ PyList_SET_ITEM(filters, pos++,
+ create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL));
PyList_SET_ITEM(filters, pos++,
- create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore));
+ create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL));
PyList_SET_ITEM(filters, pos++,
- create_filter(PyExc_ImportWarning, &PyId_ignore));
+ create_filter(PyExc_ImportWarning, &PyId_ignore, NULL));
PyList_SET_ITEM(filters, pos++,
- create_filter(PyExc_ResourceWarning, &PyId_ignore));
+ create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL));
for (size_t x = 0; x < pos; x++) {
if (PyList_GET_ITEM(filters, x) == NULL) {