How does help() indent doc strings?

R

Roy Smith

I'm trying to use argparse.RawDescriptionHelpFormatter to get my epilog
string formatted the way I want. This works:

def parse_cli():
epilog = """\
This my very long epilog string
which goes on for several lines.
"""

parser = argparse.ArgumentParser(\
formatter_class=argparse.RawDescriptionHelpFormatter,
pilog=textwrap.dedent(epilog))

but it's annoying to have to type my triple-quoted string with the
backslash for the first line (following the example from
http://docs.python.org/2.7/library/textwrap.html). It would be much(*)
nicer to be able to do:

epilog = """This my very long epilog string
which goes on for several lines.
"""

and have dedent() figure out the indenting like help() does for
docstrings. How can I do that (in python 2.7)?

(*) For, I suppose, a relatively small value of much, but one which is
bugging the heck out of me at the moment :)
 
S

Steven D'Aprano

Roy said:
It would be much nicer to be able to do:

epilog = """This my very long epilog string
which goes on for several lines.
"""

and have dedent() figure out the indenting like help() does for
docstrings. How can I do that (in python 2.7)?

The Source is strong^W tricky in this one...

The site module adds the help() function to the builtins:

http://hg.python.org/cpython/file/2.7/Lib/site.py

The help() function in turn calls pydoc to do the actual work:

http://docs.python.org/2/library/pydoc.html

The source is rather large and not the easiest to read, but if you read it
you will see it does not use textwrap.dedent anywhere.

http://hg.python.org/cpython/file/2.7/Lib/pydoc.py

You're welcome to read it and decipher how it formats text if you like. But
possibly the easiest way to get the effect you are after is with a small
helper function:

def prepare(text):
spaces = (' ', '\t')
if text and not text.startswith(spaces):
# Find the indent of the *second* non-blank line.
indent = []
lines = text.splitlines()
for linenum, line in enumerate(lines[1:], 1):
line.rstrip()
if line.startswith(spaces):
for c in line:
if c in spaces: indent.append(c)
else: break
break
lines[0] = ''.join(indent) + lines[0]
text = '\n'.join(lines)
return text



And in use:

py> epilogue = """This my very long epilogue string
.... which goes on for several lines.
.... Like this.
.... """
py>
py> print textwrap.dedent(epilogue)
This my very long epilogue string
which goes on for several lines.
Like this.

py> print textwrap.dedent(prepare(epilogue))
This my very long epilogue string
which goes on for several lines.
Like this.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top