[Python-checkins] CVS: python/nondist/sandbox/help pydoc.py,1.5,1.6

Ka-Ping Yee ping@users.sourceforge.net
Tue, 27 Feb 2001 04:21:05 -0800


Update of /cvsroot/python/python/nondist/sandbox/help
In directory usw-pr-cvs1:/tmp/cvs-serv22643

Modified Files:
	pydoc.py 
Log Message:
Properly distinguish ImportError for modules we can't find from
    ImportError in modules we load that fail to import other modules.
Work around problem in mimetools.Message when rfc822 is reloaded.
Hyperlink URLs and RFC references.
Some formatting fixes.


Index: pydoc.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/help/pydoc.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** pydoc.py	2001/02/27 09:25:38	1.5
--- pydoc.py	2001/02/27 12:21:02	1.6
***************
*** 174,178 ****
          if inspect.isbuiltin(object): return apply(self.docbuiltin, args)
          if inspect.isfunction(object): return apply(self.docfunction, args)
!         raise TypeError, 'don\'t know how to document this kind of object'
  
  # -------------------------------------------- HTML documentation generator
--- 174,179 ----
          if inspect.isbuiltin(object): return apply(self.docbuiltin, args)
          if inspect.isfunction(object): return apply(self.docfunction, args)
!         raise TypeError, "don't know how to document objects of type " + \
!             type(object).__name__
  
  # -------------------------------------------- HTML documentation generator
***************
*** 201,205 ****
      def repr_string(self, x, level):
          text = self.escape(cram(x, self.maxstring))
!         return re.sub(r'((\\[\abfnrtv]|\\x..|\\u....)+)',
                        r'<font color="#c040c0">\1</font>', repr(text))
  
--- 202,206 ----
      def repr_string(self, x, level):
          text = self.escape(cram(x, self.maxstring))
!         return re.sub(r'((\\[\\abfnrtv]|\\x..|\\u....)+)',
                        r'<font color="#c040c0">\1</font>', repr(text))
  
***************
*** 326,343 ****
          results = []
          here = 0
!         pattern = re.compile('(self\.)?(\w+)')
          while 1:
              match = pattern.search(text, here)
              if not match: break
!             start, end = match.regs[2]
!             found, name = match.group(0), match.group(2)
              results.append(escape(text[here:start]))
  
!             if text[end:end+1] == '(':
!                 results.append(self.namelink(name, methods, funcs, classes))
!             elif match.group(1):
!                 results.append('<strong>%s</strong>' % name)
              else:
!                 results.append(self.namelink(name, classes))
              here = end
          results.append(escape(text[here:]))
--- 327,352 ----
          results = []
          here = 0
!         pattern = re.compile(r'\b(((http|ftp)://\S+[\w/])|'
!                                 r'(RFC[- ]?(\d+))|'
!                                 r'(self\.)?(\w+))\b')
          while 1:
              match = pattern.search(text, here)
              if not match: break
!             start, end = match.span()
              results.append(escape(text[here:start]))
  
!             all, url, scheme, rfc, rfcnum, selfdot, name = match.groups()
!             if url:
!                 results.append('<a href="%s">%s</a>' % (url, escape(url)))
!             elif rfc:
!                 url = 'http://www.rfc-editor.org/rfc/rfc%s.txt' % rfcnum
!                 results.append('<a href="%s">%s</a>' % (url, escape(rfc)))
              else:
!                 if text[end:end+1] == '(':
!                     results.append(self.namelink(name, methods, funcs, classes))
!                 elif selfdot:
!                     results.append('self.<strong>%s</strong>' % name)
!                 else:
!                     results.append(self.namelink(name, classes))
              here = end
          results.append(escape(text[here:]))
***************
*** 377,381 ****
          if hasattr(object, '__version__'):
              head = head + ' (version: %s)' % self.escape(object.__version__)
!         result = result + self.heading(head, '#ffffff', '#7799ee', filelink)
  
          second = lambda list: list[1]
--- 386,391 ----
          if hasattr(object, '__version__'):
              head = head + ' (version: %s)' % self.escape(object.__version__)
!         result = result + self.heading(
!             head, '#ffffff', '#7799ee', '<a href=".">index</a><br>' + filelink)
  
          second = lambda list: list[1]
***************
*** 408,412 ****
          doc = self.markup(getdoc(object), self.preformat, fdict, cdict)
          doc = doc and '<tt>%s</tt>' % doc
!         result = result + '<p><small>%s</small>\n' % doc
  
          if hasattr(object, '__path__'):
--- 418,422 ----
          doc = self.markup(getdoc(object), self.preformat, fdict, cdict)
          doc = doc and '<tt>%s</tt>' % doc
!         result = result + '<p><small>%s</small></p>\n' % doc
  
          if hasattr(object, '__path__'):
***************
*** 786,793 ****
      try:
          pipe.write(text)
      except IOError:
          # Ignore broken pipes caused by quitting the pager program.
          pass
-     pipe.close()
  
  def tempfilepager(text, cmd):
--- 796,803 ----
      try:
          pipe.write(text)
+         pipe.close()
      except IOError:
          # Ignore broken pipes caused by quitting the pager program.
          pass
  
  def tempfilepager(text, cmd):
***************
*** 868,873 ****
      return repr(thing)
  
! def find(path):
      """Locate an object by name (or dotted path), importing as necessary."""
      if type(path) is not types.StringType:
          return None, path
--- 878,885 ----
      return repr(thing)
  
! def locate(path):
      """Locate an object by name (or dotted path), importing as necessary."""
+     if not path: # special case: imp.find_module('') strangely succeeds
+         return None, None
      if type(path) is not types.StringType:
          return None, path
***************
*** 878,893 ****
      while n <= len(parts):
          path = join(parts[:n], '.')
-         try:
-             file, filename, (ext, mode, kind) = imp.find_module(path)
-         except ImportError: # module not found, so keep looking
-             break
-         if file: file.close()
          try:
!             mod = __import__(path)
!             mod = reload(mod)
!         except: # error occurred in the module during import, so report it
              raise DocImportError(filename, sys.exc_type, sys.exc_value)
          try:
!             x = mod
              for p in parts[1:]:
                  x = getattr(x, p)
--- 890,909 ----
      while n <= len(parts):
          path = join(parts[:n], '.')
          try:
!             module = __import__(path)
!             module = reload(module)
!         except:
!             # Did the error occur before or after we found the module?
!             if sys.modules.has_key(path):
!                 filename = sys.modules[path].__file__
!             elif sys.exc_type is SyntaxError:
!                 filename = sys.exc_value.filename
!             else:
!                 # module not found, so stop looking
!                 break
!             # error occurred in the imported module, so report it
              raise DocImportError(filename, sys.exc_type, sys.exc_value)
          try:
!             x = module
              for p in parts[1:]:
                  x = getattr(x, p)
***************
*** 907,911 ****
      if type(thing) is type(""):
          try:
!             path, x = find(thing)
          except DocImportError, value:
              print 'problem in %s - %s' % (value.filename, value.args)
--- 923,927 ----
      if type(thing) is type(""):
          try:
!             path, x = locate(thing)
          except DocImportError, value:
              print 'problem in %s - %s' % (value.filename, value.args)
***************
*** 914,918 ****
              thing = x
          else:
!             print 'could not import or find %s' % repr(thing)
              return
  
--- 930,934 ----
              thing = x
          else:
!             print 'could not find or import %s' % repr(thing)
              return
  
***************
*** 939,943 ****
  def writedoc(key):
      """Write HTML documentation to a file in the current directory."""
!     path, object = find(key)
      if object:
          file = open(key + '.html', 'w')
--- 955,959 ----
  def writedoc(key):
      """Write HTML documentation to a file in the current directory."""
!     path, object = locate(key)
      if object:
          file = open(key + '.html', 'w')
***************
*** 952,957 ****
  help(module) or call help('modulename')."""
  
!     def __call__(self, object):
!         doc(object)
  
  help = Helper()
--- 968,976 ----
  help(module) or call help('modulename')."""
  
!     def __call__(self, *args):
!         if args:
!             doc(args[0])
!         else:
!             print repr(self)
  
  help = Helper()
***************
*** 959,963 ****
  def man(key):
      """Display documentation on an object in a form similar to man(1)."""
!     path, object = find(key)
      if object:
          title = 'Python Library Documentation: ' + describe(object)
--- 978,982 ----
  def man(key):
      """Display documentation on an object in a form similar to man(1)."""
!     path, object = locate(key)
      if object:
          title = 'Python Library Documentation: ' + describe(object)
***************
*** 966,970 ****
          found = 1
      else:
!         print 'no Python documentation found for %s' % key
  
  def apropos(key):
--- 985,989 ----
          found = 1
      else:
!         print 'could not find or import %s' % repr(key)
  
  def apropos(key):
***************
*** 992,997 ****
  
  def serve(address, callback=None):
!     import BaseHTTPServer
  
      class DocHandler(BaseHTTPServer.BaseHTTPRequestHandler):
          def send_document(self, title, contents):
--- 1011,1025 ----
  
  def serve(address, callback=None):
!     import BaseHTTPServer, mimetools
  
+     # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded.
+     class Message(mimetools.Message):
+         def __init__(self, fp, seekable=1):
+             Message.__bases__[0].__bases__[0].__init__(self, fp, seekable)
+             self.encodingheader = self.getheader('content-transfer-encoding')
+             self.typeheader = self.getheader('content-type')
+             self.parsetype()
+             self.parseplist()
+ 
      class DocHandler(BaseHTTPServer.BaseHTTPRequestHandler):
          def send_document(self, title, contents):
***************
*** 1009,1014 ****
              if path[-5:] == '.html': path = path[:-5]
              if path[:1] == '/': path = path[1:]
!             if path:
!                 p, x = find(path)
                  if x:
                      self.send_document(describe(x), html.document(x))
--- 1037,1047 ----
              if path[-5:] == '.html': path = path[:-5]
              if path[:1] == '/': path = path[1:]
!             if path and path != '.':
!                 try:
!                     p, x = locate(path)
!                 except DocImportError, value:
!                     self.send_document(path, html.escape(
!                         'problem with %s - %s' % (value.filename, value.args)))
!                     return
                  if x:
                      self.send_document(describe(x), html.document(x))
***************
*** 1044,1047 ****
--- 1077,1081 ----
      DocServer.base = BaseHTTPServer.HTTPServer
      DocServer.handler = DocHandler
+     DocHandler.MessageClass = Message
      try:
          DocServer(address, callback).serve_forever()
***************
*** 1103,1112 ****
  
      except (getopt.error, BadUsage):
!         print """%s <object> ...
      Show documentation on something.
!     <object> may be the name of a Python function, module,
!     package, or a dotted reference to a class or function
!     within a module or module in a package, or the name of
!     a Python source file to import.
  
  %s -k <keyword>
--- 1137,1145 ----
  
      except (getopt.error, BadUsage):
!         print """%s <name> ...
      Show documentation on something.
!     <name> may be the name of a Python function, module, or package,
!     or a dotted reference to a class or function within a module or
!     module in a package, or the filename of a Python module to import.
  
  %s -k <keyword>
***************
*** 1120,1124 ****
  
  %s -w <moduledir>
!     Write out the HTML documentation for all modules under
!     a directory to files in the current directory.
  """ % ((sys.argv[0],) * 5)
--- 1153,1157 ----
  
  %s -w <moduledir>
!     Write out the HTML documentation for all modules in the tree
!     under a given directory to files in the current directory.
  """ % ((sys.argv[0],) * 5)