Unverified Kaydet (Commit) c9758784 authored tarafından Victor Stinner's avatar Victor Stinner Kaydeden (comit) GitHub

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.
üst 21c77307
...@@ -125,6 +125,7 @@ class FilterTests(BaseTest): ...@@ -125,6 +125,7 @@ class FilterTests(BaseTest):
self.module.filterwarnings("ignore", category=UserWarning) self.module.filterwarnings("ignore", category=UserWarning)
self.module.warn("FilterTests.test_ignore", UserWarning) self.module.warn("FilterTests.test_ignore", UserWarning)
self.assertEqual(len(w), 0) self.assertEqual(len(w), 0)
self.assertEqual(list(__warningregistry__), ['version'])
def test_ignore_after_default(self): def test_ignore_after_default(self):
with original_warnings.catch_warnings(record=True, with original_warnings.catch_warnings(record=True,
......
...@@ -364,7 +364,6 @@ def warn_explicit(message, category, filename, lineno, ...@@ -364,7 +364,6 @@ def warn_explicit(message, category, filename, lineno,
action = defaultaction action = defaultaction
# Early exit actions # Early exit actions
if action == "ignore": if action == "ignore":
registry[key] = 1
return return
# Prime the linecache for formatting, in case the # Prime the linecache for formatting, in case the
......
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.
...@@ -528,16 +528,21 @@ warn_explicit(PyObject *category, PyObject *message, ...@@ -528,16 +528,21 @@ warn_explicit(PyObject *category, PyObject *message,
goto cleanup; goto cleanup;
} }
if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
goto return_none;
}
/* Store in the registry that we've been here, *except* when the action /* Store in the registry that we've been here, *except* when the action
is "always". */ is "always". */
rc = 0; rc = 0;
if (!_PyUnicode_EqualToASCIIString(action, "always")) { if (!_PyUnicode_EqualToASCIIString(action, "always")) {
if (registry != NULL && registry != Py_None && if (registry != NULL && registry != Py_None &&
PyDict_SetItem(registry, key, Py_True) < 0) PyDict_SetItem(registry, key, Py_True) < 0)
{
goto cleanup; 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) { if (registry == NULL || registry == Py_None) {
registry = get_once_registry(); registry = get_once_registry();
if (registry == NULL) if (registry == NULL)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment