@@ -295,6 +295,30 @@ static char* sys_files[] = {
295295 NULL
296296};
297297
298+ static int
299+ is_essential_module (PyObject * name )
300+ {
301+ Py_ssize_t name_len ;
302+ char * name_str = PyUnicode_AsUTF8AndSize (name , & name_len );
303+
304+ if (name_str == NULL ) {
305+ PyErr_Clear ();
306+ return 0 ;
307+ }
308+ if (strcmp (name_str , "builtins" ) == 0 )
309+ return 1 ;
310+ if (strcmp (name_str , "sys" ) == 0 )
311+ return 1 ;
312+ /* These are all needed for stderr to still function */
313+ if (strcmp (name_str , "codecs" ) == 0 )
314+ return 1 ;
315+ if (strcmp (name_str , "_codecs" ) == 0 )
316+ return 1 ;
317+ if (strncmp (name_str , "encodings." , 10 ) == 0 )
318+ return 1 ;
319+ return 0 ;
320+ }
321+
298322
299323/* Un-initialize things, as good as we can */
300324
@@ -374,9 +398,7 @@ PyImport_Cleanup(void)
374398 if (value -> ob_refcnt != 1 )
375399 continue ;
376400 if (PyUnicode_Check (key ) && PyModule_Check (value )) {
377- if (PyUnicode_CompareWithASCIIString (key , "builtins" ) == 0 )
378- continue ;
379- if (PyUnicode_CompareWithASCIIString (key , "sys" ) == 0 )
401+ if (is_essential_module (key ))
380402 continue ;
381403 if (Py_VerboseFlag )
382404 PySys_FormatStderr (
@@ -392,9 +414,7 @@ PyImport_Cleanup(void)
392414 pos = 0 ;
393415 while (PyDict_Next (modules , & pos , & key , & value )) {
394416 if (PyUnicode_Check (key ) && PyModule_Check (value )) {
395- if (PyUnicode_CompareWithASCIIString (key , "builtins" ) == 0 )
396- continue ;
397- if (PyUnicode_CompareWithASCIIString (key , "sys" ) == 0 )
417+ if (is_essential_module (key ))
398418 continue ;
399419 if (Py_VerboseFlag )
400420 PySys_FormatStderr ("# cleanup[2] %U\n" , key );
@@ -411,20 +431,15 @@ PyImport_Cleanup(void)
411431 machinery. */
412432 _PyGC_DumpShutdownStats ();
413433
414- /* Next, delete sys and builtins (in that order) */
415- value = PyDict_GetItemString (modules , "sys" );
416- if (value != NULL && PyModule_Check (value )) {
417- if (Py_VerboseFlag )
418- PySys_WriteStderr ("# cleanup sys\n" );
419- _PyModule_Clear (value );
420- PyDict_SetItemString (modules , "sys" , Py_None );
421- }
422- value = PyDict_GetItemString (modules , "builtins" );
423- if (value != NULL && PyModule_Check (value )) {
424- if (Py_VerboseFlag )
425- PySys_WriteStderr ("# cleanup builtins\n" );
426- _PyModule_Clear (value );
427- PyDict_SetItemString (modules , "builtins" , Py_None );
434+ /* Next, delete all remaining modules */
435+ pos = 0 ;
436+ while (PyDict_Next (modules , & pos , & key , & value )) {
437+ if (PyUnicode_Check (key ) && PyModule_Check (value )) {
438+ if (Py_VerboseFlag )
439+ PySys_FormatStderr ("# cleanup[3] %U\n" , key );
440+ _PyModule_Clear (value );
441+ PyDict_SetItem (modules , key , Py_None );
442+ }
428443 }
429444
430445 /* Finally, clear and delete the modules directory */
0 commit comments