summaryrefslogtreecommitdiff
path: root/numpy/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core/src')
-rw-r--r--numpy/core/src/multiarray/buffer.c9
-rw-r--r--numpy/core/src/multiarray/multiarray_tests.c.src117
2 files changed, 118 insertions, 8 deletions
diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c
index 326b73b42..d69cd36c5 100644
--- a/numpy/core/src/multiarray/buffer.c
+++ b/numpy/core/src/multiarray/buffer.c
@@ -604,23 +604,22 @@ array_getbuffer(PyObject *obj, Py_buffer *view, int flags)
/* Check whether we can provide the wanted properties */
if ((flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS &&
- !PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)) {
+ !PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)) {
PyErr_SetString(PyExc_ValueError, "ndarray is not C-contiguous");
goto fail;
}
if ((flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS &&
- !PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)) {
+ !PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)) {
PyErr_SetString(PyExc_ValueError, "ndarray is not Fortran contiguous");
goto fail;
}
if ((flags & PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS
- && !PyArray_ISONESEGMENT(self)) {
+ && !PyArray_ISONESEGMENT(self)) {
PyErr_SetString(PyExc_ValueError, "ndarray is not contiguous");
goto fail;
}
if ((flags & PyBUF_STRIDES) != PyBUF_STRIDES &&
- (flags & PyBUF_ND) == PyBUF_ND &&
- !PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)) {
+ !PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)) {
/* Non-strided N-dim buffers must be C-contiguous */
PyErr_SetString(PyExc_ValueError, "ndarray is not C-contiguous");
goto fail;
diff --git a/numpy/core/src/multiarray/multiarray_tests.c.src b/numpy/core/src/multiarray/multiarray_tests.c.src
index 0aea85f66..98b4dc2ba 100644
--- a/numpy/core/src/multiarray/multiarray_tests.c.src
+++ b/numpy/core/src/multiarray/multiarray_tests.c.src
@@ -522,9 +522,6 @@ inplace_increment(PyObject *dummy, PyObject *args)
}
type_number = PyArray_TYPE(a);
-
-
-
while (type_numbers[i] >= 0 && addition_funcs[i] != NULL){
if (type_number == type_numbers[i]) {
add_inplace = addition_funcs[i];
@@ -558,6 +555,7 @@ fail:
return NULL;
}
+
#if !defined(NPY_PY3K)
static PyObject *
int_subclass(PyObject *dummy, PyObject *args)
@@ -581,6 +579,116 @@ int_subclass(PyObject *dummy, PyObject *args)
}
#endif
+
+/*
+ * Create python string from a FLAG and or the corresponding PyBuf flag
+ * for the use in get_buffer_info.
+ */
+#define GET_PYBUF_FLAG(FLAG) \
+ buf_flag = PyUnicode_FromString(#FLAG); \
+ flag_matches = PyObject_RichCompareBool(buf_flag, tmp, Py_EQ); \
+ Py_DECREF(buf_flag); \
+ if (flag_matches == 1) { \
+ Py_DECREF(tmp); \
+ flags |= PyBUF_##FLAG; \
+ continue; \
+ } \
+ else if (flag_matches == -1) { \
+ Py_DECREF(tmp); \
+ return NULL; \
+ }
+
+
+/*
+ * Get information for a buffer through PyBuf_GetBuffer with the
+ * corresponding flags or'ed. Note that the python caller has to
+ * make sure that or'ing those flags actually makes sense.
+ * More information should probably be returned for future tests.
+ */
+static PyObject *
+get_buffer_info(PyObject *NPY_UNUSED(self), PyObject *args)
+{
+ PyObject *buffer_obj, *pyflags;
+ PyObject *tmp, *buf_flag;
+ Py_buffer buffer;
+ PyObject *shape, *strides;
+ Py_ssize_t i, n;
+ int flag_matches;
+ int flags = 0;
+
+ if (!PyArg_ParseTuple(args, "OO", &buffer_obj, &pyflags)) {
+ return NULL;
+ }
+
+ n = PySequence_Length(pyflags);
+ if (n < 0) {
+ return NULL;
+ }
+
+ for (i=0; i < n; i++) {
+ tmp = PySequence_GetItem(pyflags, i);
+ if (tmp == NULL) {
+ return NULL;
+ }
+
+ GET_PYBUF_FLAG(SIMPLE);
+ GET_PYBUF_FLAG(WRITABLE);
+ GET_PYBUF_FLAG(STRIDES);
+ GET_PYBUF_FLAG(ND);
+ GET_PYBUF_FLAG(C_CONTIGUOUS);
+ GET_PYBUF_FLAG(F_CONTIGUOUS);
+ GET_PYBUF_FLAG(ANY_CONTIGUOUS);
+ GET_PYBUF_FLAG(INDIRECT);
+ GET_PYBUF_FLAG(FORMAT);
+ GET_PYBUF_FLAG(STRIDED);
+ GET_PYBUF_FLAG(STRIDED_RO);
+ GET_PYBUF_FLAG(RECORDS);
+ GET_PYBUF_FLAG(RECORDS_RO);
+ GET_PYBUF_FLAG(FULL);
+ GET_PYBUF_FLAG(FULL_RO);
+ GET_PYBUF_FLAG(CONTIG);
+ GET_PYBUF_FLAG(CONTIG_RO);
+
+ Py_DECREF(tmp);
+
+ /* One of the flags must match */
+ PyErr_SetString(PyExc_ValueError, "invalid flag used.");
+ return NULL;
+ }
+
+ if (PyObject_GetBuffer(buffer_obj, &buffer, flags) < 0) {
+ return NULL;
+ }
+
+ if (buffer.shape == NULL) {
+ Py_INCREF(Py_None);
+ shape = Py_None;
+ }
+ else {
+ shape = PyTuple_New(buffer.ndim);
+ for (i=0; i < buffer.ndim; i++) {
+ PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(buffer.shape[i]));
+ }
+ }
+
+ if (buffer.strides == NULL) {
+ Py_INCREF(Py_None);
+ strides = Py_None;
+ }
+ else {
+ strides = PyTuple_New(buffer.ndim);
+ for (i=0; i < buffer.ndim; i++) {
+ PyTuple_SET_ITEM(strides, i, PyLong_FromSsize_t(buffer.strides[i]));
+ }
+ }
+
+ PyBuffer_Release(&buffer);
+ return Py_BuildValue("(NN)", shape, strides);
+}
+
+#undef GET_PYBUF_FLAG
+
+
static PyMethodDef Multiarray_TestsMethods[] = {
{"test_neighborhood_iterator",
test_neighborhood_iterator,
@@ -602,6 +710,9 @@ static PyMethodDef Multiarray_TestsMethods[] = {
int_subclass,
METH_VARARGS, NULL},
#endif
+ {"get_buffer_info",
+ get_buffer_info,
+ METH_VARARGS, NULL},
{NULL, NULL, 0, NULL} /* Sentinel */
};