summaryrefslogtreecommitdiffstats
path: root/Objects/unicodeobject.c
diff options
context:
space:
mode:
authorMarc-André Lemburg <mal@egenix.com>2006-08-14 10:55:19 (GMT)
committerMarc-André Lemburg <mal@egenix.com>2006-08-14 10:55:19 (GMT)
commit040f76b79c0ce86dc33b9c525fbcd84b2254e559 (patch)
treee907d6c112d52b1a92d7b98c63023ca338c9a188 /Objects/unicodeobject.c
parente6dd31c50be76a5b57917226e16bdaa6ca20a28f (diff)
downloadcpython-040f76b79c0ce86dc33b9c525fbcd84b2254e559.zip
cpython-040f76b79c0ce86dc33b9c525fbcd84b2254e559.tar.gz
cpython-040f76b79c0ce86dc33b9c525fbcd84b2254e559.tar.bz2
Slightly revised version of patch #1538956:
Replace UnicodeDecodeErrors raised during == and != compares of Unicode and other objects with a new UnicodeWarning. All other comparisons continue to raise exceptions. Exceptions other than UnicodeDecodeErrors are also left untouched.
Diffstat (limited to 'Objects/unicodeobject.c')
-rw-r--r--Objects/unicodeobject.c87
1 files changed, 83 insertions, 4 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index ababda1..f4e3755 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)
{
@@ -6985,11 +7061,14 @@ static PySequenceMethods unicode_as_sequence = {
PyUnicode_Contains, /* sq_contains */
};
+#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
+
static PyObject*
unicode_subscript(PyUnicodeObject* self, PyObject* item)
{
- if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ PyNumberMethods *nb = item->ob_type->tp_as_number;
+ if (nb != NULL && HASINDEX(item) && nb->nb_index != NULL) {
+ Py_ssize_t i = nb->nb_index(item);
if (i == -1 && PyErr_Occurred())
return NULL;
if (i < 0)
@@ -7859,7 +7938,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 */
@@ -7875,7 +7954,7 @@ PyTypeObject PyUnicode_Type = {
unicode_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
- 0, /* tp_richcompare */
+ PyUnicode_RichCompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */