diff options
author | Benjamin Peterson <benjamin@python.org> | 2015-05-03 15:28:46 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2015-05-03 15:28:46 (GMT) |
commit | 8c59816b70a30d8ec2ff4e60a8b4a747f8ff75db (patch) | |
tree | c09195c80d4594c6261c072ca9dda43b2201f469 | |
parent | b9c04db64fd0315a30c4360d7ad33b975d5fbfc1 (diff) | |
parent | deff2b76ec3824ff238ad0812c29aca95534ecb4 (diff) | |
download | cpython-8c59816b70a30d8ec2ff4e60a8b4a747f8ff75db.zip cpython-8c59816b70a30d8ec2ff4e60a8b4a747f8ff75db.tar.gz cpython-8c59816b70a30d8ec2ff4e60a8b4a747f8ff75db.tar.bz2 |
merge 3.3 (#24096)
-rw-r--r-- | Lib/test/test_warnings.py | 12 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Python/_warnings.c | 37 |
3 files changed, 42 insertions, 10 deletions
diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py index fb01b83..ddcea8e 100644 --- a/Lib/test/test_warnings.py +++ b/Lib/test/test_warnings.py @@ -247,6 +247,18 @@ class FilterTests(BaseTest): self.assertEqual(str(w[-1].message), text) self.assertTrue(w[-1].category is UserWarning) + def test_mutate_filter_list(self): + class X: + def match(self, a): + L[:] = [] + + L = [("default",X(),UserWarning,X(),0) for i in range(2)] + with original_warnings.catch_warnings(record=True, + module=self.module) as w: + self.module.filters = L + self.module.warn_explicit(UserWarning("b"), None, "f.py", 42) + self.assertEqual(str(w[-1].message), "b") + class CFilterTests(FilterTests, unittest.TestCase): module = c_warnings @@ -10,6 +10,9 @@ Release date: tba Core and Builtins ----------------- +- Issue #24096: Make warnings.warn_explicit more robust against mutation of the + warnings.filters list. + - Issue #23996: Avoid a crash when a delegated generator raises an unnormalized StopIteration exception. Patch by Stefan Behnel. diff --git a/Python/_warnings.c b/Python/_warnings.c index bef5647..6dff0a2 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -101,7 +101,7 @@ get_default_action(void) } -/* The item is a borrowed reference. */ +/* The item is a new reference. */ static PyObject* get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, PyObject *module, PyObject **item) @@ -132,14 +132,15 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, Py_ssize_t ln; int is_subclass, good_msg, good_mod; - tmp_item = *item = PyList_GET_ITEM(_filters, i); - if (PyTuple_Size(tmp_item) != 5) { + tmp_item = PyList_GET_ITEM(_filters, i); + if (!PyTuple_Check(tmp_item) || PyTuple_GET_SIZE(tmp_item) != 5) { PyErr_Format(PyExc_ValueError, MODULE_NAME ".filters item %zd isn't a 5-tuple", i); return NULL; } /* Python code: action, msg, cat, mod, ln = item */ + Py_INCREF(tmp_item); action = PyTuple_GET_ITEM(tmp_item, 0); msg = PyTuple_GET_ITEM(tmp_item, 1); cat = PyTuple_GET_ITEM(tmp_item, 2); @@ -147,28 +148,43 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, ln_obj = PyTuple_GET_ITEM(tmp_item, 4); good_msg = check_matched(msg, text); - if (good_msg == -1) + if (good_msg == -1) { + Py_DECREF(tmp_item); return NULL; + } good_mod = check_matched(mod, module); - if (good_mod == -1) + if (good_mod == -1) { + Py_DECREF(tmp_item); return NULL; + } is_subclass = PyObject_IsSubclass(category, cat); - if (is_subclass == -1) + if (is_subclass == -1) { + Py_DECREF(tmp_item); return NULL; + } ln = PyLong_AsSsize_t(ln_obj); - if (ln == -1 && PyErr_Occurred()) + if (ln == -1 && PyErr_Occurred()) { + Py_DECREF(tmp_item); return NULL; + } - if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) + if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) { + *item = tmp_item; return action; + } + + Py_DECREF(tmp_item); } action = get_default_action(); - if (action != NULL) + if (action != NULL) { + Py_INCREF(Py_None); + *item = Py_None; return action; + } PyErr_SetString(PyExc_ValueError, MODULE_NAME ".defaultaction not found"); @@ -349,7 +365,7 @@ warn_explicit(PyObject *category, PyObject *message, PyObject *module, PyObject *registry, PyObject *sourceline) { PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL; - PyObject *item = Py_None; + PyObject *item = NULL; PyObject *action; int rc; @@ -488,6 +504,7 @@ warn_explicit(PyObject *category, PyObject *message, Py_INCREF(result); cleanup: + Py_XDECREF(item); Py_XDECREF(key); Py_XDECREF(text); Py_XDECREF(lineno_obj); |