diff options
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 102 | ||||
-rw-r--r-- | Objects/bytesobject.c | 9 | ||||
-rw-r--r-- | Objects/exceptions.c | 10 | ||||
-rw-r--r-- | Objects/intobject.c | 17 | ||||
-rw-r--r-- | Objects/listobject.c | 25 | ||||
-rw-r--r-- | Objects/longobject.c | 49 | ||||
-rw-r--r-- | Objects/object.c | 17 | ||||
-rw-r--r-- | Objects/sliceobject.c | 2 | ||||
-rw-r--r-- | Objects/stringobject.c | 12 | ||||
-rw-r--r-- | Objects/structseq.c | 4 | ||||
-rw-r--r-- | Objects/tupleobject.c | 5 | ||||
-rw-r--r-- | Objects/typeobject.c | 33 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 85 |
13 files changed, 233 insertions, 137 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 79dfe40..8810762 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -6,6 +6,7 @@ #include "longintrepr.h" + /* Shorthands to return certain errors */ static PyObject * @@ -117,9 +118,9 @@ PyObject_GetItem(PyObject *o, PyObject *key) return m->mp_subscript(o, key); if (o->ob_type->tp_as_sequence) { - PyNumberMethods *nb = key->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t key_value = nb->nb_index(key); + if (PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); if (key_value == -1 && PyErr_Occurred()) return NULL; return PySequence_GetItem(o, key_value); @@ -146,9 +147,9 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) return m->mp_ass_subscript(o, key, value); if (o->ob_type->tp_as_sequence) { - PyNumberMethods *nb = key->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t key_value = nb->nb_index(key); + if (PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); if (key_value == -1 && PyErr_Occurred()) return -1; return PySequence_SetItem(o, key_value, value); @@ -178,9 +179,9 @@ PyObject_DelItem(PyObject *o, PyObject *key) return m->mp_ass_subscript(o, key, (PyObject*)NULL); if (o->ob_type->tp_as_sequence) { - PyNumberMethods *nb = key->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t key_value = nb->nb_index(key); + if (PyIndex_Check(key)) { + Py_ssize_t key_value; + key_value = PyNumber_AsSsize_t(key, PyExc_IndexError); if (key_value == -1 && PyErr_Occurred()) return -1; return PySequence_DelItem(o, key_value); @@ -530,9 +531,8 @@ static PyObject * sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n) { Py_ssize_t count; - PyNumberMethods *nb = n->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - count = nb->nb_index(n); + if (PyIndex_Check(n)) { + count = PyNumber_AsSsize_t(n, PyExc_OverflowError); if (count == -1 && PyErr_Occurred()) return NULL; } @@ -809,23 +809,87 @@ int_from_string(const char *s, Py_ssize_t len) return x; } -/* Return a Py_ssize_t integer from the object item */ -Py_ssize_t +/* Return a Python Int or Long from the object item + Raise TypeError if the result is not an int-or-long + or if the object cannot be interpreted as an index. +*/ +PyObject * PyNumber_Index(PyObject *item) { - Py_ssize_t value = -1; - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - value = nb->nb_index(item); + PyObject *result = NULL; + if (item == NULL) + return null_error(); + if (PyInt_Check(item) || PyLong_Check(item)) { + Py_INCREF(item); + return item; + } + if (PyIndex_Check(item)) { + result = item->ob_type->tp_as_number->nb_index(item); + if (result && + !PyInt_Check(result) && !PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__index__ returned non-(int,long) " \ + "(type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } } else { PyErr_Format(PyExc_TypeError, "'%.200s' object cannot be interpreted " "as an index", item->ob_type->tp_name); } - return value; + return result; } +/* Return an error on Overflow only if err is not NULL*/ + +Py_ssize_t +PyNumber_AsSsize_t(PyObject *item, PyObject *err) +{ + Py_ssize_t result; + PyObject *runerr; + PyObject *value = PyNumber_Index(item); + if (value == NULL) + return -1; + + /* We're done if PyInt_AsSsize_t() returns without error. */ + result = PyInt_AsSsize_t(value); + if (result != -1 || !(runerr = PyErr_Occurred())) + goto finish; + + /* Error handling code -- only manage OverflowError differently */ + if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) + goto finish; + + PyErr_Clear(); + /* If no error-handling desired then the default clipping + is sufficient. + */ + if (!err) { + assert(PyLong_Check(value)); + /* Whether or not it is less than or equal to + zero is determined by the sign of ob_size + */ + if (_PyLong_Sign(value) < 0) + result = PY_SSIZE_T_MIN; + else + result = PY_SSIZE_T_MAX; + } + else { + /* Otherwise replace the error with caller's error object. */ + PyErr_Format(err, + "cannot fit '%.200s' into an index-sized integer", + item->ob_type->tp_name); + } + + finish: + Py_DECREF(value); + return result; +} + + PyObject * PyNumber_Int(PyObject *o) { diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 2ee71bb..241281e 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -245,10 +245,9 @@ bytes_contains(PyBytesObject *self, PyObject *value) if (PyBytes_Check(value)) return bytes_substring(self, (PyBytesObject *)value); - ival = PyNumber_Index(value); + ival = PyNumber_AsSsize_t(value, PyExc_TypeError); if (ival == -1 && PyErr_Occurred()) return -1; - if (ival < 0 || ival >= 256) { PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); return -1; @@ -366,7 +365,7 @@ bytes_setitem(PyBytesObject *self, Py_ssize_t i, PyObject *value) if (value == NULL) return bytes_setslice(self, i, i+1, NULL); - ival = PyNumber_Index(value); + ival = PyNumber_AsSsize_t(value, PyExc_TypeError); if (ival == -1 && PyErr_Occurred()) return -1; @@ -449,7 +448,7 @@ bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds) } /* Is it an int? */ - count = PyNumber_Index(arg); + count = PyNumber_AsSsize_t(arg, PyExc_TypeError); if (count == -1 && PyErr_Occurred()) PyErr_Clear(); else { @@ -501,7 +500,7 @@ bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds) } /* Interpret it as an int (__index__) */ - value = PyNumber_Index(item); + value = PyNumber_AsSsize_t(item, PyExc_TypeError); Py_DECREF(item); if (value == -1 && PyErr_Occurred()) goto error; diff --git a/Objects/exceptions.c b/Objects/exceptions.c index be9627c..c3ead69 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1948,6 +1948,14 @@ SimpleExtendsException(PyExc_Warning, ImportWarning, "Base class for warnings about probable mistakes in module imports"); +/* + * UnicodeWarning extends Warning + */ +SimpleExtendsException(PyExc_Warning, UnicodeWarning, + "Base class for warnings about Unicode related problems, mostly\n" + "related to conversion problems."); + + /* Pre-computed MemoryError instance. Best to create this as early as * possible and not wait until a MemoryError is actually raised! */ @@ -2048,6 +2056,7 @@ _PyExc_Init(void) PRE_INIT(RuntimeWarning) PRE_INIT(FutureWarning) PRE_INIT(ImportWarning) + PRE_INIT(UnicodeWarning) m = Py_InitModule4("exceptions", functions, exceptions_doc, (PyObject *)NULL, PYTHON_API_VERSION); @@ -2113,6 +2122,7 @@ _PyExc_Init(void) POST_INIT(RuntimeWarning) POST_INIT(FutureWarning) POST_INIT(ImportWarning) + POST_INIT(UnicodeWarning) PyExc_MemoryErrorInst = BaseException_new(&_PyExc_MemoryError, NULL, NULL); if (!PyExc_MemoryErrorInst) diff --git a/Objects/intobject.c b/Objects/intobject.c index f070404..0ff2321 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -193,16 +193,21 @@ PyInt_AsSsize_t(register PyObject *op) PyIntObject *io; Py_ssize_t val; #endif - if (op && !PyInt_CheckExact(op) && PyLong_Check(op)) + + if (op == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + + if (PyInt_Check(op)) + return PyInt_AS_LONG((PyIntObject*) op); + if (PyLong_Check(op)) return _PyLong_AsSsize_t(op); #if SIZEOF_SIZE_T == SIZEOF_LONG return PyInt_AsLong(op); #else - if (op && PyInt_Check(op)) - return PyInt_AS_LONG((PyIntObject*) op); - - if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || + if ((nb = op->ob_type->tp_as_number) == NULL || (nb->nb_int == NULL && nb->nb_long == 0)) { PyErr_SetString(PyExc_TypeError, "an integer is required"); return -1; @@ -1045,7 +1050,7 @@ static PyNumberMethods int_as_number = { int_true_divide, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ - PyInt_AsSsize_t, /* nb_index */ + (unaryfunc)int_int, /* nb_index */ }; PyTypeObject PyInt_Type = { diff --git a/Objects/listobject.c b/Objects/listobject.c index b84998f..ab408e9 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1398,7 +1398,7 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject *compare; PyObject **dest; int result = -1; /* guilty until proved innocent */ - Py_ssize_t min_gallop = ms->min_gallop; + Py_ssize_t min_gallop; assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb); if (MERGE_GETMEM(ms, na) < 0) @@ -1414,6 +1414,7 @@ merge_lo(MergeState *ms, PyObject **pa, Py_ssize_t na, if (na == 1) goto CopyB; + min_gallop = ms->min_gallop; compare = ms->compare; for (;;) { Py_ssize_t acount = 0; /* # of times A won in a row */ @@ -1531,7 +1532,7 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t int result = -1; /* guilty until proved innocent */ PyObject **basea; PyObject **baseb; - Py_ssize_t min_gallop = ms->min_gallop; + Py_ssize_t min_gallop; assert(ms && pa && pb && na > 0 && nb > 0 && pa + na == pb); if (MERGE_GETMEM(ms, nb) < 0) @@ -1550,6 +1551,7 @@ merge_hi(MergeState *ms, PyObject **pa, Py_ssize_t na, PyObject **pb, Py_ssize_t if (nb == 1) goto CopyA; + min_gallop = ms->min_gallop; compare = ms->compare; for (;;) { Py_ssize_t acount = 0; /* # of times A won in a row */ @@ -2445,9 +2447,9 @@ PyDoc_STRVAR(list_doc, static PyObject * list_subscript(PyListObject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i; + i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) @@ -2494,9 +2496,8 @@ list_subscript(PyListObject* self, PyObject* item) static int list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return -1; if (i < 0) @@ -2531,6 +2532,10 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) garbage = (PyObject**) PyMem_MALLOC(slicelength*sizeof(PyObject*)); + if (!garbage) { + PyErr_NoMemory(); + return -1; + } /* drawing pictures might help understand these for loops */ @@ -2579,9 +2584,9 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) else { seq = PySequence_Fast(value, "must assign iterable to extended slice"); - if (!seq) - return -1; } + if (!seq) + return -1; if (PySequence_Fast_GET_SIZE(seq) != slicelength) { PyErr_Format(PyExc_ValueError, diff --git a/Objects/longobject.c b/Objects/longobject.c index a2690a2..16c7043 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -240,8 +240,11 @@ PyLong_AsLong(PyObject *vv) return -1; } -static Py_ssize_t -_long_as_ssize_t(PyObject *vv) { +/* Get a Py_ssize_t from a long int object. + Returns -1 and sets an error condition if overflow occurs. */ + +Py_ssize_t +_PyLong_AsSsize_t(PyObject *vv) { register PyLongObject *v; size_t x, prev; Py_ssize_t i; @@ -277,45 +280,7 @@ _long_as_ssize_t(PyObject *vv) { overflow: PyErr_SetString(PyExc_OverflowError, "long int too large to convert to int"); - if (sign > 0) - return PY_SSIZE_T_MAX; - else - return PY_SSIZE_T_MIN; -} - -/* Get a Py_ssize_t from a long int object. - Returns -1 and sets an error condition if overflow occurs. */ - -Py_ssize_t -_PyLong_AsSsize_t(PyObject *vv) -{ - Py_ssize_t x; - - x = _long_as_ssize_t(vv); - if (PyErr_Occurred()) return -1; - return x; -} - - -/* Get a Py_ssize_t from a long int object. - Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX, - and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1. - On error, return -1 with an exception set. -*/ - -static Py_ssize_t -long_index(PyObject *vv) -{ - Py_ssize_t x; - - x = _long_as_ssize_t(vv); - if (PyErr_Occurred()) { - /* If overflow error, ignore the error */ - if (x != -1) { - PyErr_Clear(); - } - } - return x; + return -1; } /* Get a C unsigned long int from a long int object. @@ -3379,7 +3344,7 @@ static PyNumberMethods long_as_number = { long_true_divide, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ - long_index, /* nb_index */ + long_long, /* nb_index */ }; PyTypeObject PyLong_Type = { diff --git a/Objects/object.c b/Objects/object.c index 44b3f7d..cb60320 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -725,23 +725,6 @@ default_3way_compare(PyObject *v, PyObject *w) return (vv < ww) ? -1 : (vv > ww) ? 1 : 0; } -#ifdef Py_USING_UNICODE - /* Special case for Unicode */ - if (PyUnicode_Check(v) || PyUnicode_Check(w)) { - c = PyUnicode_Compare(v, w); - if (!PyErr_Occurred()) - return c; - /* TypeErrors are ignored: if Unicode coercion fails due - to one of the arguments not having the right type, we - continue as defined by the coercion protocol (see - above). Luckily, decoding errors are reported as - ValueErrors and are not masked by this technique. */ - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return -2; - PyErr_Clear(); - } -#endif - /* None is smaller than anything */ if (v == Py_None) return -1; diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 271a9ad..d8a2465 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -252,7 +252,7 @@ slice_indices(PySliceObject* self, PyObject* len) { Py_ssize_t ilen, start, stop, step, slicelength; - ilen = PyInt_AsSsize_t(len); + ilen = PyNumber_AsSsize_t(len, PyExc_OverflowError); if (ilen == -1 && PyErr_Occurred()) { return NULL; diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 7ba15a0..028b375 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -1187,9 +1187,8 @@ string_hash(PyStringObject *a) static PyObject* string_subscript(PyStringObject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) @@ -4226,12 +4225,17 @@ _PyString_FormatLong(PyObject *val, int flags, int prec, int type, if (!result) return NULL; + buf = PyString_AsString(result); + if (!buf) { + Py_DECREF(result); + return NULL; + } + /* To modify the string in-place, there can only be one reference. */ if (result->ob_refcnt != 1) { PyErr_BadInternalCall(); return NULL; } - buf = PyString_AsString(result); llen = PyString_Size(result); if (llen > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_ValueError, "string too large in _PyString_FormatLong"); diff --git a/Objects/structseq.c b/Objects/structseq.c index e074810..7ac2a1f 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -215,6 +215,8 @@ structseq_contains(PyStructSequence *obj, PyObject *o) PyObject *tup; int result; tup = make_tuple(obj); + if (!tup) + return -1; result = PySequence_Contains(tup, o); Py_DECREF(tup); return result; @@ -226,6 +228,8 @@ structseq_hash(PyObject *obj) PyObject *tup; long result; tup = make_tuple((PyStructSequence*) obj); + if (!tup) + return -1; result = PyObject_Hash(tup); Py_DECREF(tup); return result; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 53afab5..6f3711f 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -580,9 +580,8 @@ static PySequenceMethods tuple_as_sequence = { static PyObject* tuplesubscript(PyTupleObject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e9ffa87..1578801 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3373,7 +3373,7 @@ wrap_indexargfunc(PyObject *self, PyObject *args, void *wrapped) if (!PyArg_UnpackTuple(args, "", 1, 1, &o)) return NULL; - i = PyNumber_Index(o); + i = PyNumber_AsSsize_t(o, PyExc_OverflowError); if (i == -1 && PyErr_Occurred()) return NULL; return (*func)(self, i); @@ -3384,7 +3384,7 @@ getindex(PyObject *self, PyObject *arg) { Py_ssize_t i; - i = PyNumber_Index(arg); + i = PyNumber_AsSsize_t(arg, PyExc_OverflowError); if (i == -1 && PyErr_Occurred()) return -1; if (i < 0) { @@ -3956,19 +3956,17 @@ slot_sq_length(PyObject *self) { static PyObject *len_str; PyObject *res = call_method(self, "__len__", &len_str, "()"); - Py_ssize_t temp; Py_ssize_t len; if (res == NULL) return -1; - temp = PyInt_AsSsize_t(res); - len = (int)temp; + len = PyInt_AsSsize_t(res); Py_DECREF(res); if (len == -1 && PyErr_Occurred()) return -1; -#if SIZEOF_SIZE_T < SIZEOF_LONG +#if SIZEOF_SIZE_T < SIZEOF_INT /* Overflow check -- range of PyInt is more than C ssize_t */ - if (len != temp) { + if (len != (int)len) { PyErr_SetString(PyExc_OverflowError, "__len__() should return 0 <= outcome < 2**31"); return -1; @@ -4189,26 +4187,11 @@ slot_nb_nonzero(PyObject *self) } -static Py_ssize_t +static PyObject * slot_nb_index(PyObject *self) { static PyObject *index_str; - PyObject *temp = call_method(self, "__index__", &index_str, "()"); - Py_ssize_t result; - - if (temp == NULL) - return -1; - if (PyInt_CheckExact(temp) || PyLong_CheckExact(temp)) { - result = temp->ob_type->tp_as_number->nb_index(temp); - } - else { - PyErr_Format(PyExc_TypeError, - "__index__ must return an int or a long, " - "not '%.200s'", temp->ob_type->tp_name); - result = -1; - } - Py_DECREF(temp); - return result; + return call_method(self, "__index__", &index_str, "()"); } @@ -4882,7 +4865,7 @@ static slotdef slotdefs[] = { "oct(x)"), UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc, "hex(x)"), - NBSLOT("__index__", nb_index, slot_nb_index, wrap_lenfunc, + NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, "x[y:z] <==> x[y.__index__():z.__index__()]"), IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, wrap_binaryfunc, "+"), diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index e63e629..92301c0 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -5405,6 +5405,82 @@ onError: return -1; } +PyObject *PyUnicode_RichCompare(PyObject *left, + PyObject *right, + int op) +{ + int result; + + result = PyUnicode_Compare(left, right); + if (result == -1 && PyErr_Occurred()) + goto onError; + + /* Convert the return value to a Boolean */ + switch (op) { + case Py_EQ: + result = (result == 0); + break; + case Py_NE: + result = (result != 0); + break; + case Py_LE: + result = (result <= 0); + break; + case Py_GE: + result = (result >= 0); + break; + case Py_LT: + result = (result == -1); + break; + case Py_GT: + result = (result == 1); + break; + } + return PyBool_FromLong(result); + + onError: + + /* Standard case + + Type errors mean that PyUnicode_FromObject() could not convert + one of the arguments (usually the right hand side) to Unicode, + ie. we can't handle the comparison request. However, it is + possible that the other object knows a comparison method, which + is why we return Py_NotImplemented to give the other object a + chance. + + */ + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + if (op != Py_EQ && op != Py_NE) + return NULL; + + /* Equality comparison. + + This is a special case: we silence any PyExc_UnicodeDecodeError + and instead turn it into a PyErr_UnicodeWarning. + + */ + if (!PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) + return NULL; + PyErr_Clear(); + if (PyErr_Warn(PyExc_UnicodeWarning, + (op == Py_EQ) ? + "Unicode equal comparison " + "failed to convert both arguments to Unicode - " + "interpreting them as being unequal" : + "Unicode unequal comparison " + "failed to convert both arguments to Unicode - " + "interpreting them as being unequal" + ) < 0) + return NULL; + result = (op == Py_NE); + return PyBool_FromLong(result); +} + int PyUnicode_Contains(PyObject *container, PyObject *element) { @@ -6987,9 +7063,8 @@ static PySequenceMethods unicode_as_sequence = { static PyObject* unicode_subscript(PyUnicodeObject* self, PyObject* item) { - PyNumberMethods *nb = item->ob_type->tp_as_number; - if (nb != NULL && nb->nb_index != NULL) { - Py_ssize_t i = nb->nb_index(item); + if (PyIndex_Check(item)) { + Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) @@ -7861,7 +7936,7 @@ PyTypeObject PyUnicode_Type = { 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - (cmpfunc) unicode_compare, /* tp_compare */ + 0, /* tp_compare */ unicode_repr, /* tp_repr */ &unicode_as_number, /* tp_as_number */ &unicode_as_sequence, /* tp_as_sequence */ @@ -7876,7 +7951,7 @@ PyTypeObject PyUnicode_Type = { unicode_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - 0, /* tp_richcompare */ + PyUnicode_RichCompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ unicode_iter, /* tp_iter */ 0, /* tp_iternext */ |