{
  "__type": "IngestedDoc",
  "__tag": 4010,
  "_content": {},
  "_ordered_sections": [],
  "item_file": null,
  "item_line": null,
  "item_type": null,
  "aliases": [],
  "example_section_data": {
    "__type": "Section",
    "__tag": 4015,
    "children": [],
    "title": [],
    "level": 0,
    "target": null
  },
  "see_also": [],
  "signature": null,
  "references": null,
  "qa": "reference:arrays.interface",
  "arbitrary": [
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "note",
          "base_type": "note",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "note "
                }
              ]
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "This page describes the NumPy-specific API for accessing the contents of a NumPy array from other C extensions. "
                },
                {
                  "__type": "Link",
                  "__tag": 4049,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Pep 3118"
                    }
                  ],
                  "url": "https://peps.python.org/pep-3118/",
                  "title": ""
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " -- "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "The Revised Buffer Protocol <PyObject_GetBuffer>"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " introduces similar, standardized API for any extension module to use. "
                },
                {
                  "__type": "InlineRole",
                  "__tag": 4003,
                  "value": "Cython__",
                  "domain": null,
                  "role": null,
                  "inventory": null
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "'s buffer array support uses the "
                },
                {
                  "__type": "Link",
                  "__tag": 4049,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Pep 3118"
                    }
                  ],
                  "url": "https://peps.python.org/pep-3118/",
                  "title": ""
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " API; see the "
                },
                {
                  "__type": "InlineRole",
                  "__tag": 4003,
                  "value": "Cython NumPy tutorial",
                  "domain": null,
                  "role": null,
                  "inventory": null
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "."
                }
              ]
            }
          ]
        },
        {
          "__type": "Unimplemented",
          "__tag": 4018,
          "placeholder": "target",
          "value": "__ https://cython.org/"
        },
        {
          "__type": "Unimplemented",
          "__tag": 4018,
          "placeholder": "target",
          "value": "__ https://github.com/cython/cython/wiki/tutorials-numpy"
        },
        {
          "__type": "FieldList",
          "__tag": 4035,
          "children": [
            {
              "__type": "FieldListItem",
              "__tag": 4036,
              "name": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "version"
                }
              ],
              "body": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "3"
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The array interface (sometimes called array protocol) was created in 2005 as a means for array-like Python objects to reuse each other's data buffers intelligently whenever possible. The homogeneous N-dimensional array interface is a default mechanism for objects to share N-dimensional array memory and information.  The interface consists of a Python-side and a C-side using two attributes.  Objects wishing to be considered an N-dimensional array in application code should support at least one of these attributes.  Objects wishing to support an N-dimensional array in application code should look for at least one of these attributes and use the information provided appropriately."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This interface describes homogeneous arrays in the sense that each item of the array has the same \"type\".  This type can be very simple or it can be a quite arbitrary and complicated C-like structure."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "There are two ways to use the interface: A Python side and a C-side. Both are separate attributes."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "The array interface protocol"
        }
      ],
      "level": 0,
      "target": "arrays.interface"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This approach to the interface consists of the object having an "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "~object.__array_interface__",
              "domain": null,
              "role": "data",
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " attribute."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Python side"
        }
      ],
      "level": 1,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This approach to the array interface allows for faster access to an array using only one attribute lookup and a well-defined C-structure."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "PyArrayInterface"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " structure is defined in "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "numpy/ndarrayobject.h"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " as    "
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "typedef struct {\n  int two;              /* contains the integer 2 -- simple sanity check */\n  int nd;               /* number of dimensions */\n  char typekind;        /* kind in array --- character code of typestr */\n  int itemsize;         /* size of each element */\n  int flags;            /* flags indicating how the data should be interpreted */\n                        /*   must set ARR_HAS_DESCR bit to validate descr */\n  Py_ssize_t *shape;    /* A length-nd array of shape information */\n  Py_ssize_t *strides;  /* A length-nd array of stride information */\n  void *data;           /* A pointer to the first element of the array */\n  PyObject *descr;      /* NULL or data-description (same as descr key\n                                of __array_interface__) -- must set ARR_HAS_DESCR\n                                flag or this will be ignored. */\n} PyArrayInterface;",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "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 "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "NPY_ARRAY_C_CONTIGUOUS"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " (0x1), "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "NPY_ARRAY_F_CONTIGUOUS"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " (0x2), "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "NPY_ARRAY_ALIGNED"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " (0x100), "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "NPY_ARRAY_NOTSWAPPED"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " (0x200), and "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "NPY_ARRAY_WRITEABLE"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " (0x400).  A final flag "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "NPY_ARR_HAS_DESCR"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " (0x800) indicates whether or not this structure has the arrdescr field.  The field should not be accessed unless this flag is present."
            }
          ]
        },
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "admonition",
          "base_type": "note",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "New since June 16, 2006:"
                }
              ]
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "In the past most implementations used the "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "desc"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " member of the "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "PyCObject"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " (now "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "PyCapsule"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": ") itself (do not confuse this with the \"descr\" member of the "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "PyArrayInterface"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " structure above --- they are two separate things) to hold the pointer to the object exposing the interface. This is now an explicit part of the interface.  Be sure to take a reference to the object and call "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "PyCapsule_SetContext"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " before returning the "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "PyCapsule"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": ", and configure a destructor to decref this reference."
                }
              ]
            }
          ]
        },
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "note",
          "base_type": "note",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "note "
                }
              ]
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "InlineRole",
                  "__tag": 4003,
                  "value": "~object.__array_struct__",
                  "domain": null,
                  "role": "obj",
                  "inventory": null
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " is considered legacy and should not be used for new code. Use the "
                },
                {
                  "__type": "CrossRef",
                  "__tag": 4002,
                  "value": "buffer protocol",
                  "reference": {
                    "__type": "LocalRef",
                    "__tag": 4022,
                    "kind": "docs",
                    "path": "python:c-api/buffer"
                  },
                  "kind": "docs"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " or the DLPack protocol "
                },
                {
                  "__type": "CrossRef",
                  "__tag": 4002,
                  "value": "numpy.from_dlpack",
                  "reference": {
                    "__type": "RefInfo",
                    "__tag": 4000,
                    "module": "numpy",
                    "version": "*",
                    "kind": "api",
                    "path": "numpy:from_dlpack"
                  },
                  "kind": "module"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " instead."
                }
              ]
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "C-struct access"
        }
      ],
      "level": 1,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "For clarity it is useful to provide some examples of the type description and corresponding "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "~object.__array_interface__",
              "domain": null,
              "role": "data",
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " 'descr' entries.  Thanks to Scott Gilbert for these examples:"
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In every case, the 'descr' key is optional, but of course provides more information which may be important for various applications       "
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "* Float data\n    typestr == '>f4'\n    descr == [('','>f4')]\n\n* Complex double\n    typestr == '>c8'\n    descr == [('real','>f4'), ('imag','>f4')]\n\n* RGB Pixel data\n    typestr == '|V3'\n    descr == [('r','|u1'), ('g','|u1'), ('b','|u1')]\n\n* Mixed endian (weird but could happen).\n    typestr == '|V8' (or '>u8')\n    descr == [('big','>i4'), ('little','<i4')]\n\n* Nested structure\n    struct {\n        int ival;\n        struct {\n            unsigned short sval;\n            unsigned char bval;\n            unsigned char cval;\n        } sub;\n    }\n    typestr == '|V8' (or '<u8' if you want)\n    descr == [('ival','<i4'), ('sub', [('sval','<u2'), ('bval','|u1'), ('cval','|u1') ]) ]\n\n* Nested array\n    struct {\n        int ival;\n        double data[16*4];\n    }\n    typestr == '|V516'\n    descr == [('ival','>i4'), ('data','>f8',(16,4))]\n\n* Padded structure\n    struct {\n        int ival;\n        double dval;\n    }\n    typestr == '|V16'\n    descr == [('ival','>i4'),('','|V4'),('dval','>f8')]",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "It should be clear that any structured type could be described using this interface."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Type description examples"
        }
      ],
      "level": 1,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The version 2 interface was very similar.  The differences were largely aesthetic.  In particular:"
            }
          ]
        },
        {
          "__type": "BulletList",
          "__tag": 4053,
          "ordered": true,
          "start": 1,
          "children": [
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The PyArrayInterface structure had no descr member at the end    (and therefore no flag ARR_HAS_DESCR)"
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "context"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " member of the "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "PyCapsule"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " (formally the "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "desc"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "    member of the "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "PyCObject"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": ") returned from "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "__array_struct__"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " 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). It is now an explicit requirement that this field    be used in some way to hold a reference to the owning object."
                    }
                  ]
                },
                {
                  "__type": "Admonition",
                  "__tag": 4056,
                  "kind": "note",
                  "base_type": "note",
                  "children": [
                    {
                      "__type": "AdmonitionTitle",
                      "__tag": 4055,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "note "
                        }
                      ]
                    },
                    {
                      "__type": "Paragraph",
                      "__tag": 4045,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "Until August 2020, this said:"
                        }
                      ]
                    },
                    {
                      "__type": "Blockquote",
                      "__tag": 4059,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "Text",
                              "__tag": 4046,
                              "value": "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."
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "Blockquote",
                      "__tag": 4059,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "Text",
                              "__tag": 4046,
                              "value": "This design was retracted almost immediately after it was proposed, in    <https://mail.python.org/pipermail/numpy-discussion/2006-June/020995.html>.    Despite 14 years of documentation to the contrary, at no point was it    valid to assume that "
                            },
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "__array_interface__"
                            },
                            {
                              "__type": "Text",
                              "__tag": 4046,
                              "value": " capsules held this tuple    content."
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The tuple returned from "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "__array_interface__['data']"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " used to be a    hex-string (now it is an integer or a long integer)."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "There was no "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "__array_interface__"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " attribute instead all of the keys    (except for version) in the "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "__array_interface__"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " dictionary were    their own attribute: Thus to obtain the Python-side information you    had to access separately the attributes:"
                    }
                  ]
                },
                {
                  "__type": "BulletList",
                  "__tag": 4053,
                  "ordered": false,
                  "start": 1,
                  "children": [
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "__array_data__"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "__array_shape__"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "__array_strides__"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "__array_typestr__"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "__array_descr__"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "__array_offset__"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "InlineCode",
                              "__tag": 4051,
                              "value": "__array_mask__"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Differences with array interface (version 2)"
        }
      ],
      "level": 1,
      "target": null
    }
  ],
  "local_refs": []
}