-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind_types.py
81 lines (58 loc) · 2.26 KB
/
find_types.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
import re
import ast
from collections import namedtuple
from ast import dump, get_docstring
# A type for holding source code and docstring type hints
TypePair = namedtuple("TypePair", ["src", "doc"])
class Analyzer(ast.NodeVisitor):
def __init__(self) -> None:
self.type_pairs_set = set()
# Pattern for finding docstring type hint
self.pattern = re.compile('.* ->(.*)$', re.MULTILINE)
def visit_FunctionDef(self, node) -> None:
docstring = get_docstring(node)
# If a function has a docstring, has a return type annotation
# and there is "->" in the docstring
if not (docstring and node.returns and "->" in docstring):
self.generic_visit(node)
return
# Look for type hint annotation in docstring
match = self.pattern.search(docstring)
if not match:
self.generic_visit(node)
return
src_type = node.returns.s
doc_type = match.groups()[0].strip()
# Add to the set
type_map = TypePair(src=src_type, doc=doc_type)
self.type_pairs_set.add(type_map)
# Visit child nodes
self.generic_visit(node)
def skip(pair: TypePair) -> bool:
return \
"void" in pair.src or \
"std::vector" in pair.src or \
"InterpreterObject" in pair.src or \
"std::map" in pair.src or \
"UT_Tuple" in pair.src or \
"std::pair" in pair.src or \
"HOM_IterableList" in pair.src or \
"HOM_EnumValue &" in pair.src or \
pair.doc == '' # Cases where return type is on the next line in the docstring
def print_pairs(pairs) -> None:
for pair in pairs:
print(f'"{pair.src}" = {pair.doc}')
def main() -> None:
with open("/opt/hfs19.0.657/houdini/python3.7libs/hou.py", "r") as src:
tree = ast.parse(src.read())
analyzer = Analyzer()
analyzer.visit(tree)
pairs = analyzer.type_pairs_set # First batch of type pairs
# Filter out some types, see the skip function
pairs_skipped = tuple(pair for pair in pairs if not skip(pair))
# Sort by source type to find duplicates
pairs_sorted = sorted(pairs_skipped, key=lambda x: x.src)
#Print out results
print_pairs(pairs_sorted)
if __name__ == "__main__":
main()