-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathautodoc.py
More file actions
105 lines (75 loc) · 2.64 KB
/
autodoc.py
File metadata and controls
105 lines (75 loc) · 2.64 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
from inspect import getfullargspec, isclass
from io import StringIO
from typing import Callable
def inspectFunction(__func__: Callable) -> dict:
"""
Extract details about a function.
Returns a dict with:
- name: function name
- args: list of arguments
- default: dict of default arguments (if any)
- varargs: variable arguments (*args)
- varkw: keyword arguments (**kwargs)
- annotation: type annotations
"""
allData: dict = {}
allData["name"] = __func__.__name__
fullargs = getfullargspec(__func__)
argument = fullargs.args
allData["args"] = argument
defaultValue = fullargs.defaults
if defaultValue:
defaultLen = len(defaultValue)
defaultArgs = fullargs.args[::-1][:defaultLen][::-1]
defaultDict = {}
for key, value in zip(defaultArgs, defaultValue):
defaultDict[key] = value
allData["default"] = defaultDict
if fullargs.varargs:
allData["varargs"] = fullargs.varargs
if fullargs.varkw:
allData["varkw"] = fullargs.varkw
allData["annotation"] = fullargs.annotations
return allData
def buildDoc(__func__: Callable, read: bool = False) -> str:
"""
Build a documentation string for a function.
If read=True, generates a human-readable version.
Otherwise, generates a template with placeholders.
"""
__doc__ = StringIO()
write = __doc__.write
index = 1
detail = inspectFunction(__func__)
if read:
write("Function name: ")
write(detail["name"])
if not read:
write(": __description__")
write("\n\nArgument:\n")
for args in detail["args"]:
__type = detail["annotation"].get(args, "Unknown")
if isclass(__type):
__type = __type.__name__
extra = ""
if "default" in detail and args in detail["default"]:
default = detail["default"][args]
__type = f"{__type}, optional"
extra = f" Default is {default!r}."
write(
f" {args} ({__type}): {' __summary__.' if not read else f'parameter {index}.'}{extra}\n"
)
index += 1
returnType = detail["annotation"].get("return", "<unknown>")
if returnType != "<unknown>":
if isclass(returnType):
returnType = returnType.__name__
write(f"\nReturns: {returnType if read else ''}")
if not read:
write(f"\n {returnType}: __summary__.")
return __doc__.getvalue()
if __name__ == "__main__":
def testFunc(a: int, b: str = "Hi") -> str:
return b * a
print(inspectFunction(testFunc))
print(buildDoc(testFunc, read=True))