Skip to content

Commit

Permalink
Get Python 3.13 to work (#1692)
Browse files Browse the repository at this point in the history
* Get debug launch working

* Turn Cython support back on

* Fix test failures

* Fix gevent test to be skipped

* Missed a version change in pipeline

* Fix comment

* Review feedback
  • Loading branch information
rchiodo authored Oct 10, 2024
1 parent 25955a0 commit f7d5df0
Show file tree
Hide file tree
Showing 14 changed files with 7,025 additions and 6,769 deletions.
6 changes: 6 additions & 0 deletions azure-pipelines/pipelines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ jobs:
python.version: "3.11"
py312:
python.version: "3.12"
py313:
python.version: "3.13"

steps:

Expand Down Expand Up @@ -93,6 +95,8 @@ jobs:
python.version: "3.11"
py312:
python.version: "3.12"
py313:
python.version: "3.13"

steps:

Expand Down Expand Up @@ -124,6 +128,8 @@ jobs:
python.version: "3.11"
py312:
python.version: "3.12"
py313:
python.version: "3.13"

steps:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# circumstances).
# It is required to debug threads started by start_new_thread in Python 3.4
_temp = threading.Thread()
if hasattr(_temp, "_is_stopped"): # Python 3.x has this
if hasattr(_temp, "_is_stopped"): # Python 3.12 and earlier has this

def is_thread_alive(t):
return not t._is_stopped
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
)
from _pydev_bundle import pydev_log
from _pydev_bundle._pydev_saved_modules import threading
from _pydev_bundle.pydev_is_thread_alive import is_thread_alive
import weakref

version = 11
Expand Down Expand Up @@ -135,7 +136,7 @@ def _get_related_thread(self):
if thread is None:
return False

if thread._is_stopped:
if not is_thread_alive(thread):
return None

if thread._ident is None: # Can this happen?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,11 @@ def _current_frames():
IS_PY310_OR_GREATER = sys.version_info >= (3, 10)
IS_PY311_OR_GREATER = sys.version_info >= (3, 11)
IS_PY312_OR_GREATER = sys.version_info >= (3, 12)
IS_PY313_OR_GREATER = sys.version_info >= (3, 13)
IS_PY314_OR_GREATER = sys.version_info >= (3, 14)

# Not currently supported in Python 3.12.
SUPPORT_ATTACH_TO_PID = not IS_PY312_OR_GREATER
# Not currently supported in Python 3.14.
SUPPORT_ATTACH_TO_PID = not IS_PY314_OR_GREATER


def version_str(v):
Expand Down
7,677 changes: 3,858 additions & 3,819 deletions src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_cython.c

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ from _pydevd_bundle.pydevd_constants import (
)
from _pydev_bundle import pydev_log
from _pydev_bundle._pydev_saved_modules import threading
from _pydev_bundle.pydev_is_thread_alive import is_thread_alive
import weakref

version = 11
Expand Down Expand Up @@ -141,7 +142,7 @@ cdef class PyDBAdditionalThreadInfo:
if thread is None:
return False

if thread._is_stopped:
if not is_thread_alive(thread):
return None

if thread._ident is None: # Can this happen?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ def add_exception_to_frame(frame, exception_info):


def remove_exception_from_frame(frame):
frame.f_locals.pop("__exception__", None)
# In 3.13 frame.f_locals became a proxy for a dict, so we need to copy it to a real dict
# so we can call the defined update method. Just deleting the entry throws in 3.13.
items = {key: value for key, value in frame.f_locals.items()}
if "__exception__" in items:
del items["__exception__"]
frame.f_locals.update(items)


FILES_WITH_IMPORT_HOOKS = ["pydev_monkey_qt.py", "pydev_import_hook.py"]
Expand Down Expand Up @@ -140,6 +145,7 @@ def map_columns_to_line(self, original_line: str):
def _utf8_byte_offset_to_character_offset(s: str, offset: int):
byte_offset = 0
char_offset = 0
offset = offset or 0

for char_offset, character in enumerate(s):
byte_offset += 1
Expand Down
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 (
GlobalDebuggerHolder,
Expand Down Expand Up @@ -459,9 +460,10 @@ def _get_code_line_info(code_obj, _cache={}):
last_line = None

for offset, line in dis.findlinestarts(code_obj):
line_to_offset[line] = offset
if offset is not None and line is not None:
line_to_offset[line] = offset

if line_to_offset:
if len(line_to_offset):
first_line = min(line_to_offset)
last_line = max(line_to_offset)
ret = _CodeLineInfo(line_to_offset, first_line, last_line)
Expand Down Expand Up @@ -837,7 +839,7 @@ def _unwind_event(code, instruction, exc):
if py_db is None or py_db.pydb_disposed:
return

if not thread_info.trace or thread_info.thread._is_stopped:
if not thread_info.trace or not is_thread_alive(thread_info.thread):
# For thread-related stuff we can't disable the code tracing because other
# threads may still want it...
return
Expand Down Expand Up @@ -911,7 +913,7 @@ def _raise_event(code, instruction, exc):
if py_db is None or py_db.pydb_disposed:
return

if not thread_info.trace or thread_info.thread._is_stopped:
if not thread_info.trace or not is_thread_alive(thread_info.thread):
# For thread-related stuff we can't disable the code tracing because other
# threads may still want it...
return
Expand Down Expand Up @@ -1029,7 +1031,7 @@ def _return_event(code, instruction, retval):
if py_db is None or py_db.pydb_disposed:
return monitor.DISABLE

if not thread_info.trace or thread_info.thread._is_stopped:
if not thread_info.trace or not is_thread_alive(thread_info.thread):
# For thread-related stuff we can't disable the code tracing because other
# threads may still want it...
return
Expand Down Expand Up @@ -1340,7 +1342,7 @@ def _jump_event(code, from_offset, to_offset):
if py_db is None or py_db.pydb_disposed:
return monitor.DISABLE

if not thread_info.trace or thread_info.thread._is_stopped:
if not thread_info.trace or not is_thread_alive(thread_info.thread):
# For thread-related stuff we can't disable the code tracing because other
# threads may still want it...
return
Expand Down Expand Up @@ -1397,7 +1399,7 @@ def _line_event(code, line):
if py_db is None or py_db.pydb_disposed:
return monitor.DISABLE

if not thread_info.trace or thread_info.thread._is_stopped:
if not thread_info.trace or not is_thread_alive(thread_info.thread):
# For thread-related stuff we can't disable the code tracing because other
# threads may still want it...
return
Expand Down Expand Up @@ -1644,7 +1646,7 @@ def _start_method_event(code, instruction_offset):
if py_db is None or py_db.pydb_disposed:
return monitor.DISABLE

if not thread_info.trace or thread_info.thread._is_stopped:
if not thread_info.trace or not is_thread_alive(thread_info.thread):
# For thread-related stuff we can't disable the code tracing because other
# threads may still want it...
return
Expand Down
Loading

0 comments on commit f7d5df0

Please sign in to comment.