Skip to content

Instantly share code, notes, and snippets.

@tbnorth
Last active August 20, 2019 21:56
Show Gist options
  • Save tbnorth/e8d5d29ac240654fa6396b7528851caf to your computer and use it in GitHub Desktop.
Save tbnorth/e8d5d29ac240654fa6396b7528851caf to your computer and use it in GitHub Desktop.
"""
docstrings.py - show docstrings for .py files
Terry N. Brown [email protected] Tue Aug 20 16:25:39 EDT 2019
"""
import argparse
import ast
import os
from functools import reduce
from textwrap import indent
def make_parser():
parser = argparse.ArgumentParser(
description="""Show doc. strings for pyfiles""",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument('files', nargs='*', help="Files to describe")
parser.add_argument("--skip", help="Skip lines matching SKIP, e.g."
"`--skip @` to skip recurring email lines")
parser.add_argument(
"--name",
action='store_true',
help="If the first text is the name of the file it's hidden, "
"use this option to show it.",
)
return parser
def get_options(args=None):
"""
get_options - use argparse to parse args, and return a
argparse.Namespace, possibly with some changes / expansions /
validatations.
Client code should call this method with args as per sys.argv[1:],
rather than calling make_parser() directly.
Args:
args ([str]): arguments to parse
Returns:
argparse.Namespace: options with modifications / validations
"""
opt = make_parser().parse_args(args)
# modifications / validations go here
return opt
def main():
opt = get_options()
if not opt.files:
opt.files = [i for i in os.listdir('.') if i.lower().endswith('.py')]
opt.files.sort()
for pyfile in opt.files:
print(pyfile)
tree = ast.parse(open(pyfile).read())
for node in ast.walk(tree):
if 'str' in node.__class__.__name__.lower():
text = node.s.strip().split('\n')
text = [i for i in text if opt.skip not in i]
# collapse double blank lines
text = reduce(
lambda a, b: (a[:-1] if a.endswith('\n\n') else a)
+ '\n'
+ b,
text,
).strip()
if not opt.name and text.startswith(pyfile):
text = text[len(pyfile):]
print(indent(text, ' '))
break
print()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment