145 lines
4.4 KiB
Python
Executable File
145 lines
4.4 KiB
Python
Executable File
#!/usr/bin/python
|
|
import sys
|
|
import os
|
|
import re
|
|
|
|
"""
|
|
@todo: fix .find('"\"\"')
|
|
@todo: string trailing "#"
|
|
@todo: support function args split into multiple lines
|
|
"""
|
|
|
|
args = sys.argv[1:]
|
|
indent_level = 4 # spaces
|
|
func_reg = re.compile(r"\s*def.*?\w\(.*?\):$")
|
|
indent_level_reg = re.compile(r"^\s*")
|
|
args_reg = re.compile(r"\(.*?\)")
|
|
do_docstring_private = False
|
|
do_docstring_protected = True
|
|
do_write_return_docstring = True
|
|
|
|
if not args:
|
|
sys.stdout.write("usage: %s [path]\n" % (sys.argv[0],))
|
|
raise SystemExit(1)
|
|
|
|
def write_new_line(buf, data):
|
|
buf.write(data)
|
|
sys.stdout.write(data)
|
|
|
|
for path in args:
|
|
|
|
if not os.access(path, os.F_OK | os.R_OK | os.W_OK):
|
|
sys.stderr.write("unable to deal with %s\n" % (path,))
|
|
sys.stderr.flush()
|
|
continue
|
|
|
|
f = open(path, "r")
|
|
line = f.readline()
|
|
|
|
out = open(path + ".ds", "w")
|
|
|
|
while line:
|
|
|
|
# function name
|
|
r_match = func_reg.match(line)
|
|
if r_match is not None:
|
|
|
|
###
|
|
### extract metadata
|
|
###
|
|
# we've found a defined function
|
|
raw_func_str = r_match.group()
|
|
my_indent_level = len(indent_level_reg.match(line).group())
|
|
extr_str = r_match.group()[:-1].strip()[len("def"):].strip()
|
|
dodoc = True
|
|
if extr_str.startswith("__") and not do_docstring_private:
|
|
dodoc = False
|
|
elif extr_str.startswith("__") and not do_docstring_protected:
|
|
dodoc = False
|
|
|
|
dowrite = False
|
|
grab_lines = []
|
|
args_string = ''
|
|
if dodoc:
|
|
|
|
# write current line, to make sure to have function definition
|
|
# in place
|
|
write_new_line(out, line)
|
|
|
|
my_indent_level += indent_level
|
|
|
|
# extract arguments
|
|
my_args = args_reg.findall(extr_str)
|
|
if my_args:
|
|
my_args = my_args[0][1:-1].split(",")
|
|
if "self" in my_args:
|
|
my_args.remove("self")
|
|
|
|
# eventually write arguments string
|
|
for myarg in my_args:
|
|
|
|
if "=" in myarg:
|
|
myarg = myarg.strip().split()[0]
|
|
# keyword arg
|
|
args_string += '%s@keyword %s:\n' % (
|
|
" "*my_indent_level, myarg,)
|
|
else:
|
|
myarg = myarg.strip()
|
|
# arg
|
|
args_string += '%s@param %s:\n' % (
|
|
" "*my_indent_level, myarg,)
|
|
|
|
args_string += '%s@type %s:\n' % (
|
|
" "*my_indent_level, myarg,)
|
|
|
|
if do_write_return_docstring:
|
|
args_string += '%s@return:\n' % (
|
|
" "*my_indent_level,)
|
|
args_string += '%s@rtype:\n' % (
|
|
" "*my_indent_level,)
|
|
|
|
|
|
# now it is necessary to check if a docstring is
|
|
# already set, if so, skip this
|
|
# grab next line
|
|
while 1:
|
|
line = f.readline()
|
|
if not line.strip():
|
|
# line empty
|
|
grab_lines.append(line)
|
|
continue
|
|
elif line.find('"""') == -1:
|
|
# line is not empty and does not contain
|
|
# a docstring
|
|
dowrite = True
|
|
grab_lines.append(line)
|
|
# current line will be written to stdout
|
|
# after if condition
|
|
break
|
|
|
|
if dowrite:
|
|
|
|
mydocstr = '%s"""\n%s%s\n\n%s\n%s"""\n' % (
|
|
" "*my_indent_level, " "*my_indent_level,
|
|
"docstring_title", args_string,
|
|
" "*my_indent_level,
|
|
)
|
|
grab_lines.insert(0, mydocstr)
|
|
|
|
# flushing read lines, preparing for contining or
|
|
# writing docstring
|
|
for grab_line in grab_lines:
|
|
write_new_line(out, grab_line)
|
|
|
|
if dowrite:
|
|
line = f.readline()
|
|
continue
|
|
|
|
write_new_line(out, line)
|
|
line = f.readline()
|
|
|
|
sys.stdout.flush()
|
|
out.flush()
|
|
out.close()
|
|
f.close()
|