From: Victor Stinner Date: Mon, 27 Nov 2017 15:57:07 +0000 (+0100) Subject: bpo-27535: Fix memory leak with warnings ignore (#4489) X-Git-Tag: v3.7.0a3~78 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c9758784eb321fb9771e0bc7205b296e4d658045;p=thirdparty%2FPython%2Fcpython.git bpo-27535: Fix memory leak with warnings ignore (#4489) The warnings module doesn't leak memory anymore in the hidden warnings registry for the "ignore" action of warnings filters. The warn_explicit() function doesn't add the warning key to the registry anymore for the "ignore" action. --- diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index e007dc7e39e0..f2fdaa5386b7 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -125,6 +125,7 @@ class FilterTests(BaseTest): self.module.filterwarnings("ignore", category=UserWarning) self.module.warn("FilterTests.test_ignore", UserWarning) self.assertEqual(len(w), 0) + self.assertEqual(list(__warningregistry__), ['version']) def test_ignore_after_default(self): with original_warnings.catch_warnings(record=True, diff --git a/Lib/warnings.py b/Lib/warnings.py index c4bb22ec92a6..d7ea057a688a 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -364,7 +364,6 @@ def warn_explicit(message, category, filename, lineno, action = defaultaction # Early exit actions if action == "ignore": - registry[key] = 1 return # Prime the linecache for formatting, in case the diff --git a/Misc/NEWS.d/next/Library/2017-11-21-16-05-35.bpo-27535.JLhcNz.rst b/Misc/NEWS.d/next/Library/2017-11-21-16-05-35.bpo-27535.JLhcNz.rst new file mode 100644 index 000000000000..51bcfb7d7695 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-11-21-16-05-35.bpo-27535.JLhcNz.rst @@ -0,0 +1,4 @@ +The warnings module doesn't leak memory anymore in the hidden warnings +registry for the "ignore" action of warnings filters. warn_explicit() +function doesn't add the warning key to the registry anymore for the +"ignore" action. diff --git a/Python/_warnings.c b/Python/_warnings.c index 27f5b813a7ef..29370369e25d 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -528,16 +528,21 @@ warn_explicit(PyObject *category, PyObject *message, goto cleanup; } + if (_PyUnicode_EqualToASCIIString(action, "ignore")) { + goto return_none; + } + /* Store in the registry that we've been here, *except* when the action is "always". */ rc = 0; if (!_PyUnicode_EqualToASCIIString(action, "always")) { if (registry != NULL && registry != Py_None && - PyDict_SetItem(registry, key, Py_True) < 0) + PyDict_SetItem(registry, key, Py_True) < 0) + { goto cleanup; - else if (_PyUnicode_EqualToASCIIString(action, "ignore")) - goto return_none; - else if (_PyUnicode_EqualToASCIIString(action, "once")) { + } + + if (_PyUnicode_EqualToASCIIString(action, "once")) { if (registry == NULL || registry == Py_None) { registry = get_once_registry(); if (registry == NULL)