def cmd_ignore_thrown_exception_at(self, py_db, cmd_id, seq, text): if text: replace = 'REPLACE:' # Not all 3.x versions support u'REPLACE:', so, doing workaround. if not IS_PY3K: replace = unicode(replace) # noqa if text.startswith(replace): text = text[8:] py_db.filename_to_lines_where_exceptions_are_ignored.clear() if text: for line in text.split('||'): # Can be bulk-created (one in each line) original_filename, line_number = line.split('|') original_filename = self.api.filename_to_server(original_filename) canonical_normalized_filename = pydevd_file_utils.canonical_normalized_path(original_filename) absolute_filename = pydevd_file_utils.absolute_path(original_filename) if os.path.exists(absolute_filename): lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored.get(canonical_normalized_filename) if lines_ignored is None: lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored[canonical_normalized_filename] = {} lines_ignored[int(line_number)] = 1 else: sys.stderr.write('pydev debugger: warning: trying to ignore exception thrown'\ ' on file that does not exist: %s (will have no effect)\n' % (absolute_filename,))
def set_source_mapping(self, py_db, source_filename, mapping): ''' :param str source_filename: The filename for the source mapping (bytes on py2 and str on py3). This filename will be made absolute in this function. :param list(SourceMappingEntry) mapping: A list with the source mapping entries to be applied to the given filename. :return str: An error message if it was not possible to set the mapping or an empty string if everything is ok. ''' source_filename = self.filename_to_server(source_filename) absolute_source_filename = pydevd_file_utils.absolute_path( source_filename) for map_entry in mapping: map_entry.source_filename = absolute_source_filename error_msg = py_db.source_mapping.set_source_mapping( absolute_source_filename, mapping) if error_msg: return error_msg self.reapply_breakpoints(py_db) return ''
def _get_template_line(frame): if IS_DJANGO19_OR_HIGHER: node = frame.f_locals['self'] if hasattr(node, 'token') and hasattr(node.token, 'lineno'): return node.token.lineno else: return None source = _get_source_django_18_or_lower(frame) original_filename = _get_template_original_file_name_from_frame(frame) if original_filename is not None: try: absolute_filename = absolute_path(original_filename) return _offset_to_line_number(_read_file(absolute_filename), source[1][0]) except: return None return None
def debug(address, **kwargs): if _settrace.called: raise RuntimeError("this process already has a debug adapter") try: _, port = address except Exception: port = address address = ("127.0.0.1", port) try: port.__index__() # ensure it's int-like except Exception: raise ValueError("expected port or (host, port)") if not (0 <= port < 2**16): raise ValueError("invalid port number") ensure_logging() log.debug("{0}({1!r}, **{2!r})", func.__name__, address, kwargs) log.info("Initial debug configuration: {0!j}", _config) qt_mode = _config.get("qt", "none") if qt_mode != "none": pydevd.enable_qt_support(qt_mode) settrace_kwargs = { "suspend": False, "patch_multiprocessing": _config.get("subProcess", True), } debugpy_path = os.path.dirname(absolute_path(debugpy.__file__)) settrace_kwargs["dont_trace_start_patterns"] = (debugpy_path, ) settrace_kwargs["dont_trace_end_patterns"] = ( str("debugpy_launcher.py"), ) try: return func(address, settrace_kwargs, **kwargs) except Exception: log.reraise_exception("{0}() failed:", func.__name__, level="info")
def _absolute_normalized_path(self, filename): ''' Provides a version of the filename that's absolute and normalized. ''' return normcase(pydevd_file_utils.absolute_path(filename))
def add_breakpoint(self, py_db, original_filename, breakpoint_type, breakpoint_id, line, condition, func_name, expression, suspend_policy, hit_condition, is_logpoint, adjust_line=False): ''' :param str original_filename: Note: must be sent as it was received in the protocol. It may be translated in this function and its final value will be available in the returned _AddBreakpointResult. :param str breakpoint_type: One of: 'python-line', 'django-line', 'jinja2-line'. :param int breakpoint_id: :param int line: Note: it's possible that a new line was actually used. If that's the case its final value will be available in the returned _AddBreakpointResult. :param condition: Either None or the condition to activate the breakpoint. :param str func_name: If "None" (str), may hit in any context. Empty string will hit only top level. Any other value must match the scope of the method to be matched. :param str expression: None or the expression to be evaluated. :param suspend_policy: Either "NONE" (to suspend only the current thread when the breakpoint is hit) or "ALL" (to suspend all threads when a breakpoint is hit). :param str hit_condition: An expression where `@HIT@` will be replaced by the number of hits. i.e.: `@HIT@ == x` or `@HIT@ >= x` :param bool is_logpoint: If True and an expression is passed, pydevd will create an io message command with the result of the evaluation. :return _AddBreakpointResult: ''' assert original_filename.__class__ == str, 'Expected str, found: %s' % ( original_filename.__class__, ) # i.e.: bytes on py2 and str on py3 pydev_log.debug('Request for breakpoint in: %s line: %s', original_filename, line) # Parameters to reapply breakpoint. api_add_breakpoint_params = (original_filename, breakpoint_type, breakpoint_id, line, condition, func_name, expression, suspend_policy, hit_condition, is_logpoint) translated_filename = self.filename_to_server( original_filename) # Apply user path mapping. pydev_log.debug('Breakpoint (after path translation) in: %s line: %s', translated_filename, line) func_name = self.to_str(func_name) assert translated_filename.__class__ == str # i.e.: bytes on py2 and str on py3 assert func_name.__class__ == str # i.e.: bytes on py2 and str on py3 # Apply source mapping (i.e.: ipython). source_mapped_filename, new_line, multi_mapping_applied = py_db.source_mapping.map_to_server( translated_filename, line) if multi_mapping_applied: pydev_log.debug( 'Breakpoint (after source mapping) in: %s line: %s', source_mapped_filename, new_line) # Note that source mapping is internal and does not change the resulting filename nor line # (we want the outside world to see the line in the original file and not in the ipython # cell, otherwise the editor wouldn't be correct as the returned line is the line to # which the breakpoint will be moved in the editor). result = self._AddBreakpointResult(original_filename, line) # If a multi-mapping was applied, consider it the canonical / source mapped version (translated to ipython cell). translated_absolute_filename = source_mapped_filename canonical_normalized_filename = pydevd_file_utils.normcase( source_mapped_filename) line = new_line else: translated_absolute_filename = pydevd_file_utils.absolute_path( translated_filename) canonical_normalized_filename = pydevd_file_utils.canonical_normalized_path( translated_filename) if adjust_line and not translated_absolute_filename.startswith( '<'): # Validate breakpoints and adjust their positions. try: lines = sorted( _get_code_lines(translated_absolute_filename)) except Exception: pass else: if line not in lines: # Adjust to the first preceding valid line. idx = bisect.bisect_left(lines, line) if idx > 0: line = lines[idx - 1] result = self._AddBreakpointResult(original_filename, line) py_db.api_received_breakpoints[(original_filename, breakpoint_id)] = ( canonical_normalized_filename, api_add_breakpoint_params) if not translated_absolute_filename.startswith('<'): # Note: if a mapping pointed to a file starting with '<', don't validate. if not pydevd_file_utils.exists(translated_absolute_filename): result.error_code = self.ADD_BREAKPOINT_FILE_NOT_FOUND return result if (py_db.is_files_filter_enabled and not py_db.get_require_module_for_filters() and py_db.apply_files_filter( self._DummyFrame(translated_absolute_filename), translated_absolute_filename, False)): # Note that if `get_require_module_for_filters()` returns False, we don't do this check. # This is because we don't have the module name given a file at this point (in # runtime it's gotten from the frame.f_globals). # An option could be calculate it based on the filename and current sys.path, # but on some occasions that may be wrong (for instance with `__main__` or if # the user dynamically changes the PYTHONPATH). # Note: depending on the use-case, filters may be changed, so, keep on going and add the # breakpoint even with the error code. result.error_code = self.ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS if breakpoint_type == 'python-line': added_breakpoint = LineBreakpoint(line, condition, func_name, expression, suspend_policy, hit_condition=hit_condition, is_logpoint=is_logpoint) breakpoints = py_db.breakpoints file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint supported_type = True else: add_plugin_breakpoint_result = None plugin = py_db.get_plugin_lazy_init() if plugin is not None: add_plugin_breakpoint_result = plugin.add_breakpoint( 'add_line_breakpoint', py_db, breakpoint_type, canonical_normalized_filename, line, condition, expression, func_name, hit_condition=hit_condition, is_logpoint=is_logpoint) if add_plugin_breakpoint_result is not None: supported_type = True added_breakpoint, breakpoints = add_plugin_breakpoint_result file_to_id_to_breakpoint = py_db.file_to_id_to_plugin_breakpoint else: supported_type = False if not supported_type: raise NameError(breakpoint_type) if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0: pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n', canonical_normalized_filename, line, func_name) if canonical_normalized_filename in file_to_id_to_breakpoint: id_to_pybreakpoint = file_to_id_to_breakpoint[ canonical_normalized_filename] else: id_to_pybreakpoint = file_to_id_to_breakpoint[ canonical_normalized_filename] = {} id_to_pybreakpoint[breakpoint_id] = added_breakpoint py_db.consolidate_breakpoints(canonical_normalized_filename, id_to_pybreakpoint, breakpoints) if py_db.plugin is not None: py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks() py_db.on_breakpoints_changed() return result