xref: /third_party/python/Objects/memoryobject.c (revision 7db96d56)
1/*
2 * Memoryview object implementation
3 * --------------------------------
4 *
5 *   This implementation is a complete rewrite contributed by Stefan Krah in
6 *   Python 3.3.  Substantial credit goes to Antoine Pitrou (who had already
7 *   fortified and rewritten the previous implementation) and Nick Coghlan
8 *   (who came up with the idea of the ManagedBuffer) for analyzing the complex
9 *   ownership rules.
10 *
11 */
12
13#include "Python.h"
14#include "pycore_abstract.h"      // _PyIndex_Check()
15#include "pycore_object.h"        // _PyObject_GC_UNTRACK()
16#include "pycore_strhex.h"        // _Py_strhex_with_sep()
17#include <stddef.h>               // offsetof()
18
19/*[clinic input]
20class memoryview "PyMemoryViewObject *" "&PyMemoryView_Type"
21[clinic start generated code]*/
22/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e2e49d2192835219]*/
23
24#include "clinic/memoryobject.c.h"
25
26/****************************************************************************/
27/*                           ManagedBuffer Object                           */
28/****************************************************************************/
29
30/*
31   ManagedBuffer Object:
32   ---------------------
33
34     The purpose of this object is to facilitate the handling of chained
35     memoryviews that have the same underlying exporting object. PEP-3118
36     allows the underlying object to change while a view is exported. This
37     could lead to unexpected results when constructing a new memoryview
38     from an existing memoryview.
39
40     Rather than repeatedly redirecting buffer requests to the original base
41     object, all chained memoryviews use a single buffer snapshot. This
42     snapshot is generated by the constructor _PyManagedBuffer_FromObject().
43
44   Ownership rules:
45   ----------------
46
47     The master buffer inside a managed buffer is filled in by the original
48     base object. shape, strides, suboffsets and format are read-only for
49     all consumers.
50
51     A memoryview's buffer is a private copy of the exporter's buffer. shape,
52     strides and suboffsets belong to the memoryview and are thus writable.
53
54     If a memoryview itself exports several buffers via memory_getbuf(), all
55     buffer copies share shape, strides and suboffsets. In this case, the
56     arrays are NOT writable.
57
58   Reference count assumptions:
59   ----------------------------
60
61     The 'obj' member of a Py_buffer must either be NULL or refer to the
62     exporting base object. In the Python codebase, all getbufferprocs
63     return a new reference to view.obj (example: bytes_buffer_getbuffer()).
64
65     PyBuffer_Release() decrements view.obj (if non-NULL), so the
66     releasebufferprocs must NOT decrement view.obj.
67*/
68
69
70static inline _PyManagedBufferObject *
71mbuf_alloc(void)
72{
73    _PyManagedBufferObject *mbuf;
74
75    mbuf = (_PyManagedBufferObject *)
76        PyObject_GC_New(_PyManagedBufferObject, &_PyManagedBuffer_Type);
77    if (mbuf == NULL)
78        return NULL;
79    mbuf->flags = 0;
80    mbuf->exports = 0;
81    mbuf->master.obj = NULL;
82    _PyObject_GC_TRACK(mbuf);
83
84    return mbuf;
85}
86
87static PyObject *
88_PyManagedBuffer_FromObject(PyObject *base)
89{
90    _PyManagedBufferObject *mbuf;
91
92    mbuf = mbuf_alloc();
93    if (mbuf == NULL)
94        return NULL;
95
96    if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) {
97        mbuf->master.obj = NULL;
98        Py_DECREF(mbuf);
99        return NULL;
100    }
101
102    return (PyObject *)mbuf;
103}
104
105static void
106mbuf_release(_PyManagedBufferObject *self)
107{
108    if (self->flags&_Py_MANAGED_BUFFER_RELEASED)
109        return;
110
111    /* NOTE: at this point self->exports can still be > 0 if this function
112       is called from mbuf_clear() to break up a reference cycle. */
113    self->flags |= _Py_MANAGED_BUFFER_RELEASED;
114
115    /* PyBuffer_Release() decrements master->obj and sets it to NULL. */
116    _PyObject_GC_UNTRACK(self);
117    PyBuffer_Release(&self->master);
118}
119
120static void
121mbuf_dealloc(_PyManagedBufferObject *self)
122{
123    assert(self->exports == 0);
124    mbuf_release(self);
125    if (self->flags&_Py_MANAGED_BUFFER_FREE_FORMAT)
126        PyMem_Free(self->master.format);
127    PyObject_GC_Del(self);
128}
129
130static int
131mbuf_traverse(_PyManagedBufferObject *self, visitproc visit, void *arg)
132{
133    Py_VISIT(self->master.obj);
134    return 0;
135}
136
137static int
138mbuf_clear(_PyManagedBufferObject *self)
139{
140    assert(self->exports >= 0);
141    mbuf_release(self);
142    return 0;
143}
144
145PyTypeObject _PyManagedBuffer_Type = {
146    PyVarObject_HEAD_INIT(&PyType_Type, 0)
147    "managedbuffer",
148    sizeof(_PyManagedBufferObject),
149    0,
150    (destructor)mbuf_dealloc,                /* tp_dealloc */
151    0,                                       /* tp_vectorcall_offset */
152    0,                                       /* tp_getattr */
153    0,                                       /* tp_setattr */
154    0,                                       /* tp_as_async */
155    0,                                       /* tp_repr */
156    0,                                       /* tp_as_number */
157    0,                                       /* tp_as_sequence */
158    0,                                       /* tp_as_mapping */
159    0,                                       /* tp_hash */
160    0,                                       /* tp_call */
161    0,                                       /* tp_str */
162    PyObject_GenericGetAttr,                 /* tp_getattro */
163    0,                                       /* tp_setattro */
164    0,                                       /* tp_as_buffer */
165    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
166    0,                                       /* tp_doc */
167    (traverseproc)mbuf_traverse,             /* tp_traverse */
168    (inquiry)mbuf_clear                      /* tp_clear */
169};
170
171
172/****************************************************************************/
173/*                             MemoryView Object                            */
174/****************************************************************************/
175
176/* In the process of breaking reference cycles mbuf_release() can be
177   called before memory_release(). */
178#define BASE_INACCESSIBLE(mv) \
179    (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED || \
180     ((PyMemoryViewObject *)mv)->mbuf->flags&_Py_MANAGED_BUFFER_RELEASED)
181
182#define CHECK_RELEASED(mv) \
183    if (BASE_INACCESSIBLE(mv)) {                                  \
184        PyErr_SetString(PyExc_ValueError,                         \
185            "operation forbidden on released memoryview object"); \
186        return NULL;                                              \
187    }
188
189#define CHECK_RELEASED_INT(mv) \
190    if (BASE_INACCESSIBLE(mv)) {                                  \
191        PyErr_SetString(PyExc_ValueError,                         \
192            "operation forbidden on released memoryview object"); \
193        return -1;                                                \
194    }
195
196/* See gh-92888. These macros signal that we need to check the memoryview
197   again due to possible read after frees. */
198#define CHECK_RELEASED_AGAIN(mv) CHECK_RELEASED(mv)
199#define CHECK_RELEASED_INT_AGAIN(mv) CHECK_RELEASED_INT(mv)
200
201#define CHECK_LIST_OR_TUPLE(v) \
202    if (!PyList_Check(v) && !PyTuple_Check(v)) { \
203        PyErr_SetString(PyExc_TypeError,         \
204            #v " must be a list or a tuple");    \
205        return NULL;                             \
206    }
207
208#define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view)
209
210/* Check for the presence of suboffsets in the first dimension. */
211#define HAVE_PTR(suboffsets, dim) (suboffsets && suboffsets[dim] >= 0)
212/* Adjust ptr if suboffsets are present. */
213#define ADJUST_PTR(ptr, suboffsets, dim) \
214    (HAVE_PTR(suboffsets, dim) ? *((char**)ptr) + suboffsets[dim] : ptr)
215
216/* Memoryview buffer properties */
217#define MV_C_CONTIGUOUS(flags) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C))
218#define MV_F_CONTIGUOUS(flags) \
219    (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN))
220#define MV_ANY_CONTIGUOUS(flags) \
221    (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN))
222
223/* Fast contiguity test. Caller must ensure suboffsets==NULL and ndim==1. */
224#define MV_CONTIGUOUS_NDIM1(view) \
225    ((view)->shape[0] == 1 || (view)->strides[0] == (view)->itemsize)
226
227/* getbuffer() requests */
228#define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT)
229#define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS)
230#define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS)
231#define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS)
232#define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES)
233#define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND)
234#define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE)
235#define REQ_FORMAT(flags) (flags&PyBUF_FORMAT)
236
237
238/**************************************************************************/
239/*                       Copy memoryview buffers                          */
240/**************************************************************************/
241
242/* The functions in this section take a source and a destination buffer
243   with the same logical structure: format, itemsize, ndim and shape
244   are identical, with ndim > 0.
245
246   NOTE: All buffers are assumed to have PyBUF_FULL information, which
247   is the case for memoryviews! */
248
249
250/* Assumptions: ndim >= 1. The macro tests for a corner case that should
251   perhaps be explicitly forbidden in the PEP. */
252#define HAVE_SUBOFFSETS_IN_LAST_DIM(view) \
253    (view->suboffsets && view->suboffsets[dest->ndim-1] >= 0)
254
255static inline int
256last_dim_is_contiguous(const Py_buffer *dest, const Py_buffer *src)
257{
258    assert(dest->ndim > 0 && src->ndim > 0);
259    return (!HAVE_SUBOFFSETS_IN_LAST_DIM(dest) &&
260            !HAVE_SUBOFFSETS_IN_LAST_DIM(src) &&
261            dest->strides[dest->ndim-1] == dest->itemsize &&
262            src->strides[src->ndim-1] == src->itemsize);
263}
264
265/* This is not a general function for determining format equivalence.
266   It is used in copy_single() and copy_buffer() to weed out non-matching
267   formats. Skipping the '@' character is specifically used in slice
268   assignments, where the lvalue is already known to have a single character
269   format. This is a performance hack that could be rewritten (if properly
270   benchmarked). */
271static inline int
272equiv_format(const Py_buffer *dest, const Py_buffer *src)
273{
274    const char *dfmt, *sfmt;
275
276    assert(dest->format && src->format);
277    dfmt = dest->format[0] == '@' ? dest->format+1 : dest->format;
278    sfmt = src->format[0] == '@' ? src->format+1 : src->format;
279
280    if (strcmp(dfmt, sfmt) != 0 ||
281        dest->itemsize != src->itemsize) {
282        return 0;
283    }
284
285    return 1;
286}
287
288/* Two shapes are equivalent if they are either equal or identical up
289   to a zero element at the same position. For example, in NumPy arrays
290   the shapes [1, 0, 5] and [1, 0, 7] are equivalent. */
291static inline int
292equiv_shape(const Py_buffer *dest, const Py_buffer *src)
293{
294    int i;
295
296    if (dest->ndim != src->ndim)
297        return 0;
298
299    for (i = 0; i < dest->ndim; i++) {
300        if (dest->shape[i] != src->shape[i])
301            return 0;
302        if (dest->shape[i] == 0)
303            break;
304    }
305
306    return 1;
307}
308
309/* Check that the logical structure of the destination and source buffers
310   is identical. */
311static int
312equiv_structure(const Py_buffer *dest, const Py_buffer *src)
313{
314    if (!equiv_format(dest, src) ||
315        !equiv_shape(dest, src)) {
316        PyErr_SetString(PyExc_ValueError,
317            "memoryview assignment: lvalue and rvalue have different "
318            "structures");
319        return 0;
320    }
321
322    return 1;
323}
324
325/* Base case for recursive multi-dimensional copying. Contiguous arrays are
326   copied with very little overhead. Assumptions: ndim == 1, mem == NULL or
327   sizeof(mem) == shape[0] * itemsize. */
328static void
329copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize,
330          char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
331          char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
332          char *mem)
333{
334    if (mem == NULL) { /* contiguous */
335        Py_ssize_t size = shape[0] * itemsize;
336        if (dptr + size < sptr || sptr + size < dptr)
337            memcpy(dptr, sptr, size); /* no overlapping */
338        else
339            memmove(dptr, sptr, size);
340    }
341    else {
342        char *p;
343        Py_ssize_t i;
344        for (i=0, p=mem; i < shape[0]; p+=itemsize, sptr+=sstrides[0], i++) {
345            char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0);
346            memcpy(p, xsptr, itemsize);
347        }
348        for (i=0, p=mem; i < shape[0]; p+=itemsize, dptr+=dstrides[0], i++) {
349            char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0);
350            memcpy(xdptr, p, itemsize);
351        }
352    }
353
354}
355
356/* Recursively copy a source buffer to a destination buffer. The two buffers
357   have the same ndim, shape and itemsize. */
358static void
359copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize,
360         char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets,
361         char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets,
362         char *mem)
363{
364    Py_ssize_t i;
365
366    assert(ndim >= 1);
367
368    if (ndim == 1) {
369        copy_base(shape, itemsize,
370                  dptr, dstrides, dsuboffsets,
371                  sptr, sstrides, ssuboffsets,
372                  mem);
373        return;
374    }
375
376    for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) {
377        char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0);
378        char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0);
379
380        copy_rec(shape+1, ndim-1, itemsize,
381                 xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL,
382                 xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL,
383                 mem);
384    }
385}
386
387/* Faster copying of one-dimensional arrays. */
388static int
389copy_single(PyMemoryViewObject *self, const Py_buffer *dest, const Py_buffer *src)
390{
391    CHECK_RELEASED_INT_AGAIN(self);
392    char *mem = NULL;
393
394    assert(dest->ndim == 1);
395
396    if (!equiv_structure(dest, src))
397        return -1;
398
399    if (!last_dim_is_contiguous(dest, src)) {
400        mem = PyMem_Malloc(dest->shape[0] * dest->itemsize);
401        if (mem == NULL) {
402            PyErr_NoMemory();
403            return -1;
404        }
405    }
406
407    copy_base(dest->shape, dest->itemsize,
408              dest->buf, dest->strides, dest->suboffsets,
409              src->buf, src->strides, src->suboffsets,
410              mem);
411
412    if (mem)
413        PyMem_Free(mem);
414
415    return 0;
416}
417
418/* Recursively copy src to dest. Both buffers must have the same basic
419   structure. Copying is atomic, the function never fails with a partial
420   copy. */
421static int
422copy_buffer(const Py_buffer *dest, const Py_buffer *src)
423{
424    char *mem = NULL;
425
426    assert(dest->ndim > 0);
427
428    if (!equiv_structure(dest, src))
429        return -1;
430
431    if (!last_dim_is_contiguous(dest, src)) {
432        mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize);
433        if (mem == NULL) {
434            PyErr_NoMemory();
435            return -1;
436        }
437    }
438
439    copy_rec(dest->shape, dest->ndim, dest->itemsize,
440             dest->buf, dest->strides, dest->suboffsets,
441             src->buf, src->strides, src->suboffsets,
442             mem);
443
444    if (mem)
445        PyMem_Free(mem);
446
447    return 0;
448}
449
450/* Initialize strides for a C-contiguous array. */
451static inline void
452init_strides_from_shape(Py_buffer *view)
453{
454    Py_ssize_t i;
455
456    assert(view->ndim > 0);
457
458    view->strides[view->ndim-1] = view->itemsize;
459    for (i = view->ndim-2; i >= 0; i--)
460        view->strides[i] = view->strides[i+1] * view->shape[i+1];
461}
462
463/* Initialize strides for a Fortran-contiguous array. */
464static inline void
465init_fortran_strides_from_shape(Py_buffer *view)
466{
467    Py_ssize_t i;
468
469    assert(view->ndim > 0);
470
471    view->strides[0] = view->itemsize;
472    for (i = 1; i < view->ndim; i++)
473        view->strides[i] = view->strides[i-1] * view->shape[i-1];
474}
475
476/* Copy src to a contiguous representation. order is one of 'C', 'F' (Fortran)
477   or 'A' (Any). Assumptions: src has PyBUF_FULL information, src->ndim >= 1,
478   len(mem) == src->len. */
479static int
480buffer_to_contiguous(char *mem, const Py_buffer *src, char order)
481{
482    Py_buffer dest;
483    Py_ssize_t *strides;
484    int ret;
485
486    assert(src->ndim >= 1);
487    assert(src->shape != NULL);
488    assert(src->strides != NULL);
489
490    strides = PyMem_Malloc(src->ndim * (sizeof *src->strides));
491    if (strides == NULL) {
492        PyErr_NoMemory();
493        return -1;
494    }
495
496    /* initialize dest */
497    dest = *src;
498    dest.buf = mem;
499    /* shape is constant and shared: the logical representation of the
500       array is unaltered. */
501
502    /* The physical representation determined by strides (and possibly
503       suboffsets) may change. */
504    dest.strides = strides;
505    if (order == 'C' || order == 'A') {
506        init_strides_from_shape(&dest);
507    }
508    else {
509        init_fortran_strides_from_shape(&dest);
510    }
511
512    dest.suboffsets = NULL;
513
514    ret = copy_buffer(&dest, src);
515
516    PyMem_Free(strides);
517    return ret;
518}
519
520
521/****************************************************************************/
522/*                               Constructors                               */
523/****************************************************************************/
524
525/* Initialize values that are shared with the managed buffer. */
526static inline void
527init_shared_values(Py_buffer *dest, const Py_buffer *src)
528{
529    dest->obj = src->obj;
530    dest->buf = src->buf;
531    dest->len = src->len;
532    dest->itemsize = src->itemsize;
533    dest->readonly = src->readonly;
534    dest->format = src->format ? src->format : "B";
535    dest->internal = src->internal;
536}
537
538/* Copy shape and strides. Reconstruct missing values. */
539static void
540init_shape_strides(Py_buffer *dest, const Py_buffer *src)
541{
542    Py_ssize_t i;
543
544    if (src->ndim == 0) {
545        dest->shape = NULL;
546        dest->strides = NULL;
547        return;
548    }
549    if (src->ndim == 1) {
550        dest->shape[0] = src->shape ? src->shape[0] : src->len / src->itemsize;
551        dest->strides[0] = src->strides ? src->strides[0] : src->itemsize;
552        return;
553    }
554
555    for (i = 0; i < src->ndim; i++)
556        dest->shape[i] = src->shape[i];
557    if (src->strides) {
558        for (i = 0; i < src->ndim; i++)
559            dest->strides[i] = src->strides[i];
560    }
561    else {
562        init_strides_from_shape(dest);
563    }
564}
565
566static inline void
567init_suboffsets(Py_buffer *dest, const Py_buffer *src)
568{
569    Py_ssize_t i;
570
571    if (src->suboffsets == NULL) {
572        dest->suboffsets = NULL;
573        return;
574    }
575    for (i = 0; i < src->ndim; i++)
576        dest->suboffsets[i] = src->suboffsets[i];
577}
578
579/* len = product(shape) * itemsize */
580static inline void
581init_len(Py_buffer *view)
582{
583    Py_ssize_t i, len;
584
585    len = 1;
586    for (i = 0; i < view->ndim; i++)
587        len *= view->shape[i];
588    len *= view->itemsize;
589
590    view->len = len;
591}
592
593/* Initialize memoryview buffer properties. */
594static void
595init_flags(PyMemoryViewObject *mv)
596{
597    const Py_buffer *view = &mv->view;
598    int flags = 0;
599
600    switch (view->ndim) {
601    case 0:
602        flags |= (_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|
603                  _Py_MEMORYVIEW_FORTRAN);
604        break;
605    case 1:
606        if (MV_CONTIGUOUS_NDIM1(view))
607            flags |= (_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
608        break;
609    default:
610        if (PyBuffer_IsContiguous(view, 'C'))
611            flags |= _Py_MEMORYVIEW_C;
612        if (PyBuffer_IsContiguous(view, 'F'))
613            flags |= _Py_MEMORYVIEW_FORTRAN;
614        break;
615    }
616
617    if (view->suboffsets) {
618        flags |= _Py_MEMORYVIEW_PIL;
619        flags &= ~(_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN);
620    }
621
622    mv->flags = flags;
623}
624
625/* Allocate a new memoryview and perform basic initialization. New memoryviews
626   are exclusively created through the mbuf_add functions. */
627static inline PyMemoryViewObject *
628memory_alloc(int ndim)
629{
630    PyMemoryViewObject *mv;
631
632    mv = (PyMemoryViewObject *)
633        PyObject_GC_NewVar(PyMemoryViewObject, &PyMemoryView_Type, 3*ndim);
634    if (mv == NULL)
635        return NULL;
636
637    mv->mbuf = NULL;
638    mv->hash = -1;
639    mv->flags = 0;
640    mv->exports = 0;
641    mv->view.ndim = ndim;
642    mv->view.shape = mv->ob_array;
643    mv->view.strides = mv->ob_array + ndim;
644    mv->view.suboffsets = mv->ob_array + 2 * ndim;
645    mv->weakreflist = NULL;
646
647    _PyObject_GC_TRACK(mv);
648    return mv;
649}
650
651/*
652   Return a new memoryview that is registered with mbuf. If src is NULL,
653   use mbuf->master as the underlying buffer. Otherwise, use src.
654
655   The new memoryview has full buffer information: shape and strides
656   are always present, suboffsets as needed. Arrays are copied to
657   the memoryview's ob_array field.
658 */
659static PyObject *
660mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src)
661{
662    PyMemoryViewObject *mv;
663    Py_buffer *dest;
664
665    if (src == NULL)
666        src = &mbuf->master;
667
668    if (src->ndim > PyBUF_MAX_NDIM) {
669        PyErr_SetString(PyExc_ValueError,
670            "memoryview: number of dimensions must not exceed "
671            Py_STRINGIFY(PyBUF_MAX_NDIM));
672        return NULL;
673    }
674
675    mv = memory_alloc(src->ndim);
676    if (mv == NULL)
677        return NULL;
678
679    dest = &mv->view;
680    init_shared_values(dest, src);
681    init_shape_strides(dest, src);
682    init_suboffsets(dest, src);
683    init_flags(mv);
684
685    mv->mbuf = mbuf;
686    Py_INCREF(mbuf);
687    mbuf->exports++;
688
689    return (PyObject *)mv;
690}
691
692/* Register an incomplete view: shape, strides, suboffsets and flags still
693   need to be initialized. Use 'ndim' instead of src->ndim to determine the
694   size of the memoryview's ob_array.
695
696   Assumption: ndim <= PyBUF_MAX_NDIM. */
697static PyObject *
698mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src,
699                         int ndim)
700{
701    PyMemoryViewObject *mv;
702    Py_buffer *dest;
703
704    if (src == NULL)
705        src = &mbuf->master;
706
707    assert(ndim <= PyBUF_MAX_NDIM);
708
709    mv = memory_alloc(ndim);
710    if (mv == NULL)
711        return NULL;
712
713    dest = &mv->view;
714    init_shared_values(dest, src);
715
716    mv->mbuf = mbuf;
717    Py_INCREF(mbuf);
718    mbuf->exports++;
719
720    return (PyObject *)mv;
721}
722
723/* Expose a raw memory area as a view of contiguous bytes. flags can be
724   PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes).
725   The memoryview has complete buffer information. */
726PyObject *
727PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags)
728{
729    _PyManagedBufferObject *mbuf;
730    PyObject *mv;
731    int readonly;
732
733    assert(mem != NULL);
734    assert(flags == PyBUF_READ || flags == PyBUF_WRITE);
735
736    mbuf = mbuf_alloc();
737    if (mbuf == NULL)
738        return NULL;
739
740    readonly = (flags == PyBUF_WRITE) ? 0 : 1;
741    (void)PyBuffer_FillInfo(&mbuf->master, NULL, mem, size, readonly,
742                            PyBUF_FULL_RO);
743
744    mv = mbuf_add_view(mbuf, NULL);
745    Py_DECREF(mbuf);
746
747    return mv;
748}
749
750/* Create a memoryview from a given Py_buffer. For simple byte views,
751   PyMemoryView_FromMemory() should be used instead.
752   This function is the only entry point that can create a master buffer
753   without full information. Because of this fact init_shape_strides()
754   must be able to reconstruct missing values.  */
755PyObject *
756PyMemoryView_FromBuffer(const Py_buffer *info)
757{
758    _PyManagedBufferObject *mbuf;
759    PyObject *mv;
760
761    if (info->buf == NULL) {
762        PyErr_SetString(PyExc_ValueError,
763            "PyMemoryView_FromBuffer(): info->buf must not be NULL");
764        return NULL;
765    }
766
767    mbuf = mbuf_alloc();
768    if (mbuf == NULL)
769        return NULL;
770
771    /* info->obj is either NULL or a borrowed reference. This reference
772       should not be decremented in PyBuffer_Release(). */
773    mbuf->master = *info;
774    mbuf->master.obj = NULL;
775
776    mv = mbuf_add_view(mbuf, NULL);
777    Py_DECREF(mbuf);
778
779    return mv;
780}
781
782/* Create a memoryview from an object that implements the buffer protocol.
783   If the object is a memoryview, the new memoryview must be registered
784   with the same managed buffer. Otherwise, a new managed buffer is created. */
785PyObject *
786PyMemoryView_FromObject(PyObject *v)
787{
788    _PyManagedBufferObject *mbuf;
789
790    if (PyMemoryView_Check(v)) {
791        PyMemoryViewObject *mv = (PyMemoryViewObject *)v;
792        CHECK_RELEASED(mv);
793        return mbuf_add_view(mv->mbuf, &mv->view);
794    }
795    else if (PyObject_CheckBuffer(v)) {
796        PyObject *ret;
797        mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v);
798        if (mbuf == NULL)
799            return NULL;
800        ret = mbuf_add_view(mbuf, NULL);
801        Py_DECREF(mbuf);
802        return ret;
803    }
804
805    PyErr_Format(PyExc_TypeError,
806        "memoryview: a bytes-like object is required, not '%.200s'",
807        Py_TYPE(v)->tp_name);
808    return NULL;
809}
810
811/* Copy the format string from a base object that might vanish. */
812static int
813mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt)
814{
815    if (fmt != NULL) {
816        char *cp = PyMem_Malloc(strlen(fmt)+1);
817        if (cp == NULL) {
818            PyErr_NoMemory();
819            return -1;
820        }
821        mbuf->master.format = strcpy(cp, fmt);
822        mbuf->flags |= _Py_MANAGED_BUFFER_FREE_FORMAT;
823    }
824
825    return 0;
826}
827
828/*
829   Return a memoryview that is based on a contiguous copy of src.
830   Assumptions: src has PyBUF_FULL_RO information, src->ndim > 0.
831
832   Ownership rules:
833     1) As usual, the returned memoryview has a private copy
834        of src->shape, src->strides and src->suboffsets.
835     2) src->format is copied to the master buffer and released
836        in mbuf_dealloc(). The releasebufferproc of the bytes
837        object is NULL, so it does not matter that mbuf_release()
838        passes the altered format pointer to PyBuffer_Release().
839*/
840static PyObject *
841memory_from_contiguous_copy(const Py_buffer *src, char order)
842{
843    _PyManagedBufferObject *mbuf;
844    PyMemoryViewObject *mv;
845    PyObject *bytes;
846    Py_buffer *dest;
847    int i;
848
849    assert(src->ndim > 0);
850    assert(src->shape != NULL);
851
852    bytes = PyBytes_FromStringAndSize(NULL, src->len);
853    if (bytes == NULL)
854        return NULL;
855
856    mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes);
857    Py_DECREF(bytes);
858    if (mbuf == NULL)
859        return NULL;
860
861    if (mbuf_copy_format(mbuf, src->format) < 0) {
862        Py_DECREF(mbuf);
863        return NULL;
864    }
865
866    mv = (PyMemoryViewObject *)mbuf_add_incomplete_view(mbuf, NULL, src->ndim);
867    Py_DECREF(mbuf);
868    if (mv == NULL)
869        return NULL;
870
871    dest = &mv->view;
872
873    /* shared values are initialized correctly except for itemsize */
874    dest->itemsize = src->itemsize;
875
876    /* shape and strides */
877    for (i = 0; i < src->ndim; i++) {
878        dest->shape[i] = src->shape[i];
879    }
880    if (order == 'C' || order == 'A') {
881        init_strides_from_shape(dest);
882    }
883    else {
884        init_fortran_strides_from_shape(dest);
885    }
886    /* suboffsets */
887    dest->suboffsets = NULL;
888
889    /* flags */
890    init_flags(mv);
891
892    if (copy_buffer(dest, src) < 0) {
893        Py_DECREF(mv);
894        return NULL;
895    }
896
897    return (PyObject *)mv;
898}
899
900/*
901   Return a new memoryview object based on a contiguous exporter with
902   buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}.
903   The logical structure of the input and output buffers is the same
904   (i.e. tolist(input) == tolist(output)), but the physical layout in
905   memory can be explicitly chosen.
906
907   As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable,
908   otherwise it may be writable or read-only.
909
910   If the exporter is already contiguous with the desired target order,
911   the memoryview will be directly based on the exporter.
912
913   Otherwise, if the buffertype is PyBUF_READ, the memoryview will be
914   based on a new bytes object. If order={'C', 'A'ny}, use 'C' order,
915   'F'ortran order otherwise.
916*/
917PyObject *
918PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order)
919{
920    PyMemoryViewObject *mv;
921    PyObject *ret;
922    Py_buffer *view;
923
924    assert(buffertype == PyBUF_READ || buffertype == PyBUF_WRITE);
925    assert(order == 'C' || order == 'F' || order == 'A');
926
927    mv = (PyMemoryViewObject *)PyMemoryView_FromObject(obj);
928    if (mv == NULL)
929        return NULL;
930
931    view = &mv->view;
932    if (buffertype == PyBUF_WRITE && view->readonly) {
933        PyErr_SetString(PyExc_BufferError,
934            "underlying buffer is not writable");
935        Py_DECREF(mv);
936        return NULL;
937    }
938
939    if (PyBuffer_IsContiguous(view, order))
940        return (PyObject *)mv;
941
942    if (buffertype == PyBUF_WRITE) {
943        PyErr_SetString(PyExc_BufferError,
944            "writable contiguous buffer requested "
945            "for a non-contiguous object.");
946        Py_DECREF(mv);
947        return NULL;
948    }
949
950    ret = memory_from_contiguous_copy(view, order);
951    Py_DECREF(mv);
952    return ret;
953}
954
955
956/*[clinic input]
957@classmethod
958memoryview.__new__
959
960    object: object
961
962Create a new memoryview object which references the given object.
963[clinic start generated code]*/
964
965static PyObject *
966memoryview_impl(PyTypeObject *type, PyObject *object)
967/*[clinic end generated code: output=7de78e184ed66db8 input=f04429eb0bdf8c6e]*/
968{
969    return PyMemoryView_FromObject(object);
970}
971
972
973/****************************************************************************/
974/*                         Previously in abstract.c                         */
975/****************************************************************************/
976
977typedef struct {
978    Py_buffer view;
979    Py_ssize_t array[1];
980} Py_buffer_full;
981
982int
983PyBuffer_ToContiguous(void *buf, const Py_buffer *src, Py_ssize_t len, char order)
984{
985    Py_buffer_full *fb = NULL;
986    int ret;
987
988    assert(order == 'C' || order == 'F' || order == 'A');
989
990    if (len != src->len) {
991        PyErr_SetString(PyExc_ValueError,
992            "PyBuffer_ToContiguous: len != view->len");
993        return -1;
994    }
995
996    if (PyBuffer_IsContiguous(src, order)) {
997        memcpy((char *)buf, src->buf, len);
998        return 0;
999    }
1000
1001    /* buffer_to_contiguous() assumes PyBUF_FULL */
1002    fb = PyMem_Malloc(sizeof *fb + 3 * src->ndim * (sizeof *fb->array));
1003    if (fb == NULL) {
1004        PyErr_NoMemory();
1005        return -1;
1006    }
1007    fb->view.ndim = src->ndim;
1008    fb->view.shape = fb->array;
1009    fb->view.strides = fb->array + src->ndim;
1010    fb->view.suboffsets = fb->array + 2 * src->ndim;
1011
1012    init_shared_values(&fb->view, src);
1013    init_shape_strides(&fb->view, src);
1014    init_suboffsets(&fb->view, src);
1015
1016    src = &fb->view;
1017
1018    ret = buffer_to_contiguous(buf, src, order);
1019    PyMem_Free(fb);
1020    return ret;
1021}
1022
1023
1024/****************************************************************************/
1025/*                           Release/GC management                          */
1026/****************************************************************************/
1027
1028/* Inform the managed buffer that this particular memoryview will not access
1029   the underlying buffer again. If no other memoryviews are registered with
1030   the managed buffer, the underlying buffer is released instantly and
1031   marked as inaccessible for both the memoryview and the managed buffer.
1032
1033   This function fails if the memoryview itself has exported buffers. */
1034static int
1035_memory_release(PyMemoryViewObject *self)
1036{
1037    if (self->flags & _Py_MEMORYVIEW_RELEASED)
1038        return 0;
1039
1040    if (self->exports == 0) {
1041        self->flags |= _Py_MEMORYVIEW_RELEASED;
1042        assert(self->mbuf->exports > 0);
1043        if (--self->mbuf->exports == 0)
1044            mbuf_release(self->mbuf);
1045        return 0;
1046    }
1047    if (self->exports > 0) {
1048        PyErr_Format(PyExc_BufferError,
1049            "memoryview has %zd exported buffer%s", self->exports,
1050            self->exports==1 ? "" : "s");
1051        return -1;
1052    }
1053
1054    PyErr_SetString(PyExc_SystemError,
1055                    "_memory_release(): negative export count");
1056    return -1;
1057}
1058
1059/*[clinic input]
1060memoryview.release
1061
1062Release the underlying buffer exposed by the memoryview object.
1063[clinic start generated code]*/
1064
1065static PyObject *
1066memoryview_release_impl(PyMemoryViewObject *self)
1067/*[clinic end generated code: output=d0b7e3ba95b7fcb9 input=bc71d1d51f4a52f0]*/
1068{
1069    if (_memory_release(self) < 0)
1070        return NULL;
1071    Py_RETURN_NONE;
1072}
1073
1074static void
1075memory_dealloc(PyMemoryViewObject *self)
1076{
1077    assert(self->exports == 0);
1078    _PyObject_GC_UNTRACK(self);
1079    (void)_memory_release(self);
1080    Py_CLEAR(self->mbuf);
1081    if (self->weakreflist != NULL)
1082        PyObject_ClearWeakRefs((PyObject *) self);
1083    PyObject_GC_Del(self);
1084}
1085
1086static int
1087memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg)
1088{
1089    Py_VISIT(self->mbuf);
1090    return 0;
1091}
1092
1093static int
1094memory_clear(PyMemoryViewObject *self)
1095{
1096    (void)_memory_release(self);
1097    Py_CLEAR(self->mbuf);
1098    return 0;
1099}
1100
1101static PyObject *
1102memory_enter(PyObject *self, PyObject *args)
1103{
1104    CHECK_RELEASED(self);
1105    Py_INCREF(self);
1106    return self;
1107}
1108
1109static PyObject *
1110memory_exit(PyObject *self, PyObject *args)
1111{
1112    return memoryview_release_impl((PyMemoryViewObject *)self);
1113}
1114
1115
1116/****************************************************************************/
1117/*                         Casting format and shape                         */
1118/****************************************************************************/
1119
1120#define IS_BYTE_FORMAT(f) (f == 'b' || f == 'B' || f == 'c')
1121
1122static inline Py_ssize_t
1123get_native_fmtchar(char *result, const char *fmt)
1124{
1125    Py_ssize_t size = -1;
1126
1127    if (fmt[0] == '@') fmt++;
1128
1129    switch (fmt[0]) {
1130    case 'c': case 'b': case 'B': size = sizeof(char); break;
1131    case 'h': case 'H': size = sizeof(short); break;
1132    case 'i': case 'I': size = sizeof(int); break;
1133    case 'l': case 'L': size = sizeof(long); break;
1134    case 'q': case 'Q': size = sizeof(long long); break;
1135    case 'n': case 'N': size = sizeof(Py_ssize_t); break;
1136    case 'f': size = sizeof(float); break;
1137    case 'd': size = sizeof(double); break;
1138    case '?': size = sizeof(_Bool); break;
1139    case 'P': size = sizeof(void *); break;
1140    }
1141
1142    if (size > 0 && fmt[1] == '\0') {
1143        *result = fmt[0];
1144        return size;
1145    }
1146
1147    return -1;
1148}
1149
1150static inline const char *
1151get_native_fmtstr(const char *fmt)
1152{
1153    int at = 0;
1154
1155    if (fmt[0] == '@') {
1156        at = 1;
1157        fmt++;
1158    }
1159    if (fmt[0] == '\0' || fmt[1] != '\0') {
1160        return NULL;
1161    }
1162
1163#define RETURN(s) do { return at ? "@" s : s; } while (0)
1164
1165    switch (fmt[0]) {
1166    case 'c': RETURN("c");
1167    case 'b': RETURN("b");
1168    case 'B': RETURN("B");
1169    case 'h': RETURN("h");
1170    case 'H': RETURN("H");
1171    case 'i': RETURN("i");
1172    case 'I': RETURN("I");
1173    case 'l': RETURN("l");
1174    case 'L': RETURN("L");
1175    case 'q': RETURN("q");
1176    case 'Q': RETURN("Q");
1177    case 'n': RETURN("n");
1178    case 'N': RETURN("N");
1179    case 'f': RETURN("f");
1180    case 'd': RETURN("d");
1181    case '?': RETURN("?");
1182    case 'P': RETURN("P");
1183    }
1184
1185    return NULL;
1186}
1187
1188
1189/* Cast a memoryview's data type to 'format'. The input array must be
1190   C-contiguous. At least one of input-format, output-format must have
1191   byte size. The output array is 1-D, with the same byte length as the
1192   input array. Thus, view->len must be a multiple of the new itemsize. */
1193static int
1194cast_to_1D(PyMemoryViewObject *mv, PyObject *format)
1195{
1196    Py_buffer *view = &mv->view;
1197    PyObject *asciifmt;
1198    char srcchar, destchar;
1199    Py_ssize_t itemsize;
1200    int ret = -1;
1201
1202    assert(view->ndim >= 1);
1203    assert(Py_SIZE(mv) == 3*view->ndim);
1204    assert(view->shape == mv->ob_array);
1205    assert(view->strides == mv->ob_array + view->ndim);
1206    assert(view->suboffsets == mv->ob_array + 2*view->ndim);
1207
1208    asciifmt = PyUnicode_AsASCIIString(format);
1209    if (asciifmt == NULL)
1210        return ret;
1211
1212    itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt));
1213    if (itemsize < 0) {
1214        PyErr_SetString(PyExc_ValueError,
1215            "memoryview: destination format must be a native single "
1216            "character format prefixed with an optional '@'");
1217        goto out;
1218    }
1219
1220    if ((get_native_fmtchar(&srcchar, view->format) < 0 ||
1221         !IS_BYTE_FORMAT(srcchar)) && !IS_BYTE_FORMAT(destchar)) {
1222        PyErr_SetString(PyExc_TypeError,
1223            "memoryview: cannot cast between two non-byte formats");
1224        goto out;
1225    }
1226    if (view->len % itemsize) {
1227        PyErr_SetString(PyExc_TypeError,
1228            "memoryview: length is not a multiple of itemsize");
1229        goto out;
1230    }
1231
1232    view->format = (char *)get_native_fmtstr(PyBytes_AS_STRING(asciifmt));
1233    if (view->format == NULL) {
1234        /* NOT_REACHED: get_native_fmtchar() already validates the format. */
1235        PyErr_SetString(PyExc_RuntimeError,
1236            "memoryview: internal error");
1237        goto out;
1238    }
1239    view->itemsize = itemsize;
1240
1241    view->ndim = 1;
1242    view->shape[0] = view->len / view->itemsize;
1243    view->strides[0] = view->itemsize;
1244    view->suboffsets = NULL;
1245
1246    init_flags(mv);
1247
1248    ret = 0;
1249
1250out:
1251    Py_DECREF(asciifmt);
1252    return ret;
1253}
1254
1255/* The memoryview must have space for 3*len(seq) elements. */
1256static Py_ssize_t
1257copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim,
1258           Py_ssize_t itemsize)
1259{
1260    Py_ssize_t x, i;
1261    Py_ssize_t len = itemsize;
1262
1263    for (i = 0; i < ndim; i++) {
1264        PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i);
1265        if (!PyLong_Check(tmp)) {
1266            PyErr_SetString(PyExc_TypeError,
1267                "memoryview.cast(): elements of shape must be integers");
1268            return -1;
1269        }
1270        x = PyLong_AsSsize_t(tmp);
1271        if (x == -1 && PyErr_Occurred()) {
1272            return -1;
1273        }
1274        if (x <= 0) {
1275            /* In general elements of shape may be 0, but not for casting. */
1276            PyErr_Format(PyExc_ValueError,
1277                "memoryview.cast(): elements of shape must be integers > 0");
1278            return -1;
1279        }
1280        if (x > PY_SSIZE_T_MAX / len) {
1281            PyErr_Format(PyExc_ValueError,
1282                "memoryview.cast(): product(shape) > SSIZE_MAX");
1283            return -1;
1284        }
1285        len *= x;
1286        shape[i] = x;
1287    }
1288
1289    return len;
1290}
1291
1292/* Cast a 1-D array to a new shape. The result array will be C-contiguous.
1293   If the result array does not have exactly the same byte length as the
1294   input array, raise ValueError. */
1295static int
1296cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim)
1297{
1298    Py_buffer *view = &mv->view;
1299    Py_ssize_t len;
1300
1301    assert(view->ndim == 1); /* ndim from cast_to_1D() */
1302    assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */
1303    assert(view->shape == mv->ob_array);
1304    assert(view->strides == mv->ob_array + (ndim==0?1:ndim));
1305    assert(view->suboffsets == NULL);
1306
1307    view->ndim = ndim;
1308    if (view->ndim == 0) {
1309        view->shape = NULL;
1310        view->strides = NULL;
1311        len = view->itemsize;
1312    }
1313    else {
1314        len = copy_shape(view->shape, shape, ndim, view->itemsize);
1315        if (len < 0)
1316            return -1;
1317        init_strides_from_shape(view);
1318    }
1319
1320    if (view->len != len) {
1321        PyErr_SetString(PyExc_TypeError,
1322            "memoryview: product(shape) * itemsize != buffer size");
1323        return -1;
1324    }
1325
1326    init_flags(mv);
1327
1328    return 0;
1329}
1330
1331static int
1332zero_in_shape(PyMemoryViewObject *mv)
1333{
1334    Py_buffer *view = &mv->view;
1335    Py_ssize_t i;
1336
1337    for (i = 0; i < view->ndim; i++)
1338        if (view->shape[i] == 0)
1339            return 1;
1340
1341    return 0;
1342}
1343
1344/*
1345   Cast a copy of 'self' to a different view. The input view must
1346   be C-contiguous. The function always casts the input view to a
1347   1-D output according to 'format'. At least one of input-format,
1348   output-format must have byte size.
1349
1350   If 'shape' is given, the 1-D view from the previous step will
1351   be cast to a C-contiguous view with new shape and strides.
1352
1353   All casts must result in views that will have the exact byte
1354   size of the original input. Otherwise, an error is raised.
1355*/
1356/*[clinic input]
1357memoryview.cast
1358
1359    format: unicode
1360    shape: object = NULL
1361
1362Cast a memoryview to a new format or shape.
1363[clinic start generated code]*/
1364
1365static PyObject *
1366memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format,
1367                     PyObject *shape)
1368/*[clinic end generated code: output=bae520b3a389cbab input=138936cc9041b1a3]*/
1369{
1370    PyMemoryViewObject *mv = NULL;
1371    Py_ssize_t ndim = 1;
1372
1373    CHECK_RELEASED(self);
1374
1375    if (!MV_C_CONTIGUOUS(self->flags)) {
1376        PyErr_SetString(PyExc_TypeError,
1377            "memoryview: casts are restricted to C-contiguous views");
1378        return NULL;
1379    }
1380    if ((shape || self->view.ndim != 1) && zero_in_shape(self)) {
1381        PyErr_SetString(PyExc_TypeError,
1382            "memoryview: cannot cast view with zeros in shape or strides");
1383        return NULL;
1384    }
1385    if (shape) {
1386        CHECK_LIST_OR_TUPLE(shape)
1387        ndim = PySequence_Fast_GET_SIZE(shape);
1388        if (ndim > PyBUF_MAX_NDIM) {
1389            PyErr_SetString(PyExc_ValueError,
1390                "memoryview: number of dimensions must not exceed "
1391                Py_STRINGIFY(PyBUF_MAX_NDIM));
1392            return NULL;
1393        }
1394        if (self->view.ndim != 1 && ndim != 1) {
1395            PyErr_SetString(PyExc_TypeError,
1396                "memoryview: cast must be 1D -> ND or ND -> 1D");
1397            return NULL;
1398        }
1399    }
1400
1401    mv = (PyMemoryViewObject *)
1402        mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim);
1403    if (mv == NULL)
1404        return NULL;
1405
1406    if (cast_to_1D(mv, format) < 0)
1407        goto error;
1408    if (shape && cast_to_ND(mv, shape, (int)ndim) < 0)
1409        goto error;
1410
1411    return (PyObject *)mv;
1412
1413error:
1414    Py_DECREF(mv);
1415    return NULL;
1416}
1417
1418/*[clinic input]
1419memoryview.toreadonly
1420
1421Return a readonly version of the memoryview.
1422[clinic start generated code]*/
1423
1424static PyObject *
1425memoryview_toreadonly_impl(PyMemoryViewObject *self)
1426/*[clinic end generated code: output=2c7e056f04c99e62 input=dc06d20f19ba236f]*/
1427{
1428    CHECK_RELEASED(self);
1429    /* Even if self is already readonly, we still need to create a new
1430     * object for .release() to work correctly.
1431     */
1432    self = (PyMemoryViewObject *) mbuf_add_view(self->mbuf, &self->view);
1433    if (self != NULL) {
1434        self->view.readonly = 1;
1435    };
1436    return (PyObject *) self;
1437}
1438
1439
1440/**************************************************************************/
1441/*                               getbuffer                                */
1442/**************************************************************************/
1443
1444static int
1445memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
1446{
1447    Py_buffer *base = &self->view;
1448    int baseflags = self->flags;
1449
1450    CHECK_RELEASED_INT(self);
1451
1452    /* start with complete information */
1453    *view = *base;
1454    view->obj = NULL;
1455
1456    if (REQ_WRITABLE(flags) && base->readonly) {
1457        PyErr_SetString(PyExc_BufferError,
1458            "memoryview: underlying buffer is not writable");
1459        return -1;
1460    }
1461    if (!REQ_FORMAT(flags)) {
1462        /* NULL indicates that the buffer's data type has been cast to 'B'.
1463           view->itemsize is the _previous_ itemsize. If shape is present,
1464           the equality product(shape) * itemsize = len still holds at this
1465           point. The equality calcsize(format) = itemsize does _not_ hold
1466           from here on! */
1467        view->format = NULL;
1468    }
1469
1470    if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) {
1471        PyErr_SetString(PyExc_BufferError,
1472            "memoryview: underlying buffer is not C-contiguous");
1473        return -1;
1474    }
1475    if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) {
1476        PyErr_SetString(PyExc_BufferError,
1477            "memoryview: underlying buffer is not Fortran contiguous");
1478        return -1;
1479    }
1480    if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) {
1481        PyErr_SetString(PyExc_BufferError,
1482            "memoryview: underlying buffer is not contiguous");
1483        return -1;
1484    }
1485    if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) {
1486        PyErr_SetString(PyExc_BufferError,
1487            "memoryview: underlying buffer requires suboffsets");
1488        return -1;
1489    }
1490    if (!REQ_STRIDES(flags)) {
1491        if (!MV_C_CONTIGUOUS(baseflags)) {
1492            PyErr_SetString(PyExc_BufferError,
1493                "memoryview: underlying buffer is not C-contiguous");
1494            return -1;
1495        }
1496        view->strides = NULL;
1497    }
1498    if (!REQ_SHAPE(flags)) {
1499        /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous,
1500           so base->buf = ndbuf->data. */
1501        if (view->format != NULL) {
1502            /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do
1503               not make sense. */
1504            PyErr_Format(PyExc_BufferError,
1505                "memoryview: cannot cast to unsigned bytes if the format flag "
1506                "is present");
1507            return -1;
1508        }
1509        /* product(shape) * itemsize = len and calcsize(format) = itemsize
1510           do _not_ hold from here on! */
1511        view->ndim = 1;
1512        view->shape = NULL;
1513    }
1514
1515
1516    view->obj = (PyObject *)self;
1517    Py_INCREF(view->obj);
1518    self->exports++;
1519
1520    return 0;
1521}
1522
1523static void
1524memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
1525{
1526    self->exports--;
1527    return;
1528    /* PyBuffer_Release() decrements view->obj after this function returns. */
1529}
1530
1531/* Buffer methods */
1532static PyBufferProcs memory_as_buffer = {
1533    (getbufferproc)memory_getbuf,         /* bf_getbuffer */
1534    (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */
1535};
1536
1537
1538/****************************************************************************/
1539/*           Optimized pack/unpack for all native format specifiers         */
1540/****************************************************************************/
1541
1542/*
1543  Fix exceptions:
1544     1) Include format string in the error message.
1545     2) OverflowError -> ValueError.
1546     3) The error message from PyNumber_Index() is not ideal.
1547*/
1548static int
1549type_error_int(const char *fmt)
1550{
1551    PyErr_Format(PyExc_TypeError,
1552        "memoryview: invalid type for format '%s'", fmt);
1553    return -1;
1554}
1555
1556static int
1557value_error_int(const char *fmt)
1558{
1559    PyErr_Format(PyExc_ValueError,
1560        "memoryview: invalid value for format '%s'", fmt);
1561    return -1;
1562}
1563
1564static int
1565fix_error_int(const char *fmt)
1566{
1567    assert(PyErr_Occurred());
1568    if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1569        PyErr_Clear();
1570        return type_error_int(fmt);
1571    }
1572    else if (PyErr_ExceptionMatches(PyExc_OverflowError) ||
1573             PyErr_ExceptionMatches(PyExc_ValueError)) {
1574        PyErr_Clear();
1575        return value_error_int(fmt);
1576    }
1577
1578    return -1;
1579}
1580
1581/* Accept integer objects or objects with an __index__() method. */
1582static long
1583pylong_as_ld(PyObject *item)
1584{
1585    PyObject *tmp;
1586    long ld;
1587
1588    tmp = _PyNumber_Index(item);
1589    if (tmp == NULL)
1590        return -1;
1591
1592    ld = PyLong_AsLong(tmp);
1593    Py_DECREF(tmp);
1594    return ld;
1595}
1596
1597static unsigned long
1598pylong_as_lu(PyObject *item)
1599{
1600    PyObject *tmp;
1601    unsigned long lu;
1602
1603    tmp = _PyNumber_Index(item);
1604    if (tmp == NULL)
1605        return (unsigned long)-1;
1606
1607    lu = PyLong_AsUnsignedLong(tmp);
1608    Py_DECREF(tmp);
1609    return lu;
1610}
1611
1612static long long
1613pylong_as_lld(PyObject *item)
1614{
1615    PyObject *tmp;
1616    long long lld;
1617
1618    tmp = _PyNumber_Index(item);
1619    if (tmp == NULL)
1620        return -1;
1621
1622    lld = PyLong_AsLongLong(tmp);
1623    Py_DECREF(tmp);
1624    return lld;
1625}
1626
1627static unsigned long long
1628pylong_as_llu(PyObject *item)
1629{
1630    PyObject *tmp;
1631    unsigned long long llu;
1632
1633    tmp = _PyNumber_Index(item);
1634    if (tmp == NULL)
1635        return (unsigned long long)-1;
1636
1637    llu = PyLong_AsUnsignedLongLong(tmp);
1638    Py_DECREF(tmp);
1639    return llu;
1640}
1641
1642static Py_ssize_t
1643pylong_as_zd(PyObject *item)
1644{
1645    PyObject *tmp;
1646    Py_ssize_t zd;
1647
1648    tmp = _PyNumber_Index(item);
1649    if (tmp == NULL)
1650        return -1;
1651
1652    zd = PyLong_AsSsize_t(tmp);
1653    Py_DECREF(tmp);
1654    return zd;
1655}
1656
1657static size_t
1658pylong_as_zu(PyObject *item)
1659{
1660    PyObject *tmp;
1661    size_t zu;
1662
1663    tmp = _PyNumber_Index(item);
1664    if (tmp == NULL)
1665        return (size_t)-1;
1666
1667    zu = PyLong_AsSize_t(tmp);
1668    Py_DECREF(tmp);
1669    return zu;
1670}
1671
1672/* Timings with the ndarray from _testbuffer.c indicate that using the
1673   struct module is around 15x slower than the two functions below. */
1674
1675#define UNPACK_SINGLE(dest, ptr, type) \
1676    do {                                   \
1677        type x;                            \
1678        memcpy((char *)&x, ptr, sizeof x); \
1679        dest = x;                          \
1680    } while (0)
1681
1682/* Unpack a single item. 'fmt' can be any native format character in struct
1683   module syntax. This function is very sensitive to small changes. With this
1684   layout gcc automatically generates a fast jump table. */
1685static inline PyObject *
1686unpack_single(PyMemoryViewObject *self, const char *ptr, const char *fmt)
1687{
1688    unsigned long long llu;
1689    unsigned long lu;
1690    size_t zu;
1691    long long lld;
1692    long ld;
1693    Py_ssize_t zd;
1694    double d;
1695    unsigned char uc;
1696    void *p;
1697
1698    CHECK_RELEASED_AGAIN(self);
1699
1700    switch (fmt[0]) {
1701
1702    /* signed integers and fast path for 'B' */
1703    case 'B': uc = *((const unsigned char *)ptr); goto convert_uc;
1704    case 'b': ld =   *((const signed char *)ptr); goto convert_ld;
1705    case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld;
1706    case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld;
1707    case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld;
1708
1709    /* boolean */
1710    case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool;
1711
1712    /* unsigned integers */
1713    case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu;
1714    case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu;
1715    case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu;
1716
1717    /* native 64-bit */
1718    case 'q': UNPACK_SINGLE(lld, ptr, long long); goto convert_lld;
1719    case 'Q': UNPACK_SINGLE(llu, ptr, unsigned long long); goto convert_llu;
1720
1721    /* ssize_t and size_t */
1722    case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd;
1723    case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu;
1724
1725    /* floats */
1726    case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double;
1727    case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double;
1728
1729    /* bytes object */
1730    case 'c': goto convert_bytes;
1731
1732    /* pointer */
1733    case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer;
1734
1735    /* default */
1736    default: goto err_format;
1737    }
1738
1739convert_uc:
1740    /* PyLong_FromUnsignedLong() is slower */
1741    return PyLong_FromLong(uc);
1742convert_ld:
1743    return PyLong_FromLong(ld);
1744convert_lu:
1745    return PyLong_FromUnsignedLong(lu);
1746convert_lld:
1747    return PyLong_FromLongLong(lld);
1748convert_llu:
1749    return PyLong_FromUnsignedLongLong(llu);
1750convert_zd:
1751    return PyLong_FromSsize_t(zd);
1752convert_zu:
1753    return PyLong_FromSize_t(zu);
1754convert_double:
1755    return PyFloat_FromDouble(d);
1756convert_bool:
1757    return PyBool_FromLong(ld);
1758convert_bytes:
1759    return PyBytes_FromStringAndSize(ptr, 1);
1760convert_pointer:
1761    return PyLong_FromVoidPtr(p);
1762err_format:
1763    PyErr_Format(PyExc_NotImplementedError,
1764        "memoryview: format %s not supported", fmt);
1765    return NULL;
1766}
1767
1768#define PACK_SINGLE(ptr, src, type) \
1769    do {                                     \
1770        type x;                              \
1771        x = (type)src;                       \
1772        memcpy(ptr, (char *)&x, sizeof x);   \
1773    } while (0)
1774
1775/* Pack a single item. 'fmt' can be any native format character in
1776   struct module syntax. */
1777static int
1778pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt)
1779{
1780    unsigned long long llu;
1781    unsigned long lu;
1782    size_t zu;
1783    long long lld;
1784    long ld;
1785    Py_ssize_t zd;
1786    double d;
1787    void *p;
1788
1789    switch (fmt[0]) {
1790    /* signed integers */
1791    case 'b': case 'h': case 'i': case 'l':
1792        ld = pylong_as_ld(item);
1793        if (ld == -1 && PyErr_Occurred())
1794            goto err_occurred;
1795        CHECK_RELEASED_INT_AGAIN(self);
1796        switch (fmt[0]) {
1797        case 'b':
1798            if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range;
1799            *((signed char *)ptr) = (signed char)ld; break;
1800        case 'h':
1801            if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range;
1802            PACK_SINGLE(ptr, ld, short); break;
1803        case 'i':
1804            if (ld < INT_MIN || ld > INT_MAX) goto err_range;
1805            PACK_SINGLE(ptr, ld, int); break;
1806        default: /* 'l' */
1807            PACK_SINGLE(ptr, ld, long); break;
1808        }
1809        break;
1810
1811    /* unsigned integers */
1812    case 'B': case 'H': case 'I': case 'L':
1813        lu = pylong_as_lu(item);
1814        if (lu == (unsigned long)-1 && PyErr_Occurred())
1815            goto err_occurred;
1816        CHECK_RELEASED_INT_AGAIN(self);
1817        switch (fmt[0]) {
1818        case 'B':
1819            if (lu > UCHAR_MAX) goto err_range;
1820            *((unsigned char *)ptr) = (unsigned char)lu; break;
1821        case 'H':
1822            if (lu > USHRT_MAX) goto err_range;
1823            PACK_SINGLE(ptr, lu, unsigned short); break;
1824        case 'I':
1825            if (lu > UINT_MAX) goto err_range;
1826            PACK_SINGLE(ptr, lu, unsigned int); break;
1827        default: /* 'L' */
1828            PACK_SINGLE(ptr, lu, unsigned long); break;
1829        }
1830        break;
1831
1832    /* native 64-bit */
1833    case 'q':
1834        lld = pylong_as_lld(item);
1835        if (lld == -1 && PyErr_Occurred())
1836            goto err_occurred;
1837        CHECK_RELEASED_INT_AGAIN(self);
1838        PACK_SINGLE(ptr, lld, long long);
1839        break;
1840    case 'Q':
1841        llu = pylong_as_llu(item);
1842        if (llu == (unsigned long long)-1 && PyErr_Occurred())
1843            goto err_occurred;
1844        CHECK_RELEASED_INT_AGAIN(self);
1845        PACK_SINGLE(ptr, llu, unsigned long long);
1846        break;
1847
1848    /* ssize_t and size_t */
1849    case 'n':
1850        zd = pylong_as_zd(item);
1851        if (zd == -1 && PyErr_Occurred())
1852            goto err_occurred;
1853        CHECK_RELEASED_INT_AGAIN(self);
1854        PACK_SINGLE(ptr, zd, Py_ssize_t);
1855        break;
1856    case 'N':
1857        zu = pylong_as_zu(item);
1858        if (zu == (size_t)-1 && PyErr_Occurred())
1859            goto err_occurred;
1860        CHECK_RELEASED_INT_AGAIN(self);
1861        PACK_SINGLE(ptr, zu, size_t);
1862        break;
1863
1864    /* floats */
1865    case 'f': case 'd':
1866        d = PyFloat_AsDouble(item);
1867        if (d == -1.0 && PyErr_Occurred())
1868            goto err_occurred;
1869        CHECK_RELEASED_INT_AGAIN(self);
1870        if (fmt[0] == 'f') {
1871            PACK_SINGLE(ptr, d, float);
1872        }
1873        else {
1874            PACK_SINGLE(ptr, d, double);
1875        }
1876        break;
1877
1878    /* bool */
1879    case '?':
1880        ld = PyObject_IsTrue(item);
1881        if (ld < 0)
1882            return -1; /* preserve original error */
1883        CHECK_RELEASED_INT_AGAIN(self);
1884        PACK_SINGLE(ptr, ld, _Bool);
1885         break;
1886
1887    /* bytes object */
1888    case 'c':
1889        if (!PyBytes_Check(item))
1890            return type_error_int(fmt);
1891        if (PyBytes_GET_SIZE(item) != 1)
1892            return value_error_int(fmt);
1893        *ptr = PyBytes_AS_STRING(item)[0];
1894        break;
1895
1896    /* pointer */
1897    case 'P':
1898        p = PyLong_AsVoidPtr(item);
1899        if (p == NULL && PyErr_Occurred())
1900            goto err_occurred;
1901        CHECK_RELEASED_INT_AGAIN(self);
1902        PACK_SINGLE(ptr, p, void *);
1903        break;
1904
1905    /* default */
1906    default: goto err_format;
1907    }
1908
1909    return 0;
1910
1911err_occurred:
1912    return fix_error_int(fmt);
1913err_range:
1914    return value_error_int(fmt);
1915err_format:
1916    PyErr_Format(PyExc_NotImplementedError,
1917        "memoryview: format %s not supported", fmt);
1918    return -1;
1919}
1920
1921
1922/****************************************************************************/
1923/*                       unpack using the struct module                     */
1924/****************************************************************************/
1925
1926/* For reasonable performance it is necessary to cache all objects required
1927   for unpacking. An unpacker can handle the format passed to unpack_from().
1928   Invariant: All pointer fields of the struct should either be NULL or valid
1929   pointers. */
1930struct unpacker {
1931    PyObject *unpack_from; /* Struct.unpack_from(format) */
1932    PyObject *mview;       /* cached memoryview */
1933    char *item;            /* buffer for mview */
1934    Py_ssize_t itemsize;   /* len(item) */
1935};
1936
1937static struct unpacker *
1938unpacker_new(void)
1939{
1940    struct unpacker *x = PyMem_Malloc(sizeof *x);
1941
1942    if (x == NULL) {
1943        PyErr_NoMemory();
1944        return NULL;
1945    }
1946
1947    x->unpack_from = NULL;
1948    x->mview = NULL;
1949    x->item = NULL;
1950    x->itemsize = 0;
1951
1952    return x;
1953}
1954
1955static void
1956unpacker_free(struct unpacker *x)
1957{
1958    if (x) {
1959        Py_XDECREF(x->unpack_from);
1960        Py_XDECREF(x->mview);
1961        PyMem_Free(x->item);
1962        PyMem_Free(x);
1963    }
1964}
1965
1966/* Return a new unpacker for the given format. */
1967static struct unpacker *
1968struct_get_unpacker(const char *fmt, Py_ssize_t itemsize)
1969{
1970    PyObject *structmodule;     /* XXX cache these two */
1971    PyObject *Struct = NULL;    /* XXX in globals?     */
1972    PyObject *structobj = NULL;
1973    PyObject *format = NULL;
1974    struct unpacker *x = NULL;
1975
1976    structmodule = PyImport_ImportModule("struct");
1977    if (structmodule == NULL)
1978        return NULL;
1979
1980    Struct = PyObject_GetAttrString(structmodule, "Struct");
1981    Py_DECREF(structmodule);
1982    if (Struct == NULL)
1983        return NULL;
1984
1985    x = unpacker_new();
1986    if (x == NULL)
1987        goto error;
1988
1989    format = PyBytes_FromString(fmt);
1990    if (format == NULL)
1991        goto error;
1992
1993    structobj = PyObject_CallOneArg(Struct, format);
1994    if (structobj == NULL)
1995        goto error;
1996
1997    x->unpack_from = PyObject_GetAttrString(structobj, "unpack_from");
1998    if (x->unpack_from == NULL)
1999        goto error;
2000
2001    x->item = PyMem_Malloc(itemsize);
2002    if (x->item == NULL) {
2003        PyErr_NoMemory();
2004        goto error;
2005    }
2006    x->itemsize = itemsize;
2007
2008    x->mview = PyMemoryView_FromMemory(x->item, itemsize, PyBUF_WRITE);
2009    if (x->mview == NULL)
2010        goto error;
2011
2012
2013out:
2014    Py_XDECREF(Struct);
2015    Py_XDECREF(format);
2016    Py_XDECREF(structobj);
2017    return x;
2018
2019error:
2020    unpacker_free(x);
2021    x = NULL;
2022    goto out;
2023}
2024
2025/* unpack a single item */
2026static PyObject *
2027struct_unpack_single(const char *ptr, struct unpacker *x)
2028{
2029    PyObject *v;
2030
2031    memcpy(x->item, ptr, x->itemsize);
2032    v = PyObject_CallOneArg(x->unpack_from, x->mview);
2033    if (v == NULL)
2034        return NULL;
2035
2036    if (PyTuple_GET_SIZE(v) == 1) {
2037        PyObject *tmp = PyTuple_GET_ITEM(v, 0);
2038        Py_INCREF(tmp);
2039        Py_DECREF(v);
2040        return tmp;
2041    }
2042
2043    return v;
2044}
2045
2046
2047/****************************************************************************/
2048/*                              Representations                             */
2049/****************************************************************************/
2050
2051/* allow explicit form of native format */
2052static inline const char *
2053adjust_fmt(const Py_buffer *view)
2054{
2055    const char *fmt;
2056
2057    fmt = (view->format[0] == '@') ? view->format+1 : view->format;
2058    if (fmt[0] && fmt[1] == '\0')
2059        return fmt;
2060
2061    PyErr_Format(PyExc_NotImplementedError,
2062        "memoryview: unsupported format %s", view->format);
2063    return NULL;
2064}
2065
2066/* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */
2067static PyObject *
2068tolist_base(PyMemoryViewObject *self, const char *ptr, const Py_ssize_t *shape,
2069            const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2070            const char *fmt)
2071{
2072    PyObject *lst, *item;
2073    Py_ssize_t i;
2074
2075    lst = PyList_New(shape[0]);
2076    if (lst == NULL)
2077        return NULL;
2078
2079    for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2080        const char *xptr = ADJUST_PTR(ptr, suboffsets, 0);
2081        item = unpack_single(self, xptr, fmt);
2082        if (item == NULL) {
2083            Py_DECREF(lst);
2084            return NULL;
2085        }
2086        PyList_SET_ITEM(lst, i, item);
2087    }
2088
2089    return lst;
2090}
2091
2092/* Unpack a multi-dimensional array into a nested list.
2093   Assumption: ndim >= 1. */
2094static PyObject *
2095tolist_rec(PyMemoryViewObject *self, const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape,
2096           const Py_ssize_t *strides, const Py_ssize_t *suboffsets,
2097           const char *fmt)
2098{
2099    PyObject *lst, *item;
2100    Py_ssize_t i;
2101
2102    assert(ndim >= 1);
2103    assert(shape != NULL);
2104    assert(strides != NULL);
2105
2106    if (ndim == 1)
2107        return tolist_base(self, ptr, shape, strides, suboffsets, fmt);
2108
2109    lst = PyList_New(shape[0]);
2110    if (lst == NULL)
2111        return NULL;
2112
2113    for (i = 0; i < shape[0]; ptr+=strides[0], i++) {
2114        const char *xptr = ADJUST_PTR(ptr, suboffsets, 0);
2115        item = tolist_rec(self, xptr, ndim-1, shape+1,
2116                          strides+1, suboffsets ? suboffsets+1 : NULL,
2117                          fmt);
2118        if (item == NULL) {
2119            Py_DECREF(lst);
2120            return NULL;
2121        }
2122        PyList_SET_ITEM(lst, i, item);
2123    }
2124
2125    return lst;
2126}
2127
2128/* Return a list representation of the memoryview. Currently only buffers
2129   with native format strings are supported. */
2130/*[clinic input]
2131memoryview.tolist
2132
2133Return the data in the buffer as a list of elements.
2134[clinic start generated code]*/
2135
2136static PyObject *
2137memoryview_tolist_impl(PyMemoryViewObject *self)
2138/*[clinic end generated code: output=a6cda89214fd5a1b input=21e7d0c1860b211a]*/
2139{
2140    const Py_buffer *view = &self->view;
2141    const char *fmt;
2142
2143    CHECK_RELEASED(self);
2144
2145    fmt = adjust_fmt(view);
2146    if (fmt == NULL)
2147        return NULL;
2148    if (view->ndim == 0) {
2149        return unpack_single(self, view->buf, fmt);
2150    }
2151    else if (view->ndim == 1) {
2152        return tolist_base(self, view->buf, view->shape,
2153                           view->strides, view->suboffsets,
2154                           fmt);
2155    }
2156    else {
2157        return tolist_rec(self, view->buf, view->ndim, view->shape,
2158                          view->strides, view->suboffsets,
2159                          fmt);
2160    }
2161}
2162
2163/*[clinic input]
2164memoryview.tobytes
2165
2166    order: str(accept={str, NoneType}, c_default="NULL") = 'C'
2167
2168Return the data in the buffer as a byte string.
2169
2170Order can be {'C', 'F', 'A'}. When order is 'C' or 'F', the data of the
2171original array is converted to C or Fortran order. For contiguous views,
2172'A' returns an exact copy of the physical memory. In particular, in-memory
2173Fortran order is preserved. For non-contiguous views, the data is converted
2174to C first. order=None is the same as order='C'.
2175[clinic start generated code]*/
2176
2177static PyObject *
2178memoryview_tobytes_impl(PyMemoryViewObject *self, const char *order)
2179/*[clinic end generated code: output=1288b62560a32a23 input=0efa3ddaeda573a8]*/
2180{
2181    Py_buffer *src = VIEW_ADDR(self);
2182    char ord = 'C';
2183    PyObject *bytes;
2184
2185    CHECK_RELEASED(self);
2186
2187    if (order) {
2188        if (strcmp(order, "F") == 0) {
2189            ord = 'F';
2190        }
2191        else if (strcmp(order, "A") == 0) {
2192            ord = 'A';
2193        }
2194        else if (strcmp(order, "C") != 0) {
2195            PyErr_SetString(PyExc_ValueError,
2196                "order must be 'C', 'F' or 'A'");
2197            return NULL;
2198        }
2199    }
2200
2201    bytes = PyBytes_FromStringAndSize(NULL, src->len);
2202    if (bytes == NULL)
2203        return NULL;
2204
2205    if (PyBuffer_ToContiguous(PyBytes_AS_STRING(bytes), src, src->len, ord) < 0) {
2206        Py_DECREF(bytes);
2207        return NULL;
2208    }
2209
2210    return bytes;
2211}
2212
2213/*[clinic input]
2214memoryview.hex
2215
2216    sep: object = NULL
2217        An optional single character or byte to separate hex bytes.
2218    bytes_per_sep: int = 1
2219        How many bytes between separators.  Positive values count from the
2220        right, negative values count from the left.
2221
2222Return the data in the buffer as a str of hexadecimal numbers.
2223
2224Example:
2225>>> value = memoryview(b'\xb9\x01\xef')
2226>>> value.hex()
2227'b901ef'
2228>>> value.hex(':')
2229'b9:01:ef'
2230>>> value.hex(':', 2)
2231'b9:01ef'
2232>>> value.hex(':', -2)
2233'b901:ef'
2234[clinic start generated code]*/
2235
2236static PyObject *
2237memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep,
2238                    int bytes_per_sep)
2239/*[clinic end generated code: output=430ca760f94f3ca7 input=539f6a3a5fb56946]*/
2240{
2241    Py_buffer *src = VIEW_ADDR(self);
2242    PyObject *bytes;
2243    PyObject *ret;
2244
2245    CHECK_RELEASED(self);
2246
2247    if (MV_C_CONTIGUOUS(self->flags)) {
2248        return _Py_strhex_with_sep(src->buf, src->len, sep, bytes_per_sep);
2249    }
2250
2251    bytes = PyBytes_FromStringAndSize(NULL, src->len);
2252    if (bytes == NULL)
2253        return NULL;
2254
2255    if (PyBuffer_ToContiguous(PyBytes_AS_STRING(bytes), src, src->len, 'C') < 0) {
2256        Py_DECREF(bytes);
2257        return NULL;
2258    }
2259
2260    ret = _Py_strhex_with_sep(
2261            PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes),
2262            sep, bytes_per_sep);
2263    Py_DECREF(bytes);
2264
2265    return ret;
2266}
2267
2268static PyObject *
2269memory_repr(PyMemoryViewObject *self)
2270{
2271    if (self->flags & _Py_MEMORYVIEW_RELEASED)
2272        return PyUnicode_FromFormat("<released memory at %p>", self);
2273    else
2274        return PyUnicode_FromFormat("<memory at %p>", self);
2275}
2276
2277
2278/**************************************************************************/
2279/*                          Indexing and slicing                          */
2280/**************************************************************************/
2281
2282static char *
2283lookup_dimension(const Py_buffer *view, char *ptr, int dim, Py_ssize_t index)
2284{
2285    Py_ssize_t nitems; /* items in the given dimension */
2286
2287    assert(view->shape);
2288    assert(view->strides);
2289
2290    nitems = view->shape[dim];
2291    if (index < 0) {
2292        index += nitems;
2293    }
2294    if (index < 0 || index >= nitems) {
2295        PyErr_Format(PyExc_IndexError,
2296                     "index out of bounds on dimension %d", dim + 1);
2297        return NULL;
2298    }
2299
2300    ptr += view->strides[dim] * index;
2301
2302    ptr = ADJUST_PTR(ptr, view->suboffsets, dim);
2303
2304    return ptr;
2305}
2306
2307/* Get the pointer to the item at index. */
2308static char *
2309ptr_from_index(const Py_buffer *view, Py_ssize_t index)
2310{
2311    char *ptr = (char *)view->buf;
2312    return lookup_dimension(view, ptr, 0, index);
2313}
2314
2315/* Get the pointer to the item at tuple. */
2316static char *
2317ptr_from_tuple(const Py_buffer *view, PyObject *tup)
2318{
2319    char *ptr = (char *)view->buf;
2320    Py_ssize_t dim, nindices = PyTuple_GET_SIZE(tup);
2321
2322    if (nindices > view->ndim) {
2323        PyErr_Format(PyExc_TypeError,
2324                     "cannot index %zd-dimension view with %zd-element tuple",
2325                     view->ndim, nindices);
2326        return NULL;
2327    }
2328
2329    for (dim = 0; dim < nindices; dim++) {
2330        Py_ssize_t index;
2331        index = PyNumber_AsSsize_t(PyTuple_GET_ITEM(tup, dim),
2332                                   PyExc_IndexError);
2333        if (index == -1 && PyErr_Occurred())
2334            return NULL;
2335        ptr = lookup_dimension(view, ptr, (int)dim, index);
2336        if (ptr == NULL)
2337            return NULL;
2338    }
2339    return ptr;
2340}
2341
2342/* Return the item at index. In a one-dimensional view, this is an object
2343   with the type specified by view->format. Otherwise, the item is a sub-view.
2344   The function is used in memory_subscript() and memory_as_sequence. */
2345static PyObject *
2346memory_item(PyMemoryViewObject *self, Py_ssize_t index)
2347{
2348    Py_buffer *view = &(self->view);
2349    const char *fmt;
2350
2351    CHECK_RELEASED(self);
2352
2353    fmt = adjust_fmt(view);
2354    if (fmt == NULL)
2355        return NULL;
2356
2357    if (view->ndim == 0) {
2358        PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
2359        return NULL;
2360    }
2361    if (view->ndim == 1) {
2362        char *ptr = ptr_from_index(view, index);
2363        if (ptr == NULL)
2364            return NULL;
2365        return unpack_single(self, ptr, fmt);
2366    }
2367
2368    PyErr_SetString(PyExc_NotImplementedError,
2369        "multi-dimensional sub-views are not implemented");
2370    return NULL;
2371}
2372
2373/* Return the item at position *key* (a tuple of indices). */
2374static PyObject *
2375memory_item_multi(PyMemoryViewObject *self, PyObject *tup)
2376{
2377    Py_buffer *view = &(self->view);
2378    const char *fmt;
2379    Py_ssize_t nindices = PyTuple_GET_SIZE(tup);
2380    char *ptr;
2381
2382    CHECK_RELEASED(self);
2383
2384    fmt = adjust_fmt(view);
2385    if (fmt == NULL)
2386        return NULL;
2387
2388    if (nindices < view->ndim) {
2389        PyErr_SetString(PyExc_NotImplementedError,
2390                        "sub-views are not implemented");
2391        return NULL;
2392    }
2393    ptr = ptr_from_tuple(view, tup);
2394    if (ptr == NULL)
2395        return NULL;
2396    return unpack_single(self, ptr, fmt);
2397}
2398
2399static inline int
2400init_slice(Py_buffer *base, PyObject *key, int dim)
2401{
2402    Py_ssize_t start, stop, step, slicelength;
2403
2404    if (PySlice_Unpack(key, &start, &stop, &step) < 0) {
2405        return -1;
2406    }
2407    slicelength = PySlice_AdjustIndices(base->shape[dim], &start, &stop, step);
2408
2409
2410    if (base->suboffsets == NULL || dim == 0) {
2411    adjust_buf:
2412        base->buf = (char *)base->buf + base->strides[dim] * start;
2413    }
2414    else {
2415        Py_ssize_t n = dim-1;
2416        while (n >= 0 && base->suboffsets[n] < 0)
2417            n--;
2418        if (n < 0)
2419            goto adjust_buf; /* all suboffsets are negative */
2420        base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start;
2421    }
2422    base->shape[dim] = slicelength;
2423    base->strides[dim] = base->strides[dim] * step;
2424
2425    return 0;
2426}
2427
2428static int
2429is_multislice(PyObject *key)
2430{
2431    Py_ssize_t size, i;
2432
2433    if (!PyTuple_Check(key))
2434        return 0;
2435    size = PyTuple_GET_SIZE(key);
2436    if (size == 0)
2437        return 0;
2438
2439    for (i = 0; i < size; i++) {
2440        PyObject *x = PyTuple_GET_ITEM(key, i);
2441        if (!PySlice_Check(x))
2442            return 0;
2443    }
2444    return 1;
2445}
2446
2447static Py_ssize_t
2448is_multiindex(PyObject *key)
2449{
2450    Py_ssize_t size, i;
2451
2452    if (!PyTuple_Check(key))
2453        return 0;
2454    size = PyTuple_GET_SIZE(key);
2455    for (i = 0; i < size; i++) {
2456        PyObject *x = PyTuple_GET_ITEM(key, i);
2457        if (!_PyIndex_Check(x)) {
2458            return 0;
2459        }
2460    }
2461    return 1;
2462}
2463
2464/* mv[obj] returns an object holding the data for one element if obj
2465   fully indexes the memoryview or another memoryview object if it
2466   does not.
2467
2468   0-d memoryview objects can be referenced using mv[...] or mv[()]
2469   but not with anything else. */
2470static PyObject *
2471memory_subscript(PyMemoryViewObject *self, PyObject *key)
2472{
2473    Py_buffer *view;
2474    view = &(self->view);
2475
2476    CHECK_RELEASED(self);
2477
2478    if (view->ndim == 0) {
2479        if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) {
2480            const char *fmt = adjust_fmt(view);
2481            if (fmt == NULL)
2482                return NULL;
2483            return unpack_single(self, view->buf, fmt);
2484        }
2485        else if (key == Py_Ellipsis) {
2486            Py_INCREF(self);
2487            return (PyObject *)self;
2488        }
2489        else {
2490            PyErr_SetString(PyExc_TypeError,
2491                "invalid indexing of 0-dim memory");
2492            return NULL;
2493        }
2494    }
2495
2496    if (_PyIndex_Check(key)) {
2497        Py_ssize_t index;
2498        index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2499        if (index == -1 && PyErr_Occurred())
2500            return NULL;
2501        return memory_item(self, index);
2502    }
2503    else if (PySlice_Check(key)) {
2504        PyMemoryViewObject *sliced;
2505
2506        sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view);
2507        if (sliced == NULL)
2508            return NULL;
2509
2510        if (init_slice(&sliced->view, key, 0) < 0) {
2511            Py_DECREF(sliced);
2512            return NULL;
2513        }
2514        init_len(&sliced->view);
2515        init_flags(sliced);
2516
2517        return (PyObject *)sliced;
2518    }
2519    else if (is_multiindex(key)) {
2520        return memory_item_multi(self, key);
2521    }
2522    else if (is_multislice(key)) {
2523        PyErr_SetString(PyExc_NotImplementedError,
2524            "multi-dimensional slicing is not implemented");
2525        return NULL;
2526    }
2527
2528    PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2529    return NULL;
2530}
2531
2532static int
2533memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value)
2534{
2535    Py_buffer *view = &(self->view);
2536    Py_buffer src;
2537    const char *fmt;
2538    char *ptr;
2539
2540    CHECK_RELEASED_INT(self);
2541
2542    fmt = adjust_fmt(view);
2543    if (fmt == NULL)
2544        return -1;
2545
2546    if (view->readonly) {
2547        PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory");
2548        return -1;
2549    }
2550    if (value == NULL) {
2551        PyErr_SetString(PyExc_TypeError, "cannot delete memory");
2552        return -1;
2553    }
2554    if (view->ndim == 0) {
2555        if (key == Py_Ellipsis ||
2556            (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
2557            ptr = (char *)view->buf;
2558            return pack_single(self, ptr, value, fmt);
2559        }
2560        else {
2561            PyErr_SetString(PyExc_TypeError,
2562                "invalid indexing of 0-dim memory");
2563            return -1;
2564        }
2565    }
2566
2567    if (_PyIndex_Check(key)) {
2568        Py_ssize_t index;
2569        if (1 < view->ndim) {
2570            PyErr_SetString(PyExc_NotImplementedError,
2571                            "sub-views are not implemented");
2572            return -1;
2573        }
2574        index = PyNumber_AsSsize_t(key, PyExc_IndexError);
2575        if (index == -1 && PyErr_Occurred())
2576            return -1;
2577        ptr = ptr_from_index(view, index);
2578        if (ptr == NULL)
2579            return -1;
2580        return pack_single(self, ptr, value, fmt);
2581    }
2582    /* one-dimensional: fast path */
2583    if (PySlice_Check(key) && view->ndim == 1) {
2584        Py_buffer dest; /* sliced view */
2585        Py_ssize_t arrays[3];
2586        int ret = -1;
2587
2588        /* rvalue must be an exporter */
2589        if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0)
2590            return ret;
2591
2592        dest = *view;
2593        dest.shape = &arrays[0]; dest.shape[0] = view->shape[0];
2594        dest.strides = &arrays[1]; dest.strides[0] = view->strides[0];
2595        if (view->suboffsets) {
2596            dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0];
2597        }
2598
2599        if (init_slice(&dest, key, 0) < 0)
2600            goto end_block;
2601        dest.len = dest.shape[0] * dest.itemsize;
2602
2603        ret = copy_single(self, &dest, &src);
2604
2605    end_block:
2606        PyBuffer_Release(&src);
2607        return ret;
2608    }
2609    if (is_multiindex(key)) {
2610        char *ptr;
2611        if (PyTuple_GET_SIZE(key) < view->ndim) {
2612            PyErr_SetString(PyExc_NotImplementedError,
2613                            "sub-views are not implemented");
2614            return -1;
2615        }
2616        ptr = ptr_from_tuple(view, key);
2617        if (ptr == NULL)
2618            return -1;
2619        return pack_single(self, ptr, value, fmt);
2620    }
2621    if (PySlice_Check(key) || is_multislice(key)) {
2622        /* Call memory_subscript() to produce a sliced lvalue, then copy
2623           rvalue into lvalue. This is already implemented in _testbuffer.c. */
2624        PyErr_SetString(PyExc_NotImplementedError,
2625            "memoryview slice assignments are currently restricted "
2626            "to ndim = 1");
2627        return -1;
2628    }
2629
2630    PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key");
2631    return -1;
2632}
2633
2634static Py_ssize_t
2635memory_length(PyMemoryViewObject *self)
2636{
2637    CHECK_RELEASED_INT(self);
2638    return self->view.ndim == 0 ? 1 : self->view.shape[0];
2639}
2640
2641/* As mapping */
2642static PyMappingMethods memory_as_mapping = {
2643    (lenfunc)memory_length,               /* mp_length */
2644    (binaryfunc)memory_subscript,         /* mp_subscript */
2645    (objobjargproc)memory_ass_sub,        /* mp_ass_subscript */
2646};
2647
2648/* As sequence */
2649static PySequenceMethods memory_as_sequence = {
2650        (lenfunc)memory_length,           /* sq_length */
2651        0,                                /* sq_concat */
2652        0,                                /* sq_repeat */
2653        (ssizeargfunc)memory_item,        /* sq_item */
2654};
2655
2656
2657/**************************************************************************/
2658/*                             Comparisons                                */
2659/**************************************************************************/
2660
2661#define MV_COMPARE_EX -1       /* exception */
2662#define MV_COMPARE_NOT_IMPL -2 /* not implemented */
2663
2664/* Translate a StructError to "not equal". Preserve other exceptions. */
2665static int
2666fix_struct_error_int(void)
2667{
2668    assert(PyErr_Occurred());
2669    /* XXX Cannot get at StructError directly? */
2670    if (PyErr_ExceptionMatches(PyExc_ImportError) ||
2671        PyErr_ExceptionMatches(PyExc_MemoryError)) {
2672        return MV_COMPARE_EX;
2673    }
2674    /* StructError: invalid or unknown format -> not equal */
2675    PyErr_Clear();
2676    return 0;
2677}
2678
2679/* Unpack and compare single items of p and q using the struct module. */
2680static int
2681struct_unpack_cmp(const char *p, const char *q,
2682                  struct unpacker *unpack_p, struct unpacker *unpack_q)
2683{
2684    PyObject *v, *w;
2685    int ret;
2686
2687    /* At this point any exception from the struct module should not be
2688       StructError, since both formats have been accepted already. */
2689    v = struct_unpack_single(p, unpack_p);
2690    if (v == NULL)
2691        return MV_COMPARE_EX;
2692
2693    w = struct_unpack_single(q, unpack_q);
2694    if (w == NULL) {
2695        Py_DECREF(v);
2696        return MV_COMPARE_EX;
2697    }
2698
2699    /* MV_COMPARE_EX == -1: exceptions are preserved */
2700    ret = PyObject_RichCompareBool(v, w, Py_EQ);
2701    Py_DECREF(v);
2702    Py_DECREF(w);
2703
2704    return ret;
2705}
2706
2707/* Unpack and compare single items of p and q. If both p and q have the same
2708   single element native format, the comparison uses a fast path (gcc creates
2709   a jump table and converts memcpy into simple assignments on x86/x64).
2710
2711   Otherwise, the comparison is delegated to the struct module, which is
2712   30-60x slower. */
2713#define CMP_SINGLE(p, q, type) \
2714    do {                                 \
2715        type x;                          \
2716        type y;                          \
2717        memcpy((char *)&x, p, sizeof x); \
2718        memcpy((char *)&y, q, sizeof y); \
2719        equal = (x == y);                \
2720    } while (0)
2721
2722static inline int
2723unpack_cmp(const char *p, const char *q, char fmt,
2724           struct unpacker *unpack_p, struct unpacker *unpack_q)
2725{
2726    int equal;
2727
2728    switch (fmt) {
2729
2730    /* signed integers and fast path for 'B' */
2731    case 'B': return *((const unsigned char *)p) == *((const unsigned char *)q);
2732    case 'b': return *((const signed char *)p) == *((const signed char *)q);
2733    case 'h': CMP_SINGLE(p, q, short); return equal;
2734    case 'i': CMP_SINGLE(p, q, int); return equal;
2735    case 'l': CMP_SINGLE(p, q, long); return equal;
2736
2737    /* boolean */
2738    case '?': CMP_SINGLE(p, q, _Bool); return equal;
2739
2740    /* unsigned integers */
2741    case 'H': CMP_SINGLE(p, q, unsigned short); return equal;
2742    case 'I': CMP_SINGLE(p, q, unsigned int); return equal;
2743    case 'L': CMP_SINGLE(p, q, unsigned long); return equal;
2744
2745    /* native 64-bit */
2746    case 'q': CMP_SINGLE(p, q, long long); return equal;
2747    case 'Q': CMP_SINGLE(p, q, unsigned long long); return equal;
2748
2749    /* ssize_t and size_t */
2750    case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal;
2751    case 'N': CMP_SINGLE(p, q, size_t); return equal;
2752
2753    /* floats */
2754    /* XXX DBL_EPSILON? */
2755    case 'f': CMP_SINGLE(p, q, float); return equal;
2756    case 'd': CMP_SINGLE(p, q, double); return equal;
2757
2758    /* bytes object */
2759    case 'c': return *p == *q;
2760
2761    /* pointer */
2762    case 'P': CMP_SINGLE(p, q, void *); return equal;
2763
2764    /* use the struct module */
2765    case '_':
2766        assert(unpack_p);
2767        assert(unpack_q);
2768        return struct_unpack_cmp(p, q, unpack_p, unpack_q);
2769    }
2770
2771    /* NOT REACHED */
2772    PyErr_SetString(PyExc_RuntimeError,
2773        "memoryview: internal error in richcompare");
2774    return MV_COMPARE_EX;
2775}
2776
2777/* Base case for recursive array comparisons. Assumption: ndim == 1. */
2778static int
2779cmp_base(const char *p, const char *q, const Py_ssize_t *shape,
2780         const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2781         const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
2782         char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
2783{
2784    Py_ssize_t i;
2785    int equal;
2786
2787    for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2788        const char *xp = ADJUST_PTR(p, psuboffsets, 0);
2789        const char *xq = ADJUST_PTR(q, qsuboffsets, 0);
2790        equal = unpack_cmp(xp, xq, fmt, unpack_p, unpack_q);
2791        if (equal <= 0)
2792            return equal;
2793    }
2794
2795    return 1;
2796}
2797
2798/* Recursively compare two multi-dimensional arrays that have the same
2799   logical structure. Assumption: ndim >= 1. */
2800static int
2801cmp_rec(const char *p, const char *q,
2802        Py_ssize_t ndim, const Py_ssize_t *shape,
2803        const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets,
2804        const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets,
2805        char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q)
2806{
2807    Py_ssize_t i;
2808    int equal;
2809
2810    assert(ndim >= 1);
2811    assert(shape != NULL);
2812    assert(pstrides != NULL);
2813    assert(qstrides != NULL);
2814
2815    if (ndim == 1) {
2816        return cmp_base(p, q, shape,
2817                        pstrides, psuboffsets,
2818                        qstrides, qsuboffsets,
2819                        fmt, unpack_p, unpack_q);
2820    }
2821
2822    for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) {
2823        const char *xp = ADJUST_PTR(p, psuboffsets, 0);
2824        const char *xq = ADJUST_PTR(q, qsuboffsets, 0);
2825        equal = cmp_rec(xp, xq, ndim-1, shape+1,
2826                        pstrides+1, psuboffsets ? psuboffsets+1 : NULL,
2827                        qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL,
2828                        fmt, unpack_p, unpack_q);
2829        if (equal <= 0)
2830            return equal;
2831    }
2832
2833    return 1;
2834}
2835
2836static PyObject *
2837memory_richcompare(PyObject *v, PyObject *w, int op)
2838{
2839    PyObject *res;
2840    Py_buffer wbuf, *vv;
2841    Py_buffer *ww = NULL;
2842    struct unpacker *unpack_v = NULL;
2843    struct unpacker *unpack_w = NULL;
2844    char vfmt, wfmt;
2845    int equal = MV_COMPARE_NOT_IMPL;
2846
2847    if (op != Py_EQ && op != Py_NE)
2848        goto result; /* Py_NotImplemented */
2849
2850    assert(PyMemoryView_Check(v));
2851    if (BASE_INACCESSIBLE(v)) {
2852        equal = (v == w);
2853        goto result;
2854    }
2855    vv = VIEW_ADDR(v);
2856
2857    if (PyMemoryView_Check(w)) {
2858        if (BASE_INACCESSIBLE(w)) {
2859            equal = (v == w);
2860            goto result;
2861        }
2862        ww = VIEW_ADDR(w);
2863    }
2864    else {
2865        if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) {
2866            PyErr_Clear();
2867            goto result; /* Py_NotImplemented */
2868        }
2869        ww = &wbuf;
2870    }
2871
2872    if (!equiv_shape(vv, ww)) {
2873        PyErr_Clear();
2874        equal = 0;
2875        goto result;
2876    }
2877
2878    /* Use fast unpacking for identical primitive C type formats. */
2879    if (get_native_fmtchar(&vfmt, vv->format) < 0)
2880        vfmt = '_';
2881    if (get_native_fmtchar(&wfmt, ww->format) < 0)
2882        wfmt = '_';
2883    if (vfmt == '_' || wfmt == '_' || vfmt != wfmt) {
2884        /* Use struct module unpacking. NOTE: Even for equal format strings,
2885           memcmp() cannot be used for item comparison since it would give
2886           incorrect results in the case of NaNs or uninitialized padding
2887           bytes. */
2888        vfmt = '_';
2889        unpack_v = struct_get_unpacker(vv->format, vv->itemsize);
2890        if (unpack_v == NULL) {
2891            equal = fix_struct_error_int();
2892            goto result;
2893        }
2894        unpack_w = struct_get_unpacker(ww->format, ww->itemsize);
2895        if (unpack_w == NULL) {
2896            equal = fix_struct_error_int();
2897            goto result;
2898        }
2899    }
2900
2901    if (vv->ndim == 0) {
2902        equal = unpack_cmp(vv->buf, ww->buf,
2903                           vfmt, unpack_v, unpack_w);
2904    }
2905    else if (vv->ndim == 1) {
2906        equal = cmp_base(vv->buf, ww->buf, vv->shape,
2907                         vv->strides, vv->suboffsets,
2908                         ww->strides, ww->suboffsets,
2909                         vfmt, unpack_v, unpack_w);
2910    }
2911    else {
2912        equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape,
2913                        vv->strides, vv->suboffsets,
2914                        ww->strides, ww->suboffsets,
2915                        vfmt, unpack_v, unpack_w);
2916    }
2917
2918result:
2919    if (equal < 0) {
2920        if (equal == MV_COMPARE_NOT_IMPL)
2921            res = Py_NotImplemented;
2922        else /* exception */
2923            res = NULL;
2924    }
2925    else if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
2926        res = Py_True;
2927    else
2928        res = Py_False;
2929
2930    if (ww == &wbuf)
2931        PyBuffer_Release(ww);
2932
2933    unpacker_free(unpack_v);
2934    unpacker_free(unpack_w);
2935
2936    Py_XINCREF(res);
2937    return res;
2938}
2939
2940/**************************************************************************/
2941/*                                Hash                                    */
2942/**************************************************************************/
2943
2944static Py_hash_t
2945memory_hash(PyMemoryViewObject *self)
2946{
2947    if (self->hash == -1) {
2948        Py_buffer *view = &self->view;
2949        char *mem = view->buf;
2950        Py_ssize_t ret;
2951        char fmt;
2952
2953        CHECK_RELEASED_INT(self);
2954
2955        if (!view->readonly) {
2956            PyErr_SetString(PyExc_ValueError,
2957                "cannot hash writable memoryview object");
2958            return -1;
2959        }
2960        ret = get_native_fmtchar(&fmt, view->format);
2961        if (ret < 0 || !IS_BYTE_FORMAT(fmt)) {
2962            PyErr_SetString(PyExc_ValueError,
2963                "memoryview: hashing is restricted to formats 'B', 'b' or 'c'");
2964            return -1;
2965        }
2966        if (view->obj != NULL && PyObject_Hash(view->obj) == -1) {
2967            /* Keep the original error message */
2968            return -1;
2969        }
2970
2971        if (!MV_C_CONTIGUOUS(self->flags)) {
2972            mem = PyMem_Malloc(view->len);
2973            if (mem == NULL) {
2974                PyErr_NoMemory();
2975                return -1;
2976            }
2977            if (buffer_to_contiguous(mem, view, 'C') < 0) {
2978                PyMem_Free(mem);
2979                return -1;
2980            }
2981        }
2982
2983        /* Can't fail */
2984        self->hash = _Py_HashBytes(mem, view->len);
2985
2986        if (mem != view->buf)
2987            PyMem_Free(mem);
2988    }
2989
2990    return self->hash;
2991}
2992
2993
2994/**************************************************************************/
2995/*                                 getters                                */
2996/**************************************************************************/
2997
2998static PyObject *
2999_IntTupleFromSsizet(int len, Py_ssize_t *vals)
3000{
3001    int i;
3002    PyObject *o;
3003    PyObject *intTuple;
3004
3005    if (vals == NULL)
3006        return PyTuple_New(0);
3007
3008    intTuple = PyTuple_New(len);
3009    if (!intTuple)
3010        return NULL;
3011    for (i=0; i<len; i++) {
3012        o = PyLong_FromSsize_t(vals[i]);
3013        if (!o) {
3014            Py_DECREF(intTuple);
3015            return NULL;
3016        }
3017        PyTuple_SET_ITEM(intTuple, i, o);
3018    }
3019    return intTuple;
3020}
3021
3022static PyObject *
3023memory_obj_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
3024{
3025    Py_buffer *view = &self->view;
3026
3027    CHECK_RELEASED(self);
3028    if (view->obj == NULL) {
3029        Py_RETURN_NONE;
3030    }
3031    Py_INCREF(view->obj);
3032    return view->obj;
3033}
3034
3035static PyObject *
3036memory_nbytes_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
3037{
3038    CHECK_RELEASED(self);
3039    return PyLong_FromSsize_t(self->view.len);
3040}
3041
3042static PyObject *
3043memory_format_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
3044{
3045    CHECK_RELEASED(self);
3046    return PyUnicode_FromString(self->view.format);
3047}
3048
3049static PyObject *
3050memory_itemsize_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
3051{
3052    CHECK_RELEASED(self);
3053    return PyLong_FromSsize_t(self->view.itemsize);
3054}
3055
3056static PyObject *
3057memory_shape_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
3058{
3059    CHECK_RELEASED(self);
3060    return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
3061}
3062
3063static PyObject *
3064memory_strides_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
3065{
3066    CHECK_RELEASED(self);
3067    return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
3068}
3069
3070static PyObject *
3071memory_suboffsets_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
3072{
3073    CHECK_RELEASED(self);
3074    return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
3075}
3076
3077static PyObject *
3078memory_readonly_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
3079{
3080    CHECK_RELEASED(self);
3081    return PyBool_FromLong(self->view.readonly);
3082}
3083
3084static PyObject *
3085memory_ndim_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored))
3086{
3087    CHECK_RELEASED(self);
3088    return PyLong_FromLong(self->view.ndim);
3089}
3090
3091static PyObject *
3092memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy)
3093{
3094    CHECK_RELEASED(self);
3095    return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags));
3096}
3097
3098static PyObject *
3099memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy)
3100{
3101    CHECK_RELEASED(self);
3102    return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags));
3103}
3104
3105static PyObject *
3106memory_contiguous(PyMemoryViewObject *self, PyObject *dummy)
3107{
3108    CHECK_RELEASED(self);
3109    return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags));
3110}
3111
3112PyDoc_STRVAR(memory_obj_doc,
3113             "The underlying object of the memoryview.");
3114PyDoc_STRVAR(memory_nbytes_doc,
3115             "The amount of space in bytes that the array would use in\n"
3116             " a contiguous representation.");
3117PyDoc_STRVAR(memory_readonly_doc,
3118             "A bool indicating whether the memory is read only.");
3119PyDoc_STRVAR(memory_itemsize_doc,
3120             "The size in bytes of each element of the memoryview.");
3121PyDoc_STRVAR(memory_format_doc,
3122             "A string containing the format (in struct module style)\n"
3123             " for each element in the view.");
3124PyDoc_STRVAR(memory_ndim_doc,
3125             "An integer indicating how many dimensions of a multi-dimensional\n"
3126             " array the memory represents.");
3127PyDoc_STRVAR(memory_shape_doc,
3128             "A tuple of ndim integers giving the shape of the memory\n"
3129             " as an N-dimensional array.");
3130PyDoc_STRVAR(memory_strides_doc,
3131             "A tuple of ndim integers giving the size in bytes to access\n"
3132             " each element for each dimension of the array.");
3133PyDoc_STRVAR(memory_suboffsets_doc,
3134             "A tuple of integers used internally for PIL-style arrays.");
3135PyDoc_STRVAR(memory_c_contiguous_doc,
3136             "A bool indicating whether the memory is C contiguous.");
3137PyDoc_STRVAR(memory_f_contiguous_doc,
3138             "A bool indicating whether the memory is Fortran contiguous.");
3139PyDoc_STRVAR(memory_contiguous_doc,
3140             "A bool indicating whether the memory is contiguous.");
3141
3142
3143static PyGetSetDef memory_getsetlist[] = {
3144    {"obj",             (getter)memory_obj_get,        NULL, memory_obj_doc},
3145    {"nbytes",          (getter)memory_nbytes_get,     NULL, memory_nbytes_doc},
3146    {"readonly",        (getter)memory_readonly_get,   NULL, memory_readonly_doc},
3147    {"itemsize",        (getter)memory_itemsize_get,   NULL, memory_itemsize_doc},
3148    {"format",          (getter)memory_format_get,     NULL, memory_format_doc},
3149    {"ndim",            (getter)memory_ndim_get,       NULL, memory_ndim_doc},
3150    {"shape",           (getter)memory_shape_get,      NULL, memory_shape_doc},
3151    {"strides",         (getter)memory_strides_get,    NULL, memory_strides_doc},
3152    {"suboffsets",      (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc},
3153    {"c_contiguous",    (getter)memory_c_contiguous,   NULL, memory_c_contiguous_doc},
3154    {"f_contiguous",    (getter)memory_f_contiguous,   NULL, memory_f_contiguous_doc},
3155    {"contiguous",      (getter)memory_contiguous,     NULL, memory_contiguous_doc},
3156    {NULL, NULL, NULL, NULL},
3157};
3158
3159
3160static PyMethodDef memory_methods[] = {
3161    MEMORYVIEW_RELEASE_METHODDEF
3162    MEMORYVIEW_TOBYTES_METHODDEF
3163    MEMORYVIEW_HEX_METHODDEF
3164    MEMORYVIEW_TOLIST_METHODDEF
3165    MEMORYVIEW_CAST_METHODDEF
3166    MEMORYVIEW_TOREADONLY_METHODDEF
3167    {"__enter__",   memory_enter, METH_NOARGS, NULL},
3168    {"__exit__",    memory_exit, METH_VARARGS, NULL},
3169    {NULL,          NULL}
3170};
3171
3172/**************************************************************************/
3173/*                          Memoryview Iterator                           */
3174/**************************************************************************/
3175
3176PyTypeObject _PyMemoryIter_Type;
3177
3178typedef struct {
3179    PyObject_HEAD
3180    Py_ssize_t it_index;
3181    PyMemoryViewObject *it_seq; // Set to NULL when iterator is exhausted
3182    Py_ssize_t it_length;
3183    const char *it_fmt;
3184} memoryiterobject;
3185
3186static void
3187memoryiter_dealloc(memoryiterobject *it)
3188{
3189    _PyObject_GC_UNTRACK(it);
3190    Py_XDECREF(it->it_seq);
3191    PyObject_GC_Del(it);
3192}
3193
3194static int
3195memoryiter_traverse(memoryiterobject *it, visitproc visit, void *arg)
3196{
3197    Py_VISIT(it->it_seq);
3198    return 0;
3199}
3200
3201static PyObject *
3202memoryiter_next(memoryiterobject *it)
3203{
3204    PyMemoryViewObject *seq;
3205    seq = it->it_seq;
3206    if (seq == NULL) {
3207        return NULL;
3208    }
3209
3210    if (it->it_index < it->it_length) {
3211        CHECK_RELEASED(seq);
3212        Py_buffer *view = &(seq->view);
3213        char *ptr = (char *)seq->view.buf;
3214
3215        ptr += view->strides[0] * it->it_index++;
3216        ptr = ADJUST_PTR(ptr, view->suboffsets, 0);
3217        if (ptr == NULL) {
3218            return NULL;
3219        }
3220        return unpack_single(seq, ptr, it->it_fmt);
3221    }
3222
3223    it->it_seq = NULL;
3224    Py_DECREF(seq);
3225    return NULL;
3226}
3227
3228static PyObject *
3229memory_iter(PyObject *seq)
3230{
3231    if (!PyMemoryView_Check(seq)) {
3232        PyErr_BadInternalCall();
3233        return NULL;
3234    }
3235    PyMemoryViewObject *obj = (PyMemoryViewObject *)seq;
3236    int ndims = obj->view.ndim;
3237    if (ndims == 0) {
3238        PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
3239        return NULL;
3240    }
3241    if (ndims != 1) {
3242        PyErr_SetString(PyExc_NotImplementedError,
3243            "multi-dimensional sub-views are not implemented");
3244        return NULL;
3245    }
3246
3247    const char *fmt = adjust_fmt(&obj->view);
3248    if (fmt == NULL) {
3249        return NULL;
3250    }
3251
3252    memoryiterobject *it;
3253    it = PyObject_GC_New(memoryiterobject, &_PyMemoryIter_Type);
3254    if (it == NULL) {
3255        return NULL;
3256    }
3257    it->it_fmt = fmt;
3258    it->it_length = memory_length(obj);
3259    it->it_index = 0;
3260    Py_INCREF(seq);
3261    it->it_seq = obj;
3262    _PyObject_GC_TRACK(it);
3263    return (PyObject *)it;
3264}
3265
3266PyTypeObject _PyMemoryIter_Type = {
3267    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3268    .tp_name = "memory_iterator",
3269    .tp_basicsize = sizeof(memoryiterobject),
3270    // methods
3271    .tp_dealloc = (destructor)memoryiter_dealloc,
3272    .tp_getattro = PyObject_GenericGetAttr,
3273    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
3274    .tp_traverse = (traverseproc)memoryiter_traverse,
3275    .tp_iter = PyObject_SelfIter,
3276    .tp_iternext = (iternextfunc)memoryiter_next,
3277};
3278
3279PyTypeObject PyMemoryView_Type = {
3280    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3281    "memoryview",                             /* tp_name */
3282    offsetof(PyMemoryViewObject, ob_array),   /* tp_basicsize */
3283    sizeof(Py_ssize_t),                       /* tp_itemsize */
3284    (destructor)memory_dealloc,               /* tp_dealloc */
3285    0,                                        /* tp_vectorcall_offset */
3286    0,                                        /* tp_getattr */
3287    0,                                        /* tp_setattr */
3288    0,                                        /* tp_as_async */
3289    (reprfunc)memory_repr,                    /* tp_repr */
3290    0,                                        /* tp_as_number */
3291    &memory_as_sequence,                      /* tp_as_sequence */
3292    &memory_as_mapping,                       /* tp_as_mapping */
3293    (hashfunc)memory_hash,                    /* tp_hash */
3294    0,                                        /* tp_call */
3295    0,                                        /* tp_str */
3296    PyObject_GenericGetAttr,                  /* tp_getattro */
3297    0,                                        /* tp_setattro */
3298    &memory_as_buffer,                        /* tp_as_buffer */
3299    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
3300       Py_TPFLAGS_SEQUENCE,                   /* tp_flags */
3301    memoryview__doc__,                        /* tp_doc */
3302    (traverseproc)memory_traverse,            /* tp_traverse */
3303    (inquiry)memory_clear,                    /* tp_clear */
3304    memory_richcompare,                       /* tp_richcompare */
3305    offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */
3306    memory_iter,                              /* tp_iter */
3307    0,                                        /* tp_iternext */
3308    memory_methods,                           /* tp_methods */
3309    0,                                        /* tp_members */
3310    memory_getsetlist,                        /* tp_getset */
3311    0,                                        /* tp_base */
3312    0,                                        /* tp_dict */
3313    0,                                        /* tp_descr_get */
3314    0,                                        /* tp_descr_set */
3315    0,                                        /* tp_dictoffset */
3316    0,                                        /* tp_init */
3317    0,                                        /* tp_alloc */
3318    memoryview,                               /* tp_new */
3319};
3320