-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathPySummary.py
More file actions
180 lines (140 loc) · 5.29 KB
/
Copy pathPySummary.py
File metadata and controls
180 lines (140 loc) · 5.29 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
"""PySummary
A PySummary instance reads a Python file and creates a summary of the file
which you can access by using it as a (e.g., %s or str()).
The notion of a "category" is recognized. A category is simply a group of
methods with a given name. The default prefix for denoting a category is ##.
"""
import os
class PySummary(object):
## Init ##
def __init__(self):
self._filename = None
self._lines = []
self.invalidateCache()
if os.path.exists('PySummary.config'):
self.readConfig('PySummary.config')
## Config ##
def readConfig(self, filename):
self._settings = eval(open(filename).read())
assert isinstance(self._settings, dict)
## Reading files ##
def readFileNamed(self, filename):
self._filename = filename
with open(filename) as f:
self.readFile(f)
def readFile(self, file):
self.invalidateCache()
lines = file.readlines()
while lines:
line = lines.pop(0).rstrip()
sline = line.lstrip()
if not sline:
continue
try:
if sline[:6] == 'class ' and sline[6] != '_' and (
sline.find('(', 7) >= 0 or sline.find(':', 7) >= 0):
self._lines.append(Line('class', line)) # a class
line = lines.pop(0).lstrip()
if line[:3] == '"""': # skip docstring
while lines and line.rstrip()[-3:] != '"""':
line = lines.pop(0)
while lines and line.lstrip(): # skip body
line = lines.pop(0)
elif sline[:4] == 'def ' and (sline[4] != '_'
or sline[5] == '_') and sline.find('(', 5) >= 0:
self._lines.append(Line('def', line)) # a method
line = lines.pop(0).lstrip()
if line[:3] == '"""': # skip docstring
while lines and line.rstrip()[-3:] != '"""':
line = lines.pop(0)
while lines and line.lstrip(): # skip body
line = lines.pop(0)
elif sline[:3] == '## ': # a category
self._lines.append(Line('category', line))
except IndexError:
pass
## Reports ##
def text(self):
return self.render('text')
def html(self):
return self.render('html')
def render(self, format):
filename = self._filename
path, basename = os.path.split(filename)
module = os.path.splitext(basename)[0]
package = '%s.%s' % (path, module)
span = format == 'html'
settings = self._settings[format]
res = [settings['file'][0] % locals()]
if self._lines:
for line in self._lines:
lineType = line.type()
if (line.text()[:1].lstrip()
and settings[lineType][0][:1] == '\n'):
res.append('\n')
res.append(settings[lineType][0])
if span:
res.append('<span class="line_%s">' % lineType)
res.append(getattr(line, format)()) # e.g., line.format()
if span:
res.append('</span>')
res.append('\n')
res.append(settings[lineType][1])
else:
res.append('# No classes or functions defined in this module.')
res.append('\n')
res.append(settings['file'][1] % locals())
res = ''.join(res)
res = res.replace('\t', settings['tabSubstitute'])
return res
## As strings ##
def __repr__(self):
return self.text()
def __str__(self):
return self.html()
## Self utility ##
def invalidateCache(self):
self._text = None
self._html = None
class Line(object):
def __init__(self, type, contents):
self._type = type
self._text = contents
self._html = None
def type(self):
return self._type
def text(self):
return self._text
def html(self):
if self._html is None:
if self._type == 'class' or self._type == 'def':
ht = self._text
start = ht.find(self._type) + len(self._type) + 1
end = ht.find('(', start)
if end < 0:
end = ht.find(':', start)
if end < 0:
end = start
if self._type == 'def':
end2 = ht.find(')', end + 1)
if end2 >= 0:
ht = ht[:end2+1]
ht = '%s<span class="name_%s">%s</span>%s' % (
ht[:start], self._type, ht[start:end], ht[end:])
else:
ht = self._text
self._html = ht
return self._html
def __str__(self):
return self.text()
## Auxiliary functions ##
def test():
print 'Testing on self...'
sum = PySummary()
sum.readFileNamed('PySummary.py')
open('PySummary.py.sum.text', 'w').write(sum.text())
open('PySummary.py.sum.html', 'w').write(sum.html())
print 'Wrote PySummary.py.sum.* files.'
print 'Finished.'
if __name__ == '__main__':
test()