diff -r 670fb496f1f6 Lib/test/test_bytes.py --- a/Lib/test/test_bytes.py Sun May 11 23:37:26 2014 -0400 +++ b/Lib/test/test_bytes.py Tue May 13 03:21:07 2014 +0200 @@ -13,6 +13,7 @@ import functools import pickle import tempfile import unittest +import warnings import test.test_support import test.string_tests import test.buffer_tests @@ -194,9 +195,9 @@ class BaseBytesTest(unittest.TestCase): sample = u"Hello world\n\x80\x81\xfe\xff" b = self.type2test(sample, "latin1") self.assertRaises(UnicodeDecodeError, b.decode, "utf8") - self.assertEqual(b.decode("utf8", "ignore"), "Hello world\n") + self.assertEqual(b.decode("utf8", "ignore"), u"Hello world\n") self.assertEqual(b.decode(errors="ignore", encoding="utf8"), - "Hello world\n") + u"Hello world\n") def test_from_int(self): b = self.type2test(0) @@ -518,6 +519,28 @@ class BaseBytesTest(unittest.TestCase): self.assertRaisesRegexp(TypeError, r'\bendswith\b', b.endswith, x, None, None, None) + def test_compare(self): + if sys.flags.bytes_warning: + import contextlib + @contextlib.contextmanager + def bytes_warning(): + with warnings.catch_warnings(record=True) as warns: + warnings.simplefilter("default", BytesWarning) + yield + self.assertEqual(len(warns), 1, warns) + self.assertIsInstance(warns[0], warnings.WarningMessage) + with bytes_warning(): + self.type2test('') == u'' + with bytes_warning(): + self.type2test('') != u'' + + with bytes_warning(): + u'' == self.type2test('') + with bytes_warning(): + u'' != self.type2test('') + else: + self.skipTest("BytesWarning is needed for this test: use -bb option") + class ByteArrayTest(BaseBytesTest): type2test = bytearray diff -r 670fb496f1f6 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Sun May 11 23:37:26 2014 -0400 +++ b/Objects/bytearrayobject.c Tue May 13 03:21:07 2014 +0200 @@ -1029,7 +1029,7 @@ bytearray_richcompare(PyObject *self, Py #ifdef Py_USING_UNICODE if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) || PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) { - if (Py_BytesWarningFlag && op == Py_EQ) { + if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) { if (PyErr_WarnEx(PyExc_BytesWarning, "Comparison between bytearray and string", 1)) return NULL; diff -r 670fb496f1f6 Objects/stringobject.c --- a/Objects/stringobject.c Sun May 11 23:37:26 2014 -0400 +++ b/Objects/stringobject.c Tue May 13 03:21:07 2014 +0200 @@ -1197,6 +1197,15 @@ string_richcompare(PyStringObject *a, Py /* Make sure both arguments are strings. */ if (!(PyString_Check(a) && PyString_Check(b))) { + if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE) && + (PyObject_IsInstance((PyObject*)a, + (PyObject*)&PyUnicode_Type) || + PyObject_IsInstance((PyObject*)b, + (PyObject*)&PyUnicode_Type))) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytes and string", 1)) + return NULL; + } result = Py_NotImplemented; goto out; } diff -r 670fb496f1f6 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Sun May 11 23:37:26 2014 -0400 +++ b/Objects/unicodeobject.c Tue May 13 03:21:07 2014 +0200 @@ -6186,6 +6186,14 @@ int PyUnicode_Compare(PyObject *left, PyUnicodeObject *u = NULL, *v = NULL; int result; + if (Py_BytesWarningFlag + && (PyString_Check(left) || PyByteArray_Check(left) || + PyString_Check(right) || PyByteArray_Check(right))) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytearray and string", 1)) + return -1; + } + /* Coerce the two arguments */ u = (PyUnicodeObject *)PyUnicode_FromObject(left); if (u == NULL)