4
4
import sys
5
5
from _pydev_bundle ._pydev_saved_modules import threading
6
6
from _pydevd_bundle .pydevd_constants import (
7
+ IS_PY313_OR_GREATER ,
7
8
get_global_debugger ,
8
9
IS_WINDOWS ,
9
10
IS_JYTHON ,
@@ -1173,11 +1174,13 @@ def _get_threading_modules_to_patch():
1173
1174
1174
1175
1175
1176
def patch_thread_module (thread_module ):
1177
+ attr = "_start_joinable_thread" if IS_PY313_OR_GREATER else "_start_new_thread"
1178
+ is_start_joinable = thread_module is threading and IS_PY313_OR_GREATER
1176
1179
if getattr (thread_module , "_original_start_new_thread" , None ) is None :
1177
1180
if thread_module is threading :
1178
- if not hasattr (thread_module , "_start_new_thread" ):
1181
+ if not hasattr (thread_module , attr ):
1179
1182
return # Jython doesn't have it.
1180
- _original_start_new_thread = thread_module ._original_start_new_thread = thread_module . _start_new_thread
1183
+ _original_start_new_thread = thread_module ._original_start_new_thread = getattr ( thread_module , attr )
1181
1184
else :
1182
1185
_original_start_new_thread = thread_module ._original_start_new_thread = thread_module .start_new_thread
1183
1186
else :
@@ -1191,6 +1194,16 @@ def pydev_start_new_thread(self, function, args=(), kwargs={}):
1191
1194
"""
1192
1195
return _original_start_new_thread (_UseNewThreadStartup (function , args , kwargs ), ())
1193
1196
1197
+ class ClassWithPydevStartJoinableThread :
1198
+ def pydev_start_joinable_thread (self , function , * args , ** kwargs ):
1199
+ """
1200
+ We need to replace the original thread_module._start_joinable_thread with this function so that threads started
1201
+ through it and not through the threading module are properly traced.
1202
+ """
1203
+ handle = kwargs .pop ("handle" , None )
1204
+ daemon = kwargs .pop ("daemon" , True )
1205
+ return _original_start_new_thread (_UseNewThreadStartup (function , args , kwargs ), handle = handle , daemon = daemon )
1206
+
1194
1207
# This is a hack for the situation where the thread_module.start_new_thread is declared inside a class, such as the one below
1195
1208
# class F(object):
1196
1209
# start_new_thread = thread_module.start_new_thread
@@ -1199,13 +1212,17 @@ def pydev_start_new_thread(self, function, args=(), kwargs={}):
1199
1212
# self.start_new_thread(self.function, args, kwargs)
1200
1213
# So, if it's an already bound method, calling self.start_new_thread won't really receive a different 'self' -- it
1201
1214
# does work in the default case because in builtins self isn't passed either.
1202
- pydev_start_new_thread = ClassWithPydevStartNewThread ().pydev_start_new_thread
1215
+ pydev_start_new_thread = (
1216
+ ClassWithPydevStartJoinableThread ().pydev_start_joinable_thread
1217
+ if is_start_joinable
1218
+ else ClassWithPydevStartNewThread ().pydev_start_new_thread
1219
+ )
1203
1220
1204
1221
try :
1205
1222
# We need to replace the original thread_module.start_new_thread with this function so that threads started through
1206
1223
# it and not through the threading module are properly traced.
1207
1224
if thread_module is threading :
1208
- thread_module . _start_new_thread = pydev_start_new_thread
1225
+ setattr ( thread_module , attr , pydev_start_new_thread )
1209
1226
else :
1210
1227
thread_module .start_new_thread = pydev_start_new_thread
1211
1228
thread_module .start_new = pydev_start_new_thread
0 commit comments