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