GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — __import__ is not thread-safe on Python 3 · Issue #83065 · python/cpython

__import__ is not thread-safe on Python 3 #83065

New issue
Copy link
New issue
Copy link
Closed
#137196
Closed
__import__ is not thread-safe on Python 3#83065
#137196
Copy link
Assignees
gpshead
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-importlibtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

ValentynTymofieiev
mannequin
opened on Nov 21, 2019
Issue body actions
BPO 38884
Nosy @brettcannon, @gpshead, @ncoghlan, @ericsnowcurrently, @mulka
Files
  • import_module_not_found.py
  • import_deadlock.py
  • issue38884.zip
  • 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 = None
    closed_at = None
    created_at = <Date 2019-11-21.19:11:54.536>
    labels = ['3.7', '3.8', '3.9']
    title = '__import__ is not thread-safe on Python 3'
    updated_at = <Date 2021-12-08.22:53:27.704>
    user = 'https://bugs.python.org/ValentynTymofieiev'

    bugs.python.org fields:

    activity = <Date 2021-12-08.22:53:27.704>
    actor = 'Valentyn Tymofieiev'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = []
    creation = <Date 2019-11-21.19:11:54.536>
    creator = 'Valentyn Tymofieiev'
    dependencies = []
    files = ['48734', '48735', '48737']
    hgrepos = []
    issue_num = 38884
    keywords = []
    message_count = 14.0
    messages = ['357198', '357199', '357202', '357214', '357227', '357228', '357230', '357234', '357464', '360068', '360069', '362746', '375958', '408052']
    nosy_count = 9.0
    nosy_names = ['brett.cannon', 'gregory.p.smith', 'gjb1002', 'ncoghlan', 'eric.snow', 'ryan.petrello', 'Valentyn Tymofieiev', 'Martin Laus', 'repalviglator']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = None
    status = 'open'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue38884'
    versions = ['Python 3.7', 'Python 3.8', 'Python 3.9']

    Linked PRs

    • GH-83065: Fix import deadlock by implementing hierarchical module locking #137196
    Reacted by Daniel Shokouhi, J. Nick Koston, Antonio G. De Crisci, Jorim Tielemans, yousaf465, TheJulianJES, elmurato, Jan-Philipp Benecke, Ståle Storø Hauknes and Michael Berdyshev
    Reacted by J. Nick Koston and yousaf465

    Activity

    Next
    1. ValentynTymofieiev commented on Nov 21, 2019

      @ValentynTymofieiev
      ValentynTymofieievmannequin
      on Nov 21, 2019
      MannequinAuthor
      More actions

      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
    2. ValentynTymofieiev
      added
      3.7 (EOL)end of lifeend of life
      on Nov 21, 2019
    3. ValentynTymofieiev commented on Nov 21, 2019

      @ValentynTymofieiev
      ValentynTymofieievmannequin
      on Nov 21, 2019
      MannequinAuthor
      More actions

      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.

    4. ValentynTymofieiev commented on Nov 21, 2019

      @ValentynTymofieiev
      ValentynTymofieievmannequin
      on Nov 21, 2019
      MannequinAuthor
      More actions

      Possibly related: https://bugs.python.org/issue35943

    5. brettcannon commented on Nov 21, 2019

      @brettcannon
      brettcannon
      on Nov 21, 2019
      Member
      More actions

      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.

    6. ValentynTymofieiev commented on Nov 21, 2019

      @ValentynTymofieiev
      ValentynTymofieievmannequin
      on Nov 21, 2019
      MannequinAuthor
      More actions

      Attaching a minimal repro with simple project hierarchy.

    7. ValentynTymofieiev commented on Nov 21, 2019

      @ValentynTymofieiev
      ValentynTymofieievmannequin
      on Nov 21, 2019
      MannequinAuthor
      More actions

      Repro: unpack bpo-38884.zip
      python input_deadlock.py

      (fails on Python 3.7, but not on 2.7).

    8. ValentynTymofieiev commented on Nov 21, 2019

      @ValentynTymofieiev
      ValentynTymofieievmannequin
      on Nov 21, 2019
      MannequinAuthor
      More actions

      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.

    9. ValentynTymofieiev commented on Nov 21, 2019

      @ValentynTymofieiev
      ValentynTymofieievmannequin
      on Nov 21, 2019
      MannequinAuthor
      More actions

      The behavior changes between Python 3.2 (no deadlock) and Python 3.3 (deadlock). Deadlock also reproducible on Python 3.8.

    10. ValentynTymofieiev
      added
      3.8 (EOL)end of lifeend of life
      on Nov 22, 2019
    11. ValentynTymofieiev commented on Nov 25, 2019

      @ValentynTymofieiev
      ValentynTymofieievmannequin
      on Nov 25, 2019
      MannequinAuthor
      More actions

      @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.

    12. ValentynTymofieiev commented on Jan 15, 2020

      @ValentynTymofieiev
      ValentynTymofieievmannequin
      on Jan 15, 2020
      MannequinAuthor
      More actions

      Just checking - is bpo-38884.zip an acceptable repro for this issue?
      Thanks.

    13. brettcannon commented on Jan 15, 2020

      @brettcannon
      brettcannon
      on Jan 15, 2020
      Member
      More actions

      @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.

    14. ryanpetrello commented on Feb 26, 2020

      @ryanpetrello
      ryanpetrellomannequin
      on Feb 26, 2020
      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.

      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

    15. mulka
      added
      3.9 (EOL)end of lifeend of life
      on Aug 26, 2020
    16. 11 remaining items

    17. emmatyping commented on Jul 29, 2025

      @emmatyping
      emmatyping
      on Jul 29, 2025
      Member
      More actions

      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.

    18. gpshead
      added a commit that references this issue on Jul 29, 2025

      pythongh-83065: Fix import deadlock by implementing hierarchical modu…

      78d4373
    19. gpshead commented on Jul 29, 2025

      @gpshead
      gpshead
      on Jul 29, 2025
      Member
      More actions

      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!)
      • run the reindent tool -- (it knows how via my CLAUDE.local.md)
      • commmit your work, credit Emma for the analysis in the commit message.
      • be sure to put markdown backticks around __init__.py
      • push to the gpshead remote and create a Draft PR, prefix the title of the PR with "__import__ is not thread-safe on Python 3 #83065: "

      half an hour of API use. this cost $$ money (stated just to let others know the scale).

      Reacted by Jacob Coffee
    20. gpshead
      added a commit that references this issue on Apr 28, 2026

      Add NEWS entry and What's New for the pythongh-83065 import deadlock fix

      12eb777
    21. gpshead
      self-assigned this
      on Apr 28, 2026
    22. gpshead
      added a commit that references this issue on Apr 28, 2026

      GH-83065: Fix import deadlock by implementing hierarchical module loc…

      9a57179
    23. gpshead
      closed this as completedin #137196on Apr 28, 2026
    24. github-project-automation
      moved this from In Progress to Done in Threading issues 🧵on Apr 28, 2026
    25. gpshead commented on Apr 28, 2026

      @gpshead
      gpshead
      on Apr 28, 2026
      Member
      More actions

      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.

      Reacted by Emma Smith
    26. bdraco commented on Apr 28, 2026

      @bdraco
      bdraco
      on Apr 28, 2026
      Contributor
      More actions

      Thanks for fixing this. I have personally made a donation to PSF in your honor.

      Reacted by Gregory P. Smith, Emma Smith and Jacob Coffee
    27. gpshead commented on May 8, 2026

      @gpshead
      gpshead
      on May 8, 2026
      Member
      More actions

      thanks! 😁

    28. steve-s commented on Sep 2, 2026

      @steve-s
      steve-s
      on Sep 2, 2026
      Contributor
      More actions

      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 
      

      self-contained reproducer fails for me locally on 3.13 and passes on 3.15 dev build

    29. gpshead commented on Oct 13, 2026

      @gpshead
      gpshead
      on Oct 13, 2026
      Member
      More actions

      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.

      Reacted by TheJulianJES
      Reacted by Emma Smith
    30. gpshead
      added 2 commits that reference this issue on Oct 25, 2026

      gh-159963: Don't hold parent package import locks while a submodule e…

      7159b15

      [3.15] gh-159963: Don't hold parent package import locks while a subm…

      3255d5d
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    • @gpshead
      gpshead

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-importlibtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    • Threading issues 🧵
      Status
      Done
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.