blob: 272888e26d161c6b80f14afc62d0c5df18a23f68 [file] [log] [blame]
Tor Norbye3a2425a2013-11-04 10:16:08 -08001from pydevd_file_utils import GetFileNameAndBaseFromFile
2import pydev_log
3import traceback
4
5def read_file(filename):
6 f = open(filename, "r")
7 s = f.read()
8 f.close()
9 return s
10
11
12def offset_to_line_number(text, offset):
13 curLine = 1
14 curOffset = 0
15 while curOffset < offset:
16 if curOffset == len(text):
17 return -1
18 c = text[curOffset]
19 if c == '\n':
20 curLine += 1
21 elif c == '\r':
22 curLine += 1
23 if curOffset < len(text) and text[curOffset + 1] == '\n':
24 curOffset += 1
25
26 curOffset += 1
27
28 return curLine
29
30
31def get_source(frame):
32 try:
33 node = frame.f_locals['self']
34 if hasattr(node, 'source'):
35 return node.source
36 else:
37 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")
38 return None
39
40 except:
41 pydev_log.debug(traceback.format_exc())
42 return None
43
44
45def get_template_file_name(frame):
46 try:
47 source = get_source(frame)
48 if source is None:
49 pydev_log.debug("Source is None\n")
50 return None
51 fname = source[0].name
52 pydev_log.debug("Source name is %s\n" % fname)
53 filename, base = GetFileNameAndBaseFromFile(fname)
54 return filename
55 except:
56 pydev_log.debug(traceback.format_exc())
57 return None
58
59
60def get_template_line(frame):
61 source = get_source(frame)
62 file_name = get_template_file_name(frame)
63 try:
64 return offset_to_line_number(read_file(file_name), source[1][0])
65 except:
66 return None
67
68
69class DjangoTemplateFrame:
70 def __init__(self, frame):
71 file_name = get_template_file_name(frame)
72 self.back_context = frame.f_locals['context']
73 self.f_code = FCode('Django Template', file_name)
74 self.f_lineno = get_template_line(frame)
75 self.f_back = frame
76 self.f_globals = {}
77 self.f_locals = self.collect_context(self.back_context)
78 self.f_trace = None
79
80 def collect_context(self, context):
81 res = {}
82 try:
83 for d in context.dicts:
84 for k, v in d.items():
85 res[k] = v
86 except AttributeError:
87 pass
88 return res
89
90 def changeVariable(self, name, value):
91 for d in self.back_context.dicts:
92 for k, v in d.items():
93 if k == name:
94 d[k] = value
95
96
97class FCode:
98 def __init__(self, name, filename):
99 self.co_name = name
100 self.co_filename = filename
101
102
103def is_django_exception_break_context(frame):
104 try:
105 name = frame.f_code.co_name
106 except:
107 name = None
108 return name in ['_resolve_lookup', 'find_template']
109
110
111def just_raised(trace):
112 if trace is None:
113 return False
114 return trace.tb_next is None
115