summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c102
-rw-r--r--Objects/bytesobject.c9
-rw-r--r--Objects/exceptions.c10
-rw-r--r--Objects/intobject.c17
-rw-r--r--Objects/listobject.c25
-rw-r--r--Objects/longobject.c49
-rw-r--r--Objects/object.c17
-rw-r--r--Objects/sliceobject.c2
-rw-r--r--Objects/stringobject.c12
-rw-r--r--Objects/structseq.c4
-rw-r--r--Objects/tupleobject.c5
-rw-r--r--Objects/typeobject.c33
-rw-r--r--Objects/unicodeobject.c85
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 */