diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 19582e757161fc..cac2f801e6dd45 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/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. 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,