You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2019-11-21.19:11:54.536>labels= ['3.7', '3.8', '3.9']
title='__import__ is not thread-safe on Python 3'updated_at=<Date2021-12-08.22:53:27.704>user='https://bugs.python.org/ValentynTymofieiev'
Attached import_module_not_found.py consistently fails for me on Python 3.7.5 and earlier Python 3 versions that I have tried with
File "/usr/lib/python3.7/threading.py", line 926, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "import_module_not_found.py", line 8, in t2
return __import__("tensorflow.estimator", level=0)
ModuleNotFoundError: No module named 'tensorflow.estimator
Threads in this example finish successfully if executed sequentially.
I have not tried higher versions of Python, but I cannot reproduce this on Python 2.7.
Is this an expected behavior?
Thank you.
Reacted by Antonio G. De Crisci and Martijn van der Pol
...
File "<frozen importlib._bootstrap>", line 980, in _find_and_load
File "<frozen importlib._bootstrap>", line 149, in __enter__
File "<frozen importlib._bootstrap>", line 94, in acquire
_frozen_importlib._DeadlockError: deadlock detected by _ModuleLock('tensorflow_transform.tf_metadata.metadata_io')
Can you test this with a package that isn't tensorflow (e.g. something else in the stdlib or something created manually; basically a smaller reproducer)? It's hard to diagnose if this is really Python or not without a smaller reproducer as tensorflow might be doing some things behind the scenes that would break this due to it being an extension module.
ValentynTymofieiev commented on Nov 21, 2019
ValentynTymofieievmannequin
MannequinAuthor
More actions
Attaching a minimal repro with simple project hierarchy.
@brett.cannon, looks like I inadvertently dropped you from nosy list, so in case you missed the updates - please take a look at bpo-38884.zip. Thank you.
ValentynTymofieiev commented on Jan 15, 2020
ValentynTymofieievmannequin
MannequinAuthor
More actions
Just checking - is bpo-38884.zip an acceptable repro for this issue?
Thanks.
@Valentyn just assume it's good enough unless some asks otherwise. People are probably too busy right now to be looking at this and so you might be waiting a while for a more definitive answer.
ryanpetrello commented on Feb 26, 2020
ryanpetrellomannequin
Mannequin
More actions
I believe I'm also encountering some version of this bug while importing code from the kombu library within a multi-threaded context.
The case as I understand it is that T1 imports package.subpackage, which in it's __init__.py imports package.subpackage.module
Simultaneously, T2 is trying to import package.subpackage.module, which should involve importing package.subpackage?
Then you end up with a deadlock where T1 needs to resolve package.subpackage.module to resolve package.subpackage, while T2 needs to resolve package.subpackage to resolve package.subpackage.module, so we end up with a deadlock where they are holding mutually referential locks.
Here's the traceback on main:
Exception in thread Thread-1 (t1):
Traceback (most recent call last):
File "/home/emma/cpython/Lib/threading.py", line 1074, in _bootstrap_inner
self._context.run(self.run)
~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/home/emma/cpython/Lib/threading.py", line 1016, in run
self._target(*self._args, **self._kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/emma/test_import_race/import_deadlock.py", line 5, in t1
return __import__("package.subpackage", level=0)
File "/home/emma/test_import_race/package/__init__.py", line 1, in <module>
from package import subpackage
File "/home/emma/test_import_race/package/subpackage/__init__.py", line 1, in <module>
from package.subpackage.module import *
File "<frozen importlib._bootstrap>", line 1368, in _find_and_load
File "<frozen importlib._bootstrap>", line 421, in __enter__
File "<frozen importlib._bootstrap>", line 346, in acquire
_frozen_importlib._DeadlockError: deadlock detected by _ModuleLock('package.subpackage.module') at 138200313720016
I'm not really sure what can be done to solve this other than some kind of earlier check when resolving package.subpackage.module if another thread is resolving a parent (in this case package.subpackage) and may need to resolve package.subpackage.module? Then block that thread until the other thread is done.
The blunt force workaround for import madness of this form regardless of cause has always been: Do your imports from the main thread. Not super friendly, and extra annoying when it's something nobody likes to think about such as unplanned indirect imports such as those from codecs dynamically loading infrequently used codec implementations, possibly due to untrusted data, in a serving stack.
Out of curiosity, I just had Claude Opus 4 take a stab at this as Emma's analysis sounded right. Draft PR from that attached. If that is sensible (I'll give it more of a look later), I think real performance tests are needed. But hierarchical lock acquisition was also going to be my suggestion w/o having re-read importlib guts as well, so it maybe served as a bit of validation of both the issue & analysis and that thought.
Claude code prompts (/model is opus 4):
load github issue 83065 and analyze the workings of Lib/importlib/ to understand the situation. focus on emmatyping's issue comment, is that accurate given how the importlib code works? what could be done to avoid this?
Plan the import system improvements
before benchmarking, look over the diff so far with the eye of a code reviewer and simplify it. also remove the _use_hierarchical_import_locks logic, we'll always want this enabled. -- (this helped the code quality a lot!)
thanks all for earlier reviews! i found some remaining nits and fixed them, polished up, documented and merged. if we uncover problems with this during 3.15 betas - reverting to the prior status quo can happen. so many things in the world have worked around this long-standing flaw in odd manners. it'll be nice to stop encountering those.
FTR there seem to be also a rare race in stdlib with collections/collections.abc fixed by the linked PR, and causing ModuleNotFoundError: No module named 'collections.abc'
Thread A:
import collections
-> _find_and_load("collections")
-> execute collections/__init__.py
-> stop between these lines:
```
# collections/__init__.py:29
import _collections_abc
import sys
# INTERRUPTED HERE
_sys.modules['collections.abc'] = _collections_abc
abc = _collections_abc
```
-> "collections" is already in sys.modules
-> although spec._initializing is still True
Thread B:
import collections.abc
-> _find_and_load("collections.abc")
-> parent "collections" already exists in sys.modules
-> do not wait for the parent package to finish (no check of _initializing on the spec)
-> search collections.__path__ for an abc submodule
-> no collections/abc.py so no finder result
-> ModuleNotFoundError at _bootstrap.py:1329
FYI - The fix we landed in 3.15 is not complete and I & claude have discovered problems with it. I'll open a new issue with details and a proposed fix soon.
Activity
ValentynTymofieiev commentedon Nov 21, 2019
Attached import_module_not_found.py consistently fails for me on Python 3.7.5 and earlier Python 3 versions that I have tried with
File "/usr/lib/python3.7/threading.py", line 926, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "import_module_not_found.py", line 8, in t2
return __import__("tensorflow.estimator", level=0)
ModuleNotFoundError: No module named 'tensorflow.estimator
Threads in this example finish successfully if executed sequentially.
I have not tried higher versions of Python, but I cannot reproduce this on Python 2.7.
Is this an expected behavior?
Thank you.
ValentynTymofieiev commentedon Nov 21, 2019
Attached import_deadlock.py fails with
...
File "<frozen importlib._bootstrap>", line 980, in _find_and_load
File "<frozen importlib._bootstrap>", line 149, in __enter__
File "<frozen importlib._bootstrap>", line 94, in acquire
_frozen_importlib._DeadlockError: deadlock detected by _ModuleLock('tensorflow_transform.tf_metadata.metadata_io')
under the same conditions.
ValentynTymofieiev commentedon Nov 21, 2019
Possibly related: https://bugs.python.org/issue35943
brettcannon commentedon Nov 21, 2019
Can you test this with a package that isn't tensorflow (e.g. something else in the stdlib or something created manually; basically a smaller reproducer)? It's hard to diagnose if this is really Python or not without a smaller reproducer as tensorflow might be doing some things behind the scenes that would break this due to it being an extension module.
ValentynTymofieiev commentedon Nov 21, 2019
Attaching a minimal repro with simple project hierarchy.
ValentynTymofieiev commentedon Nov 21, 2019
Repro: unpack bpo-38884.zip
python input_deadlock.py
(fails on Python 3.7, but not on 2.7).
ValentynTymofieiev commentedon Nov 21, 2019
input_deadlock.py in bpo-38884.zip has a left-over comment:
# Requires pip install tensorflow==2.0.0 tensorflow-transform==0.15.0
Please ignore that.
ValentynTymofieiev commentedon Nov 21, 2019
The behavior changes between Python 3.2 (no deadlock) and Python 3.3 (deadlock). Deadlock also reproducible on Python 3.8.
ValentynTymofieiev commentedon Nov 25, 2019
@brett.cannon, looks like I inadvertently dropped you from nosy list, so in case you missed the updates - please take a look at bpo-38884.zip. Thank you.
ValentynTymofieiev commentedon Jan 15, 2020
Just checking - is bpo-38884.zip an acceptable repro for this issue?
Thanks.
brettcannon commentedon Jan 15, 2020
@Valentyn just assume it's good enough unless some asks otherwise. People are probably too busy right now to be looking at this and so you might be waiting a while for a more definitive answer.
ryanpetrello commentedon Feb 26, 2020
I believe I'm also encountering some version of this bug while importing code from the kombu library within a multi-threaded context.
For what it's worth, I'm able to reproduce the reported deadlock (https://bugs.python.org/file48737/issue38884.zip) using python3.8 on RHEL8 and CentOS 8 builds.
More details about what I'm encountering here: ansible/awx#5617
ansible/awx#5617 (comment)
My intended workaround for now is to just not use a thread (we'll see if it helps):
ansible/awx#6093
9 remaining items
emmatyping commentedon Jul 29, 2025
The case as I understand it is that T1 imports
package.subpackage, which in it's__init__.pyimportspackage.subpackage.moduleSimultaneously, T2 is trying to import
package.subpackage.module, which should involve importingpackage.subpackage?Then you end up with a deadlock where T1 needs to resolve
package.subpackage.moduleto resolvepackage.subpackage, while T2 needs to resolvepackage.subpackageto resolvepackage.subpackage.module, so we end up with a deadlock where they are holding mutually referential locks.Here's the traceback on main:
I'm not really sure what can be done to solve this other than some kind of earlier check when resolving
package.subpackage.moduleif another thread is resolving a parent (in this casepackage.subpackage) and may need to resolvepackage.subpackage.module? Then block that thread until the other thread is done.pythongh-83065: Fix import deadlock by implementing hierarchical modu…
gpshead commentedon Jul 29, 2025
The blunt force workaround for import madness of this form regardless of cause has always been: Do your imports from the main thread. Not super friendly, and extra annoying when it's something nobody likes to think about such as unplanned indirect imports such as those from
codecsdynamically loading infrequently used codec implementations, possibly due to untrusted data, in a serving stack.Out of curiosity, I just had Claude Opus 4 take a stab at this as Emma's analysis sounded right. Draft PR from that attached. If that is sensible (I'll give it more of a look later), I think real performance tests are needed. But hierarchical lock acquisition was also going to be my suggestion w/o having re-read importlib guts as well, so it maybe served as a bit of validation of both the issue & analysis and that thought.
Claude code prompts (/model is opus 4):
__init__.pyhalf an hour of API use. this cost $$ money (stated just to let others know the scale).
Add NEWS entry and What's New for the pythongh-83065 import deadlock fix
GH-83065: Fix import deadlock by implementing hierarchical module loc…
gpshead commentedon Apr 28, 2026
thanks all for earlier reviews! i found some remaining nits and fixed them, polished up, documented and merged. if we uncover problems with this during 3.15 betas - reverting to the prior status quo can happen. so many things in the world have worked around this long-standing flaw in odd manners. it'll be nice to stop encountering those.
bdraco commentedon Apr 28, 2026
Thanks for fixing this. I have personally made a donation to PSF in your honor.
gpshead commentedon May 8, 2026
thanks! 😁
steve-s commentedon Sep 2, 2026
FTR there seem to be also a rare race in stdlib with
collections/collections.abcfixed by the linked PR, and causingModuleNotFoundError: No module named 'collections.abc'self-contained reproducer fails for me locally on 3.13 and passes on 3.15 dev build
gpshead commentedon Oct 13, 2026
FYI - The fix we landed in 3.15 is not complete and I & claude have discovered problems with it. I'll open a new issue with details and a proposed fix soon.