[pypy-commit] pypy pypy-pyarray: raise exceptions on invalid or non-implemented args, try harder to catch invalid args
mattip
noreply at buildbot.pypy.org
Mon Sep 9 00:05:15 CEST 2013
Author: Matti Picus <matti.picus at gmail.com>
Branch: pypy-pyarray
Changeset: r66854:3d8f4373ec61
Date: 2013-09-08 23:04 +0200
http://bitbucket.org/pypy/pypy/changeset/3d8f4373ec61/
Log: raise exceptions on invalid or non-implemented args, try harder to
catch invalid args
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -159,7 +159,7 @@
numpy_headers = numpy_include_dir.listdir('*.h') + numpy_include_dir.listdir('*.inl')
_copy_header_files(numpy_headers, numpy_dstdir)
-
+
class NotSpecified(object):
pass
_NOT_SPECIFIED = NotSpecified()
@@ -303,9 +303,23 @@
elif isinstance(input_arg, W_Root):
arg = input_arg
else:
- arg = from_ref(space,
+ try:
+ arg = from_ref(space,
rffi.cast(PyObject, input_arg))
+ except TypeError, e:
+ err = OperationError(space.w_TypeError,
+ space.wrap(
+ "could not cast arg to PyObject"))
+ if not catch_exception:
+ raise err
+ state = space.fromcache(State)
+ state.set_exception(err)
+ if is_PyObject(restype):
+ return None
+ else:
+ return api_function.error_value
else:
+ # convert to a wrapped object
arg = input_arg
newargs += (arg, )
try:
@@ -403,13 +417,13 @@
'PyStructSequence_InitType', 'PyStructSequence_New',
'PyFunction_Type', 'PyMethod_Type', 'PyRange_Type', 'PyTraceBack_Type',
-
+
'PyArray_Type', '_PyArray_FILLWBYTE', '_PyArray_ZEROS', '_PyArray_CopyInto',
'Py_DebugFlag', 'Py_VerboseFlag', 'Py_InteractiveFlag', 'Py_InspectFlag',
- 'Py_OptimizeFlag', 'Py_NoSiteFlag', 'Py_BytesWarningFlag', 'Py_UseClassExceptionsFlag',
- 'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag',
- 'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory',
+ 'Py_OptimizeFlag', 'Py_NoSiteFlag', 'Py_BytesWarningFlag', 'Py_UseClassExceptionsFlag',
+ 'Py_FrozenFlag', 'Py_TabcheckFlag', 'Py_UnicodeFlag', 'Py_IgnoreEnvironmentFlag',
+ 'Py_DivisionWarningFlag', 'Py_DontWriteBytecodeFlag', 'Py_NoUserSiteDirectory',
'_Py_QnewFlag', 'Py_Py3kWarningFlag', 'Py_HashRandomizationFlag', '_Py_PackageContext',
]
TYPES = {}
diff --git a/pypy/module/cpyext/ndarrayobject.py b/pypy/module/cpyext/ndarrayobject.py
--- a/pypy/module/cpyext/ndarrayobject.py
+++ b/pypy/module/cpyext/ndarrayobject.py
@@ -60,7 +60,7 @@
@cpython_api([PyObject], rffi.INT_real, error=-1)
def _PyArray_FLAGS(space, w_array):
if not isinstance(w_array, W_NDimArray):
- raise OperationError(space.w_ValueError, space.wrap(
+ raise OperationError(space.w_TypeError, space.wrap(
'_PyArray_FLAGS(ndarray) called with non-ndarray'))
flags = NPY_BEHAVED_NS
if isinstance(w_array.implementation, ConcreteArray):
@@ -76,49 +76,49 @@
@cpython_api([PyObject], rffi.INT_real, error=-1)
def _PyArray_NDIM(space, w_array):
if not isinstance(w_array, W_NDimArray):
- raise OperationError(space.w_ValueError, space.wrap(
+ raise OperationError(space.w_TypeError, space.wrap(
'_PyArray_NDIM(ndarray) called with non-ndarray'))
return len(w_array.get_shape())
@cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=-1)
def _PyArray_DIM(space, w_array, n):
if not isinstance(w_array, W_NDimArray):
- raise OperationError(space.w_ValueError, space.wrap(
+ raise OperationError(space.w_TypeError, space.wrap(
'_PyArray_DIM called with non-ndarray'))
return w_array.get_shape()[n]
@cpython_api([PyObject, Py_ssize_t], Py_ssize_t, error=-1)
def _PyArray_STRIDE(space, w_array, n):
if not isinstance(w_array, W_NDimArray):
- raise OperationError(space.w_ValueError, space.wrap(
+ raise OperationError(space.w_TypeError, space.wrap(
'_PyArray_STRIDE called with non-ndarray'))
return w_array.implementation.get_strides()[n]
@cpython_api([PyObject], Py_ssize_t, error=-1)
def _PyArray_SIZE(space, w_array):
if not isinstance(w_array, W_NDimArray):
- raise OperationError(space.w_ValueError, space.wrap(
+ raise OperationError(space.w_TypeError, space.wrap(
'_PyArray_SIZE called with non-ndarray'))
return w_array.get_size()
@cpython_api([PyObject], rffi.INT_real, error=-1)
def _PyArray_ITEMSIZE(space, w_array):
if not isinstance(w_array, W_NDimArray):
- raise OperationError(space.w_ValueError, space.wrap(
+ raise OperationError(space.w_TypeError, space.wrap(
'_PyArray_ITEMSIZE called with non-ndarray'))
return w_array.get_dtype().get_size()
@cpython_api([PyObject], Py_ssize_t, error=-1)
def _PyArray_NBYTES(space, w_array):
if not isinstance(w_array, W_NDimArray):
- raise OperationError(space.w_ValueError, space.wrap(
+ raise OperationError(space.w_TypeError, space.wrap(
'_PyArray_NBYTES called with non-ndarray'))
return w_array.get_size() * w_array.get_dtype().get_size()
@cpython_api([PyObject], rffi.INT_real, error=-1)
def _PyArray_TYPE(space, w_array):
if not isinstance(w_array, W_NDimArray):
- raise OperationError(space.w_ValueError, space.wrap(
+ raise OperationError(space.w_TypeError, space.wrap(
'_PyArray_TYPE called with non-ndarray'))
return w_array.get_dtype().num
@@ -127,15 +127,53 @@
def _PyArray_DATA(space, w_array):
# fails on scalars - see PyArray_FromAny()
if not isinstance(w_array, W_NDimArray):
- raise OperationError(space.w_ValueError, space.wrap(
+ raise OperationError(space.w_TypeError, space.wrap(
'_PyArray_DATA called with non-ndarray'))
return rffi.cast(rffi.VOIDP, w_array.implementation.storage)
@cpython_api([PyObject, rffi.VOIDP, Py_ssize_t, Py_ssize_t, Py_ssize_t, rffi.VOIDP],
- PyObject)
+ PyObject, error=CANNOT_FAIL)
def _PyArray_FromAny(space, w_obj, dtype, min_depth, max_depth, requirements, context):
- # ignore all additional arguments for now
+ """ This is the main function used to obtain an array from any nested
+ sequence, or object that exposes the array interface, op. The
+ parameters allow specification of the required dtype, the
+ minimum (min_depth) and maximum (max_depth) number of dimensions
+ acceptable, and other requirements for the array.
+
+ The dtype argument needs to be a PyArray_Descr structure indicating
+ the desired data-type (including required byteorder). The dtype
+ argument may be NULL, indicating that any data-type (and byteorder)
+ is acceptable.
+ Unless FORCECAST is present in flags, this call will generate an error
+ if the data type cannot be safely obtained from the object. If you
+ want to use NULL for the dtype and ensure the array is notswapped then
+ use PyArray_CheckFromAny.
+
+ A value of 0 for either of the depth parameters causes the parameter
+ to be ignored.
+
+ Any of the following array flags can be added (e.g. using |) to get
+ the requirements argument. If your code can handle general (e.g.
+ strided, byte-swapped, or unaligned arrays) then requirements
+ may be 0. Also, if op is not already an array (or does not expose
+ the array interface), then a new array will be created (and filled
+ from op using the sequence protocol). The new array will have
+ NPY_DEFAULT as its flags member.
+
+ The context argument is passed to the __array__ method of op and is
+ only used if the array is constructed that way. Almost always this
+ parameter is NULL.
+ """
+ if dtype:
+ raise OperationError(space.w_NotImplementedError, space.wrap(
+ '_PyArray_FromAny called with not-implemented dtype argument'))
+ if min_depth !=0 or max_depth != 0:
+ raise OperationError(space.w_NotImplementedError, space.wrap(
+ '_PyArray_FromAny called with not-implemented min_dpeth or max_depth argument'))
+ if requirements not in (0, NPY_DEFAULT):
+ raise OperationError(space.w_NotImplementedError, space.wrap(
+ '_PyArray_FromAny called with not-implemented requirements argument'))
w_array = convert_to_array(space, w_obj)
if w_array.is_scalar():
# since PyArray_DATA() fails on scalars, create a 1D array and set empty
@@ -151,7 +189,9 @@
@cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject)
def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth):
- # ignore min_depth and max_depth for now
+ if min_depth !=0 or max_depth != 0:
+ raise OperationError(space.w_NotImplementedError, space.wrap(
+ '_PyArray_FromObject called with not-implemented min_dpeth or max_depth argument'))
dtype = get_dtype_cache(space).dtypes_by_num[typenum]
w_array = convert_to_array(space, w_obj)
impl = w_array.implementation
diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py b/pypy/module/cpyext/test/test_ndarrayobject.py
--- a/pypy/module/cpyext/test/test_ndarrayobject.py
+++ b/pypy/module/cpyext/test/test_ndarrayobject.py
@@ -62,6 +62,7 @@
def test_NBYTES(self, space, api):
a = array(space, [10, 5, 3])
assert api._PyArray_NBYTES(a) == 1200
+ self.raises(space, api, TypeError, api._PyArray_NBYTES, space.wrap([10]))
def test_TYPE(self, space, api):
a = array(space, [10, 5, 3])
@@ -86,6 +87,9 @@
def test_FromAny(self, space, api):
a = array(space, [10, 5, 3])
assert api._PyArray_FromAny(a, NULL, 0, 0, 0, NULL) is a
+ self.raises(space, api, NotImplementedError, api._PyArray_FromAny,
+ space.wrap(a), space.w_None, space.wrap(0),
+ space.wrap(3), space.wrap(0), space.w_None)
def test_list_from_fixedptr(self, space, api):
A = lltype.GcArray(lltype.Float)
More information about the pypy-commit
mailing list