+import _codecs
import codecs
import contextlib
import copy
self.assertEqual(codecs.iconv_encode(enc, 'a€b', 'xmlcharrefreplace')[0],
b'a€b')
+ def test_encode_errors_unencodable_replacement(self):
+ # Encoding the replacement must not call the error handler again.
+ enc = self.require('ASCII')
+ codecs.register_error('test.iconv', lambda exc: ('€', exc.end))
+ self.addCleanup(_codecs._unregister_error, 'test.iconv')
+ with self.assertRaises(UnicodeEncodeError) as cm:
+ codecs.iconv_encode(enc, 'a€b', 'test.iconv')
+ self.assertEqual((cm.exception.start, cm.exception.end), (1, 2))
+ self.assertEqual(cm.exception.reason,
+ 'unable to encode error handler result')
+
def test_decode_errors(self):
enc = self.require('ASCII')
bad = b'a\xffb'
replen = PyBytes_GET_SIZE(rep);
}
else {
- /* A str replacement is encoded through the same codec. */
+ /* A str replacement is encoded through the same codec, but
+ strictly: handling its errors in turn could never terminate. */
assert(PyUnicode_Check(rep));
- repbytes = _PyUnicode_EncodeIconv(encoding, rep, errors);
+ repbytes = _PyUnicode_EncodeIconv(encoding, rep, NULL);
Py_DECREF(rep);
if (repbytes == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
+ /* Report the input the caller knows about, not the
+ replacement. */
+ PyErr_Clear();
+ raise_encode_exception(&exc, encoding, unicode, pos, pos + 1,
+ "unable to encode error handler result");
+ }
goto done;
}
repdata = PyBytes_AS_STRING(repbytes);