-
Notifications
You must be signed in to change notification settings - Fork 1
/
generate_hierarchy.py
110 lines (95 loc) · 4.11 KB
/
generate_hierarchy.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import logging
import os
import subprocess
import sys
from collections import defaultdict
from operator import itemgetter
logging.basicConfig(level=logging.DEBUG)
class GenerateHierarchy:
def __init__(self):
# it will have a module:class:children mapping.
self.class_dict = defaultdict(lambda: defaultdict(list))
def show_class(self, name, class_data):
"""show the class and its contents.
Arguments:
name {str} -- name of the class for which data is to be shown.
class_data {list} -- complete class_data as generated from pyclbr.
"""
# logging.debug(class_data)
self.class_dict[name] = []
self.show_super_classes(name, class_data)
def show_methods(self, class_name, class_data):
"""generates all the methods in a given class
Arguments:
class_name {str} -- name of the class whose methods are to be shown.
class_data {list} -- complete class_data as generated from pyclbr.
Returns:
list -- all the methods that are declared in the given class(name param)
"""
methods = []
for name, _ in sorted(class_data.methods.items(), key=itemgetter(1)):
# logging.debug(' Method: {0} [{1}]'.format(name, lineno))
methods.append(name)
return methods
def show_super_classes(self, name, class_data, object):
"""Shows super classes for a given class
Arguments:
name {str} -- name of the class for which superclasses are to be collected
class_data {#TODO} -- complete class_data as generated from pyclbr.
Returns:
list -- names of superclasses
"""
super_class_names = []
for super_class in class_data.super:
if super_class == 'object':
continue
if isinstance(super_class, str):
# find the class in covered modules
found = False
for module in object.class_object_mapping.keys():
for class_ in object.class_object_mapping[module].keys():
if object.class_object_mapping[module][class_].name == super_class:
found = True
super_class = object.class_object_mapping[module][class_]
break
if found:
break
if not found: # the parent class is not in the source code base, it is imported.
continue
super_class_names.append(
{
'parent_module': super_class.module,
'parent_class': super_class.name
}
)
for super_class_name in super_class_names:
if self.class_dict.get(super_class_name['parent_module']):
if self.class_dict.get(super_class_name['parent_class']):
self.class_dict[super_class_name['parent_module']][super_class_name['parent_class']].append(
{
'child_module': class_data.module,
'child_class': name
}
)
else:
self.class_dict[super_class_name['parent_module']][super_class_name['parent_class']] = [
{
'child_module': class_data.module,
'child_class': name
}
]
# adding all parents for a class in one place for later usage: children
return super_class_names
def get_children(self, name, class_data):
"""returns all the computed children for a given class if any
otherwise returns an empty list.
Arguments:
name {[type]} -- [description]
Returns:
list -- list of classes that are children for a given class.
"""
module = class_data.module
if self.class_dict.get(module, None):
if self.class_dict[module].get(name):
return self.class_dict[class_data.module][name]
return []