blob: 37ee04299cc67a9bf3c67b19a7313d21210124c7 [file] [log] [blame]
Tor Norbye3a2425a2013-11-04 10:16:08 -08001import inspect
2from django_frame import DjangoTemplateFrame, get_template_file_name, get_template_line
3from pydevd_comm import CMD_SET_BREAK
4from pydevd_constants import DJANGO_SUSPEND, GetThreadId
5from pydevd_file_utils import NormFileToServer
6from runfiles import DictContains
7from pydevd_breakpoints import LineBreakpoint
8import pydevd_vars
9import traceback
10
11class DjangoLineBreakpoint(LineBreakpoint):
12 def __init__(self, type, file, line, flag, condition, func_name, expression):
13 self.file = file
14 self.line = line
15 LineBreakpoint.__init__(self, type, flag, condition, func_name, expression)
16
17 def __eq__(self, other):
18 if not isinstance(other, DjangoLineBreakpoint):
19 return False
20 return self.file == other.file and self.line == other.line
21
22 def is_triggered(self, frame):
23 file = get_template_file_name(frame)
24 line = get_template_line(frame)
25 return self.file == file and self.line == line
26
27 def __str__(self):
28 return "DjangoLineBreakpoint: %s-%d" %(self.file, self.line)
29
30
31def inherits(cls, *names):
32 if cls.__name__ in names:
33 return True
34 inherits_node = False
35 for base in inspect.getmro(cls):
36 if base.__name__ in names:
37 inherits_node = True
38 break
39 return inherits_node
40
41
42def is_django_render_call(frame):
43 try:
44 name = frame.f_code.co_name
45 if name != 'render':
46 return False
47
48 if not DictContains(frame.f_locals, 'self'):
49 return False
50
51 cls = frame.f_locals['self'].__class__
52
53 inherits_node = inherits(cls, 'Node')
54
55 if not inherits_node:
56 return False
57
58 clsname = cls.__name__
59 return clsname != 'TextNode' and clsname != 'NodeList'
60 except:
61 traceback.print_exc()
62 return False
63
64
65def is_django_context_get_call(frame):
66 try:
67 if not DictContains(frame.f_locals, 'self'):
68 return False
69
70 cls = frame.f_locals['self'].__class__
71
72 return inherits(cls, 'BaseContext')
73 except:
74 traceback.print_exc()
75 return False
76
77
78def is_django_resolve_call(frame):
79 try:
80 name = frame.f_code.co_name
81 if name != '_resolve_lookup':
82 return False
83
84 if not DictContains(frame.f_locals, 'self'):
85 return False
86
87 cls = frame.f_locals['self'].__class__
88
89 clsname = cls.__name__
90 return clsname == 'Variable'
91 except:
92 traceback.print_exc()
93 return False
94
95
96def is_django_suspended(thread):
97 return thread.additionalInfo.suspend_type == DJANGO_SUSPEND
98
99
100def suspend_django(py_db_frame, mainDebugger, thread, frame, cmd=CMD_SET_BREAK):
101 frame = DjangoTemplateFrame(frame)
102
103 if frame.f_lineno is None:
104 return None
105
106 #try:
107 # if thread.additionalInfo.filename == frame.f_code.co_filename and thread.additionalInfo.line == frame.f_lineno:
108 # return None # don't stay twice on the same line
109 #except AttributeError:
110 # pass
111
112 pydevd_vars.addAdditionalFrameById(GetThreadId(thread), {id(frame): frame})
113
114 py_db_frame.setSuspend(thread, cmd)
115 thread.additionalInfo.suspend_type = DJANGO_SUSPEND
116
117 thread.additionalInfo.filename = frame.f_code.co_filename
118 thread.additionalInfo.line = frame.f_lineno
119
120 return frame
121
122
123def find_django_render_frame(frame):
124 while frame is not None and not is_django_render_call(frame):
125 frame = frame.f_back
126
127 return frame
128
129
130
131
132