Skip to content

Broken circular import between threading and _threading_local #156341

Description

@x42005e1f

Bug report

Bug description:

The threading module defines local as follows:

cpython/Lib/threading.py

Lines 67 to 70 in ee521e8

try:
from _thread import _local as local
except ImportError:
from _threading_local import local

But _threading_local also uses threading as follows:

from threading import current_thread, RLock

This was fine at first, since threading never used thread-local data (the import was near the end). However, this changed in gh-114424:

cpython/Lib/threading.py

Lines 1540 to 1542 in ee521e8

# Helper thread-local instance to detect when a _DummyThread
# is collected. Not a part of the public API.
_thread_local_info = local()

The _threading_local.local object depends on threading.current_thread(), and this dependency occurs when the object is created:

# We need to create the thread dict in anticipation of
# __init__ being called, to make sure we don't call it
# again ourselves.
impl.create_dict()

def create_dict(self):
"""Create a new dict for the current thread, and return it."""
localdict = {}
key = self.key
thread = current_thread()

The object is created (and local is imported) before current_thread() is defined. As a result, there is the broken circular import, which can be reproduced as follows:

>>> import _thread
>>> del _thread._local
>>> import threading
Traceback (most recent call last):
  File "/home/user/.local/share/mise/installs/python/3.14.7/lib/python3.14/threading.py", line 67, in <module>
    from _thread import _local as local
ImportError: cannot import name '_local' from '_thread' (unknown location)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<python-input-2>", line 1, in <module>
    import threading
  File "/home/user/.local/share/mise/installs/python/3.14.7/lib/python3.14/threading.py", line 69, in <module>
    from _threading_local import local
  File "/home/user/.local/share/mise/installs/python/3.14.7/lib/python3.14/_threading_local.py", line 120, in <module>
    from threading import current_thread, RLock
ImportError: cannot import name 'current_thread' from partially initialized module 'threading' (most likely due to a circular import) (/home/user/.local/share/mise/installs/python/3.14.7/lib/python3.14/threading.py)

Since the issue has not been reported before, this raises a legitimate question: is the fallback still relevant?

Related: #141460.

CPython versions tested on:

3.13, 3.14

Operating systems tested on:

Linux

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions