From 729c3e930cb375c14a8353a5ea29b20f7b2d1cb0 Mon Sep 17 00:00:00 2001 From: tynn Date: Sat, 1 Jul 2017 20:33:45 +0200 Subject: [PATCH 1/2] TST: Add tests for numpy.ctypeslib.as_array --- numpy/tests/test_ctypeslib.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/numpy/tests/test_ctypeslib.py b/numpy/tests/test_ctypeslib.py index 0f0d6dbc4891..508a348c145a 100644 --- a/numpy/tests/test_ctypeslib.py +++ b/numpy/tests/test_ctypeslib.py @@ -4,9 +4,9 @@ import pytest import numpy as np -from numpy.ctypeslib import ndpointer, load_library +from numpy.ctypeslib import ndpointer, load_library, as_array from numpy.distutils.misc_util import get_shared_lib_extension -from numpy.testing import assert_, assert_raises +from numpy.testing import assert_, assert_array_equal, assert_raises try: cdll = None @@ -113,3 +113,25 @@ def test_cache(self): a1 = ndpointer(dtype=np.float64) a2 = ndpointer(dtype=np.float64) assert_(a1 == a2) + +class TestAsArray(object): + @pytest.mark.skipif(not _HAS_CTYPE, + reason="ctypes not available on this python installation") + def test_array(self): + from ctypes import c_int + at = c_int * 2 + a = as_array(at(1, 2)) + assert_(a.shape == (2,)) + assert_array_equal(a, np.array([1, 2])) + a = as_array((at * 3)(at(1, 2), at(3, 4), at(5, 6))) + assert_(a.shape == (3, 2)) + assert_array_equal(a, np.array([[1, 2], [3, 4], [5, 6]])) + + @pytest.mark.skipif(not _HAS_CTYPE, + reason="ctypes not available on this python installation") + def test_pointer(self): + from ctypes import c_int, cast, POINTER + p = cast((c_int * 10)(*range(10)), POINTER(c_int)) + a = as_array(p, (10,)) + assert_(a.shape == (10,)) + assert_array_equal(a, np.array(range(10))) From 06e6b1a59d9e3bd804854e4e68722d16890059aa Mon Sep 17 00:00:00 2001 From: tynn Date: Fri, 30 Mar 2018 09:49:27 +0200 Subject: [PATCH 2/2] BUG: Fix shape update in numpy.ctypeslib.as_array(pointer, shape) --- numpy/ctypeslib.py | 16 +++++++++++----- numpy/tests/test_ctypeslib.py | 4 ++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/numpy/ctypeslib.py b/numpy/ctypeslib.py index b8457c78b2c5..6be3d8e7ba6a 100644 --- a/numpy/ctypeslib.py +++ b/numpy/ctypeslib.py @@ -402,9 +402,15 @@ def prep_pointer(pointer_obj, shape): attach an __array_interface__ property to it if it does not yet have one. """ - try: pointer_obj.__array_interface__ - except AttributeError: pass - else: return + try: + inter = pointer_obj.__array_interface__ + except AttributeError: + pass + else: + # update shape if possible + try: inter['shape'] = shape + except TypeError: pass + return contents = pointer_obj.contents dtype = _dtype(type(contents)) @@ -423,8 +429,8 @@ def as_array(obj, shape=None): """Create a numpy array from a ctypes array or a ctypes POINTER. The numpy array shares the memory with the ctypes object. - The size parameter must be given if converting from a ctypes POINTER. - The size parameter is ignored if converting from a ctypes array + The shape parameter must be given if converting from a ctypes POINTER. + The shape parameter is ignored if converting from a ctypes array """ tp = type(obj) try: tp.__array_interface__ diff --git a/numpy/tests/test_ctypeslib.py b/numpy/tests/test_ctypeslib.py index 508a348c145a..5564ac5bc9b7 100644 --- a/numpy/tests/test_ctypeslib.py +++ b/numpy/tests/test_ctypeslib.py @@ -135,3 +135,7 @@ def test_pointer(self): a = as_array(p, (10,)) assert_(a.shape == (10,)) assert_array_equal(a, np.array(range(10))) + a = as_array(p, (3, 2)) + assert_(a.shape == (3, 2)) + assert_array_equal(a, np.array([[0, 1], [2, 3], [4, 5]])) + assert_raises(TypeError, as_array, p)