Repository navigation
concurrent/futures/process.py: mp.util.debug is called, but mp.util is never imported #99368
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Nov 11, 2022 - changed the title
[-]Bug: mp.util.debug is called, but mp.util is never imported in process.py[/-][+]concurrent/futures/process.py: mp.util.debug is called, but mp.util is never imported[/+]on Nov 11, 2022 Was this perhaps at process shutdown called from a destructor?
Notice that the error message is 'NoneType' object has no attribute 'util' which means that "mp" was None. So this isn't about mp.util not being imported, it's about "mp" in the context of when this ran being None. Which is possible in GC destructor context at process shutdown where a lot of the world has already been torn down, the kind of place that weakref callbacks may happen in.
If you can reproduce this, the proper fix is not neccessarily to remove the call, but add mp_util=mp.util as a keyword argument to that weakref_cb function and use that instead of looking up mp.util from the global scope in the function body.
This same issue started happening in a Python 3.9 environment of mine:
Exception ignored in: <function _ExecutorManagerThread.__init__.<locals>.weakref_cb at 0x7f2926625e50> Traceback (most recent call last): File "/usr/local/lib/python3.9/concurrent/futures/process.py", line 285, in weakref_cb AttributeError: 'NoneType' object has no attribute 'util'My script looked like it was running properly and the issue was happening when the script was ending.
I could fix the issue by doing the following:
def weakref_cb(_, thread_wakeup=self.thread_wakeup, shutdown_lock=self.shutdown_lock): # I added this 'if mp:' check if mp: mp.util.debug('Executor collected: triggering callback for' ' QueueManager wakeup') with shutdown_lock: thread_wakeup.wakeup()
This fix mentioned above also worked for me:
def weakref_cb(_, thread_wakeup=self.thread_wakeup, shutdown_lock=self.shutdown_lock, mp_util_debug=mp.util.debug): mp_util_debug('Executor collected: triggering callback for' ' QueueManager wakeup') with shutdown_lock: thread_wakeup.wakeup()
- addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Nov 26, 2023 @ktbyers, do you want to send a PR?
Fixed by gh-118112 (3.13+), which binds
mp.util.debugas a default argument ofweakref_cbas suggested above.Quick local test on main on MacOS:
>>> import concurrent.futures.process as p ... ... ex = p.ProcessPoolExecutor() ... ex.submit(pow, 2, 3).result() ... cb = ex._executor_manager_thread.executor_reference.__callback__ ... p.mp, mp = None, p.mp ... cb(None) # No AttributeError ... p.mp = mp ... ex.shutdown() ... >>>
I think this can be closed.
Bug report
In
Lib/concurrent/futures/process.py,mp.util.debugis called, butmp.utilis never imported.This leads to the following:
My environment is Python 3.10, but this bug exists in the latest cpython.
My impression is that this is relic debug code (but if it is not, non-working code is not helpful). I am about to make a PR removing this debug code.