Update test_array.py from 3.14.3

This commit is contained in:
ShaharNaveh
2026-02-10 12:58:50 +02:00
parent b6ebbfd365
commit 28ed23f7ca

369
Lib/test/test_array.py vendored
View File

@@ -8,16 +8,20 @@ from test import support
from test.support import import_helper
from test.support import os_helper
from test.support import _2G
from test.support import subTests
import weakref
import pickle
import operator
import struct
import sys
import warnings
import array
from array import _array_reconstructor as array_reconstructor
sizeof_wchar = array.array('u').itemsize
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
sizeof_wchar = array.array('u').itemsize
class ArraySubclass(array.array):
@@ -27,7 +31,7 @@ class ArraySubclassWithKwargs(array.array):
def __init__(self, typecode, newarg=None):
array.array.__init__(self)
typecodes = 'ubBhHiIlLfdqQ'
typecodes = 'uwbBhHiIlLfdqQ'
class MiscTest(unittest.TestCase):
@@ -93,8 +97,17 @@ UTF16_BE = 19
UTF32_LE = 20
UTF32_BE = 21
class ArrayReconstructorTest(unittest.TestCase):
def setUp(self):
self.enterContext(warnings.catch_warnings())
warnings.filterwarnings(
"ignore",
message="The 'u' type code is deprecated and "
"will be removed in Python 3.16",
category=DeprecationWarning)
def test_error(self):
self.assertRaises(TypeError, array_reconstructor,
"", "b", 0, b"")
@@ -176,21 +189,23 @@ class ArrayReconstructorTest(unittest.TestCase):
self.assertEqual(a, b,
msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase))
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_unicode(self):
teststr = "Bonne Journ\xe9e \U0002030a\U00020347"
testcases = (
(UTF16_LE, "UTF-16-LE"),
(UTF16_BE, "UTF-16-BE"),
(UTF32_LE, "UTF-32-LE"), # TODO: RUSTPYTHON
(UTF32_BE, "UTF-32-BE") # TODO: RUSTPYTHON
(UTF32_LE, "UTF-32-LE"),
(UTF32_BE, "UTF-32-BE")
)
for testcase in testcases:
mformat_code, encoding = testcase
a = array.array('u', teststr)
b = array_reconstructor(
array.array, 'u', mformat_code, teststr.encode(encoding))
self.assertEqual(a, b,
msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase))
for c in 'uw':
a = array.array(c, teststr)
b = array_reconstructor(
array.array, c, mformat_code, teststr.encode(encoding))
self.assertEqual(a, b,
msg="{0!r} != {1!r}; testcase={2!r}".format(a, b, testcase))
class BaseTest:
@@ -202,6 +217,14 @@ class BaseTest:
# outside: An entry that is not in example
# minitemsize: the minimum guaranteed itemsize
def setUp(self):
self.enterContext(warnings.catch_warnings())
warnings.filterwarnings(
"ignore",
message="The 'u' type code is deprecated and "
"will be removed in Python 3.16",
category=DeprecationWarning)
def assertEntryEqual(self, entry1, entry2):
self.assertEqual(entry1, entry2)
@@ -234,7 +257,7 @@ class BaseTest:
self.assertEqual(bi[1], len(a))
def test_byteswap(self):
if self.typecode == 'u':
if self.typecode in ('u', 'w'):
example = '\U00100100'
else:
example = self.example
@@ -993,6 +1016,29 @@ class BaseTest:
array.array(self.typecode, self.example[3:]+self.example[:-1])
)
def test_clear(self):
a = array.array(self.typecode, self.example)
with self.assertRaises(TypeError):
a.clear(42)
a.clear()
self.assertEqual(len(a), 0)
self.assertEqual(a.typecode, self.typecode)
a = array.array(self.typecode)
a.clear()
self.assertEqual(len(a), 0)
self.assertEqual(a.typecode, self.typecode)
a = array.array(self.typecode, self.example)
a.clear()
a.append(self.example[2])
a.append(self.example[3])
self.assertEqual(a, array.array(self.typecode, self.example[2:4]))
with memoryview(a):
with self.assertRaises(BufferError):
a.clear()
def test_reverse(self):
a = array.array(self.typecode, self.example)
self.assertRaises(TypeError, a.reverse, 42)
@@ -1079,7 +1125,7 @@ class BaseTest:
self.assertEqual(m.tobytes(), expected)
self.assertRaises(BufferError, a.frombytes, a.tobytes())
self.assertEqual(m.tobytes(), expected)
if self.typecode == 'u':
if self.typecode in ('u', 'w'):
self.assertRaises(BufferError, a.fromunicode, a.tounicode())
self.assertEqual(m.tobytes(), expected)
self.assertRaises(BufferError, operator.imul, a, 2)
@@ -1134,17 +1180,19 @@ class BaseTest:
basesize = support.calcvobjsize('Pn2Pi')
support.check_sizeof(self, a, basesize)
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_initialize_with_unicode(self):
if self.typecode != 'u':
if self.typecode not in ('u', 'w'):
with self.assertRaises(TypeError) as cm:
a = array.array(self.typecode, 'foo')
self.assertIn("cannot use a str", str(cm.exception))
with self.assertRaises(TypeError) as cm:
a = array.array(self.typecode, array.array('u', 'foo'))
a = array.array(self.typecode, array.array('w', 'foo'))
self.assertIn("cannot use a unicode array", str(cm.exception))
else:
a = array.array(self.typecode, "foo")
a = array.array(self.typecode, array.array('u', 'foo'))
a = array.array(self.typecode, array.array('w', 'foo'))
@support.cpython_only
def test_obsolete_write_lock(self):
@@ -1152,8 +1200,7 @@ class BaseTest:
a = array.array('B', b"")
self.assertRaises(BufferError, _testcapi.getbuffer_with_null_view, a)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_free_after_iterating(self):
support.check_free_after_iterating(self, iter, array.array,
(self.typecode,))
@@ -1173,40 +1220,256 @@ class UnicodeTest(StringTest, unittest.TestCase):
smallerexample = '\x01\u263a\x00\ufefe'
biggerexample = '\x01\u263a\x01\ufeff'
outside = str('\x33')
minitemsize = 2
minitemsize = sizeof_wchar
def test_unicode(self):
self.assertRaises(TypeError, array.array, 'b', 'foo')
a = array.array('u', '\xa0\xc2\u1234')
a = array.array(self.typecode, '\xa0\xc2\u1234')
a.fromunicode(' ')
a.fromunicode('')
a.fromunicode('')
a.fromunicode('\x11abc\xff\u1234')
s = a.tounicode()
self.assertEqual(s, '\xa0\xc2\u1234 \x11abc\xff\u1234')
self.assertEqual(a.itemsize, sizeof_wchar)
self.assertEqual(a.itemsize, self.minitemsize)
s = '\x00="\'a\\b\x80\xff\u0000\u0001\u1234'
a = array.array('u', s)
a = array.array(self.typecode, s)
self.assertEqual(
repr(a),
"array('u', '\\x00=\"\\'a\\\\b\\x80\xff\\x00\\x01\u1234')")
f"array('{self.typecode}', '\\x00=\"\\'a\\\\b\\x80\xff\\x00\\x01\u1234')")
self.assertRaises(TypeError, a.fromunicode)
def test_issue17223(self):
# this used to crash
if sizeof_wchar == 4:
# U+FFFFFFFF is an invalid code point in Unicode 6.0
invalid_str = b'\xff\xff\xff\xff'
else:
if self.typecode == 'u' and sizeof_wchar == 2:
# PyUnicode_FromUnicode() cannot fail with 16-bit wchar_t
self.skipTest("specific to 32-bit wchar_t")
a = array.array('u', invalid_str)
# this used to crash
# U+FFFFFFFF is an invalid code point in Unicode 6.0
invalid_str = b'\xff\xff\xff\xff'
a = array.array(self.typecode, invalid_str)
self.assertRaises(ValueError, a.tounicode)
self.assertRaises(ValueError, str, a)
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: DeprecationWarning not triggered
def test_typecode_u_deprecation(self):
with self.assertWarns(DeprecationWarning):
array.array("u")
def test_empty_string_mem_leak_gh140474(self):
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
for _ in range(1000):
a = array.array('u', '')
self.assertEqual(len(a), 0)
self.assertEqual(a.typecode, 'u')
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_add(self):
return super().test_add()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_extend(self):
return super().test_extend()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_iadd(self):
return super().test_iadd()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_setiadd(self):
return super().test_setiadd()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_setslice(self):
return super().test_setslice()
class UCS4Test(UnicodeTest):
typecode = 'w'
minitemsize = 4
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_buffer(self):
return super().test_buffer()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_buffer_info(self):
return super().test_buffer_info()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_byteswap(self):
return super().test_byteswap()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_clear(self):
return super().test_clear()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_cmp(self):
return super().test_cmp()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_constructor(self):
return super().test_constructor()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_constructor_with_iterable_argument(self):
return super().test_constructor_with_iterable_argument()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_copy(self):
return super().test_copy()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_count(self):
return super().test_count()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_coveritertraverse(self):
return super().test_coveritertraverse()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_deepcopy(self):
return super().test_deepcopy()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_delitem(self):
return super().test_delitem()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_exhausted_iterator(self):
return super().test_exhausted_iterator()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_exhausted_reverse_iterator(self):
return super().test_exhausted_reverse_iterator()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_extended_getslice(self):
return super().test_extended_getslice()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_extended_set_del_slice(self):
return super().test_extended_set_del_slice()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_filewrite(self):
return super().test_filewrite()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_fromarray(self):
return super().test_fromarray()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_fromfile_ioerror(self):
return super().test_fromfile_ioerror()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_getitem(self):
return super().test_getitem()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_getslice(self):
return super().test_getslice()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_imul(self):
return super().test_imul()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_index(self):
return super().test_index()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_insert(self):
return super().test_insert()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_issue17223(self):
return super().test_issue17223()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_iterator_pickle(self):
return super().test_iterator_pickle()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_len(self):
return super().test_len()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_mul(self):
return super().test_mul()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_pickle(self):
return super().test_pickle()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_pickle_for_empty_array(self):
return super().test_pickle_for_empty_array()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_pop(self):
return super().test_pop()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_reduce_ex(self):
return super().test_reduce_ex()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_remove(self):
return super().test_remove()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_repr(self):
return super().test_repr()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_reverse(self):
return super().test_reverse()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_reverse_iterator(self):
return super().test_reverse_iterator()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_reverse_iterator_picking(self):
return super().test_reverse_iterator_picking()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_setitem(self):
return super().test_setitem()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_str(self):
return super().test_str()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_tofrombytes(self):
return super().test_tofrombytes()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_tofromfile(self):
return super().test_tofromfile()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_tofromlist(self):
return super().test_tofromlist()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_unicode(self):
return super().test_unicode()
@unittest.expectedFailure # TODO: RUSTPYTHON; Add support for 'w'
def test_weakref(self):
return super().test_weakref()
class NumberTest(BaseTest):
def test_extslice(self):
@@ -1438,8 +1701,8 @@ class FPTest(NumberTest):
if a.itemsize==1:
self.assertEqual(a, b)
else:
# On alphas treating the byte swapped bit patters as
# floats/doubles results in floating point exceptions
# On alphas treating the byte swapped bit patterns as
# floats/doubles results in floating-point exceptions
# => compare the 8bit string values instead
self.assertNotEqual(a.tobytes(), b.tobytes())
b.byteswap()
@@ -1611,5 +1874,55 @@ class LargeArrayTest(unittest.TestCase):
self.assertEqual(ls[:8], list(example[:8]))
self.assertEqual(ls[-8:], list(example[-8:]))
def test_gh_128961(self):
a = array.array('i')
it = iter(a)
list(it)
it.__setstate__(0)
self.assertRaises(StopIteration, next, it)
# Tests for NULL pointer dereference in array.__setitem__
# when the index conversion mutates the array.
# See: https://github.com/python/cpython/issues/142555.
@unittest.skip("TODO: RUSTPYTHON; Hangs")
@subTests("dtype", ["b", "B", "h", "H", "i", "l", "q", "I", "L", "Q"])
def test_setitem_use_after_clear_with_int_data(self, dtype):
victim = array.array(dtype, list(range(64)))
class Index:
def __index__(self):
victim.clear()
return 0
self.assertRaises(IndexError, victim.__setitem__, 1, Index())
self.assertEqual(len(victim), 0)
@unittest.skip("TODO: RUSTPYTHON; Hangs")
def test_setitem_use_after_shrink_with_int_data(self):
victim = array.array('b', [1, 2, 3])
class Index:
def __index__(self):
victim.pop()
victim.pop()
return 0
self.assertRaises(IndexError, victim.__setitem__, 1, Index())
@unittest.skip("TODO: RUSTPYTHON; Hangs")
@subTests("dtype", ["f", "d"])
def test_setitem_use_after_clear_with_float_data(self, dtype):
victim = array.array(dtype, [1.0, 2.0, 3.0])
class Float:
def __float__(self):
victim.clear()
return 0.0
self.assertRaises(IndexError, victim.__setitem__, 1, Float())
self.assertEqual(len(victim), 0)
if __name__ == "__main__":
unittest.main()