Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion _pydev_bundle/pydev_is_thread_alive.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
# It is required to debug threads started by start_new_thread in Python 3.4
_temp = threading.Thread()

if hasattr(_temp, "_handle") and hasattr(_temp, "_started"): # Python 3.13 and later has this
if hasattr(_temp, "_os_thread_handle") and hasattr(_temp, "_started"): # Python 3.14 has no `_handle`

def is_thread_alive(t):
return not t._os_thread_handle.is_done()

elif hasattr(_temp, "_handle") and hasattr(_temp, "_started"): # Python 3.13 and later has this

def is_thread_alive(t):
return not t._handle.is_done()
Expand Down
10 changes: 3 additions & 7 deletions _pydevd_sys_monitoring/_pydevd_sys_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from os.path import basename, splitext

from _pydev_bundle import pydev_log
from _pydev_bundle.pydev_is_thread_alive import is_thread_alive
from _pydevd_bundle import pydevd_dont_trace
from _pydevd_bundle.pydevd_constants import (
IS_PY313_OR_GREATER,
Expand Down Expand Up @@ -255,7 +256,6 @@ def _get_unhandled_exception_frame(exc, depth: int) -> Optional[FrameType]:
# cdef PyDBAdditionalThreadInfo additional_info
# thread: threading.Thread
# trace: bool
# _use_is_stopped: bool
# ELSE
class ThreadInfo:
additional_info: PyDBAdditionalThreadInfo
Expand All @@ -276,19 +276,15 @@ def __init__(self, thread: threading.Thread, thread_ident: int, trace: bool, add
self.thread_ident = thread_ident
self.additional_info = additional_info
self.trace = trace
self._use_is_stopped = hasattr(thread, '_is_stopped')


# fmt: off
# IFDEF CYTHON
# cdef bint is_thread_alive(self):
# ELSE
def is_thread_alive(self):
# ENDIF
# fmt: on
if self._use_is_stopped:
return not self.thread._is_stopped
else:
return not self.thread._handle.is_done()
return is_thread_alive(self.thread)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally any checks for Python 3.12 onwards would be done here and not delegated to a pure-python implementation (i.e.: the constructor should determine which check to do and here it uses the proper approach without calling out to non-cython code).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roger that, fixed



class _DeleteDummyThreadOnDel:
Expand Down
10 changes: 3 additions & 7 deletions _pydevd_sys_monitoring/_pydevd_sys_monitoring_cython.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ from typing import Dict, Optional, Tuple, Any
from os.path import basename, splitext

from _pydev_bundle import pydev_log
from _pydev_bundle.pydev_is_thread_alive import is_thread_alive
from _pydevd_bundle import pydevd_dont_trace
from _pydevd_bundle.pydevd_constants import (
IS_PY313_OR_GREATER,
Expand Down Expand Up @@ -247,7 +248,6 @@ cdef class ThreadInfo:
cdef PyDBAdditionalThreadInfo additional_info
thread: threading.Thread
trace: bool
_use_is_stopped: bool
# ELSE
# class ThreadInfo:
# additional_info: PyDBAdditionalThreadInfo
Expand All @@ -268,19 +268,15 @@ cdef class ThreadInfo:
self.thread_ident = thread_ident
self.additional_info = additional_info
self.trace = trace
self._use_is_stopped = hasattr(thread, '_is_stopped')


# fmt: off
# IFDEF CYTHON -- DONT EDIT THIS FILE (it is automatically generated)
cdef bint is_thread_alive(self):
# ELSE
# def is_thread_alive(self):
# ENDIF
# fmt: on
if self._use_is_stopped:
return not self.thread._is_stopped
else:
return not self.thread._handle.is_done()
return is_thread_alive(self.thread)


class _DeleteDummyThreadOnDel:
Expand Down