Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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*.
Expand Down
4 changes: 4 additions & 0 deletions Doc/whatsnew/3.16.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions Lib/test/test_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:meth:`memoryview.cast` now allows casting from N-D to 1-D for F-contiguous.
8 changes: 5 additions & 3 deletions Objects/memoryobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading