Skip to content

Array params from object #39

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

Merged
3 commits merged into from
Feb 8, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions numpy/core/code_generators/numpy_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@
'PyArray_EinsteinSum': 274,
'PyArray_FillWithZero': 275,
'PyArray_NewLikeArray': 276,
'PyArray_GetArrayParamsFromObject': 277,
}

ufunc_types_api = {
Expand Down
105 changes: 81 additions & 24 deletions numpy/core/src/multiarray/arrayobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ PyArray_Size(PyObject *op)
NPY_NO_EXPORT int
PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object)
{
PyArrayObject *src;
PyObject *r;
int ret;
PyArrayObject *src;
PyArray_Descr *dtype = NULL;
int ndim = 0;
npy_intp dims[NPY_MAXDIMS];

Py_INCREF(src_object);
/*
* Special code to mimic Numeric behavior for
* character arrays.
Expand All @@ -90,33 +93,87 @@ PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object)
memset(new_string + n_old, ' ', n_new - n_old);
tmp = PyString_FromStringAndSize(new_string, n_new);
free(new_string);
Py_DECREF(src_object);
src_object = tmp;
}
}

if (PyArray_Check(src_object)) {
src = (PyArrayObject *)src_object;
Py_INCREF(src);
}
else if (!PyArray_IsScalar(src_object, Generic) &&
PyArray_HasArrayInterface(src_object, r)) {
src = (PyArrayObject *)r;
}
else {
PyArray_Descr* dtype;
dtype = dest->descr;
Py_INCREF(dtype);
src = (PyArrayObject *)PyArray_FromAny(src_object, dtype, 0,
dest->nd,
FORTRAN_IF(dest),
NULL);
/*
* Get either an array object we can copy from, or its parameters
* if there isn't a convenient array available.
*/
if (PyArray_GetArrayParamsFromObject(src_object, PyArray_DESCR(dest),
0, &dtype, &ndim, dims, &src, NULL) < 0) {
Py_DECREF(src_object);
return -1;
}

/* If it's not an array, either assign from a sequence or as a scalar */
if (src == NULL) {
return -1;
/* If the input is scalar */
if (ndim == 0) {
/* If there's one dest element and src is a Python scalar */
if (PyArray_IsScalar(src_object, Generic)) {
src = (PyArrayObject *)PyArray_FromScalar(src_object, dtype);
if (src == NULL) {
Py_DECREF(src_object);
return -1;
}
}
else {
if (PyArray_SIZE(dest) == 1) {
Py_DECREF(dtype);
return PyArray_DESCR(dest)->f->setitem(src_object,
PyArray_DATA(dest), dest);
}
else {
src = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type,
dtype, 0, NULL, NULL,
NULL, 0, NULL);
if (src == NULL) {
Py_DECREF(src_object);
return -1;
}
if (PyArray_DESCR(src)->f->setitem(src_object,
PyArray_DATA(src), src) < 0) {
Py_DECREF(src_object);
Py_DECREF(src);
return -1;
}
}
}
}
else {
/* If the dims match exactly, can assign directly */
if (ndim == PyArray_NDIM(dest) &&
PyArray_CompareLists(dims, PyArray_DIMS(dest),
ndim)) {
int res;
Py_DECREF(dtype);
res = PyArray_AssignFromSequence(dest, src_object);
Py_DECREF(src_object);
return res;
}
/* Otherwise convert to an array and do an array-based copy */
src = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type,
dtype, ndim, dims, NULL, NULL,
PyArray_ISFORTRAN(dest), NULL);
if (src == NULL) {
Py_DECREF(src_object);
return -1;
}
if (PyArray_AssignFromSequence(src, src_object) < 0) {
Py_DECREF(src);
Py_DECREF(src_object);
return -1;
}
}
}

/* If it's an array, do a move (handling possible overlapping data) */
ret = PyArray_MoveInto(dest, src);
Py_DECREF(src);
Py_DECREF(src_object);
return ret;
}

Expand Down Expand Up @@ -627,7 +684,7 @@ _uni_release(char *ptr, int nc)
relfunc(aptr, N1); \
return -1; \
} \
val = cmpfunc(aptr, bptr, N1, N2); \
val = compfunc(aptr, bptr, N1, N2); \
*dptr = (val CMP 0); \
PyArray_ITER_NEXT(iself); \
PyArray_ITER_NEXT(iother); \
Expand All @@ -639,7 +696,7 @@ _uni_release(char *ptr, int nc)

#define _reg_loop(CMP) { \
while(size--) { \
val = cmpfunc((void *)iself->dataptr, \
val = compfunc((void *)iself->dataptr, \
(void *)iother->dataptr, \
N1, N2); \
*dptr = (val CMP 0); \
Expand All @@ -661,18 +718,18 @@ _compare_strings(PyObject *result, PyArrayMultiIterObject *multi,
npy_intp size;
int val;
int N1, N2;
int (*cmpfunc)(void *, void *, int, int);
int (*compfunc)(void *, void *, int, int);
void (*relfunc)(char *, int);
char* (*stripfunc)(char *, char *, int);

cmpfunc = func;
compfunc = func;
dptr = (Bool *)PyArray_DATA(result);
iself = multi->iters[0];
iother = multi->iters[1];
size = multi->size;
N1 = iself->ao->descr->elsize;
N2 = iother->ao->descr->elsize;
if ((void *)cmpfunc == (void *)_myunincmp) {
if ((void *)compfunc == (void *)_myunincmp) {
N1 >>= 2;
N2 >>= 2;
stripfunc = _uni_copy_n_strip;
Expand Down
16 changes: 15 additions & 1 deletion numpy/core/src/multiarray/arraytypes.c.src
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ static int
temp = (@type@)@func2@(op);
}
if (PyErr_Occurred()) {
if (PySequence_Check(op)) {
if (PySequence_Check(op) && !PyString_Check(op) &&
!PyUnicode_Check(op)) {
PyErr_Clear();
PyErr_SetString(PyExc_ValueError,
"setting an array element with a sequence.");
Expand Down Expand Up @@ -438,6 +439,19 @@ STRING_setitem(PyObject *op, char *ov, PyArrayObject *ap)
Py_ssize_t len;
PyObject *temp = NULL;

/* Handle case of assigning from an array scalar */
if (PyArray_Check(op) && PyArray_NDIM(op) == 0) {
temp = PyArray_ToScalar(PyArray_DATA(op), op);
if (temp == NULL) {
return -1;
}
else {
int res = STRING_setitem(temp, ov, ap);
Py_DECREF(temp);
return res;
}
}

if (!PyBytes_Check(op) && !PyUnicode_Check(op)
&& PySequence_Check(op) && PySequence_Size(op) != 0) {
PyErr_SetString(PyExc_ValueError,
Expand Down
Loading