Skip to content

Commit c975878

Browse files
authored
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.
1 parent 21c7730 commit c975878

File tree

4 files changed

+14
-5
lines changed

4 files changed

+14
-5
lines changed

Lib/test/test_warnings/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ def test_ignore(self):
125125
self.module.filterwarnings("ignore", category=UserWarning)
126126
self.module.warn("FilterTests.test_ignore", UserWarning)
127127
self.assertEqual(len(w), 0)
128+
self.assertEqual(list(__warningregistry__), ['version'])
128129

129130
def test_ignore_after_default(self):
130131
with original_warnings.catch_warnings(record=True,

Lib/warnings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,6 @@ def warn_explicit(message, category, filename, lineno,
364364
action = defaultaction
365365
# Early exit actions
366366
if action == "ignore":
367-
registry[key] = 1
368367
return
369368

370369
# Prime the linecache for formatting, in case the
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The warnings module doesn't leak memory anymore in the hidden warnings
2+
registry for the "ignore" action of warnings filters. warn_explicit()
3+
function doesn't add the warning key to the registry anymore for the
4+
"ignore" action.

Python/_warnings.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -528,16 +528,21 @@ warn_explicit(PyObject *category, PyObject *message,
528528
goto cleanup;
529529
}
530530

531+
if (_PyUnicode_EqualToASCIIString(action, "ignore")) {
532+
goto return_none;
533+
}
534+
531535
/* Store in the registry that we've been here, *except* when the action
532536
is "always". */
533537
rc = 0;
534538
if (!_PyUnicode_EqualToASCIIString(action, "always")) {
535539
if (registry != NULL && registry != Py_None &&
536-
PyDict_SetItem(registry, key, Py_True) < 0)
540+
PyDict_SetItem(registry, key, Py_True) < 0)
541+
{
537542
goto cleanup;
538-
else if (_PyUnicode_EqualToASCIIString(action, "ignore"))
539-
goto return_none;
540-
else if (_PyUnicode_EqualToASCIIString(action, "once")) {
543+
}
544+
545+
if (_PyUnicode_EqualToASCIIString(action, "once")) {
541546
if (registry == NULL || registry == Py_None) {
542547
registry = get_once_registry();
543548
if (registry == NULL)

0 commit comments

Comments
 (0)