Discussion:
[Numpy-discussion] Ensuring one can operate on array-like argument in place
Pavlyk, Oleksandr
2016-11-12 17:00:07 UTC
Permalink
Hi,

In my Cython code a function processes it argument x as follows:

x_arr = PyArray_CheckFromAny(
x, NULL, 0, 0,
cnp.NPY_ELEMENTSTRIDES | cnp.NPY_ENSUREARRAY | cnp.NPY_NOTSWAPPED, NULL)

if x_arr is not x:
in_place = 1 # a copy was made, so we can work in place.

The logic is of the last line turns out to be incorrect, because the input x can be a class with an array interface:

class FakeArray(object):
def __init__(self, data):
self._data = data
self.__array_interface__ = data.__array_interface__

Feeding my function FakeArray(xx), x_arr will point into the content of xx, resulting in unwarranted content
overwrite of xx.

I am trying to replace that condition with

if x_arr is not x and cnp.PyArray_Check(x):
# a copy was made, so we can work in place.
in_place = 1 if cnp.PyArray_CHKFLAGS(x_arr, cnp.NPY_WRITEABLE) else 0

I am wondering if I perhaps overlooked some case.

Thank you,
Sasha
Pauli Virtanen
2016-11-13 14:29:06 UTC
Permalink
Sat, 12 Nov 2016 17:00:07 +0000, Pavlyk, Oleksandr kirjoitti:
[clip]
Post by Pavlyk, Oleksandr
in_place = 1 # a copy was made, so we can work in place.
The logic is of the last line turns out to be incorrect, because the
input x can be a class with an array interface.
Please see:

https://github.com/scipy/scipy/blob/master/scipy/linalg/misc.py#L169

This probably can be translated to equivalent Numpy C API calls.
Chris Barker
2016-11-14 23:20:53 UTC
Permalink
I tend to use ndarray.copy() in python code -- no reason you couldn't do
the same in Cython.

If you want to take any array-like object that may not have a copy()
method, you could call asanyarray() first:

-CHB





On Sat, Nov 12, 2016 at 9:00 AM, Pavlyk, Oleksandr <
Post by Pavlyk, Oleksandr
Hi,
x_arr = PyArray_CheckFromAny(
x, NULL, 0, 0,
cnp.NPY_ELEMENTSTRIDES | cnp.NPY_ENSUREARRAY |
cnp.NPY_NOTSWAPPED, NULL)
in_place = 1 # a copy was made, so we can work in place.
The logic is of the last line turns out to be incorrect, because the input
self._data = data
self.__array_interface__ = data.__array_interface__
Feeding my function FakeArray(xx), x_arr will point into the content of
xx, resulting in unwarranted content
overwrite of xx.
I am trying to replace that condition with
# a copy was made, so we can work in place.
in_place = 1 if cnp.PyArray_CHKFLAGS(x_arr, cnp.NPY_WRITEABLE) else 0
I am wondering if I perhaps overlooked some case.
Thank you,
Sasha
_______________________________________________
NumPy-Discussion mailing list
https://mail.scipy.org/mailman/listinfo/numpy-discussion
--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

***@noaa.gov
Continue reading on narkive:
Loading...