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