diff --git a/Include/internal/pycore_codecs.h b/Include/internal/pycore_codecs.h index dd4e175cf5eeda..5e2d5c5ce9d868 100644 --- a/Include/internal/pycore_codecs.h +++ b/Include/internal/pycore_codecs.h @@ -10,11 +10,15 @@ extern "C" { #include "pycore_lock.h" // PyMutex -/* Initialize codecs-related state for the given interpreter. Must be called - before any other _PyCodec* functions, and while only one thread is - active. */ +/* Initialize codecs-related state for the given interpreter, including + registering the first codec search function. Must be called before any other + PyCodec-related functions, and while only one thread is active. */ extern PyStatus _PyCodec_InitRegistry(PyInterpreterState *interp); +/* Finalize codecs-related state for the given interpreter. No PyCodec-related + functions other than PyCodec_Unregister() may be called after this. */ +extern void _PyCodec_Fini(PyInterpreterState *interp); + extern PyObject* _PyCodec_Lookup(const char *encoding); /* Text codec specific encoding and decoding API. diff --git a/Objects/object.c b/Objects/object.c index 4c1676d77c471e..016d0e1ded92d8 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -473,6 +473,7 @@ void PyObject_CallFinalizer(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); + if (tp->tp_finalize == NULL) return; /* tp_finalize should only be called once. */ diff --git a/Python/codecs.c b/Python/codecs.c index a02e20f4683452..bed245366f9234 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -20,17 +20,6 @@ const char *Py_hexdigits = "0123456789abcdef"; /* --- Codec Registry ----------------------------------------------------- */ -/* Import the standard encodings package which will register the first - codec search function. - - This is done in a lazy way so that the Unicode implementation does - not downgrade startup time of scripts not needing it. - - ImportErrors are silently ignored by this function. Only one try is - made. - -*/ - int PyCodec_Register(PyObject *search_function) { PyInterpreterState *interp = _PyInterpreterState_GET(); @@ -1389,7 +1378,8 @@ static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc) return PyCodec_SurrogateEscapeErrors(exc); } -PyStatus _PyCodec_InitRegistry(PyInterpreterState *interp) +PyStatus +_PyCodec_InitRegistry(PyInterpreterState *interp) { static struct { const char *name; @@ -1516,3 +1506,12 @@ PyStatus _PyCodec_InitRegistry(PyInterpreterState *interp) return PyStatus_Ok(); } + +void +_PyCodec_Fini(PyInterpreterState *interp) +{ + Py_CLEAR(interp->codecs.search_path); + Py_CLEAR(interp->codecs.search_cache); + Py_CLEAR(interp->codecs.error_registry); + interp->codecs.initialized = 0; +} diff --git a/Python/pystate.c b/Python/pystate.c index b1c83cf2daa5be..811d192820bdc8 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -838,10 +838,7 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) } PyConfig_Clear(&interp->config); - Py_CLEAR(interp->codecs.search_path); - Py_CLEAR(interp->codecs.search_cache); - Py_CLEAR(interp->codecs.error_registry); - interp->codecs.initialized = 0; + _PyCodec_Fini(interp); assert(interp->imports.modules == NULL); assert(interp->imports.modules_by_index == NULL);