I did some searching for typical Cython and C code which accesses numpy arrays, and added a section to the NEP describing how they behave in the current implementation. Cython code which uses either straight Python access or the buffer protocol is fine (after a bugfix in numpy, it wasn't failing currently as it should in the pep3118 case). C code which follows the recommended practice of using PyArray_FromAny or one of the related macros is also fine, because these functions have been made to fail on NA-masked arrays unless the flag NPY_ARRAY_ALLOWNA is provided.<div>
<br></div><div>In general, code which follows the recommended numpy practices will raise exceptions when encountering NA-masked arrays. This means programmers don't have to worry about the NA unless they want to support it. Having things go through PyArray_FromAny also provides a place where lazy evaluation arrays could be evaluated, and other similar potential future extensions can use to provide compatibility.<br>
<div><br></div><div>Here's the section I added to the NEP:</div><div><br></div><div><div>Interaction With Pre-existing C API Usage</div><div>=========================================</div><div><br></div><div>Making sure existing code using the C API, whether it's written in C, C++,</div>
<div>or Cython, does something reasonable is an important goal of this implementation.</div><div>The general strategy is to make existing code which does not explicitly</div><div>tell numpy it supports NA masks fail with an exception saying so. There are</div>
<div>a few different access patterns people use to get ahold of the numpy array data,</div><div>here we examine a few of them to see what numpy can do. These examples are</div><div>found from doing google searches of numpy C API array access.</div>
<div><br></div><div>Numpy Documentation - How to extend NumPy</div><div>-----------------------------------------</div><div><br></div><div><a href="http://docs.scipy.org/doc/numpy/user/c-info.how-to-extend.html#dealing-with-array-objects">http://docs.scipy.org/doc/numpy/user/c-info.how-to-extend.html#dealing-with-array-objects</a></div>
<div><br></div><div>This page has a section "Dealing with array objects" which has some advice for how</div><div>to access numpy arrays from C. When accepting arrays, the first step it suggests is</div><div>to use PyArray_FromAny or a macro built on that function, so code following this</div>
<div>advice will properly fail when given an NA-masked array it doesn't know how to handle.</div><div><br></div><div>The way this is handled is that PyArray_FromAny requires a special flag, NPY_ARRAY_ALLOWNA,</div><div>
before it will allow NA-masked arrays to flow through.</div><div><br></div><div><a href="http://docs.scipy.org/doc/numpy/reference/c-api.array.html#NPY_ARRAY_ALLOWNA">http://docs.scipy.org/doc/numpy/reference/c-api.array.html#NPY_ARRAY_ALLOWNA</a></div>
<div><br></div><div>Code which does not follow this advice, and instead just calls PyArray_Check() to verify</div><div>its an ndarray and checks some flags, will silently produce incorrect results. This style</div><div>of code does not provide any opportunity for numpy to say "hey, this array is special",</div>
<div>so also is not compatible with future ideas of lazy evaluation, derived dtypes, etc.</div><div><br></div><div>Tutorial From Cython Website</div><div>----------------------------</div><div><br></div><div><a href="http://docs.cython.org/src/tutorial/numpy.html">http://docs.cython.org/src/tutorial/numpy.html</a></div>
<div><br></div><div>This tutorial gives a convolution example, and all the examples fail with</div><div>Python exceptions when given inputs that contain NA values.</div><div><br></div><div>Before any Cython type annotation is introduced, the code functions just</div>
<div>as equivalent Python would in the interpreter.</div><div><br></div><div>When the type information is introduced, it is done via numpy.pxd which</div><div>defines a mapping between an ndarray declaration and PyArrayObject \*.</div>
<div>Under the hood, this maps to __Pyx_ArgTypeTest, which does a direct</div><div>comparison of Py_TYPE(obj) against the PyTypeObject for the ndarray.</div><div><br></div><div>Then the code does some dtype comparisons, and uses regular python indexing</div>
<div>to access the array elements. This python indexing still goes through the</div><div>Python API, so the NA handling and error checking in numpy still can work</div><div>like normal and fail if the inputs have NAs which cannot fit in the output</div>
<div>array. In this case it fails when trying to convert the NA into an integer</div><div>to set in in the output.</div><div><br></div><div>The next version of the code introduces more efficient indexing. This</div><div>operates based on Python's buffer protocol. This causes Cython to call</div>
<div>__Pyx_GetBufferAndValidate, which calls __Pyx_GetBuffer, which calls</div><div>PyObject_GetBuffer. This call gives numpy the opportunity to raise an</div><div>exception if the inputs are arrays with NA-masks, something not supported</div>
<div>by the Python buffer protocol.</div><div><br></div><div>Numerical Python - JPL website</div><div>------------------------------</div><div><br></div><div><a href="http://dsnra.jpl.nasa.gov/software/Python/numpydoc/numpy-13.html">http://dsnra.jpl.nasa.gov/software/Python/numpydoc/numpy-13.html</a></div>
<div><br></div><div>This document is from 2001, so does not reflect recent numpy, but it is the</div><div>second hit when searching for "numpy c api example" on google.</div><div><br></div><div>There first example, heading "A simple example", is in fact already invalid for</div>
<div>recent numpy even without the NA support. In particular, if the data is misaligned</div><div>or in a different byteorder, it may crash or produce incorrect results.</div><div><br></div><div>The next thing the document does is introduce PyArray_ContiguousFromObject, which</div>
<div>gives numpy an opportunity to raise an exception when NA-masked arrays are used,</div><div>so the later code will raise exceptions as desired.</div></div><div><br></div></div>