mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									e6dd31c50b
								
							
						
					
					
						commit
						040f76b79c
					
				
					 11 changed files with 170 additions and 36 deletions
				
			
		|  | @ -5405,6 +5405,82 @@ int PyUnicode_Compare(PyObject *left, | |||
|     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 */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Marc-André Lemburg
						Marc-André Lemburg