from pydevd_file_utils import GetFileNameAndBaseFromFile import pydev_log import traceback from pydevd_constants import DictContains def read_file(filename): f = open(filename, "r") try: s = f.read() finally: f.close() return s def offset_to_line_number(text, offset): curLine = 1 curOffset = 0 while curOffset < offset: if curOffset == len(text): return -1 c = text[curOffset] if c == '\n': curLine += 1 elif c == '\r': curLine += 1 if curOffset < len(text) and text[curOffset + 1] == '\n': curOffset += 1 curOffset += 1 return curLine def get_source(frame): try: node = frame.f_locals['self'] if hasattr(node, 'source'): return node.source else: pydev_log.error_once( "WARNING: Template path is not available. Please set TEMPLATE_DEBUG=True " "in your settings.py to make django template breakpoints working") return None except: pydev_log.debug(traceback.format_exc()) return None def get_template_file_name(frame): try: source = get_source(frame) if source is None: pydev_log.debug("Source is None\n") return None fname = source[0].name if fname == '': pydev_log.debug("Source name is %s\n" % fname) return None else: filename, base = GetFileNameAndBaseFromFile(fname) return filename except: pydev_log.debug(traceback.format_exc()) return None def get_template_line(frame, template_frame_file): source = get_source(frame) try: return offset_to_line_number(read_file(template_frame_file), source[1][0]) except: return None class DjangoTemplateFrame: def __init__( self, frame, template_frame_file=None, template_frame_line=None): if template_frame_file is None: template_frame_file = get_template_file_name(frame) self.back_context = frame.f_locals['context'] self.f_code = FCode('Django Template', template_frame_file) if template_frame_line is None: template_frame_line = get_template_line(frame, template_frame_file) self.f_lineno = template_frame_line self.f_back = frame self.f_globals = {} self.f_locals = self.collect_context() self.f_trace = None def collect_context(self): res = {} try: for d in self.back_context.dicts: res.update(d) except AttributeError: pass return res def changeVariable(self, name, value): for d in self.back_context.dicts: if DictContains(d, name): d[name] = value self.f_locals[name] = value class FCode: def __init__(self, name, filename): self.co_name = name self.co_filename = filename def is_django_exception_break_context(frame): try: return frame.f_code.co_name in ['_resolve_lookup', 'find_template'] except: return False def just_raised(trace): if trace is None: return False return trace.tb_next is None