debugpy 1.8.19 creates _DummyThread when inspecting PySide6 QThread under Python 3.13, causing teardown crash
まだ誰も着手していません。
評価
調査の方向性
debugpy/_pydevd_sys_monitoring.py の _create_thread_info() から始め、次に、記載されている Python 3.13.4、PySide6、requests、debugpy のバージョンで qt_debugpy_repro.py を実行します。QThread がどのように threading.current_thread() に到達するかを追跡し、再現で不要な _DummyThread が残らず、シャットダウン時のクラッシュも報告されなくなったことを確認します。
索引モデルが issue の本文から書いたものです。
説明
Summary
When debugging a PySide6 application using debugpy 1.8.19 (via VS Code Python Debugger extension 2025.18.0) on Python 3.13.4, debugpy’s sys‑monitoring creates _DummyThread objects while inspecting a QThread that performs HTTP requests (requests/urllib3).
During interpreter shutdown, Python 3.13 attempts to finalize these _DummyThread objects and crashes with:
Exception ignored in: <function _DeleteDummyThreadOnDel.__del__>
TypeError: 'NoneType' object does not support the context manager protocol
This does not occur:
- when running the same code outside VS Code (no debugpy)
- when using only Python threads
- when using QThread without debugpy
- when using requests/urllib3 without debugpy
The issue is reproducible with a minimal PySide6 + requests script.
I have not tested this on Python 3.12, so I cannot confirm whether the issue is specific to Python 3.13 or also affects earlier versions
Environment
- Python: 3.13.4 (Windows x64)
- VS Code Python Debugger extension: 2025.18.0
- debugpy version: 1.8.19
(verified viaimport debugpy; debugpy.__version__) - OS: Windows 11
- PySide6: 6.10.1
- requests: 2.32.5
- urllib3: 2.6.0
Minimal pip freeze:
certifi==2025.11.12
charset-normalizer==3.4.4
idna==3.11
PySide6==6.10.1
PySide6_Addons==6.10.1
PySide6_Essentials==6.10.1
requests==2.32.5
shiboken6==6.10.1
urllib3==2.6.0
Minimal Reproduction
qt_debugpy_repro.py:
import sys
import time
import threading
import requests
from PySide6.QtCore import QObject, QThread, Signal
from PySide6.QtWidgets import QApplication
import debugpy
print(f"debugpy version: {debugpy.__version__}")
class Worker(QObject):
tick = Signal()
def run(self):
# Simulate Spotipy/urllib3 behavior: property access on HTTPResponse
for _ in range(3):
r = requests.get("https://httpbin.org/get")
_ = r.raw.closed # <-- triggers urllib3.response.closed
time.sleep(0.1)
print("worker done")
def dump_threads(label):
print(f"\nTHREADS {label}:")
for t in threading.enumerate():
print(" -", t, "daemon=", t.daemon, "type=", type(t))
def main():
app = QApplication(sys.argv)
worker = Worker()
thread = QThread()
worker.moveToThread(thread)
thread.started.connect(worker.run)
thread.start()
QThread.msleep(500)
dump_threads("BEFORE SHUTDOWN")
# Stop QThread without joining (mirrors real-world teardown timing)
thread.quit()
dump_threads("AFTER QUIT")
print("exiting app")
sys.exit(0)
if __name__ == "__main__":
main()
Steps to Reproduce
- Open the script in VS Code
- Select Python 3.13.4 interpreter
- Use this launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python Debug Repro",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/qt_debugpy_repro.py",
"console": "integratedTerminal",
"python": "${workspaceFolder}/venv/Scripts/python"
}
]
}
- Run with Start Debugging
- Observe thread list and shutdown behavior
Observed Behavior (under debugpy)
In the minimal reproduction code listed above, debugpy creates a _DummyThread when inspecting a PySide6 QThread.
The minimal repro does not crash Python, but it clearly shows the unexpected _DummyThread created by debugpy:
THREADS BEFORE SHUTDOWN:
- <_MainThread(MainThread, ...)>
- <_DummyThread(Dummy-6, ...)>
THREADS AFTER QUIT:
- <_MainThread(MainThread, ...)>
- <_DummyThread(Dummy-6, ...)>
exiting app
QThread: Destroyed while thread '' is still running
Behavior in the full application
In my real application (which uses the same pattern but performs more work inside the QThread), the _DummyThread created by debugpy survives until interpreter shutdown.
On Python 3.13.4 this leads to a teardown crash:
Exception ignored in: <function _DeleteDummyThreadOnDel.__del__>
TypeError: 'NoneType' object has no support for the context manager protocol
This crash does not occur outside debugpy.
The _DummyThread is created by debugpy’s sys‑monitoring:
Example captured stack:
=== DummyThread created ===
File "qt_debugpy_repro.py", line XX, in run
File "...debugpy/_pydevd_sys_monitoring.py", line 330, in _create_thread_info
t = threading.current_thread()
File "threading.py", line 1439, in current_thread
return _DummyThread()
=== end DummyThread stack ===
Expected Behavior
- No
_DummyThreadshould be created for QThreads - No crash during interpreter shutdown
- Behavior should match Python 3.12 and non-debugpy execution
Analysis
- QThread is not a Python
threading.Thread - debugpy’s sys‑monitoring inspects thread state during property access (
urllib3.response.closed) threading.current_thread()returns_DummyThread()when the thread is not inthreading._active- Python 3.13 changed teardown order
_DummyThread.__del__now runs after parts ofthreadingare already destroyed- This leads to the observed
TypeErrorduring shutdown
This issue does not occur with:
- Python threads
- QThreads without debugpy
- requests/urllib3 without debugpy
Only the combination of debugpy + QThread + urllib3 + Python 3.13 triggers it.
Possible Fix Direction
- Avoid calling
threading.current_thread()on non‑Python threads - Or guard
_create_thread_info()against QThreads - Or avoid creating
_DummyThreadobjects during sys‑monitoring - Or ensure
_DummyThreadis not left alive until interpreter teardown
Thank you
Happy to test patches or provide additional instrumentation if needed.
- 主要言語
- Python
- スター
- 2.5k
- フォーク
- 202
- 平均マージ
- 5日 1時間
- マージ済み PR(30日)
- 1
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/debugpy のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
documentation
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
documentation
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
microsoft/debugpy の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
xinnan-tech/xiaozhi-fde-talk#263 ·
-
rules
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
huggingface/Repo2RLEnv#163 · コメント 1 件 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 95/100
huggingface/sentence-transformers#4074 ·
-
comp/dashboard invalid P3
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
NousResearch/hermes-agent#121143 ·