Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Lib/test/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
from test.support import os_helper
from test.support import _2G
from test.support import subTests
from test.support.script_helper import assert_python_ok
import weakref
import pickle
import operator
import struct
import sys
import textwrap

import array
from array import _array_reconstructor as array_reconstructor
Expand All @@ -35,6 +37,21 @@ def test_array_is_sequence(self):
self.assertIsInstance(array.array("B"), collections.abc.MutableSequence)
self.assertIsInstance(array.array("B"), collections.abc.Reversible)

@support.cpython_only
def test_module_init_mutablesequence_register_failure(self):
# gh-153210: Check that when collections.abc.MutableSequence is unavailable
# The refcount of ArrayType is decremented correctly.
# This test only catches the issue in a debug build.
script = textwrap.dedent("""
import collections.abc
del collections.abc.MutableSequence
try:
import array
except AttributeError:
pass
""")
assert_python_ok("-c", script)

def test_bad_constructor(self):
self.assertRaises(TypeError, array.array)
self.assertRaises(TypeError, array.array, spam=42)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:mod:`array`: Fix incorrect handling of reference counts when errors occur
during module import
2 changes: 0 additions & 2 deletions Modules/arraymodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3409,14 +3409,12 @@ array_modexec(PyObject *m)
PyObject *mutablesequence = PyImport_ImportModuleAttrString(
"collections.abc", "MutableSequence");
if (!mutablesequence) {
Py_DECREF((PyObject *)state->ArrayType);
return -1;
}
PyObject *res = PyObject_CallMethod(mutablesequence, "register", "O",
(PyObject *)state->ArrayType);
Py_DECREF(mutablesequence);
if (!res) {
Py_DECREF((PyObject *)state->ArrayType);
return -1;
}
Py_DECREF(res);
Expand Down
Loading