-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpymdgen.py
executable file
·114 lines (88 loc) · 2.78 KB
/
pymdgen.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
111
112
113
#!/bin/env python
import click
import importlib
import inspect
import logging
from pprint import pprint
log = logging.getLogger('pymdgen')
def doc_func(name, func, section_level=4):
docstr = inspect.getdoc(func)
# skip functions without a docstr
if not docstr:
return
spec = inspect.getargspec(func)
display = []
end_args = []
# *args and **kwargs
if spec[1]:
end_args.append('*' + spec[1])
if spec[2]:
end_args.append('**' + spec[2])
# check for args with defaults
if spec[3]:
args = spec[0][-len(spec[3]):]
default_args = list(zip(args, spec[3]))
# set args to rest
args = spec[0][:-len(spec[3])]
else:
args = spec[0]
default_args = []
if args:
display.append(', '.join(args))
if default_args:
display.append(', '.join('%s=%s' % x for x in default_args))
if end_args:
display.append(', '.join(end_args))
print('#' * section_level, name)
print()
print('```')
print(name + '(' + ', '.join(display) + ')')
print('```')
print()
print(docstr)
print()
def doc_class(name, cls, section_level=3):
docstr = inspect.getdoc(cls)
# skip functions without a docstr
if not docstr:
return
# full mro is probably overkill?
# base_classes = inspect.getmro(cls)
base_classes = cls.__bases__
base_classes = (c.__module__ + '.' + c.__name__ for c in base_classes)
print('#' * section_level, name)
print()
print('```')
print(name + '(' + ', '.join(base_classes) + ')')
print('```')
print()
print(docstr)
print()
for name, func in list(cls.__dict__.items()):
if inspect.isfunction(func):
doc_func(name, func, section_level + 1)
print()
@click.command()
@click.option('--debug', help='display debug messages', is_flag=True, default=False)
@click.option('--section-level', help='markdown section level', default=3)
@click.argument('modules', nargs=-1)
def main(modules, debug, section_level):
""" inspects given python modules and prints markdown """
if debug:
logging.basicConfig(level=logging.DEBUG)
for name in modules:
if '/' in name or name.endswith('.py'):
name = name.replace('/', '.')
name = name.rstrip('.py')
print('modules should be in python notation, trying with', name)
module = importlib.import_module(name)
for k, v in inspect.getmembers(module):
if k == '__builtins__':
continue
log.debug("checking %s:%s" % (v, k))
if inspect.isfunction(v):
doc_func(k, v, section_level)
if inspect.isclass(v):
doc_class(k, v, section_level)
if __name__ == "__main__":
main()