@@ -68,10 +68,13 @@ PyArray_Size(PyObject *op)
68
68
NPY_NO_EXPORT int
69
69
PyArray_CopyObject (PyArrayObject * dest , PyObject * src_object )
70
70
{
71
- PyArrayObject * src ;
72
- PyObject * r ;
73
71
int ret ;
72
+ PyArrayObject * src ;
73
+ PyArray_Descr * dtype = NULL ;
74
+ int ndim = 0 ;
75
+ npy_intp dims [NPY_MAXDIMS ];
74
76
77
+ Py_INCREF (src_object );
75
78
/*
76
79
* Special code to mimic Numeric behavior for
77
80
* character arrays.
@@ -90,33 +93,87 @@ PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object)
90
93
memset (new_string + n_old , ' ' , n_new - n_old );
91
94
tmp = PyString_FromStringAndSize (new_string , n_new );
92
95
free (new_string );
96
+ Py_DECREF (src_object );
93
97
src_object = tmp ;
94
98
}
95
99
}
96
100
97
- if (PyArray_Check (src_object )) {
98
- src = (PyArrayObject * )src_object ;
99
- Py_INCREF (src );
100
- }
101
- else if (!PyArray_IsScalar (src_object , Generic ) &&
102
- PyArray_HasArrayInterface (src_object , r )) {
103
- src = (PyArrayObject * )r ;
104
- }
105
- else {
106
- PyArray_Descr * dtype ;
107
- dtype = dest -> descr ;
108
- Py_INCREF (dtype );
109
- src = (PyArrayObject * )PyArray_FromAny (src_object , dtype , 0 ,
110
- dest -> nd ,
111
- FORTRAN_IF (dest ),
112
- NULL );
101
+ /*
102
+ * Get either an array object we can copy from, or its parameters
103
+ * if there isn't a convenient array available.
104
+ */
105
+ if (PyArray_GetArrayParamsFromObject (src_object , PyArray_DESCR (dest ),
106
+ 0 , & dtype , & ndim , dims , & src , NULL ) < 0 ) {
107
+ Py_DECREF (src_object );
108
+ return -1 ;
113
109
}
110
+
111
+ /* If it's not an array, either assign from a sequence or as a scalar */
114
112
if (src == NULL ) {
115
- return -1 ;
113
+ /* If the input is scalar */
114
+ if (ndim == 0 ) {
115
+ /* If there's one dest element and src is a Python scalar */
116
+ if (PyArray_IsScalar (src_object , Generic )) {
117
+ src = (PyArrayObject * )PyArray_FromScalar (src_object , dtype );
118
+ if (src == NULL ) {
119
+ Py_DECREF (src_object );
120
+ return -1 ;
121
+ }
122
+ }
123
+ else {
124
+ if (PyArray_SIZE (dest ) == 1 ) {
125
+ Py_DECREF (dtype );
126
+ return PyArray_DESCR (dest )-> f -> setitem (src_object ,
127
+ PyArray_DATA (dest ), dest );
128
+ }
129
+ else {
130
+ src = (PyArrayObject * )PyArray_NewFromDescr (& PyArray_Type ,
131
+
B41A
dtype , 0 , NULL , NULL ,
132
+ NULL , 0 , NULL );
133
+ if (src == NULL ) {
134
+ Py_DECREF (src_object );
135
+ return -1 ;
136
+ }
137
+ if (PyArray_DESCR (src )-> f -> setitem (src_object ,
138
+ PyArray_DATA (src ), src ) < 0 ) {
139
+ Py_DECREF (src_object );
140
+ Py_DECREF (src );
141
+ return -1 ;
142
+ }
143
+ }
144
+ }
145
+ }
146
+ else {
147
+ /* If the dims match exactly, can assign directly */
148
+ if (ndim == PyArray_NDIM (dest ) &&
149
+ PyArray_CompareLists (dims , PyArray_DIMS (dest ),
150
+ ndim )) {
151
+ int res ;
152
+ Py_DECREF (dtype );
153
+ res = PyArray_AssignFromSequence (dest , src_object );
154
+ Py_DECREF (src_object );
155
+ return res ;
156
+ }
157
+ /* Otherwise convert to an array and do an array-based copy */
158
+ src = (PyArrayObject * )PyArray_NewFromDescr (& PyArray_Type ,
159
+ dtype , ndim , dims , NULL , NULL ,
160
+ PyArray_ISFORTRAN (dest ), NULL );
161
+ if (src == NULL ) {
162
+ Py_DECREF (src_object );
163
+ return -1 ;
164
+ }
165
+ if (PyArray_AssignFromSequence (src , src_object ) < 0 ) {
166
+ Py_DECREF (src );
167
+ Py_DECREF (src_object );
168
+ return -1 ;
169
+ }
170
+ }
116
171
}
117
172
173
+ /* If it's an array, do a move (handling possible overlapping data) */
118
174
ret = PyArray_MoveInto (dest , src );
119
175
Py_DECREF (src );
176
+ Py_DECREF (src_object );
120
177
return ret ;
121
178
}
122
179
@@ -627,7 +684,7 @@ _uni_release(char *ptr, int nc)
627
684
relfunc(aptr, N1); \
628
685
return -1; \
629
686
} \
630
- val = cmpfunc (aptr, bptr, N1, N2); \
687
+ val = compfunc (aptr, bptr, N1, N2); \
631
688
*dptr = (val CMP 0); \
632
689
PyArray_ITER_NEXT(iself); \
633
690
PyArray_ITER_NEXT(iother); \
@@ -639,7 +696,7 @@ _uni_release(char *ptr, int nc)
639
696
640
697
#define _reg_loop (CMP ) { \
641
698
while(size--) { \
642
- val = cmpfunc ((void *)iself->dataptr, \
699
+ val = compfunc ((void *)iself->dataptr, \
643
700
(void *)iother->dataptr, \
644
701
N1, N2); \
645
702
*dptr = (val CMP 0); \
@@ -661,18 +718,18 @@ _compare_strings(PyObject *result, PyArrayMultiIterObject *multi,
661
718
npy_intp size ;
662
719
int val ;
663
720
int N1 , N2 ;
664
- int (* cmpfunc )(void * , void * , int , int );
721
+ int (* compfunc )(void * , void * , int , int );
665
722
void (* relfunc )(char * , int );
666
723
char * (* stripfunc )(char * , char * , int );
667
724
668
- cmpfunc = func ;
725
+ compfunc = func ;
669
726
dptr = (Bool * )PyArray_DATA (result );
670
727
iself = multi -> iters [0 ];
671
728
iother = multi -> iters [1 ];
672
729
size = multi -> size ;
673
730
N1 = iself -> ao -> descr -> elsize ;
674
731
N2 = iother -> ao -> descr -> elsize ;
675
- if ((void * )cmpfunc == (void * )_myunincmp ) {
732
+ if ((void * )compfunc == (void * )_myunincmp ) {
676
733
N1 >>= 2 ;
677
734
N2 >>= 2 ;
678
735
stripfunc = _uni_copy_n_strip ;
0 commit comments