[Tutor] help> modules [hacking pydoc.Helper.list() for fun and profit]

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Sun Jun 22 01:18:01 2003


On Sat, 21 Jun 2003 GREENDAY31087@aol.com wrote:

>        When I'm in the Python shell, I type in help and go to "modules."
> I was hoping to see them all but DOS went through it fast and ended up
> on a later part of the list of modules. How can I make it say <more> so
> I can simply push a button to see the next page? I'm not really
> experienced in DOS.

Hi Greenday,

Hmmm... you're right; that is annoying!  I think it should use that
'paging' utility to do one screen at a time, the same thing that it does
for displaying specific module help.


Ok, I've isolated the code that can be modified to make it do what you
want. It's in the 'pydoc.py' Standard Library, in the 'list()' method of
the Helper class --- originally, it's doing this:

###
    def list(self, items, columns=4, width=80):
        items = items[:]
        items.sort()
        colw = width / columns
        rows = (len(items) + columns - 1) / columns
        for row in range(rows):
            for col in range(columns):
                i = col * rows + row
                if i < len(items):
                    self.output.write(items[i])
                    if col < columns - 1:
                        self.output.write(' ' + ' ' *
                                           (colw-1 - len(items[i])))
            self.output.write('\n')
###



A lot of that code is layout related.  I've hacked it a bit so that the
text goes through pydoc's pager()  function instead of directly through
self.output.  Wherever there's a self.output.write(), we can modify it so
that it feeds all that output into the thing that makes it display only
one page at a time:

###
from cStringIO import StringIO          ## at the top of pydoc.py, add
                                        ## this.

    ## and within the Helper class...
    def list(self, items, columns=4, width=80):
        items = items[:]
        items.sort()
        colw = width / columns
        rows = (len(items) + columns - 1) / columns
        buffer = StringIO()
        for row in range(rows):
            for col in range(columns):
                i = col * rows + row
                if i < len(items):
                    buffer.write(items[i])
                    if col < columns - 1:
                        buffer.write(' ' + ' ' * (colw-1 - len(items[i])))
            buffer.write('\n')
        pager(buffer.getvalue())
###

Done!  *grin*

'Greenday, if you're feeling ambitious, you can fix this by diving into
the pydoc.py module in the Standard Library and making these changes
yourself.  If you go this route, make backup copies first.  *grin*

Otherwise, email me privately, and I can just send my modified source to
you.

By the way, question for everyone: is this useful enough to send as a
patch to the pydoc folks?




By the way, how about using the IDLE command prompt?  IDLE does everything
in a window that can be scrolled back, so you can probably see all the
modules from there.

You might also find:

    http://web.pydoc.org/

sufficient; it's the same content, but as a set of web pages.