diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -2455,16 +2455,22 @@ class RawUnicodeEscapeTest(unittest.Test self.assertEqual(decode(data, "ignore"), ("[]", len(data))) self.assertEqual(decode(data, "replace"), ("[\ufffd]\ufffd", len(data))) self.assertRaises(UnicodeDecodeError, decode, br"\U00110000") self.assertEqual(decode(br"\U00110000", "ignore"), ("", 10)) self.assertEqual(decode(br"\U00110000", "replace"), ("\ufffd", 10)) +class EscapeEncodeTest(unittest.TestCase): + + def test_escape_encode(self): + self.assertEqual(codecs.escape_encode(b''), (b'', 0)) + + class SurrogateEscapeTest(unittest.TestCase): def test_utf8(self): # Bad byte self.assertEqual(b"foo\x80bar".decode("utf-8", "surrogateescape"), "foo\udc80bar") self.assertEqual("foo\udc80bar".encode("utf-8", "surrogateescape"), b"foo\x80bar") diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -202,16 +202,22 @@ static PyObject * const char *errors) /*[clinic end generated code: output=fcd6f34fe4111c50 input=da9ded00992f32f2]*/ { Py_ssize_t size; Py_ssize_t newsize; PyObject *v; size = PyBytes_GET_SIZE(data); + if (size == 0) { + v = PyBytes_FromStringAndSize(NULL, size); + if (v == NULL) + return NULL; + return codec_tuple(v, size); + } if (size > PY_SSIZE_T_MAX / 4) { PyErr_SetString(PyExc_OverflowError, "string is too large to encode"); return NULL; } newsize = 4*size; v = PyBytes_FromStringAndSize(NULL, newsize);