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
.. 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*.
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
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.
--- /dev/null
+:meth:`memoryview.cast` now allows casting from N-D to 1-D for F-contiguous.
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,