From 7b751f66c7feb71646f0c2540aca2e5e67cd5db5 Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Tue, 24 Mar 2009 22:25:21 +0000 Subject: Merge from the doc wiki --- doc/source/reference/arrays.interface.rst | 125 +++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 3 deletions(-) (limited to 'doc/source/reference/arrays.interface.rst') diff --git a/doc/source/reference/arrays.interface.rst b/doc/source/reference/arrays.interface.rst index 4afa3afc1..405e6da0a 100644 --- a/doc/source/reference/arrays.interface.rst +++ b/doc/source/reference/arrays.interface.rst @@ -11,16 +11,19 @@ The Array Interface .. warning:: This page describes the old, deprecated array interface. Everything still - works as described as of numpy 1.2 and on into the foreseeable future), but + works as described as of numpy 1.2 and on into the foreseeable future, but new development should target :pep:`3118` -- :cfunc:`The Revised Buffer Protocol `. :pep:`3118` was incorporated into Python 2.6 and 3.0, and is additionally - supported by Cython's numpy buffer support. (See the Cython numpy - tutorial.) Cython provides a way to write code that supports the buffer + supported by Cython__'s numpy buffer support. (See the `Cython numpy + tutorial`__.) Cython provides a way to write code that supports the buffer protocol with Python versions older than 2.6 because it has a backward-compatible implementation utilizing the legacy array interface described here. +__ http://cython.org/ +__ http://wiki.cython.org/tutorials/numpy + :version: 3 The array interface (sometimes called array protocol) was created in @@ -206,6 +209,33 @@ array using only one attribute lookup and a well-defined C-structure. must also not reallocate their memory if other objects are referencing them. +The PyArrayInterface structure is defined in ``numpy/ndarrayobject.h`` +as:: + + typedef struct { + int two; /* contains the integer 2 -- simple sanity check */ + int nd; /* number of dimensions */ + char typekind; /* kind in array --- character code of typestr */ + int itemsize; /* size of each element */ + int flags; /* flags indicating how the data should be interpreted */ + /* must set ARR_HAS_DESCR bit to validate descr */ + Py_intptr_t *shape; /* A length-nd array of shape information */ + Py_intptr_t *strides; /* A length-nd array of stride information */ + void *data; /* A pointer to the first element of the array */ + PyObject *descr; /* NULL or data-description (same as descr key + of __array_interface__) -- must set ARR_HAS_DESCR + flag or this will be ignored. */ + } PyArrayInterface; + +The flags member may consist of 5 bits showing how the data should be +interpreted and one bit showing how the Interface should be +interpreted. The data-bits are :const:`CONTIGUOUS` (0x1), +:const:`FORTRAN` (0x2), :const:`ALIGNED` (0x100), :const:`NOTSWAPPED` +(0x200), and :const:`WRITEABLE` (0x400). A final flag +:const:`ARR_HAS_DESCR` (0x800) indicates whether or not this structure +has the arrdescr field. The field should not be accessed unless this +flag is present. + .. admonition:: New since June 16, 2006: In the past most implementations used the "desc" member of the @@ -215,3 +245,92 @@ array using only one attribute lookup and a well-defined C-structure. This is now an explicit part of the interface. Be sure to own a reference to the object when the :ctype:`PyCObject` is created using :ctype:`PyCObject_FromVoidPtrAndDesc`. + + +Type description examples +========================= + +For clarity it is useful to provide some examples of the type +description and corresponding :data:`__array_interface__` 'descr' +entries. Thanks to Scott Gilbert for these examples: + +In every case, the 'descr' key is optional, but of course provides +more information which may be important for various applications:: + + * Float data + typestr == '>f4' + descr == [('','>f4')] + + * Complex double + typestr == '>c8' + descr == [('real','>f4'), ('imag','>f4')] + + * RGB Pixel data + typestr == '|V3' + descr == [('r','|u1'), ('g','|u1'), ('b','|u1')] + + * Mixed endian (weird but could happen). + typestr == '|V8' (or '>u8') + descr == [('big','>i4'), ('little','i4'), ('data','>f8',(16,4))] + + * Padded structure + struct { + int ival; + double dval; + } + typestr == '|V16' + descr == [('ival','>i4'),('','|V4'),('dval','>f8')] + +It should be clear that any record type could be described using this interface. + +Differences with Array interface (Version 2) +============================================ + +The version 2 interface was very similar. The differences were +largely asthetic. In particular: + +1. The PyArrayInterface structure had no descr member at the end + (and therefore no flag ARR_HAS_DESCR) + +2. The desc member of the PyCObject returned from __array_struct__ was + not specified. Usually, it was the object exposing the array (so + that a reference to it could be kept and destroyed when the + C-object was destroyed). Now it must be a tuple whose first + element is a string with "PyArrayInterface Version #" and whose + second element is the object exposing the array. + +3. The tuple returned from __array_interface__['data'] used to be a + hex-string (now it is an integer or a long integer). + +4. There was no __array_interface__ attribute instead all of the keys + (except for version) in the __array_interface__ dictionary were + their own attribute: Thus to obtain the Python-side information you + had to access separately the attributes: + + * __array_data__ + * __array_shape__ + * __array_strides__ + * __array_typestr__ + * __array_descr__ + * __array_offset__ + * __array_mask__ -- cgit v1.2.1