python
threading
attributeerror
object-error
troubleshooting

'threading' object has no attribute 'Thread'

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The error 'threading' object has no attribute 'Thread' usually means Python is not referring to the standard library threading module you expected. In most cases, something named threading is shadowing the real module. Until you fix that naming problem, debugging actual thread logic is a waste of time.

The Usual Cause Is Shadowing

Python resolves names in layers. If you have a local file called threading.py, or you assign a variable named threading, then threading.Thread no longer points at the standard library class.

This breaks in two common ways.

First, a local file:

python
# bad filename: threading.py
print("this shadows the stdlib module")

Second, a variable reassignment:

python
1import threading
2
3threading = "oops"
4worker = threading.Thread(target=print, args=("hi",))

In both cases, Python is doing exactly what it was told. The wrong object is bound to the name threading.

Confirm What Was Actually Imported

Before changing any concurrency code, inspect the object you imported.

python
1import threading
2
3print("module:", threading)
4print("file:", getattr(threading, "__file__", "built-in"))
5print("has Thread:", hasattr(threading, "Thread"))

If the printed path points into your project instead of the Python standard library, you found the real problem.

Fix the Import Environment First

The repair steps are usually simple:

  1. Rename any local file named threading.py.
  2. Remove corresponding .pyc files.
  3. Delete stale __pycache__ directories.
  4. Restart the interpreter, IDE, or notebook kernel.
bash
find . -name 'threading.py' -o -name 'threading.pyc'
find . -name '__pycache__' -type d -exec rm -rf {} +

Restarting matters because an interactive session may still hold the bad import in memory even after you rename the file.

Then Verify Normal Thread Usage

Once the import is correct, creating threads is straightforward.

python
1import threading
2import time
3
4
5def worker(name: str) -> None:
6    for index in range(3):
7        print(name, index)
8        time.sleep(0.2)
9
10
11t1 = threading.Thread(target=worker, args=("A",))
12t2 = threading.Thread(target=worker, args=("B",))
13
14t1.start()
15t2.start()
16
17t1.join()
18t2.join()
19print("done")

If this runs, the threading import is healthy and any remaining problems are ordinary concurrency issues rather than import shadowing.

Watch for Indirect Shadowing Too

The error does not always come from a bad filename in the same folder. It can also come from:

  • a helper module that reassigns threading
  • a package in your project tree named threading
  • a notebook cell that reused the name
  • an IDE running the script from an unexpected working directory

That is why printing threading.__file__ is such a useful first diagnostic. It turns guesswork into evidence.

Prevent the Problem in Larger Projects

A simple discipline helps avoid these issues:

  • do not name files after standard library modules
  • avoid reusing module names for variables
  • keep import diagnostics handy in legacy scripts

A lightweight guard can help in messy environments:

python
1import threading
2
3
4def assert_threading_ok() -> None:
5    if not hasattr(threading, "Thread"):
6        raise RuntimeError("threading module is shadowed")
7
8
9assert_threading_ok()

This will not fix the issue, but it makes the failure obvious at startup instead of later in unrelated code.

Common Pitfalls

  • Renaming threading.py but forgetting to remove cached bytecode.
  • Reassigning threading in a notebook or script after importing it.
  • Assuming the standard library is broken instead of checking the import path.
  • Debugging locks and race conditions before confirming the module import is correct.
  • Running the same script from different directories and getting different import resolution.

Summary

  • This error usually comes from import shadowing, not from the threading module itself.
  • Check threading.__file__ and hasattr(threading, "Thread") first.
  • Rename conflicting files or variables and clear caches.
  • Restart the interpreter after cleanup.
  • Only debug real threading logic after the import environment is correct.

Course illustration
Course illustration

All Rights Reserved.