Skip to content

Commit b5cfeb3

Browse files
committed
Fixes for Python 3.14 (issue in reload, bytecode to src, fixed some tests).
1 parent d94358a commit b5cfeb3

File tree

7 files changed

+2904
-3187
lines changed

7 files changed

+2904
-3187
lines changed

_pydevd_bundle/pydevd_collect_bytecode_info.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -580,9 +580,13 @@ def _lookahead(self):
580580
found = []
581581
fullrepr = None
582582

583-
# Collect all the load instructions
583+
# Collect all the load instructions (include 3.12+ LOAD_SMALL_INT, LOAD_FAST_BORROW)
584+
_load_ops = (
585+
"LOAD_GLOBAL", "LOAD_FAST", "LOAD_CONST", "LOAD_NAME",
586+
"LOAD_SMALL_INT", "LOAD_FAST_BORROW",
587+
)
584588
for next_instruction in self.instructions:
585-
if next_instruction.opname in ("LOAD_GLOBAL", "LOAD_FAST", "LOAD_CONST", "LOAD_NAME"):
589+
if next_instruction.opname in _load_ops:
586590
found.append(next_instruction)
587591
else:
588592
break
@@ -721,16 +725,23 @@ def _decorate_jump_target(self, instruction, instruction_repr):
721725

722726
return instruction_repr
723727

728+
def _get_display_argrepr(self, instruction):
729+
argrepr = instruction.argrepr
730+
if isinstance(argrepr, str) and argrepr.startswith("NULL + "):
731+
argrepr = argrepr[7:]
732+
if isinstance(argrepr, str) and argrepr.endswith(" + NULL"):
733+
argrepr = argrepr[:-7]
734+
# LOAD_SMALL_INT (3.12+) has no argrepr; use argval for display
735+
if not argrepr and instruction.opname == "LOAD_SMALL_INT" and instruction.argval is not None:
736+
return str(instruction.argval)
737+
return argrepr
738+
724739
def _create_msg_part(self, instruction, tok=None, line=None):
725740
dec = self._decorate_jump_target
726741
if line is None or line in (self.BIG_LINE_INT, self.SMALL_LINE_INT):
727742
line = self.op_offset_to_line[instruction.offset]
728743

729-
argrepr = instruction.argrepr
730-
if isinstance(argrepr, str) and argrepr.startswith("NULL + "):
731-
argrepr = argrepr[7:]
732-
if isinstance(argrepr, str) and argrepr.endswith("+ NULL"):
733-
argrepr = argrepr[:-7]
744+
argrepr = self._get_display_argrepr(instruction)
734745
return _MsgPart(line, tok if tok is not None else dec(instruction, argrepr))
735746

736747
def _next_instruction_to_str(self, line_to_contents):
@@ -754,7 +765,7 @@ def _next_instruction_to_str(self, line_to_contents):
754765
if instruction.opname == "RETURN_CONST":
755766
return (msg(instruction, "return ", line=self.min_line(instruction)), msg(instruction))
756767

757-
if instruction.opname in ("LOAD_GLOBAL", "LOAD_FAST", "LOAD_CONST", "LOAD_NAME"):
768+
if instruction.opname in ("LOAD_GLOBAL", "LOAD_FAST", "LOAD_CONST", "LOAD_NAME", "LOAD_SMALL_INT", "LOAD_FAST_BORROW"):
758769
next_instruction = self.instructions[0]
759770
if next_instruction.opname in ("STORE_FAST", "STORE_NAME"):
760771
self.instructions.pop(0)
@@ -783,10 +794,10 @@ def _next_instruction_to_str(self, line_to_contents):
783794
return msg(instruction, "raise")
784795

785796
if instruction.opname == "SETUP_FINALLY":
786-
return msg(instruction, ("try(", instruction.argrepr, "):"))
797+
return msg(instruction, ("try(", self._get_display_argrepr(instruction), "):"))
787798

788799
if instruction.argrepr:
789-
return msg(instruction, (instruction.opname, "(", instruction.argrepr, ")"))
800+
return msg(instruction, (instruction.opname, "(", self._get_display_argrepr(instruction), ")"))
790801

791802
if instruction.argval:
792803
return msg(

_pydevd_bundle/pydevd_reload.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,12 @@ def notify_error(*args):
148148
# =======================================================================================================================
149149
def code_objects_equal(code0, code1):
150150
for d in dir(code0):
151-
if d.startswith("_") or "line" in d or d in ("replace", "co_positions", "co_qualname"):
151+
if d.startswith("_") or "line" in d or d in ("replace", "co_positions", "co_qualname", "co_branches"):
152152
continue
153-
if getattr(code0, d) != getattr(code1, d):
153+
val0 = getattr(code0, d)
154+
if callable(val0):
155+
continue # skip methods (e.g. co_branches in Python 3.14)
156+
if val0 != getattr(code1, d):
154157
return False
155158
return True
156159

0 commit comments

Comments
 (0)