[Python-checkins] CVS: python/nondist/sandbox/doctools textdoc.py,NONE,1.1 README,1.1,1.2 htmldoc.py,1.1,1.2 onlinehelp.py,1.1,1.2
Paul Prescod
python-dev@python.org
Sat, 22 Jul 2000 11:51:38 -0700
- Previous message: [Python-checkins] CVS: python/dist/src/Python atof.c,2.5,2.6 bltinmodule.c,2.170,2.171 ceval.c,2.185,2.186 codecs.c,2.10,2.11 compile.c,2.116,2.117 dup2.c,2.3,2.4 dynload_aix.c,2.6,2.7 errors.c,2.49,2.50 frozenmain.c,2.22,2.23 getargs.c,2.41,2.42 getcompiler.c,1.7,1.8 getcopyright.c,1.7,1.8 getcwd.c,1.12,1.13 getmtime.c,2.13,2.14 getopt.c,2.7,2.8 getplatform.c,1.6,1.7 getversion.c,1.12,1.13 hypot.c,2.1,2.2 import.c,2.141,2.142 importdl.c,2.66,2.67 marshal.c,1.52,1.53 memmove.c,2.6,2.7 modsupport.c,2.48,2.49 mystrtoul.c,2.19,2.20 pyfpe.c,2.5,2.6 pystate.c,2.11,2.12 pythonrun.c,2.104,2.105 sigcheck.c,2.6,2.7 strdup.c,2.3,2.4 strerror.c,2.8,2.9 strtod.c,1.9,1.10 structmember.c,2.16,2.17 sysmodule.c,2.69,2.70 thread.c,2.31,2.32 thread_cthread.h,2.11,2.12 thread_foobar.h,2.9,2.10 thread_lwp.h,2.11,2.12 thread_nt.h,2.14,2.15 thread_os2.h,2.8,2.9 thread_pth.h,2.4,2.5 thread_pthread.h,2.27,2.28 thread_sgi.h,2.12,2.13 thread_solaris.h,2.13,2.14 thread_wince.h,2.4,2.5 traceback.c,2.30,2.31
- Next message: [Python-checkins] CVS: python/dist/src/Parser acceler.c,2.15,2.16 bitset.c,2.9,2.10 firstsets.c,2.10,2.11 grammar.c,2.16,2.17 grammar1.c,2.10,2.11 intrcheck.c,2.33,2.34 listnode.c,2.12,2.13 metagrammar.c,2.9,2.10 myreadline.c,2.22,2.23 node.c,2.11,2.12 parser.c,2.15,2.16 parsetok.c,2.22,2.23 pgen.c,2.16,2.17 pgenmain.c,2.20,2.21 printgrammar.c,2.11,2.12 tokenizer.c,2.46,2.47
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/python/python/nondist/sandbox/doctools
In directory slayer.i.sourceforge.net:/tmp/cvs-serv15410
Modified Files:
README htmldoc.py onlinehelp.py
Added Files:
textdoc.py
Log Message:
Better support for module documentation. Extracts classes, funcs, etc.
automatically.
--- NEW FILE ---
#!/usr/bin/env python
"""Generate text documentation from Python objects.
This module uses Ka-Ping Yee's inspect module to generate text documentation
given a python object. It borrows heavily from Ka-Ping Yee's htmldoc. Further
details of those modules can be found at http://www.lfw.org/python/.
Use:
import textdoc,cgi
print textdoc.document(cgi) # document an entire module
print textdoc.document(cgi.FieldStorage) # document a class
print textdoc.document(cgi.initlog) # document a function
print textdoc.document(len) # document a builtin
contact: richard_chamberlain@ntlworld.com
"""
# I, Richard Chamberlain, the author of this contribution, hereby grant to anyone
# and everyone a nonexclusive, irrevocable, royalty-free, worldwide license to
# reproduce, distribute, perform and/or display publicly, prepare derivative
# versions, and otherwise use this contribution in any fashion, or any
# derivative versions thereof, at no cost to anyone, and to authorize others
# to do so. This software is provided "as is", with NO WARRANTY WHATSOEVER,
# not even a warranty of merchantability or fitness for any particular purpose.
__version__ = "22 July 2000"
import inspect,string
def _getdoc(object):
"""Returns doc string for a given object."""
result=''
doc = inspect.getdoc(object)
if not doc:
try: doc = inspect.getcomments(object)
except: pass
if doc:
for line in string.split(doc,'\n'):
result=result+'\t'+line+'\n'
if result=='': result='\tno doc string'
return result and string.rstrip(result) + "\n" or ""
def _tab(str,_tab=2):
"""Increase the indent on all but the first line"""
result=[]
lines=string.split(str,'\t')
result.append(lines[0])
for line in lines[1:]:
result.append(('\t')*_tab+line)
result=string.join(result)
return result
def _document_module(object):
"""Produce text documentation for a given module."""
results=[]
name=object.__name__
if hasattr(object,"__version__"):
name=name+" (version: %s)\n" % object.__version__
else: name=name+" \n"
results.append(name)
doc=_getdoc(object)
results.append(doc)
cadr = lambda list: list[0]
# Get the modules
modules = map(cadr,inspect.getmembers(object, inspect.ismodule))
if modules:
results.append('\nModules:\n\n')
results.append(string.join(modules,', '))
# Get the classes
classes=inspect.getmembers(object,inspect.isclass)
if classes:
results.append('\n\nClasses:\n\n')
for aclass in classes:
results.append(_document_class(aclass[1]))
results.append('\n')
functions=inspect.getmembers(object,inspect.isroutine)
if functions:
results.append('Module Functions:\n\n')
for function in functions:
results.append(_document_function(function[1]))
return results
def _document_class(object):
"""Produce text documentation for a given class object."""
name = object.__name__
bases = object.__bases__
results = []
title = "class %s" % name
if bases:
parents = []
for base in bases:
parents.append(base.__name__)
title = title + "(%s)" % string.join(parents, ", ")
results.append(title+":\n\n")
doc=_getdoc(object)
results.append(doc)
functions=inspect.getmembers(object,inspect.isroutine)
if functions:
results.append('\n\tMethods:\n\n')
for function in functions:
results.append("\t"+_tab(document(function[1])))
return results
def _document_method(object):
"""Produce text documentation for a given method."""
return _document_function(object.im_func)
def defaultFormat(object):
rep=repr( obj )
match=re.match( r"<(.+?) at ......>", rep )
if match:
return "<"+match.group(1)+">"
else:
return rep
def _document_function(object):
"""Produce text documentation for a given function."""
try:
args, varargs, varkw, defaults = inspect.getargspec(object)
argspec = inspect.formatargspec(
args, varargs, varkw, defaults)
except TypeError:
argspec = "(no arg info)"
if object.__name__ == "<lambda>":
decl = ["lambda ", argspec[1:-1]]
else:
decl = [object.__name__, argspec, "\n"]
doc = _getdoc(object)
return [decl, doc+"\n"]
def _document_builtin(object):
"""Produce text documentation for a given builtin."""
results=[]
results.append(object.__name__+'\n')
doc=_getdoc(object)
results.append('\n'+doc)
return results
def document(object):
"""Generate documentation for a given object."""
if inspect.ismodule(object): results = _document_module(object)
elif inspect.isclass(object): results = _document_class(object)
elif inspect.ismethod(object): results = _document_method(object)
elif inspect.isfunction(object): results = _document_function(object)
elif inspect.isbuiltin(object): results = _document_builtin(object)
else: raise TypeError, "don't know how to document this kind of object"
return _serialise(results)
def _serialise(list):
"""Combine a list containing strings and nested lists into a single
string. This lets us manipulate lists until the last moment, since
rearranging lists is faster than rearranging strings."""
results = []
if list==None: return ""
for item in list:
if type(item) is type(""): results.append(item)
else: results.append(_serialise(item))
return string.join(results, "")
if __name__=='__main__':
# Test Code
import Tkinter,cgi,calendar
print document(Tkinter) # Try a module with classes
print document(calendar) # Module without classes
print document(cgi.FieldStorage) # Just a class
print document(inspect.getdoc) # a method
print document(len) # a builtin
Index: README
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/doctools/README,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** README 2000/07/21 21:31:27 1.1
--- README 2000/07/22 18:51:36 1.2
***************
*** 4,7 ****
onlinehelp.py -- onlinehelp for Python. Read the docstring.
- htmldoc.py -- Builds HTML documentation from docstrings
inspect.py -- introspection API used by both of the above
--- 4,8 ----
onlinehelp.py -- onlinehelp for Python. Read the docstring.
inspect.py -- introspection API used by both of the above
+ htmldoc.py -- Builds HTML documentation from docstrings
+ textdoc.py -- Builds raw text documentation from docstrings
Index: htmldoc.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/doctools/htmldoc.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** htmldoc.py 2000/07/21 21:31:27 1.1
--- htmldoc.py 2000/07/22 18:51:36 1.2
***************
*** 10,15 ****
return string.replace(string.replace(str, "&", "&"), "<", "<")
def htmlrepr(object):
! return htmlescape(repr(object))
def preformat(str):
--- 10,27 ----
return string.replace(string.replace(str, "&", "&"), "<", "<")
+
+ # added by prescod
+ # physical addresses produced by repr were defeating diff and they are
+ # ugly anyhow
+ def smartRepr( obj ):
+ rep=repr( obj )
+ match=re.match( r"<(.+?) at ......>", rep )
+ if match:
+ return "<"+match.group(1)+">"
+ else:
+ return rep
+
def htmlrepr(object):
! return htmlescape(smartRepr(object))
def preformat(str):
Index: onlinehelp.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/doctools/onlinehelp.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** onlinehelp.py 2000/07/21 21:31:27 1.1
--- onlinehelp.py 2000/07/22 18:51:36 1.2
***************
*** 41,44 ****
--- 41,49 ----
python onlinehelp.py if
+
+ Security warning: this module will attempt to import modules with the same
+ names as requested topics. Don't use the modules if you
+ are not confident that everything in your pythonpath is
+ from a trusted source.
"""
***************
*** 64,67 ****
--- 69,73 ----
import os, sys
import re
+ import textdoc, types
prompt="--more-- (enter for more, q to quit) "
***************
*** 213,216 ****
--- 219,233 ----
envir_var="PYTHONDOCS"
+ def my_import(name):
+ try:
+ mod = __import__(name)
+ except ImportError:
+ return None
+
+ components = name.split('.')
+ for comp in components[1:]:
+ mod = getattr(mod, comp)
+ return mod
+
class Help:
def __init__( self, out, line_length, docdir=None ):
***************
*** 257,301 ****
def call( self, ob, out ):
self.pager=out or self.Pager( self.out, self.line_length )
! if type( ob ) in (type(""),type(u"")):
! if ob.startswith( "<" ):
! ob=ob[1:]
! if ob.endswith( ">" ):
! ob=ob[:-1]
!
! self.write( 'Topic: help( "%s" )\n' % ob )
!
! if ob.startswith("doc:"):
! path=ob[4:]
! if not self.docdir:
! self.initDocDir()
! fullpath=os.path.join( self.docdir, path )
! data=open( fullpath ).read()
! index=ob.rfind( "/" )
! self.writeHTML( ob[:index], data )
else:
! try:
! info=topics[ob]
! docrlmatch=re.search( "(<doc:[^>]+>)", info.split("\n")[0] )
! if docrlmatch: # a first-line redirect
! self( docrlmatch.group(1) )
! else:
! self.writeHTML( "", info )
! except KeyError:
! glo=__builtins__.__dict__.get( ob, 0 )
! if glo:
! self( glo )
! else:
! sys.stderr.write( "No such topic "+`ob` )
! return None
else:
! self.write( 'Topic: help( %s )\n' % ob )
! self.writeText( self.getdoc( ob ) )
! def getdoc( self, ob ):
! if hasattr( ob, "__doc__" ):
! return ob.__doc__
else:
! type( ob ).__doc__
--- 274,374 ----
def call( self, ob, out ):
self.pager=out or self.Pager( self.out, self.line_length )
+
+ if type( ob ) in (types.StringType,types.UnicodeType): #string
! # doc form of URL
! if ob.startswith("doc:") or ob.startswith( "<doc:" ):
! self.handleDocrl( ob )
else:
! self.handleTopic( ob )
else:
! self.handleObject( ob )
!
! def handleDocrl( self, docrl ):
! # strip leading/trailing "<" and ">"
! if docrl.startswith( "<" ):
! docrl=docrl[1:]
! if docrl.endswith( ">" ):
! docrl=ob[:-1]
!
! path=docrl[4:]
! if not self.docdir:
! self.initDocDir()
!
! fullpath=os.path.join( self.docdir, path )
! data=open( fullpath ).read()
! index=docrl.rfind( "/" )
!
! self.write( 'Topic: help( "%s" )\n' % docrl )
! self.writeHTML( ob[:index], data )
!
! def matchDocrlPattern( self, info ):
! firstline=info.split("\n")[0]
! docrlmatch=re.search( "<(doc:[^>]+)>", firstline )
! if docrlmatch:
! return docrlmatch.group( 1 )
! else:
! return None
! def handleTopic( self, topic ):
! # otherwise a topic
! info=topics.get(topic, 0 )
! if info:
! match=self.matchDocrlPattern( info )
! if match: # a first-line redirect
! self.handledocrl( match )
else:
! self.write( 'Topic: help( "%s" )\n' % topic )
! self.writeHTML( "", info )
! return None
!
! # try again -- this time in builtins
! glo=__builtins__.__dict__.get( topic, 0 )
! if glo:
! self.handleObject( glo )
! return None
!
! # try again -- this time as a module
! mod=my_import( topic )
! if mod:
! print mod
! self.handleObject( mod )
! return None
!
! # try again -- this time as an attribute OF a module
! ### FIXME/XXX/TODO: this code is not finished yet!
! parts=string.split( topic, "." )
! for i in range( len( parts ), -1, -1 ):
! if i:
! front=string.join( parts[:i], "." )
! mod=my_import( front )
! if mod:
! self.handleObject( mod )
! return None
!
! sys.stderr.write( "No such topic "+`topic` )
! return None
!
! def handleObject( self, ob ):
! docstr=self.getdocstring( ob )
!
! if docstr:
! match=self.matchDocrlPattern( docstr )
! else:
! match=None
!
! if match: # a first-line redirect
! self.handledocrl( match )
! else:
! text=textdoc.document( ob )
! self.write( 'Topic: help( %s )\n' % ob )
! self.writeText( text )
!
! def getdocstring( self, ob ):
! # todo: use inspect.py instead
! if hasattr( ob, "__doc__" ):
! return ob.__doc__
! else:
! return type( ob ).__doc__
***************
*** 374,377 ****
test()
else:
! help( eval( sys.argv[1] ) )
--- 447,450 ----
test()
else:
! help( sys.argv[1] )
- Previous message: [Python-checkins] CVS: python/dist/src/Python atof.c,2.5,2.6 bltinmodule.c,2.170,2.171 ceval.c,2.185,2.186 codecs.c,2.10,2.11 compile.c,2.116,2.117 dup2.c,2.3,2.4 dynload_aix.c,2.6,2.7 errors.c,2.49,2.50 frozenmain.c,2.22,2.23 getargs.c,2.41,2.42 getcompiler.c,1.7,1.8 getcopyright.c,1.7,1.8 getcwd.c,1.12,1.13 getmtime.c,2.13,2.14 getopt.c,2.7,2.8 getplatform.c,1.6,1.7 getversion.c,1.12,1.13 hypot.c,2.1,2.2 import.c,2.141,2.142 importdl.c,2.66,2.67 marshal.c,1.52,1.53 memmove.c,2.6,2.7 modsupport.c,2.48,2.49 mystrtoul.c,2.19,2.20 pyfpe.c,2.5,2.6 pystate.c,2.11,2.12 pythonrun.c,2.104,2.105 sigcheck.c,2.6,2.7 strdup.c,2.3,2.4 strerror.c,2.8,2.9 strtod.c,1.9,1.10 structmember.c,2.16,2.17 sysmodule.c,2.69,2.70 thread.c,2.31,2.32 thread_cthread.h,2.11,2.12 thread_foobar.h,2.9,2.10 thread_lwp.h,2.11,2.12 thread_nt.h,2.14,2.15 thread_os2.h,2.8,2.9 thread_pth.h,2.4,2.5 thread_pthread.h,2.27,2.28 thread_sgi.h,2.12,2.13 thread_solaris.h,2.13,2.14 thread_wince.h,2.4,2.5 traceback.c,2.30,2.31
- Next message: [Python-checkins] CVS: python/dist/src/Parser acceler.c,2.15,2.16 bitset.c,2.9,2.10 firstsets.c,2.10,2.11 grammar.c,2.16,2.17 grammar1.c,2.10,2.11 intrcheck.c,2.33,2.34 listnode.c,2.12,2.13 metagrammar.c,2.9,2.10 myreadline.c,2.22,2.23 node.c,2.11,2.12 parser.c,2.15,2.16 parsetok.c,2.22,2.23 pgen.c,2.16,2.17 pgenmain.c,2.20,2.21 printgrammar.c,2.11,2.12 tokenizer.c,2.46,2.47
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]