Quick Reference from module doc strings.

Ron Adam rrr at ronadam.com
Mon May 16 19:05:47 EDT 2005


Scott David Daniels wrote:
> Ron Adam wrote:
> 
>>Do you have any feature suggestions, additional information that could 
>>go in, something that would extend the content in some way and make it 
>>more useful?
>>
>>As it stands now, it could be just a module, so you could...
>>
> 
> The style is still a sticking point for me -- too many evals (a nasty
> lure for evil-doers).

I suppose someone could create an "evil" name in a module that would 
either cause and error when evaluated or evaluate to something other 
than the actual name.

> Recall that sys.modules is a dictionary from module names to modules.
> 
> Any python object (including a module) will return attributes listed
> in a dir(obj) with getattr(obj, attributename).  So, no evals are
> needed in this program at all.

Thanks for suggesting the concise way to to this. It was a todo item.


> I also wonder if you've ever used maxlevel>1.  It seems you'd expand
> to way too many names to be useful.

Yes, it does quickly explode in some cases, I left the maxlevel keyword 
in there because it might be useful as a general function for other 
purposes like building a dependency tree for example.  I haven't 
actually tried that yet, and there's probably better ways to do it.

> Finally, if you use StringIO (or cStringIO), most of your string
> construction can be turned into prints in a way similar to:
> 
>      def printnames(namelist, dest=None):
>          for name in sorted(namelist, key=str.lower):
>              print >>dest, name
> 
>      from cStringIO import StringIO
> 
>      def textnames(namelist):
>          hold = StringIO()
>          printnames(namelist, hold)
>          return hold.getvalue()
> 
> --Scott David Daniels
> Scott.Daniels at Acm.Org

What would be the advantage of using StringIO over list.append with 
''.join()?

I rearranged it somewhat to create a dictionary of object docs.  I think 
this approach will be better for creating lists in different orders 
without having to regenerate the whole thing.

This is where it is now...  (No evals, better organized overall I think)

Cheers, _Ron


# qref.py
"""
Generate a quick reference for a module by analyzing
a modules contents.
"""

def getobjs(obj, objlist=[]):
     """Retreive a list of sub-object (name,object) pairs
     from an object."""
     objlist.append((obj.__name__,obj))
     for name in dir(obj):
         obj2 = getattr(obj,name)
         name = obj.__name__+'.'+name
         if (obj2,name) not in objlist:
             objlist.append((name,obj2))
     return objlist

def getdocdict(objlist):
     """Build a dictionary of docs from an list of
     (name,object) tuples."""
     doc_dict = {}
     for item in objlist:
         doc_dict[item[0]] = getobjinfo(*item)
     return doc_dict

def getobjinfo(name,obj):
     """Build a formated document string from an objects
     __doc__ string, and attribues."""
     strout = []
     strout.append(name+'\n')
     if hasattr(obj, '__module__'):
         strout.append("Module:"+str(obj.__module__)+'\n')
     if hasattr(obj, '__class__'):
         strout.append(str(obj.__class__))
     else:
         strout.append(str(type(obj)))
     strout.append('\n\n')
     if isinstance(obj,str):
         if '\n' in obj:
             quotes='\n"""'
         else:
             quotes ='"'
         s = name+' = '+quotes+obj+quotes
         if len(s)>200:
             s = s[0:200]+"......"
         strout.append( s+'\n\n')
     elif isinstance(obj,(int,bool,tuple,list,dict)):
         s = name+' = '+str(obj)
         if len(s)>200:
             s = s[0:200]+"......"
         strout.append( s+'\n\n')
     if hasattr(obj,'__doc__'):
         d = ''
         if obj.__doc__ == None:
             d = 'None'
         elif obj.__doc__ != type(obj).__doc__:
             d = obj.__doc__
         elif obj is type(type):
             d = obj.__doc__
         if d != '':
             strout.append(d+'\n\n')
     return ''.join(strout)

def quickref(name):
     """
     quickref(module_name) -> printable string

     Generate a sorted quick reference guide from an objects
     doc strings.  The module_name is a string with the name of
     the module or class to get documents string from.

     Example:
         import os
         print quickref('os')
     """
     objlist = getobjs(name)
     docs = getdocdict(objlist)
     dlist = docs.keys()
     dlist.sort(lambda x,y: cmp(x.lower(),y.lower()))
     outstr = []
     outstr.append('-'*40+'\n')
     for d in dlist:
         outstr.append(docs[d])
         outstr.append('-'*40+'\n')
     return ''.join(outstr)

if __name__ == "__main__":
     print quickref(__builtins__)





















More information about the Python-list mailing list