https://github.com/python/cpython/commit/a400767e52ba47baa9de1acf5dba7800cfaa3ef4
commit: a400767e52ba47baa9de1acf5dba7800cfaa3ef4
branch: main
author: Jaemin Park <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-07-24T13:17:06Z
summary:

gh-91484: Allow memoryview cast for F-contiguous (GH-137803)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-08-15-06-28-45.gh-issue-91484.huCgHt.rst
M Doc/library/stdtypes.rst
M Doc/whatsnew/3.16.rst
M Lib/test/test_buffer.py
M Objects/memoryobject.c

diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 9df5eb78d286a5..0b6a1b488fb64f 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -4876,8 +4876,9 @@ copying.
       Cast a memoryview to a new format or shape. *shape* defaults to
       ``[byte_length//new_itemsize]``, which means that the result view
       will be one-dimensional. The return value is a new memoryview, but
-      the buffer itself is not copied. Supported casts are 1D -> 
C-:term:`contiguous`
-      and C-contiguous -> 1D.
+      the buffer itself is not copied. Supported casts are
+      1D -> C-:term:`contiguous`, C-contiguous -> 1D, and
+      F-contiguous -> 1D.
 
       The destination format is restricted to a single element native format in
       :mod:`struct` syntax. One of the formats must be a byte format
@@ -4964,6 +4965,10 @@ copying.
       .. versionchanged:: 3.5
          The source format is no longer restricted when casting to a byte view.
 
+      .. versionchanged:: next
+         Casting a multi-dimensional F-contiguous view to a one-dimensional
+         view is now supported.
+
    .. method:: count(value, /)
 
       Count the number of occurrences of *value*.
diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst
index 662defa709a246..06e831ea1e3463 100644
--- a/Doc/whatsnew/3.16.rst
+++ b/Doc/whatsnew/3.16.rst
@@ -75,6 +75,10 @@ New features
 Other language changes
 ======================
 
+* :meth:`memoryview.cast` now allows casting a multidimensional
+  F-contiguous view to a one-dimensional view.
+  (Contributed by Jaemin Park in :gh:`91484`.)
+
 * :ref:`Frame objects <frame-objects>` now support :mod:`weak references
   <weakref>`.  This allows associating extra data with active frames,
   for example in debuggers, without keeping the frames (and everything
diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py
index 453dafe2709eb2..579e680448e94e 100644
--- a/Lib/test/test_buffer.py
+++ b/Lib/test/test_buffer.py
@@ -2877,6 +2877,32 @@ class BEPoint:
             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..7bba0da22d1c4d
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-15-06-28-45.gh-issue-91484.huCgHt.rst
@@ -0,0 +1 @@
+:meth:`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 d92c7daff15dbf..f6ffa337c632a0 100644
--- a/Objects/memoryobject.c
+++ b/Objects/memoryobject.c
@@ -1485,9 +1485,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 || !MV_F_CONTIGUOUS(self->flags)) {
+            PyErr_SetString(PyExc_TypeError,
+                "memoryview: casts are restricted to contiguous views");
+            return NULL;
+        }
     }
     if ((shape || self->view.ndim != 1) && zero_in_shape(self)) {
         PyErr_SetString(PyExc_TypeError,

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to