diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index d9b608fb23d0c6..c931be6df5fdaa 100755 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -1583,6 +1583,22 @@ def test_byteswap(self): b.byteswap() self.assertEqual(a, b) + def test_byteswap_single_call_result(self): + # A single byteswap() must swap each item's two halves (real, + # imag) independently. test_byteswap above only checks that + # byteswap() twice round-trips to the original, which passes + # even if a single call scrambles multi-item arrays. + a = array.array(self.typecode, self.example) + original = a.tobytes() + a.byteswap() + itemsize = a.itemsize + half = itemsize // 2 + expected = bytearray() + for i in range(0, len(original), itemsize): + item = original[i:i + itemsize] + expected += item[half - 1::-1] + item[itemsize - 1:half - 1:-1] + self.assertEqual(a.tobytes(), bytes(expected)) + class HalfFloatTest(FPTest, unittest.TestCase): example = [-42.0, 0, 42, 1e2, -1e4] diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 9f6dec7d1c5802..7e92028cb955cb 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -490,6 +490,7 @@ def test_with_extension(ext): forget(TESTFN) unlink(source) unlink(pyc) + rmtree('__pycache__') sys.path.insert(0, os.curdir) try: @@ -668,6 +669,7 @@ def __del__(self): import importlib sys.argv.insert(0, C()) """)) + self.addCleanup(unlink, testfn) script_helper.assert_python_ok(testfn) @skip_if_dont_write_bytecode @@ -2033,6 +2035,7 @@ def test_unencodable_filename(self): # encode filenames, especially on Windows pyname = script_helper.make_script('', TESTFN_UNENCODABLE, 'pass') self.addCleanup(unlink, pyname) + self.addCleanup(rmtree, '__pycache__') name = pyname[:-3] script_helper.assert_python_ok("-c", "mod = __import__(%a)" % name, __isolated=False) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index cc37697189af3e..a27996dd01c9d1 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2682,11 +2682,8 @@ def test_fma_infinities(self): @unittest.skipIf( sys.platform.startswith(("freebsd", "wasi", "netbsd", "emscripten", "cygwin")) or (sys.platform == "android" and platform.machine() == "x86_64") - or support.linked_to_musl(), # gh-131032 + or (support.linked_to_musl() and support.linked_to_musl() < (1, 2, 6)), # gh-131032 f"this platform doesn't implement IEE 754-2008 properly") - # gh-131032: musl is fixed but the fix is not yet released; when the fixed - # version is known change this to: - # or support.linked_to_musl() < (1, ,

) def test_fma_zero_result(self): nonnegative_finites = [0.0, 1e-300, 2.3, 1e300] diff --git a/Misc/NEWS.d/next/Library/2026-07-23-20-00-00.gh-issue-154566.byteswap-zd.rst b/Misc/NEWS.d/next/Library/2026-07-23-20-00-00.gh-issue-154566.byteswap-zd.rst new file mode 100644 index 00000000000000..e86b9a979946cd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-23-20-00-00.gh-issue-154566.byteswap-zd.rst @@ -0,0 +1,4 @@ +Fix :meth:`array.array.byteswap` corrupting data for ``'Zd'`` (complex +double) arrays with more than one element: the 16-byte item loop advanced +the buffer pointer by only 8 bytes per iteration, causing items after the +first to be scrambled. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 39a399d7a49cf5..a0181c083a6036 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1617,7 +1617,7 @@ array_array_byteswap_impl(arrayobject *self) break; case 16: assert(strcmp(self->ob_descr->typecode, "Zd") == 0); - for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 8) { + for (p = self->ob_item, i = Py_SIZE(self); --i >= 0; p += 16) { char t0 = p[0]; char t1 = p[1]; char t2 = p[2];