mirror of https://github.com/python/cpython
bpo-46417: Clear _io module static objects at exit (GH-30807)
Add _PyIO_Fini() function, called by finalize_interp_clear(). It clears static objects used by the _io extension module.
This commit is contained in:
parent
1626bf4ac7
commit
9c8e490b8f
|
@ -666,6 +666,82 @@ struct PyModuleDef _PyIO_Module = {
|
|||
(freefunc)iomodule_free,
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject* static_types[] = {
|
||||
// Base classes
|
||||
&PyIOBase_Type,
|
||||
&PyIncrementalNewlineDecoder_Type,
|
||||
|
||||
// PyIOBase_Type subclasses
|
||||
&PyBufferedIOBase_Type,
|
||||
&PyRawIOBase_Type,
|
||||
&PyTextIOBase_Type,
|
||||
|
||||
// PyBufferedIOBase_Type(PyIOBase_Type) subclasses
|
||||
&PyBytesIO_Type,
|
||||
&PyBufferedReader_Type,
|
||||
&PyBufferedWriter_Type,
|
||||
&PyBufferedRWPair_Type,
|
||||
&PyBufferedRandom_Type,
|
||||
|
||||
// PyRawIOBase_Type(PyIOBase_Type) subclasses
|
||||
&PyFileIO_Type,
|
||||
&_PyBytesIOBuffer_Type,
|
||||
#ifdef MS_WINDOWS
|
||||
&PyWindowsConsoleIO_Type,
|
||||
#endif
|
||||
|
||||
// PyTextIOBase_Type(PyIOBase_Type) subclasses
|
||||
&PyStringIO_Type,
|
||||
&PyTextIOWrapper_Type,
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
_PyIO_Fini(void)
|
||||
{
|
||||
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) {
|
||||
PyTypeObject *exc = static_types[i];
|
||||
_PyStaticType_Dealloc(exc);
|
||||
}
|
||||
|
||||
/* Interned strings */
|
||||
#define CLEAR_INTERNED(name) \
|
||||
Py_CLEAR(_PyIO_str_ ## name)
|
||||
|
||||
CLEAR_INTERNED(close);
|
||||
CLEAR_INTERNED(closed);
|
||||
CLEAR_INTERNED(decode);
|
||||
CLEAR_INTERNED(encode);
|
||||
CLEAR_INTERNED(fileno);
|
||||
CLEAR_INTERNED(flush);
|
||||
CLEAR_INTERNED(getstate);
|
||||
CLEAR_INTERNED(isatty);
|
||||
CLEAR_INTERNED(locale);
|
||||
CLEAR_INTERNED(newlines);
|
||||
CLEAR_INTERNED(peek);
|
||||
CLEAR_INTERNED(read);
|
||||
CLEAR_INTERNED(read1);
|
||||
CLEAR_INTERNED(readable);
|
||||
CLEAR_INTERNED(readall);
|
||||
CLEAR_INTERNED(readinto);
|
||||
CLEAR_INTERNED(readline);
|
||||
CLEAR_INTERNED(reset);
|
||||
CLEAR_INTERNED(seek);
|
||||
CLEAR_INTERNED(seekable);
|
||||
CLEAR_INTERNED(setstate);
|
||||
CLEAR_INTERNED(tell);
|
||||
CLEAR_INTERNED(truncate);
|
||||
CLEAR_INTERNED(write);
|
||||
CLEAR_INTERNED(writable);
|
||||
#undef CLEAR_INTERNED
|
||||
|
||||
Py_CLEAR(_PyIO_str_nl);
|
||||
Py_CLEAR(_PyIO_empty_str);
|
||||
Py_CLEAR(_PyIO_empty_bytes);
|
||||
}
|
||||
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit__io(void)
|
||||
{
|
||||
|
@ -676,11 +752,6 @@ PyInit__io(void)
|
|||
state = get_io_state(m);
|
||||
state->initialized = 0;
|
||||
|
||||
#define ADD_TYPE(type) \
|
||||
if (PyModule_AddType(m, type) < 0) { \
|
||||
goto fail; \
|
||||
}
|
||||
|
||||
/* DEFAULT_BUFFER_SIZE */
|
||||
if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0)
|
||||
goto fail;
|
||||
|
@ -702,57 +773,34 @@ PyInit__io(void)
|
|||
(PyObject *) PyExc_BlockingIOError) < 0)
|
||||
goto fail;
|
||||
|
||||
/* Concrete base types of the IO ABCs.
|
||||
(the ABCs themselves are declared through inheritance in io.py)
|
||||
*/
|
||||
ADD_TYPE(&PyIOBase_Type);
|
||||
ADD_TYPE(&PyRawIOBase_Type);
|
||||
ADD_TYPE(&PyBufferedIOBase_Type);
|
||||
ADD_TYPE(&PyTextIOBase_Type);
|
||||
|
||||
/* Implementation of concrete IO objects. */
|
||||
/* FileIO */
|
||||
// Set type base classes
|
||||
PyFileIO_Type.tp_base = &PyRawIOBase_Type;
|
||||
ADD_TYPE(&PyFileIO_Type);
|
||||
|
||||
/* BytesIO */
|
||||
PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
|
||||
ADD_TYPE(&PyBytesIO_Type);
|
||||
if (PyType_Ready(&_PyBytesIOBuffer_Type) < 0)
|
||||
goto fail;
|
||||
|
||||
/* StringIO */
|
||||
PyStringIO_Type.tp_base = &PyTextIOBase_Type;
|
||||
ADD_TYPE(&PyStringIO_Type);
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/* WindowsConsoleIO */
|
||||
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
|
||||
ADD_TYPE(&PyWindowsConsoleIO_Type);
|
||||
#endif
|
||||
|
||||
/* BufferedReader */
|
||||
PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
|
||||
ADD_TYPE(&PyBufferedReader_Type);
|
||||
|
||||
/* BufferedWriter */
|
||||
PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
|
||||
ADD_TYPE(&PyBufferedWriter_Type);
|
||||
|
||||
/* BufferedRWPair */
|
||||
PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
|
||||
ADD_TYPE(&PyBufferedRWPair_Type);
|
||||
|
||||
/* BufferedRandom */
|
||||
PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
|
||||
ADD_TYPE(&PyBufferedRandom_Type);
|
||||
|
||||
/* TextIOWrapper */
|
||||
PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
|
||||
ADD_TYPE(&PyTextIOWrapper_Type);
|
||||
|
||||
/* IncrementalNewlineDecoder */
|
||||
ADD_TYPE(&PyIncrementalNewlineDecoder_Type);
|
||||
// Add types
|
||||
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
|
||||
PyTypeObject *type = static_types[i];
|
||||
// Private type not exposed in the _io module
|
||||
if (type == &_PyBytesIOBuffer_Type) {
|
||||
if (PyType_Ready(type) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (PyModule_AddType(m, type) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Interned strings */
|
||||
#define ADD_INTERNED(name) \
|
||||
|
@ -785,6 +833,7 @@ PyInit__io(void)
|
|||
ADD_INTERNED(truncate)
|
||||
ADD_INTERNED(write)
|
||||
ADD_INTERNED(writable)
|
||||
#undef ADD_INTERNED
|
||||
|
||||
if (!_PyIO_str_nl &&
|
||||
!(_PyIO_str_nl = PyUnicode_InternFromString("\n")))
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "pycore_typeobject.h" // _PyTypes_InitTypes()
|
||||
#include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
|
||||
|
||||
extern void _PyIO_Fini(void);
|
||||
|
||||
#include <locale.h> // setlocale()
|
||||
#include <stdlib.h> // getenv()
|
||||
|
||||
|
@ -1702,6 +1704,10 @@ finalize_interp_clear(PyThreadState *tstate)
|
|||
/* Clear interpreter state and all thread states */
|
||||
_PyInterpreterState_Clear(tstate);
|
||||
|
||||
if (is_main_interp) {
|
||||
_PyIO_Fini();
|
||||
}
|
||||
|
||||
/* Clear all loghooks */
|
||||
/* Both _PySys_Audit function and users still need PyObject, such as tuple.
|
||||
Call _PySys_ClearAuditHooks when PyObject available. */
|
||||
|
|
Loading…
Reference in New Issue