Inserts pydevd programmatic breaks into the code (at the given lines). :param breakpoint_lines: set with the lines where we should add breakpoints. :return: tuple(boolean flag whether insertion was successful, modified code).
(
code_to_modify,
breakpoint_lines,
code_line_info=None,
_pydev_stop_at_break=_pydev_stop_at_break,
_pydev_needs_stop_at_break=_pydev_needs_stop_at_break,
)
| 237 | |
| 238 | |
| 239 | def insert_pydevd_breaks( |
| 240 | code_to_modify, |
| 241 | breakpoint_lines, |
| 242 | code_line_info=None, |
| 243 | _pydev_stop_at_break=_pydev_stop_at_break, |
| 244 | _pydev_needs_stop_at_break=_pydev_needs_stop_at_break, |
| 245 | ): |
| 246 | """ |
| 247 | Inserts pydevd programmatic breaks into the code (at the given lines). |
| 248 | |
| 249 | :param breakpoint_lines: set with the lines where we should add breakpoints. |
| 250 | :return: tuple(boolean flag whether insertion was successful, modified code). |
| 251 | """ |
| 252 | if code_line_info is None: |
| 253 | code_line_info = _get_code_line_info(code_to_modify) |
| 254 | |
| 255 | if not code_line_info.line_to_offset: |
| 256 | return False, code_to_modify |
| 257 | |
| 258 | # Create a copy (and make sure we're dealing with a set). |
| 259 | breakpoint_lines = set(breakpoint_lines) |
| 260 | |
| 261 | # Note that we can even generate breakpoints on the first line of code |
| 262 | # now, since we generate a spurious line event -- it may be a bit pointless |
| 263 | # as we'll stop in the first line and we don't currently stop the tracing after the |
| 264 | # user resumes, but in the future, if we do that, this would be a nice |
| 265 | # improvement. |
| 266 | # if code_to_modify.co_firstlineno in breakpoint_lines: |
| 267 | # return False, code_to_modify |
| 268 | |
| 269 | for line in breakpoint_lines: |
| 270 | if line <= 0: |
| 271 | # The first line is line 1, so, a break at line 0 is not valid. |
| 272 | pydev_log.info("Trying to add breakpoint in invalid line: %s", line) |
| 273 | return False, code_to_modify |
| 274 | |
| 275 | try: |
| 276 | b = bytecode.Bytecode.from_code(code_to_modify) |
| 277 | |
| 278 | if DEBUG: |
| 279 | op_number_bytecode = debug_helper.write_bytecode(b, prefix="bytecode.") |
| 280 | |
| 281 | helper_list = _HelperBytecodeList(b) |
| 282 | |
| 283 | modified_breakpoint_lines = breakpoint_lines.copy() |
| 284 | |
| 285 | curr_node = helper_list.head |
| 286 | added_breaks_in_lines = set() |
| 287 | last_lineno = None |
| 288 | while curr_node is not None: |
| 289 | instruction = curr_node.data |
| 290 | instruction_lineno = getattr(instruction, "lineno", None) |
| 291 | curr_name = getattr(instruction, "name", None) |
| 292 | |
| 293 | if FIX_PREDICT: |
| 294 | predict_targets = _PREDICT_TABLE.get(curr_name) |
| 295 | if predict_targets: |
| 296 | # Odd case: the next instruction may have a line number but it doesn't really |
nothing calls this directly
no test coverage detected