mirror of
https://github.com/python/cpython.git
synced 2025-10-08 08:01:55 +00:00
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
2 changed files with 99 additions and 44 deletions
|
@ -666,6 +666,82 @@ struct PyModuleDef _PyIO_Module = {
|
||||||
(freefunc)iomodule_free,
|
(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
|
PyMODINIT_FUNC
|
||||||
PyInit__io(void)
|
PyInit__io(void)
|
||||||
{
|
{
|
||||||
|
@ -676,11 +752,6 @@ PyInit__io(void)
|
||||||
state = get_io_state(m);
|
state = get_io_state(m);
|
||||||
state->initialized = 0;
|
state->initialized = 0;
|
||||||
|
|
||||||
#define ADD_TYPE(type) \
|
|
||||||
if (PyModule_AddType(m, type) < 0) { \
|
|
||||||
goto fail; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DEFAULT_BUFFER_SIZE */
|
/* DEFAULT_BUFFER_SIZE */
|
||||||
if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0)
|
if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -702,57 +773,34 @@ PyInit__io(void)
|
||||||
(PyObject *) PyExc_BlockingIOError) < 0)
|
(PyObject *) PyExc_BlockingIOError) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Concrete base types of the IO ABCs.
|
// Set type base classes
|
||||||
(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 */
|
|
||||||
PyFileIO_Type.tp_base = &PyRawIOBase_Type;
|
PyFileIO_Type.tp_base = &PyRawIOBase_Type;
|
||||||
ADD_TYPE(&PyFileIO_Type);
|
|
||||||
|
|
||||||
/* BytesIO */
|
|
||||||
PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
|
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;
|
PyStringIO_Type.tp_base = &PyTextIOBase_Type;
|
||||||
ADD_TYPE(&PyStringIO_Type);
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
/* WindowsConsoleIO */
|
|
||||||
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
|
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
|
||||||
ADD_TYPE(&PyWindowsConsoleIO_Type);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* BufferedReader */
|
|
||||||
PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
|
PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
|
||||||
ADD_TYPE(&PyBufferedReader_Type);
|
|
||||||
|
|
||||||
/* BufferedWriter */
|
|
||||||
PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
|
PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
|
||||||
ADD_TYPE(&PyBufferedWriter_Type);
|
|
||||||
|
|
||||||
/* BufferedRWPair */
|
|
||||||
PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
|
PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
|
||||||
ADD_TYPE(&PyBufferedRWPair_Type);
|
|
||||||
|
|
||||||
/* BufferedRandom */
|
|
||||||
PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
|
PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
|
||||||
ADD_TYPE(&PyBufferedRandom_Type);
|
|
||||||
|
|
||||||
/* TextIOWrapper */
|
|
||||||
PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
|
PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
|
||||||
ADD_TYPE(&PyTextIOWrapper_Type);
|
|
||||||
|
|
||||||
/* IncrementalNewlineDecoder */
|
// Add types
|
||||||
ADD_TYPE(&PyIncrementalNewlineDecoder_Type);
|
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 */
|
/* Interned strings */
|
||||||
#define ADD_INTERNED(name) \
|
#define ADD_INTERNED(name) \
|
||||||
|
@ -785,6 +833,7 @@ PyInit__io(void)
|
||||||
ADD_INTERNED(truncate)
|
ADD_INTERNED(truncate)
|
||||||
ADD_INTERNED(write)
|
ADD_INTERNED(write)
|
||||||
ADD_INTERNED(writable)
|
ADD_INTERNED(writable)
|
||||||
|
#undef ADD_INTERNED
|
||||||
|
|
||||||
if (!_PyIO_str_nl &&
|
if (!_PyIO_str_nl &&
|
||||||
!(_PyIO_str_nl = PyUnicode_InternFromString("\n")))
|
!(_PyIO_str_nl = PyUnicode_InternFromString("\n")))
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "pycore_typeobject.h" // _PyTypes_InitTypes()
|
#include "pycore_typeobject.h" // _PyTypes_InitTypes()
|
||||||
#include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
|
#include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
|
||||||
|
|
||||||
|
extern void _PyIO_Fini(void);
|
||||||
|
|
||||||
#include <locale.h> // setlocale()
|
#include <locale.h> // setlocale()
|
||||||
#include <stdlib.h> // getenv()
|
#include <stdlib.h> // getenv()
|
||||||
|
|
||||||
|
@ -1702,6 +1704,10 @@ finalize_interp_clear(PyThreadState *tstate)
|
||||||
/* Clear interpreter state and all thread states */
|
/* Clear interpreter state and all thread states */
|
||||||
_PyInterpreterState_Clear(tstate);
|
_PyInterpreterState_Clear(tstate);
|
||||||
|
|
||||||
|
if (is_main_interp) {
|
||||||
|
_PyIO_Fini();
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear all loghooks */
|
/* Clear all loghooks */
|
||||||
/* Both _PySys_Audit function and users still need PyObject, such as tuple.
|
/* Both _PySys_Audit function and users still need PyObject, such as tuple.
|
||||||
Call _PySys_ClearAuditHooks when PyObject available. */
|
Call _PySys_ClearAuditHooks when PyObject available. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue