Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

calling multiple times numpy.ctypeslib.as_array(pointer, shape) always uses the same shape (Trac #2079) #2671

Closed
numpy-gitbot opened this issue Oct 19, 2012 · 3 comments

Comments

@numpy-gitbot
Copy link

Original ticket http://projects.scipy.org/numpy/ticket/2079 on 2012-03-13 by trac user pieleric, assigned to unknown.

The latest version of numpy supports numpy.ctypeslib.as_array() for a ctypes.POINTER. However, when using numpy.ctypeslib.as_array() on a pointer multiple times in a row with different shapes, it's always the shape of the first call which is used.

Example:

import ctypes
import numpy
>>> buffer = ctypes.pointer((ctypes.c_uint16 * 100)())
>>> p = ctypes.cast(buffer, ctypes.POINTER(ctypes.c_uint16))
>>> a = numpy.ctypeslib.as_array(p, shape=(100,))
>>> a.shape
(100,)
>>> b = numpy.ctypeslib.as_array(p, shape=(10,10))
>>> b.shape
(100,)

We would expect b.shape == (10,10) .

The bug is in as_array() and prep_pointer(). They are too much a copy-paste of the case of an ndarray: only create the array_interface if it is not yet there. For an ndarray this works fine as the array_interface is saved on the type. For a pointer, it should be updated every time.

So, I propose something like this:

    def prep_pointer(pointer_obj, shape):
        contents = pointer_obj.contents
        dtype = _dtype(type(contents))

        inter = {'version': 3,
                 'typestr': dtype.str,
                 'data': (ct.addressof(contents), False),
                 'shape': shape}

        pointer_obj.__array_interface__ = inter

    def as_array(obj, shape=None):
        if hasattr(obj, 'contents'):
            prep_pointer(obj, shape)
        else:
            tp = type(obj)
            try: tp.__array_interface__
            except AttributeError: prep_array(tp)
        return array(obj, copy=False)

BTW, the description of as_array() should be updated to mention the "shape" parameter instead of the "size" parameter.

@sdy7
Copy link

sdy7 commented Mar 22, 2013

I would fix this if I knew how to.
Can I vote for this bug?

cheers
Soren

@njsmith
Copy link
Member

njsmith commented Mar 22, 2013

I suppose you can, but votes don't write code so it won't directly affect
much :-). For more visible results, you could figure out how to fix it, or
try to find a friend interested in spending some time on it - perhaps on
the mailing list.
On 22 Mar 2013 15:48, "sdy7" notifications@github.com wrote:

I would fix this if I knew how to.
Can I vote for this bug?

cheers
Soren


Reply to this email directly or view it on GitHubhttps://github.com//issues/2671#issuecomment-15304274
.

@tynn
Copy link
Contributor

tynn commented Jul 30, 2015

Is it still of interest to fix this?

I had a look at it and found doing

try: pointer_obj.__array_interface__['shape'] = shape
except AttributeError: pass
except TypeError: pass
else: return

in prep_pointer would also fix this without rewriting the complete code.

This works if pointer_obj.__array_interface__ is a dictionary or something accepting keys. If the TypeError was raised, a return could pass the error handling to np.array like it would have with the original code, while a pass also ensures validity at that point.

eric-wieser added a commit to eric-wieser/numpy that referenced this issue May 26, 2018
Everything behaves a lot better if we let the array constructor handle it, which will use the ctypes PEP3118 support.

Bugs this fixes:

* Stale state being attached to pointer objects (fixes numpygh-2671, closes numpygh-6214)
* Weird failure modes on structured arrays (fixes-10978)
* A regression in numpygh-10882 (fixes numpygh-10968)
uds5501 pushed a commit to uds5501/numpy that referenced this issue Jun 28, 2018
Everything behaves a lot better if we let the array constructor handle it, which will use the ctypes PEP3118 support.

Bugs this fixes:

* Stale state being attached to pointer objects (fixes numpygh-2671, closes numpygh-6214)
* Weird failure modes on structured arrays (fixes-10978)
* A regression in numpygh-10882 (fixes numpygh-10968)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants