From 597ae6ae08e21b79aa02cb8099092b4e82ca2d31 Mon Sep 17 00:00:00 2001 From: jamie2779 Date: Fri, 15 Aug 2025 15:05:22 +0900 Subject: [PATCH 1/3] allow memoryview cast for F-contiguous --- Lib/test/test_buffer.py | 26 ++++++++++++++++++++++++++ Objects/memoryobject.c | 8 +++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 19582e757161fc..cdb1f575ff573c 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -2846,6 +2846,32 @@ class BEPoint(ctypes.BigEndianStructure): self.assertEqual(m2.strides, (1,)) self.assertEqual(m2.suboffsets, ()) + def test_memoryview_cast_f_contiguous_ND_1D(self): + nd = ndarray(list(range(12)),shape=[3, 4], format='B', flags=ND_FORTRAN) + m = memoryview(nd) + self.assertTrue(m.f_contiguous) + self.assertTrue(m.contiguous) + + m1 = m.cast('B') + self.assertEqual(m1.ndim, 1) + self.assertEqual(m1.shape, (m.nbytes,)) + self.assertEqual(m1.strides, (1,)) + self.assertTrue(m1.c_contiguous) + self.assertTrue(m1.contiguous) + self.assertEqual(m1.tobytes(), memoryview(nd).tobytes(order='F')) + + for fmt in ('B', 'b', 'c', 'H', 'I'): + size = struct.calcsize(fmt) + if m.nbytes % size == 0: + m2 = m.cast(fmt) + self.assertEqual(m2.ndim, 1) + self.assertEqual(m2.shape, (m.nbytes // size,)) + self.assertTrue(m2.contiguous) + + m3 = m[::-1] + with self.assertRaises(TypeError): + m3.cast('B') + def test_memoryview_tolist(self): # Most tolist() tests are in self.verify() etc. diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index cf673fb379edcd..c5971eb82ad5ff 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1456,9 +1456,11 @@ memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format, CHECK_RESTRICTED(self); if (!MV_C_CONTIGUOUS(self->flags)) { - PyErr_SetString(PyExc_TypeError, - "memoryview: casts are restricted to C-contiguous views"); - return NULL; + if(shape || self->view.ndim == 1 || !MV_F_CONTIGUOUS(self->flags)) { + PyErr_SetString(PyExc_TypeError, + "memoryview: casts are restricted to C-contiguous views"); + return NULL; + } } if ((shape || self->view.ndim != 1) && zero_in_shape(self)) { PyErr_SetString(PyExc_TypeError, From 3cc8a7ec723fa66d64cb5b59a82da30280d97eee Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 06:28:46 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2025-08-15-06-28-45.gh-issue-91484.huCgHt.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-08-15-06-28-45.gh-issue-91484.huCgHt.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-08-15-06-28-45.gh-issue-91484.huCgHt.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-15-06-28-45.gh-issue-91484.huCgHt.rst new file mode 100644 index 00000000000000..0131095ac44b3e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-15-06-28-45.gh-issue-91484.huCgHt.rst @@ -0,0 +1 @@ +memoryview.cast() now allows casting from N-D to 1-D for F-contiguous. From 20df3ab5cd12336d1daae16a23791bb55b40c762 Mon Sep 17 00:00:00 2001 From: jamie2779 Date: Fri, 15 Aug 2025 15:47:16 +0900 Subject: [PATCH 3/3] fix lint issue --- Lib/test/test_buffer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index cdb1f575ff573c..cac2f801e6dd45 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -2867,7 +2867,7 @@ def test_memoryview_cast_f_contiguous_ND_1D(self): self.assertEqual(m2.ndim, 1) self.assertEqual(m2.shape, (m.nbytes // size,)) self.assertTrue(m2.contiguous) - + m3 = m[::-1] with self.assertRaises(TypeError): m3.cast('B')