Skip to content

Commit 36bb229

Browse files
authored
gh-129173: Use _PyUnicodeError_GetParams in PyCodec_IgnoreErrors (#129174)
We also cleanup `PyCodec_StrictErrors` and the error message rendered when an object of incorrect type is passed to codec error handlers.
1 parent 732670d commit 36bb229

File tree

1 file changed

+43
-19
lines changed

1 file changed

+43
-19
lines changed

Python/codecs.c

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -659,44 +659,64 @@ PyObject *PyCodec_LookupError(const char *name)
659659
return handler;
660660
}
661661

662-
static void wrong_exception_type(PyObject *exc)
662+
663+
static inline void
664+
wrong_exception_type(PyObject *exc)
663665
{
664666
PyErr_Format(PyExc_TypeError,
665-
"don't know how to handle %.200s in error callback",
666-
Py_TYPE(exc)->tp_name);
667+
"don't know how to handle %T in error callback", exc);
667668
}
668669

670+
671+
#define _PyIsUnicodeEncodeError(EXC) \
672+
PyObject_TypeCheck(EXC, (PyTypeObject *)PyExc_UnicodeEncodeError)
673+
#define _PyIsUnicodeDecodeError(EXC) \
674+
PyObject_TypeCheck(EXC, (PyTypeObject *)PyExc_UnicodeDecodeError)
675+
#define _PyIsUnicodeTranslateError(EXC) \
676+
PyObject_TypeCheck(EXC, (PyTypeObject *)PyExc_UnicodeTranslateError)
677+
678+
679+
// --- handler: 'strict' ------------------------------------------------------
680+
669681
PyObject *PyCodec_StrictErrors(PyObject *exc)
670682
{
671-
if (PyExceptionInstance_Check(exc))
683+
if (PyExceptionInstance_Check(exc)) {
672684
PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
673-
else
685+
}
686+
else {
674687
PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
688+
}
675689
return NULL;
676690
}
677691

678692

679-
PyObject *PyCodec_IgnoreErrors(PyObject *exc)
693+
// --- handler: 'ignore' ------------------------------------------------------
694+
695+
static PyObject *
696+
_PyCodec_IgnoreError(PyObject *exc, int as_bytes)
680697
{
681698
Py_ssize_t end;
682-
683-
if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
684-
if (PyUnicodeEncodeError_GetEnd(exc, &end))
685-
return NULL;
699+
if (_PyUnicodeError_GetParams(exc, NULL, NULL, NULL,
700+
&end, NULL, as_bytes) < 0)
701+
{
702+
return NULL;
686703
}
687-
else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
688-
if (PyUnicodeDecodeError_GetEnd(exc, &end))
689-
return NULL;
704+
return Py_BuildValue("(Nn)", Py_GetConstant(Py_CONSTANT_EMPTY_STR), end);
705+
}
706+
707+
708+
PyObject *PyCodec_IgnoreErrors(PyObject *exc)
709+
{
710+
if (_PyIsUnicodeEncodeError(exc) || _PyIsUnicodeTranslateError(exc)) {
711+
return _PyCodec_IgnoreError(exc, false);
690712
}
691-
else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) {
692-
if (PyUnicodeTranslateError_GetEnd(exc, &end))
693-
return NULL;
713+
else if (_PyIsUnicodeDecodeError(exc)) {
714+
return _PyCodec_IgnoreError(exc, true);
694715
}
695716
else {
696717
wrong_exception_type(exc);
697718
return NULL;
698719
}
699-
return Py_BuildValue("(Nn)", Py_GetConstant(Py_CONSTANT_EMPTY_STR), end);
700720
}
701721

702722

@@ -1368,13 +1388,17 @@ PyCodec_SurrogateEscapeErrors(PyObject *exc)
13681388
}
13691389

13701390

1371-
static PyObject *strict_errors(PyObject *self, PyObject *exc)
1391+
// --- Codecs registry handlers -----------------------------------------------
1392+
1393+
static inline PyObject *
1394+
strict_errors(PyObject *Py_UNUSED(self), PyObject *exc)
13721395
{
13731396
return PyCodec_StrictErrors(exc);
13741397
}
13751398

13761399

1377-
static PyObject *ignore_errors(PyObject *self, PyObject *exc)
1400+
static inline PyObject *
1401+
ignore_errors(PyObject *Py_UNUSED(self), PyObject *exc)
13781402
{
13791403
return PyCodec_IgnoreErrors(exc);
13801404
}

0 commit comments

Comments
 (0)