@@ -414,26 +414,90 @@ array_dealloc(arrayobject *op)
414414 PyObject_Del (op );
415415}
416416
417- static int
418- array_compare ( arrayobject * v , arrayobject * w )
417+ static PyObject *
418+ array_richcompare ( PyObject * v , PyObject * w , int op )
419419{
420- int len = (v -> ob_size < w -> ob_size ) ? v -> ob_size : w -> ob_size ;
421- int i ;
422- for (i = 0 ; i < len ; i ++ ) {
423- PyObject * ai , * bi ;
420+ arrayobject * va , * wa ;
421+ PyObject * vi = NULL ;
422+ PyObject * wi = NULL ;
423+ int i , k ;
424+ PyObject * res ;
425+
426+ if (!is_arrayobject (v ) || !is_arrayobject (w )) {
427+ Py_INCREF (Py_NotImplemented );
428+ return Py_NotImplemented ;
429+ }
430+
431+ va = (arrayobject * )v ;
432+ wa = (arrayobject * )w ;
433+
434+ if (va -> ob_size != wa -> ob_size && (op == Py_EQ || op == Py_NE )) {
435+ /* Shortcut: if the lengths differ, the arrays differ */
436+ if (op == Py_EQ )
437+ res = Py_False ;
438+ else
439+ res = Py_True ;
440+ Py_INCREF (res );
441+ return res ;
442+ }
443+
444+ /* Search for the first index where items are different */
445+ k = 1 ;
446+ for (i = 0 ; i < va -> ob_size && i < wa -> ob_size ; i ++ ) {
447+ vi = getarrayitem (v , i );
448+ wi = getarrayitem (w , i );
449+ if (vi == NULL || wi == NULL ) {
450+ Py_XDECREF (vi );
451+ Py_XDECREF (wi );
452+ return NULL ;
453+ }
454+ k = PyObject_RichCompareBool (vi , wi , Py_EQ );
455+ if (k == 0 )
456+ break ; /* Keeping vi and wi alive! */
457+ Py_DECREF (vi );
458+ Py_DECREF (wi );
459+ if (k < 0 )
460+ return NULL ;
461+ }
462+
463+ if (k ) {
464+ /* No more items to compare -- compare sizes */
465+ int vs = va -> ob_size ;
466+ int ws = wa -> ob_size ;
424467 int cmp ;
425- ai = getarrayitem ((PyObject * )v , i );
426- bi = getarrayitem ((PyObject * )w , i );
427- if (ai && bi )
428- cmp = PyObject_Compare (ai , bi );
468+ switch (op ) {
469+ case Py_LT : cmp = vs < ws ; break ;
470+ case Py_LE : cmp = ws <= ws ; break ;
471+ case Py_EQ : cmp = vs == ws ; break ;
472+ case Py_NE : cmp = vs != ws ; break ;
473+ case Py_GT : cmp = vs > ws ; break ;
474+ case Py_GE : cmp = vs >= ws ; break ;
475+ default : return NULL ; /* cannot happen */
476+ }
477+ if (cmp )
478+ res = Py_True ;
429479 else
430- cmp = -1 ;
431- Py_XDECREF (ai );
432- Py_XDECREF (bi );
433- if (cmp != 0 )
434- return cmp ;
480+ res = Py_False ;
481+ Py_INCREF (res );
482+ return res ;
483+ }
484+
485+ /* We have an item that differs. First, shortcuts for EQ/NE */
486+ if (op == Py_EQ ) {
487+ Py_INCREF (Py_False );
488+ res = Py_False ;
489+ }
490+ else if (op == Py_NE ) {
491+ Py_INCREF (Py_True );
492+ res = Py_True ;
435493 }
436- return v -> ob_size - w -> ob_size ;
494+ else {
495+ /* Compare the final item again using the proper operator */
496+ res = PyObject_RichCompare (vi , wi , op );
497+ }
498+ Py_DECREF (vi );
499+ Py_DECREF (wi );
500+ return res ;
437501}
438502
439503static int
@@ -636,10 +700,11 @@ array_count(arrayobject *self, PyObject *args)
636700 return NULL ;
637701 for (i = 0 ; i < self -> ob_size ; i ++ ) {
638702 PyObject * selfi = getarrayitem ((PyObject * )self , i );
639- if (PyObject_Compare (selfi , v ) == 0 )
640- count ++ ;
703+ int cmp = PyObject_RichCompareBool (selfi , v , Py_EQ );
641704 Py_DECREF (selfi );
642- if (PyErr_Occurred ())
705+ if (cmp > 0 )
706+ count ++ ;
707+ else if (cmp < 0 )
643708 return NULL ;
644709 }
645710 return PyInt_FromLong ((long )count );
@@ -660,12 +725,12 @@ array_index(arrayobject *self, PyObject *args)
660725 return NULL ;
661726 for (i = 0 ; i < self -> ob_size ; i ++ ) {
662727 PyObject * selfi = getarrayitem ((PyObject * )self , i );
663- if (PyObject_Compare (selfi , v ) == 0 ) {
664- Py_DECREF (selfi );
728+ int cmp = PyObject_RichCompareBool (selfi , v , Py_EQ );
729+ Py_DECREF (selfi );
730+ if (cmp > 0 ) {
665731 return PyInt_FromLong ((long )i );
666732 }
667- Py_DECREF (selfi );
668- if (PyErr_Occurred ())
733+ else if (cmp < 0 )
669734 return NULL ;
670735 }
671736 PyErr_SetString (PyExc_ValueError , "array.index(x): x not in list" );
@@ -687,16 +752,16 @@ array_remove(arrayobject *self, PyObject *args)
687752 return NULL ;
688753 for (i = 0 ; i < self -> ob_size ; i ++ ) {
689754 PyObject * selfi = getarrayitem ((PyObject * )self ,i );
690- if (PyObject_Compare (selfi , v ) == 0 ) {
691- Py_DECREF (selfi );
755+ int cmp = PyObject_RichCompareBool (selfi , v , Py_EQ );
756+ Py_DECREF (selfi );
757+ if (cmp > 0 ) {
692758 if (array_ass_slice (self , i , i + 1 ,
693759 (PyObject * )NULL ) != 0 )
694760 return NULL ;
695761 Py_INCREF (Py_None );
696762 return Py_None ;
697763 }
698- Py_DECREF (selfi );
699- if (PyErr_Occurred ())
764+ else if (cmp < 0 )
700765 return NULL ;
701766 }
702767 PyErr_SetString (PyExc_ValueError , "array.remove(x): x not in list" );
@@ -750,8 +815,8 @@ array_extend(arrayobject *self, PyObject *args)
750815
751816 if (!is_arrayobject (bb )) {
752817 PyErr_Format (PyExc_TypeError ,
753- "can only extend array with array (not \"%.200s\")" ,
754- bb -> ob_type -> tp_name );
818+ "can only extend array with array (not \"%.200s\")" ,
819+ bb -> ob_type -> tp_name );
755820 return NULL ;
756821 }
757822#define b ((arrayobject *)bb)
@@ -1137,25 +1202,44 @@ Convert the array to an array of machine values and return the string\n\
11371202representation." ;
11381203
11391204PyMethodDef array_methods [] = {
1140- {"append" , (PyCFunction )array_append , METH_VARARGS , append_doc },
1141- {"buffer_info" , (PyCFunction )array_buffer_info , METH_VARARGS , buffer_info_doc },
1142- {"byteswap" , (PyCFunction )array_byteswap , METH_VARARGS , byteswap_doc },
1143- {"count" , (PyCFunction )array_count , METH_VARARGS , count_doc },
1144- {"extend" , (PyCFunction )array_extend , METH_VARARGS , extend_doc },
1145- {"fromfile" , (PyCFunction )array_fromfile , METH_VARARGS , fromfile_doc },
1146- {"fromlist" , (PyCFunction )array_fromlist , METH_VARARGS , fromlist_doc },
1147- {"fromstring" , (PyCFunction )array_fromstring , METH_VARARGS , fromstring_doc },
1148- {"index" , (PyCFunction )array_index , METH_VARARGS , index_doc },
1149- {"insert" , (PyCFunction )array_insert , METH_VARARGS , insert_doc },
1150- {"pop" , (PyCFunction )array_pop , METH_VARARGS , pop_doc },
1151- {"read" , (PyCFunction )array_fromfile , METH_VARARGS , fromfile_doc },
1152- {"remove" , (PyCFunction )array_remove , METH_VARARGS , remove_doc },
1153- {"reverse" , (PyCFunction )array_reverse , METH_VARARGS , reverse_doc },
1154- /* {"sort", (PyCFunction)array_sort, METH_VARARGS, sort_doc},*/
1155- {"tofile" , (PyCFunction )array_tofile , METH_VARARGS , tofile_doc },
1156- {"tolist" , (PyCFunction )array_tolist , METH_VARARGS , tolist_doc },
1157- {"tostring" , (PyCFunction )array_tostring , METH_VARARGS , tostring_doc },
1158- {"write" , (PyCFunction )array_tofile , METH_VARARGS , tofile_doc },
1205+ {"append" , (PyCFunction )array_append , METH_VARARGS ,
1206+ append_doc },
1207+ {"buffer_info" , (PyCFunction )array_buffer_info , METH_VARARGS ,
1208+ buffer_info_doc },
1209+ {"byteswap" , (PyCFunction )array_byteswap , METH_VARARGS ,
1210+ byteswap_doc },
1211+ {"count" , (PyCFunction )array_count , METH_VARARGS ,
1212+ count_doc },
1213+ {"extend" , (PyCFunction )array_extend , METH_VARARGS ,
1214+ extend_doc },
1215+ {"fromfile" , (PyCFunction )array_fromfile , METH_VARARGS ,
1216+ fromfile_doc },
1217+ {"fromlist" , (PyCFunction )array_fromlist , METH_VARARGS ,
1218+ fromlist_doc },
1219+ {"fromstring" , (PyCFunction )array_fromstring , METH_VARARGS ,
1220+ fromstring_doc },
1221+ {"index" , (PyCFunction )array_index , METH_VARARGS ,
1222+ index_doc },
1223+ {"insert" , (PyCFunction )array_insert , METH_VARARGS ,
1224+ insert_doc },
1225+ {"pop" , (PyCFunction )array_pop , METH_VARARGS ,
1226+ pop_doc },
1227+ {"read" , (PyCFunction )array_fromfile , METH_VARARGS ,
1228+ fromfile_doc },
1229+ {"remove" , (PyCFunction )array_remove , METH_VARARGS ,
1230+ remove_doc },
1231+ {"reverse" , (PyCFunction )array_reverse , METH_VARARGS ,
1232+ reverse_doc },
1233+ /* {"sort", (PyCFunction)array_sort, METH_VARARGS,
1234+ sort_doc},*/
1235+ {"tofile" , (PyCFunction )array_tofile , METH_VARARGS ,
1236+ tofile_doc },
1237+ {"tolist" , (PyCFunction )array_tolist , METH_VARARGS ,
1238+ tolist_doc },
1239+ {"tostring" , (PyCFunction )array_tostring , METH_VARARGS ,
1240+ tostring_doc },
1241+ {"write" , (PyCFunction )array_tofile , METH_VARARGS ,
1242+ tofile_doc },
11591243 {NULL , NULL } /* sentinel */
11601244};
11611245
@@ -1345,9 +1429,11 @@ a_array(PyObject *self, PyObject *args)
13451429 }
13461430 }
13471431 if (initial != NULL && PyString_Check (initial )) {
1348- PyObject * t_initial = Py_BuildValue ("(O)" , initial );
1432+ PyObject * t_initial = Py_BuildValue ("(O)" ,
1433+ initial );
13491434 PyObject * v =
1350- array_fromstring ((arrayobject * )a , t_initial );
1435+ array_fromstring ((arrayobject * )a ,
1436+ t_initial );
13511437 Py_DECREF (t_initial );
13521438 if (v == NULL ) {
13531439 Py_DECREF (a );
@@ -1442,23 +1528,26 @@ statichere PyTypeObject Arraytype = {
14421528 "array" ,
14431529 sizeof (arrayobject ),
14441530 0 ,
1445- (destructor )array_dealloc , /*tp_dealloc*/
1446- (printfunc )array_print , /*tp_print*/
1447- (getattrfunc )array_getattr , /*tp_getattr*/
1448- 0 , /*tp_setattr*/
1449- (cmpfunc )array_compare , /*tp_compare*/
1450- (reprfunc )array_repr , /*tp_repr*/
1451- 0 , /*tp_as_number*/
1452- & array_as_sequence , /*tp_as_sequence*/
1453- 0 , /*tp_as_mapping*/
1454- 0 , /*tp_hash*/
1455- 0 , /*tp_call*/
1456- 0 , /*tp_str*/
1457- 0 , /*tp_getattro*/
1458- 0 , /*tp_setattro*/
1459- & array_as_buffer , /*tp_as_buffer*/
1460- 0 , /*tp_xxx4*/
1461- arraytype_doc , /*tp_doc*/
1531+ (destructor )array_dealloc , /* tp_dealloc */
1532+ (printfunc )array_print , /* tp_print */
1533+ (getattrfunc )array_getattr , /* tp_getattr */
1534+ 0 , /* tp_setattr */
1535+ 0 , /* tp_compare */
1536+ (reprfunc )array_repr , /* tp_repr */
1537+ 0 , /* tp_as _number*/
1538+ & array_as_sequence , /* tp_as _sequence*/
1539+ 0 , /* tp_as _mapping*/
1540+ 0 , /* tp_hash */
1541+ 0 , /* tp_call */
1542+ 0 , /* tp_str */
1543+ 0 , /* tp_getattro */
1544+ 0 , /* tp_setattro */
1545+ & array_as_buffer , /* tp_as _buffer*/
1546+ 0 , /* tp_flags */
1547+ arraytype_doc , /* tp_doc */
1548+ 0 , /* tp_traverse */
1549+ 0 , /* tp_clear */
1550+ array_richcompare , /* tp_richcompare */
14621551};
14631552
14641553DL_EXPORT (void )
0 commit comments