diff options
author | Nick Coghlan <ncoghlan@gmail.com> | 2018-01-08 02:45:02 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-08 02:45:02 (GMT) |
commit | 9b99747386b690007027c3be2a5d7cfe3d3634f5 (patch) | |
tree | ba319d02ddc0e437bd0f90d520a4409efa7af6e2 /Python/_warnings.c | |
parent | d13889214a4c81b78fa8683d35bdbd17ff22f4fe (diff) | |
download | cpython-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.c | 40 |
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) { |