Skip to content

Commit 9d55714

Browse files
committed
Fix issues due to backward compatibility breakage in Python 3.13: dis.findlinestarts may now return line with None.
1 parent 3e88fcc commit 9d55714

26 files changed

+7788
-8008
lines changed

.settings/org.eclipse.core.resources.prefs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ encoding//pydev_ipython/inputhookqt5.py=utf-8
1111
encoding//pydev_ipython/inputhooktk.py=utf-8
1212
encoding//pydev_ipython/inputhookwx.py=utf-8
1313
encoding//pydev_ipython/version.py=utf-8
14+
encoding//pydevd_attach_to_process/winappdbg/__init__.py=utf-8
1415
encoding//pydevd_attach_to_process/winappdbg/breakpoint.py=utf-8
1516
encoding//pydevd_attach_to_process/winappdbg/crash.py=utf-8
1617
encoding//pydevd_attach_to_process/winappdbg/interactive.py=utf-8

_pydev_runfiles/pydev_runfiles_xml_rpc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def _encode_if_needed(obj):
203203

204204
elif isinstance(obj, bytes):
205205
try:
206-
return xmlrpclib.Binary(obj.decode(sys.stdin.encoding, 'replace').encode("ISO-8859-1", "xmlcharrefreplace"))
206+
return xmlrpclib.Binary(obj.decode(sys.stdin.encoding, "replace").encode("ISO-8859-1", "xmlcharrefreplace"))
207207
except:
208208
return xmlrpclib.Binary(obj) # bytes already
209209

_pydevd_bundle/_debug_adapter/__main__pydevd_gen_debug_adapter_protocol.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,9 @@ def update_class_to_generate_init(class_to_generate):
458458
# Note: added kwargs because some messages are expected to be extended by the user (so, we'll actually
459459
# make all extendable so that we don't have to worry about which ones -- we loose a little on typing,
460460
# but may be better than doing a allow list based on something only pointed out in the documentation).
461-
class_to_generate["init"] = '''def __init__(self%(args)s, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused)
461+
class_to_generate[
462+
"init"
463+
] = '''def __init__(self%(args)s, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused)
462464
"""
463465
%(docstring)s
464466
"""

_pydevd_bundle/pydevd_api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ def iterate():
8383
# bodies of nested class and function definitions, as they have their
8484
# own objects.
8585
for _, lineno in dis.findlinestarts(code):
86-
yield lineno
86+
if lineno is not None:
87+
yield lineno
8788

8889
# For nested class and function definitions, their respective code objects
8990
# are constants referenced by this object.

_pydevd_bundle/pydevd_code_to_source.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,8 +529,7 @@ def build_line_to_contents(self):
529529
instruction = instructions[0]
530530
new_line_index = op_offset_to_line.get(instruction.offset)
531531
if new_line_index is not None:
532-
if new_line_index is not None:
533-
curr_line_index = new_line_index
532+
curr_line_index = new_line_index
534533

535534
self._process_next(curr_line_index)
536535
return self.writer.line_to_contents

_pydevd_bundle/pydevd_collect_bytecode_info.py

Lines changed: 4 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -82,125 +82,8 @@ def debug(s):
8282
_Instruction = namedtuple("_Instruction", "opname, opcode, starts_line, argval, is_jump_target, offset, argrepr")
8383

8484

85-
def _iter_as_bytecode_as_instructions_py2(co):
86-
code = co.co_code
87-
op_offset_to_line = dict(dis.findlinestarts(co))
88-
labels = set(dis.findlabels(code))
89-
bytecode_len = len(code)
90-
i = 0
91-
extended_arg = 0
92-
free = None
93-
94-
op_to_name = opname
95-
96-
while i < bytecode_len:
97-
c = code[i]
98-
op = ord(c)
99-
is_jump_target = i in labels
100-
101-
curr_op_name = op_to_name[op]
102-
initial_bytecode_offset = i
103-
104-
i = i + 1
105-
if op < HAVE_ARGUMENT:
106-
yield _Instruction(
107-
curr_op_name,
108-
op,
109-
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
110-
None,
111-
is_jump_target,
112-
initial_bytecode_offset,
113-
"",
114-
)
115-
116-
else:
117-
oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg
118-
119-
extended_arg = 0
120-
i = i + 2
121-
if op == EXTENDED_ARG:
122-
extended_arg = oparg * 65536
123-
124-
if op in hasconst:
125-
yield _Instruction(
126-
curr_op_name,
127-
op,
128-
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
129-
co.co_consts[oparg],
130-
is_jump_target,
131-
initial_bytecode_offset,
132-
repr(co.co_consts[oparg]),
133-
)
134-
elif op in hasname:
135-
yield _Instruction(
136-
curr_op_name,
137-
op,
138-
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
139-
co.co_names[oparg],
140-
is_jump_target,
141-
initial_bytecode_offset,
142-
str(co.co_names[oparg]),
143-
)
144-
elif op in hasjrel:
145-
argval = i + oparg
146-
yield _Instruction(
147-
curr_op_name,
148-
op,
149-
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
150-
argval,
151-
is_jump_target,
152-
initial_bytecode_offset,
153-
"to " + repr(argval),
154-
)
155-
elif op in haslocal:
156-
yield _Instruction(
157-
curr_op_name,
158-
op,
159-
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
160-
co.co_varnames[oparg],
161-
is_jump_target,
162-
initial_bytecode_offset,
163-
str(co.co_varnames[oparg]),
164-
)
165-
elif op in hascompare:
166-
yield _Instruction(
167-
curr_op_name,
168-
op,
169-
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
170-
cmp_op[oparg],
171-
is_jump_target,
172-
initial_bytecode_offset,
173-
cmp_op[oparg],
174-
)
175-
elif op in hasfree:
176-
if free is None:
177-
free = co.co_cellvars + co.co_freevars
178-
yield _Instruction(
179-
curr_op_name,
180-
op,
181-
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
182-
free[oparg],
183-
is_jump_target,
184-
initial_bytecode_offset,
185-
str(free[oparg]),
186-
)
187-
else:
188-
yield _Instruction(
189-
curr_op_name,
190-
op,
191-
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
192-
oparg,
193-
is_jump_target,
194-
initial_bytecode_offset,
195-
str(oparg),
196-
)
197-
198-
19985
def iter_instructions(co):
200-
if sys.version_info[0] < 3:
201-
iter_in = _iter_as_bytecode_as_instructions_py2(co)
202-
else:
203-
iter_in = dis.Bytecode(co)
86+
iter_in = dis.Bytecode(co)
20487
iter_in = list(iter_in)
20588

20689
bytecode_to_instruction = {}
@@ -327,7 +210,7 @@ def collect_try_except_info(co, use_func_first_line=False):
327210

328211
try_except_info_lst = []
329212

330-
op_offset_to_line = dict(dis.findlinestarts(co))
213+
op_offset_to_line = dict(entry for entry in dis.findlinestarts(co) if entry[1] is not None)
331214

332215
offset_to_instruction_idx = {}
333216

@@ -445,7 +328,7 @@ def collect_try_except_info(co, use_func_first_line=False):
445328

446329
try_except_info_lst = []
447330

448-
op_offset_to_line = dict(dis.findlinestarts(co))
331+
op_offset_to_line = dict(entry for entry in dis.findlinestarts(co) if entry[1] is not None)
449332

450333
offset_to_instruction_idx = {}
451334

@@ -645,7 +528,7 @@ def __init__(self, co, firstlineno, level=0):
645528
self.firstlineno = firstlineno
646529
self.level = level
647530
self.instructions = list(iter_instructions(co))
648-
op_offset_to_line = self.op_offset_to_line = dict(dis.findlinestarts(co))
531+
op_offset_to_line = self.op_offset_to_line = dict(entry for entry in dis.findlinestarts(co) if entry[1] is not None)
649532

650533
# Update offsets so that all offsets have the line index (and update it based on
651534
# the passed firstlineno).

_pydevd_bundle/pydevd_comm.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,9 +1344,8 @@ def internal_evaluate_expression(dbg, seq, thread_id, frame_id, expression, is_e
13441344

13451345

13461346
def _set_expression_response(py_db, request, error_message):
1347-
body = pydevd_schema.SetExpressionResponseBody(value='')
1348-
variables_response = pydevd_base_schema.build_response(request, kwargs={
1349-
'body':body, 'success':False, 'message': error_message})
1347+
body = pydevd_schema.SetExpressionResponseBody(value="")
1348+
variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body, "success": False, "message": error_message})
13501349
py_db.writer.add_command(NetCommand(CMD_RETURN, 0, variables_response, is_json=True))
13511350

13521351

@@ -1362,18 +1361,18 @@ def internal_set_expression_json(py_db, request, thread_id):
13621361
fmt = fmt.to_dict()
13631362

13641363
frame = py_db.find_frame(thread_id, frame_id)
1365-
exec_code = '%s = (%s)' % (expression, value)
1364+
exec_code = "%s = (%s)" % (expression, value)
13661365
try:
13671366
pydevd_vars.evaluate_expression(py_db, frame, exec_code, is_exec=True)
13681367
except (Exception, KeyboardInterrupt):
1369-
_set_expression_response(py_db, request, error_message='Error executing: %s' % (exec_code,))
1368+
_set_expression_response(py_db, request, error_message="Error executing: %s" % (exec_code,))
13701369
return
13711370

13721371
# Ok, we have the result (could be an error), let's put it into the saved variables.
13731372
frame_tracker = py_db.suspended_frames_manager.get_frame_tracker(thread_id)
13741373
if frame_tracker is None:
13751374
# This is not really expected.
1376-
_set_expression_response(py_db, request, error_message='Thread id: %s is not current thread id.' % (thread_id,))
1375+
_set_expression_response(py_db, request, error_message="Thread id: %s is not current thread id." % (thread_id,))
13771376
return
13781377

13791378
# Now that the exec is done, get the actual value changed to return.

0 commit comments

Comments
 (0)