[Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.23,1.24

Ka-Ping Yee ping@users.sourceforge.net
Thu, 12 Apr 2001 03:50:25 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv5475

Modified Files:
	pydoc.py 
Log Message:
Properly qualify methods inherited from classes in other modules.
Fix so that docother() doesn't blow up.
Eliminate man() function since doc() and man() did nearly the same thing.
Various other code cleanup and refactoring to reduce duplication.
Simplify and rewrite freshimport() so modules are always up to date,
    even within packages (where reload() doesn't work).
Add finalization callback to the server (so that if the server fails to
    start for some reason, the main thread isn't left hanging).


Index: pydoc.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -r1.23 -r1.24
*** pydoc.py	2001/04/10 12:22:01	1.23
--- pydoc.py	2001/04/12 10:50:23	1.24
***************
*** 67,71 ****
          else: # text modules can be directly examined
              line = file.readline()
!             while line[:1] == '#' or strip(line) == '':
                  line = file.readline()
                  if not line: break
--- 67,71 ----
          else: # text modules can be directly examined
              line = file.readline()
!             while line[:1] == '#' or not strip(line):
                  line = file.readline()
                  if not line: break
***************
*** 126,131 ****
  def replace(text, *pairs):
      """Do a series of global replacements on a string."""
!     for old, new in pairs:
!         text = join(split(text, old), new)
      return text
  
--- 126,132 ----
  def replace(text, *pairs):
      """Do a series of global replacements on a string."""
!     while pairs:
!         text = join(split(text, pairs[0]), pairs[1])
!         pairs = pairs[2:]
      return text
  
***************
*** 225,229 ****
  
      def escape(self, text):
!         return replace(text, ('&', '&amp;'), ('<', '&lt;'), ('>', '&gt;'))
  
      def repr(self, object):
--- 226,230 ----
  
      def escape(self, text):
!         return replace(text, '&', '&amp;', '<', '&lt;', '>', '&gt;')
  
      def repr(self, object):
***************
*** 240,244 ****
          test = cram(x, self.maxstring)
          testrepr = repr(test)
!         if '\\' in test and '\\' not in replace(testrepr, (r'\\', '')):
              # Backslashes are only literal in the string and are never
              # needed to make any special characters, so show a raw string.
--- 241,245 ----
          test = cram(x, self.maxstring)
          testrepr = repr(test)
!         if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
              # Backslashes are only literal in the string and are never
              # needed to make any special characters, so show a raw string.
***************
*** 317,322 ****
          """Format literal preformatted text."""
          text = self.escape(expandtabs(text))
!         return replace(text, ('\n\n', '\n \n'), ('\n\n', '\n \n'),
!                              (' ', '&nbsp;'), ('\n', '<br>\n'))
  
      def multicolumn(self, list, format, cols=4):
--- 318,323 ----
          """Format literal preformatted text."""
          text = self.escape(expandtabs(text))
!         return replace(text, '\n\n', '\n \n', '\n\n', '\n \n',
!                              ' ', '&nbsp;', '\n', '<br>\n')
  
      def multicolumn(self, list, format, cols=4):
***************
*** 344,350 ****
      def classlink(self, object, modname, *dicts):
          """Make a link for a class."""
!         name = object.__name__
!         if object.__module__ != modname:
!             name = object.__module__ + '.' + name
          for dict in dicts:
              if dict.has_key(object):
--- 345,349 ----
      def classlink(self, object, modname, *dicts):
          """Make a link for a class."""
!         name = classname(object, modname)
          for dict in dicts:
              if dict.has_key(object):
***************
*** 426,430 ****
          return '<dl>\n%s</dl>\n' % result
  
!     def docmodule(self, object, name=None):
          """Produce HTML documentation for a module object."""
          name = object.__name__ # ignore the passed-in name
--- 425,429 ----
          return '<dl>\n%s</dl>\n' % result
  
!     def docmodule(self, object, name=None, mod=None):
          """Produce HTML documentation for a module object."""
          name = object.__name__ # ignore the passed-in name
***************
*** 510,514 ****
                  inspect.getclasstree(classlist, 1), name, cdict)]
              for key, value in classes:
!                 contents.append(self.document(value, key, fdict, cdict))
              result = result + self.bigsection(
                  'Classes', '#ffffff', '#ee77aa', join(contents))
--- 509,513 ----
                  inspect.getclasstree(classlist, 1), name, cdict)]
              for key, value in classes:
!                 contents.append(self.document(value, key, name, fdict, cdict))
              result = result + self.bigsection(
                  'Classes', '#ffffff', '#ee77aa', join(contents))
***************
*** 516,520 ****
              contents = []
              for key, value in funcs:
!                 contents.append(self.document(value, key, fdict, cdict))
              result = result + self.bigsection(
                  'Functions', '#ffffff', '#eeaa77', join(contents))
--- 515,519 ----
              contents = []
              for key, value in funcs:
!                 contents.append(self.document(value, key, name, fdict, cdict))
              result = result + self.bigsection(
                  'Functions', '#ffffff', '#eeaa77', join(contents))
***************
*** 536,540 ****
          return result
  
!     def docclass(self, object, name=None, funcs={}, classes={}):
          """Produce HTML documentation for a class object."""
          realname = object.__name__
--- 535,539 ----
          return result
  
!     def docclass(self, object, name=None, mod=None, funcs={}, classes={}):
          """Produce HTML documentation for a class object."""
          realname = object.__name__
***************
*** 543,554 ****
          contents = ''
  
!         methods, mdict = [], {}
!         for key, value in allmethods(object).items():
!             methods.append((key, value))
!             mdict[key] = mdict[value] = '#' + name + '-' + key
          methods.sort()
          for key, value in methods:
              contents = contents + self.document(
!                 value, key, funcs, classes, mdict, object)
  
          if name == realname:
--- 542,552 ----
          contents = ''
  
!         methods, mdict = allmethods(object).items(), {}
          methods.sort()
          for key, value in methods:
+             mdict[key] = mdict[value] = '#' + name + '-' + key
+         for key, value in methods:
              contents = contents + self.document(
!                 value, key, mod, funcs, classes, mdict, object)
  
          if name == realname:
***************
*** 574,578 ****
          return self.small(self.grey('=' + self.repr(object)))
  
!     def docroutine(self, object, name=None,
                     funcs={}, classes={}, methods={}, cl=None):
          """Produce HTML documentation for a function or method object."""
--- 572,576 ----
          return self.small(self.grey('=' + self.repr(object)))
  
!     def docroutine(self, object, name=None, mod=None,
                     funcs={}, classes={}, methods={}, cl=None):
          """Produce HTML documentation for a function or method object."""
***************
*** 584,599 ****
          if inspect.ismethod(object):
              if cl:
!                 if object.im_class is not cl:
!                     base = object.im_class
!                     url = '#%s-%s' % (base.__name__, name)
!                     basename = base.__name__
!                     if base.__module__ != cl.__module__:
!                         url = base.__module__ + '.html' + url
!                         basename = base.__module__ + '.' + basename
!                     note = ' from <a href="%s">%s</a>' % (url, basename)
                      skipdocs = 1
              else:
                  note = (object.im_self and
!                         ' method of ' + self.repr(object.im_self) or
                          ' unbound %s method' % object.im_class.__name__)
              object = object.im_func
--- 582,595 ----
          if inspect.ismethod(object):
              if cl:
!                 imclass = object.im_class
!                 if imclass is not cl:
!                     url = '%s.html#%s-%s' % (
!                         imclass.__module__, imclass.__name__, name)
!                     note = ' from <a href="%s">%s</a>' % (
!                         url, classname(imclass, mod))
                      skipdocs = 1
              else:
                  note = (object.im_self and
!                         ' method of %s instance' + object.im_self.__class__ or
                          ' unbound %s method' % object.im_class.__name__)
              object = object.im_func
***************
*** 632,638 ****
              return '<dl><dt>%s%s</dl>\n' % (decl, doc)
  
!     def docother(self, object, name=None):
          """Produce HTML documentation for a data object."""
!         return '<strong>%s</strong> = %s' % (name, self.repr(object))
  
      def index(self, dir, shadowed=None):
--- 628,635 ----
              return '<dl><dt>%s%s</dl>\n' % (decl, doc)
  
!     def docother(self, object, name=None, mod=None):
          """Produce HTML documentation for a data object."""
!         lhs = name and '<strong>%s</strong> = ' % name or ''
!         return lhs + self.repr(object)
  
      def index(self, dir, shadowed=None):
***************
*** 683,687 ****
          test = cram(x, self.maxstring)
          testrepr = repr(test)
!         if '\\' in test and '\\' not in replace(testrepr, (r'\\', '')):
              # Backslashes are only literal in the string and are never
              # needed to make any special characters, so show a raw string.
--- 680,684 ----
          test = cram(x, self.maxstring)
          testrepr = repr(test)
!         if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
              # Backslashes are only literal in the string and are never
              # needed to make any special characters, so show a raw string.
***************
*** 737,741 ****
          return result
  
!     def docmodule(self, object, name=None):
          """Produce text documentation for a given module object."""
          name = object.__name__ # ignore the passed-in name
--- 734,738 ----
          return result
  
!     def docmodule(self, object, name=None, mod=None):
          """Produce text documentation for a given module object."""
          name = object.__name__ # ignore the passed-in name
***************
*** 781,785 ****
                  inspect.getclasstree(classlist, 1), name)]
              for key, value in classes:
!                 contents.append(self.document(value, key))
              result = result + self.section('CLASSES', join(contents, '\n'))
  
--- 778,782 ----
                  inspect.getclasstree(classlist, 1), name)]
              for key, value in classes:
!                 contents.append(self.document(value, key, name))
              result = result + self.section('CLASSES', join(contents, '\n'))
  
***************
*** 787,791 ****
              contents = []
              for key, value in funcs:
!                 contents.append(self.document(value, key))
              result = result + self.section('FUNCTIONS', join(contents, '\n'))
  
--- 784,788 ----
              contents = []
              for key, value in funcs:
!                 contents.append(self.document(value, key, name))
              result = result + self.section('FUNCTIONS', join(contents, '\n'))
  
***************
*** 793,797 ****
              contents = []
              for key, value in constants:
!                 contents.append(self.docother(value, key, 70))
              result = result + self.section('CONSTANTS', join(contents, '\n'))
  
--- 790,794 ----
              contents = []
              for key, value in constants:
!                 contents.append(self.docother(value, key, name, 70))
              result = result + self.section('CONSTANTS', join(contents, '\n'))
  
***************
*** 809,813 ****
          return result
  
!     def docclass(self, object, name=None):
          """Produce text documentation for a given class object."""
          realname = object.__name__
--- 806,810 ----
          return result
  
!     def docclass(self, object, name=None, mod=None):
          """Produce text documentation for a given class object."""
          realname = object.__name__
***************
*** 829,833 ****
          methods.sort()
          for key, value in methods:
!             contents = contents + '\n' + self.document(value, key, object)
  
          if not contents: return title + '\n'
--- 826,830 ----
          methods.sort()
          for key, value in methods:
!             contents = contents + '\n' + self.document(value, key, mod, object)
  
          if not contents: return title + '\n'
***************
*** 838,842 ****
          return '=' + self.repr(object)
  
!     def docroutine(self, object, name=None, cl=None):
          """Produce text documentation for a function or method object."""
          realname = object.__name__
--- 835,839 ----
          return '=' + self.repr(object)
  
!     def docroutine(self, object, name=None, mod=None, cl=None):
          """Produce text documentation for a function or method object."""
          realname = object.__name__
***************
*** 845,861 ****
          skipdocs = 0
          if inspect.ismethod(object):
              if cl:
!                 if object.im_class is not cl:
!                     base = object.im_class
!                     basename = base.__name__
!                     if base.__module__ != cl.__module__:
!                         basename = base.__module__ + '.' + basename
!                     note = ' from %s' % basename
                      skipdocs = 1
              else:
!                 if object.im_self:
!                     note = ' method of %s' % self.repr(object.im_self)
!                 else:
!                     note = ' unbound %s method' % object.im_class.__name__
              object = object.im_func
  
--- 842,854 ----
          skipdocs = 0
          if inspect.ismethod(object):
+             imclass = object.im_class
              if cl:
!                 if imclass is not cl:
!                     note = ' from ' + classname(imclass, mod)
                      skipdocs = 1
              else:
!                 note = (object.im_self and
!                         ' method of %s instance' + object.im_self.__class__ or
!                         ' unbound %s method' % classname(imclass, mod))
              object = object.im_func
  
***************
*** 884,895 ****
              return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n')
  
!     def docother(self, object, name=None, maxlen=None):
          """Produce text documentation for a data object."""
          repr = self.repr(object)
          if maxlen:
!             line = name + ' = ' + repr
              chop = maxlen - len(line)
              if chop < 0: repr = repr[:chop] + '...'
!         line = self.bold(name) + ' = ' + repr
          return line
  
--- 877,888 ----
              return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n')
  
!     def docother(self, object, name=None, mod=None, maxlen=None):
          """Produce text documentation for a data object."""
          repr = self.repr(object)
          if maxlen:
!             line = (name and name + ' = ' or '') + repr
              chop = maxlen - len(line)
              if chop < 0: repr = repr[:chop] + '...'
!         line = (name and self.bold(name) + ' = ' or '') + repr
          return line
  
***************
*** 1018,1085 ****
      return type(thing).__name__
  
! def freshimport(name, cache={}):
!     """Import a module, reloading it if the source file has changed."""
!     topmodule = __import__(name)
!     module = None
!     for component in split(name, '.'):
!         if module == None:
!             module = topmodule
!             path = split(name, '.')[0]
          else:
!             module = getattr(module, component)
!             path = path + '.' + component
!         if hasattr(module, '__file__'):
!             file = module.__file__
!             if os.path.exists(file):
!                 info = (file, os.path.getmtime(file), os.path.getsize(file))
!                 if cache.get(path) == info:
!                     continue
!             module = reload(module)
!             file = module.__file__
!             if os.path.exists(file):
!                 info = (file, os.path.getmtime(file), os.path.getsize(file))
!             cache[path] = info
      return module
  
  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
!     if type(path) is not types.StringType:
!         return path
      parts = split(path, '.')
!     n = len(parts)
!     while n > 0:
!         path = join(parts[:n], '.')
!         try:
!             module = freshimport(path)
!         except:
!             # Did the error occur before or after the module was found?
!             (exc, value, tb) = info = sys.exc_info()
!             if sys.modules.has_key(path):
!                 # An error occured while executing the imported module.
!                 raise ErrorDuringImport(sys.modules[path].__file__, info)
!             elif exc is SyntaxError:
!                 # A SyntaxError occurred before we could execute the module.
!                 raise ErrorDuringImport(value.filename, info)
!             elif exc is ImportError and \
!                  split(lower(str(value)))[:2] == ['no', 'module']:
!                 # The module was not found.
!                 n = n - 1
!                 continue
!             else:
!                 # Some other error occurred before executing the module.
!                 raise ErrorDuringImport(path, sys.exc_info())
!         try:
!             x = module
!             for p in parts[n:]:
!                 x = getattr(x, p)
!             return x
!         except AttributeError:
!             n = n - 1
!             continue
!     if hasattr(__builtins__, path):
!         return getattr(__builtins__, path)
!     return None
  
  # --------------------------------------- interactive interpreter interface
--- 1011,1063 ----
      return type(thing).__name__
  
! def freshimport(path, cache={}):
!     """Import a module freshly from disk, making sure it's up to date."""
!     if sys.modules.has_key(path):
!         # This is the only way to be sure.  Checking the mtime of the file
!         # isn't good enough (e.g. what if the module contains a class that
!         # inherits from another module that has changed?).
!         if path not in sys.builtin_module_names:
!             del sys.modules[path]
!     try:
!         module = __import__(path)
!     except:
!         # Did the error occur before or after the module was found?
!         (exc, value, tb) = info = sys.exc_info()
!         if sys.modules.has_key(path):
!             # An error occured while executing the imported module.
!             raise ErrorDuringImport(sys.modules[path].__file__, info)
!         elif exc is SyntaxError:
!             # A SyntaxError occurred before we could execute the module.
!             raise ErrorDuringImport(value.filename, info)
!         elif exc is ImportError and \
!              split(lower(str(value)))[:2] == ['no', 'module']:
!             # The module was not found.
!             return None
          else:
!             # Some other error occurred during the importing process.
!             raise ErrorDuringImport(path, sys.exc_info())
!     for part in split(path, '.')[1:]:
!         try: module = getattr(module, part)
!         except AttributeError: return None
      return module
  
  def locate(path):
!     """Locate an object by name or dotted path, importing as necessary."""
      parts = split(path, '.')
!     module, n = None, 0
!     while n < len(parts):
!         nextmodule = freshimport(join(parts[:n+1], '.'))
!         if nextmodule: module, n = nextmodule, n + 1
!         else: break
!     if module:
!         object = module
!         for part in parts[n:]:
!             try: object = getattr(object, part)
!             except AttributeError: return None
!         return object
!     else:
!         import __builtin__
!         if hasattr(__builtin__, path):
!             return getattr(__builtin__, path)
  
  # --------------------------------------- interactive interpreter interface
***************
*** 1088,1094 ****
  html = HTMLDoc()
  
! def doc(thing):
!     """Display documentation on an object (for interactive use)."""
!     if type(thing) is type(""):
          try:
              object = locate(thing)
--- 1066,1073 ----
  html = HTMLDoc()
  
! def doc(thing, title='Python Library Documentation: '):
!     """Display text documentation, given an object or a path to an object."""
!     suffix, name = '', None
!     if type(thing) is type(''):
          try:
              object = locate(thing)
***************
*** 1096,1110 ****
              print value
              return
!         if object:
!             thing = object
!         else:
              print 'no Python documentation found for %s' % repr(thing)
              return
  
      desc = describe(thing)
      module = inspect.getmodule(thing)
!     if module and module is not thing:
!         desc = desc + ' in module ' + module.__name__
!     pager('Help on %s:\n\n' % desc + text.document(thing))
  
  def writedoc(key):
--- 1075,1091 ----
              print value
              return
!         if not object:
              print 'no Python documentation found for %s' % repr(thing)
              return
+         parts = split(thing, '.')
+         if len(parts) > 1: suffix = ' in ' + join(parts[:-1], '.')
+         name = parts[-1]
+         thing = object
  
      desc = describe(thing)
      module = inspect.getmodule(thing)
!     if not suffix and module and module is not thing:
!         suffix = ' in module ' + module.__name__
!     pager(title + desc + suffix + '\n\n' + text.document(object, name))
  
  def writedoc(key):
***************
*** 1155,1177 ****
  help = Helper()
  
- def man(key):
-     """Display documentation on an object in a form similar to man(1)."""
-     object = locate(key)
-     if object:
-         title = 'Python Library Documentation: ' + describe(object)
-         lastdot = rfind(key, '.')
-         if lastdot > 0: title = title + ' in ' + key[:lastdot]
-         pager('\n' + title + '\n\n' + text.document(object, key))
-         found = 1
-     else:
-         print 'no Python documentation found for %s' % repr(key)
- 
  class Scanner:
      """A generic tree iterator."""
!     def __init__(self, roots, children, recurse):
          self.roots = roots[:]
          self.state = []
          self.children = children
!         self.recurse = recurse
  
      def next(self):
--- 1136,1146 ----
  help = Helper()
  
  class Scanner:
      """A generic tree iterator."""
!     def __init__(self, roots, children, descendp):
          self.roots = roots[:]
          self.state = []
          self.children = children
!         self.descendp = descendp
  
      def next(self):
***************
*** 1186,1190 ****
              return self.next()
          child = children.pop(0)
!         if self.recurse(child):
              self.state.append((child, self.children(child)))
          return child
--- 1155,1159 ----
              return self.next()
          child = children.pop(0)
!         if self.descendp(child):
              self.state.append((child, self.children(child)))
          return child
***************
*** 1204,1208 ****
              else:
                  children.append((path, package))
!         children.sort()
          return children
  
--- 1173,1177 ----
              else:
                  children.append((path, package))
!         children.sort() # so that spam.py comes before spam.pyc or spam.pyo
          return children
  
***************
*** 1211,1214 ****
--- 1180,1184 ----
  
      def run(self, key, callback, completer=None):
+         key = lower(key)
          self.quit = 0
          seen = {}
***************
*** 1218,1222 ****
                  seen[modname] = 1
                  desc = split(freshimport(modname).__doc__ or '', '\n')[0]
!                 if find(lower(modname + ' - ' + desc), lower(key)) >= 0:
                      callback(None, modname, desc)
  
--- 1188,1192 ----
                  seen[modname] = 1
                  desc = split(freshimport(modname).__doc__ or '', '\n')[0]
!                 if find(lower(modname + ' - ' + desc), key) >= 0:
                      callback(None, modname, desc)
  
***************
*** 1229,1236 ****
                  modname = package + (package and '.') + modname
                  if not seen.has_key(modname):
!                     seen[modname] = 1
!                     desc = synopsis(path) or ''
!                     if find(lower(modname + ' - ' + desc), lower(key)) >= 0:
!                         callback(path, modname, desc)
          if completer: completer()
  
--- 1199,1209 ----
                  modname = package + (package and '.') + modname
                  if not seen.has_key(modname):
!                     seen[modname] = 1 # if we see spam.py, skip spam.pyc
!                     if key:
!                         desc = synopsis(path) or ''
!                         if find(lower(modname + ' - ' + desc), key) >= 0:
!                             callback(path, modname, desc)
!                     else:
!                         callback(path, modname, '')
          if completer: completer()
  
***************
*** 1248,1253 ****
  # --------------------------------------------------- web browser interface
  
! def serve(port, callback=None):
!     import BaseHTTPServer, mimetools, select
  
      # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded.
--- 1221,1226 ----
  # --------------------------------------------------- web browser interface
  
! def serve(port, callback=None, finalizer=None):
!     import BaseHTTPServer, SocketServer, mimetools, select
  
      # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded.
***************
*** 1307,1311 ****
          def log_message(self, *args): pass
  
!     class DocServer(BaseHTTPServer.HTTPServer):
          def __init__(self, port, callback):
              host = (sys.platform == 'mac') and '127.0.0.1' or 'localhost'
--- 1280,1284 ----
          def log_message(self, *args): pass
  
!     class DocServer(SocketServer.ForkingMixIn, BaseHTTPServer.HTTPServer):
          def __init__(self, port, callback):
              host = (sys.platform == 'mac') and '127.0.0.1' or 'localhost'
***************
*** 1330,1337 ****
      DocHandler.MessageClass = Message
      try:
!         DocServer(port, callback).serve_until_quit()
!     except (KeyboardInterrupt, select.error):
!         pass
!     print 'server stopped'
  
  # ----------------------------------------------------- graphical interface
--- 1303,1312 ----
      DocHandler.MessageClass = Message
      try:
!         try:
!             DocServer(port, callback).serve_until_quit()
!         except (KeyboardInterrupt, select.error):
!             pass
!     finally:
!         if finalizer: finalizer()
  
  # ----------------------------------------------------- graphical interface
***************
*** 1405,1409 ****
  
              import threading
!             threading.Thread(target=serve, args=(port, self.ready)).start()
  
          def ready(self, server):
--- 1380,1385 ----
  
              import threading
!             threading.Thread(
!                 target=serve, args=(port, self.ready, self.quit)).start()
  
          def ready(self, server):
***************
*** 1545,1550 ****
                      raise BadUsage
                  def ready(server):
!                     print 'server ready at %s' % server.url
!                 serve(port, ready)
                  return
              if opt == '-w':
--- 1521,1528 ----
                      raise BadUsage
                  def ready(server):
!                     print 'pydoc server ready at %s' % server.url
!                 def stopped():
!                     print 'pydoc server stopped'
!                 serve(port, ready, stopped)
                  return
              if opt == '-w':
***************
*** 1562,1566 ****
                          writedoc(arg)
                  else:
!                     man(arg)
              except ErrorDuringImport, value:
                  print value
--- 1540,1544 ----
                          writedoc(arg)
                  else:
!                     doc(arg)
              except ErrorDuringImport, value:
                  print value