Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Takes some changes from pydevd to fix line numbers being None #1734

Merged
merged 7 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
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
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ __pycache__/
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
Expand Down
1 change: 1 addition & 0 deletions build/git-subrepo
Submodule git-subrepo added at cce3d9
4 changes: 2 additions & 2 deletions src/debugpy/_vendored/pydevd/.gitrepo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/fabioz/PyDev.Debugger.git
branch = main
commit = cf2e47cbb81a7b4e159f10d56208f4d22ff5423d
parent = 942a2276127598ef84d06b7f7b889281c1047712
commit = d0f81de46ec51687ac24ae9598eb2615010a4b44
parent = 8ab4ee89e9ae9a926f711904900a27e3c96d43d4
method = merge
cmdver = 0.4.9
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ encoding//pydev_ipython/inputhookqt5.py=utf-8
encoding//pydev_ipython/inputhooktk.py=utf-8
encoding//pydev_ipython/inputhookwx.py=utf-8
encoding//pydev_ipython/version.py=utf-8
encoding//pydevd_attach_to_process/winappdbg/__init__.py=utf-8
encoding//pydevd_attach_to_process/winappdbg/breakpoint.py=utf-8
encoding//pydevd_attach_to_process/winappdbg/crash.py=utf-8
encoding//pydevd_attach_to_process/winappdbg/interactive.py=utf-8
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def _encode_if_needed(obj):

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,9 @@ def update_class_to_generate_init(class_to_generate):
# Note: added kwargs because some messages are expected to be extended by the user (so, we'll actually
# make all extendable so that we don't have to worry about which ones -- we loose a little on typing,
# but may be better than doing a allow list based on something only pointed out in the documentation).
class_to_generate["init"] = '''def __init__(self%(args)s, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused)
class_to_generate[
"init"
] = '''def __init__(self%(args)s, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused)
"""
%(docstring)s
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,8 +529,7 @@ def build_line_to_contents(self):
instruction = instructions[0]
new_line_index = op_offset_to_line.get(instruction.offset)
if new_line_index is not None:
if new_line_index is not None:
curr_line_index = new_line_index
curr_line_index = new_line_index

self._process_next(curr_line_index)
return self.writer.line_to_contents
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,125 +82,8 @@ def debug(s):
_Instruction = namedtuple("_Instruction", "opname, opcode, starts_line, argval, is_jump_target, offset, argrepr")


def _iter_as_bytecode_as_instructions_py2(co):
code = co.co_code
op_offset_to_line = dict(dis.findlinestarts(co))
labels = set(dis.findlabels(code))
bytecode_len = len(code)
i = 0
extended_arg = 0
free = None

op_to_name = opname

while i < bytecode_len:
c = code[i]
op = ord(c)
is_jump_target = i in labels

curr_op_name = op_to_name[op]
initial_bytecode_offset = i

i = i + 1
if op < HAVE_ARGUMENT:
yield _Instruction(
curr_op_name,
op,
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
None,
is_jump_target,
initial_bytecode_offset,
"",
)

else:
oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg

extended_arg = 0
i = i + 2
if op == EXTENDED_ARG:
extended_arg = oparg * 65536

if op in hasconst:
yield _Instruction(
curr_op_name,
op,
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
co.co_consts[oparg],
is_jump_target,
initial_bytecode_offset,
repr(co.co_consts[oparg]),
)
elif op in hasname:
yield _Instruction(
curr_op_name,
op,
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
co.co_names[oparg],
is_jump_target,
initial_bytecode_offset,
str(co.co_names[oparg]),
)
elif op in hasjrel:
argval = i + oparg
yield _Instruction(
curr_op_name,
op,
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
argval,
is_jump_target,
initial_bytecode_offset,
"to " + repr(argval),
)
elif op in haslocal:
yield _Instruction(
curr_op_name,
op,
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
co.co_varnames[oparg],
is_jump_target,
initial_bytecode_offset,
str(co.co_varnames[oparg]),
)
elif op in hascompare:
yield _Instruction(
curr_op_name,
op,
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
cmp_op[oparg],
is_jump_target,
initial_bytecode_offset,
cmp_op[oparg],
)
elif op in hasfree:
if free is None:
free = co.co_cellvars + co.co_freevars
yield _Instruction(
curr_op_name,
op,
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
free[oparg],
is_jump_target,
initial_bytecode_offset,
str(free[oparg]),
)
else:
yield _Instruction(
curr_op_name,
op,
_get_line(op_offset_to_line, initial_bytecode_offset, 0),
oparg,
is_jump_target,
initial_bytecode_offset,
str(oparg),
)


def iter_instructions(co):
if sys.version_info[0] < 3:
iter_in = _iter_as_bytecode_as_instructions_py2(co)
else:
iter_in = dis.Bytecode(co)
iter_in = dis.Bytecode(co)
iter_in = list(iter_in)

bytecode_to_instruction = {}
Expand Down Expand Up @@ -327,7 +210,7 @@ def collect_try_except_info(co, use_func_first_line=False):

try_except_info_lst = []

op_offset_to_line = dict(dis.findlinestarts(co))
op_offset_to_line = dict(entry for entry in dis.findlinestarts(co) if entry[1] is not None)

offset_to_instruction_idx = {}

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

try_except_info_lst = []

op_offset_to_line = dict(dis.findlinestarts(co))
op_offset_to_line = dict(entry for entry in dis.findlinestarts(co) if entry[1] is not None)

offset_to_instruction_idx = {}

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

# Update offsets so that all offsets have the line index (and update it based on
# the passed firstlineno).
Expand Down
11 changes: 5 additions & 6 deletions src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1344,9 +1344,8 @@ def internal_evaluate_expression(dbg, seq, thread_id, frame_id, expression, is_e


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


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

frame = py_db.find_frame(thread_id, frame_id)
exec_code = '%s = (%s)' % (expression, value)
exec_code = "%s = (%s)" % (expression, value)
try:
pydevd_vars.evaluate_expression(py_db, frame, exec_code, is_exec=True)
except (Exception, KeyboardInterrupt):
_set_expression_response(py_db, request, error_message='Error executing: %s' % (exec_code,))
_set_expression_response(py_db, request, error_message="Error executing: %s" % (exec_code,))
return

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

# Now that the exec is done, get the actual value changed to return.
Expand Down
Loading
Loading