-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclassname_size.py
89 lines (74 loc) · 2.62 KB
/
classname_size.py
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
#!/usr/bin/python
"""
Gather statistics on the length of fully-qualified class names in a python
source tree.
Usage: ./classname_size.py top-dir-name
"""
from __future__ import print_function
import glob
import os
import re
import sys
class CodeInfo:
def __init__(self, topdir):
self.topdir = topdir
self.classnames = set()
def process_file(self, filepath, module_name):
with open(filepath, 'r') as f:
for line in f:
m = re.match(r'class\s+(\w+)\s*(\(.*\))?\s*:', line)
if m:
classname = m.group(1)
self.classnames.add(module_name + '.' + classname)
def process(self):
for dirpath, dirnames, filenames in os.walk(self.topdir):
if '.git' in dirnames:
dirnames.remove('.git')
# Get package name for current dir based on topdir
package_name = None
if dirpath.startswith(self.topdir):
package_name = dirpath[len(self.topdir):].replace('/', '.')
package_name = package_name.lstrip('.')
for filename in filenames:
if not filename.endswith('.py'):
continue
if package_name:
module_name = package_name + '.' + filename[:-3]
else:
module_name = filename[:-3]
filepath = os.path.join(dirpath, filename)
self.process_file(filepath, module_name)
def report_classnames(self):
classnames = sorted(self.classnames)
for classname in classnames:
print(classname)
def report_classname_size_histogram(self):
sizes_names = sorted((len(classname), classname)
for classname in self.classnames)
min_size = 2**32
max_size = 0
tot_size = 0
for size, classname in sizes_names:
if size < min_size:
min_size = size
if size > max_size:
max_size = size
tot_size += size
print("{0} {1}".format(size, classname))
print()
print("min", min_size)
if len(sizes_names) > 0:
print("ave", float(tot_size) / len(sizes_names))
print("max", max_size)
def classname_sizes_report(topdir):
info = CodeInfo(topdir)
info.process()
info.report_classname_size_histogram()
def main():
if len(sys.argv) < 2 or sys.argv[1].lower() in ('-h', '--help'):
print(__doc__)
return 1
topdir = sys.argv[1]
classname_sizes_report(topdir)
if __name__ == '__main__':
sys.exit(main())