Index: Lib/multiprocessing/util.py =================================================================== --- Lib/multiprocessing/util.py (revision 84487) +++ Lib/multiprocessing/util.py (working copy) @@ -252,23 +252,30 @@ _exiting = False + +# underscore prefix these functions so that if _exit_function is +# executed after a destructor, it will still have access to the +# functions instead of creating a traceback. +_info = info +_debug = debug + def _exit_function(): global _exiting - info('process shutting down') - debug('running all "atexit" finalizers with priority >= 0') + _info('process shutting down') + _debug('running all "atexit" finalizers with priority >= 0') _run_finalizers(0) for p in active_children(): if p._daemonic: - info('calling terminate() for daemon %s', p.name) + _info('calling terminate() for daemon %s', p.name) p._popen.terminate() for p in active_children(): - info('calling join() for process %s', p.name) + _info('calling join() for process %s', p.name) p.join() - debug('running the remaining "atexit" finalizers') + _debug('running the remaining "atexit" finalizers') _run_finalizers() atexit.register(_exit_function)