commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r9786 - trunk/gnue-common/src/apps


From: johannes
Subject: [gnue] r9786 - trunk/gnue-common/src/apps
Date: Thu, 27 Sep 2007 07:37:19 -0500 (CDT)

Author: johannes
Date: 2007-09-27 07:37:18 -0500 (Thu, 27 Sep 2007)
New Revision: 9786

Modified:
   trunk/gnue-common/src/apps/GBaseApp.py
   trunk/gnue-common/src/apps/GDebug.py
Log:
set log level to logging.DEBUG even if no log.conf is available.  Also 
honor the --debug-file option given on the commandline.

issue123 in-progress


Modified: trunk/gnue-common/src/apps/GBaseApp.py
===================================================================
--- trunk/gnue-common/src/apps/GBaseApp.py      2007-09-27 08:57:00 UTC (rev 
9785)
+++ trunk/gnue-common/src/apps/GBaseApp.py      2007-09-27 12:37:18 UTC (rev 
9786)
@@ -49,12 +49,12 @@
 # Exceptions
 # =============================================================================
 
-class StartupError (errors.UserError):
-  """
-  Error raised when a gnue application fails during initial startup prior to 
-  initializing to the point that better error handlers are available.
-  """
-  pass
+class StartupError(errors.UserError):
+    """
+    Error raised when a gnue application fails during initial startup prior to
+    initializing to the point that better error handlers are available.
+    """
+    pass
 
 
 # =============================================================================
@@ -62,973 +62,990 @@
 # =============================================================================
 
 class GBaseApp:
-  """
-  The base class of the various GNUe application classes.
+    """
+    The base class of the various GNUe application classes.
 
-  GBaseApp Provides the following features
-    - Command line argument parsing
-    - Run time debug output levels
-    - An integrated profiler
-    - An integrated debugger
-  """
+    GBaseApp Provides the following features
+      - Command line argument parsing
+      - Run time debug output levels
+      - An integrated profiler
+      - An integrated debugger
+    """
 
-  # Attributes to be overwritten by subclasses
-  VERSION = "0.0.0"
-  NAME    = "GNUe Application"
-  COMMAND_OPTIONS = []      # Should be in same format as _base_options below
-  SUMMARY = "A brief summary of the program goes here."
-  COMMAND = "app"
-  USAGE   = "[options]"
-  USE_CONNECTIONS      = 1  # Set to 1 if the program uses dbdrivers
-  USE_DATABASE_OPTIONS = 0  # Also implies USE_CONNECTIONS = 1
-  USE_RPC_OPTIONS      = 0
+    # Attributes to be overwritten by subclasses
+    VERSION = "0.0.0"
+    NAME    = "GNUe Application"
+    COMMAND_OPTIONS = []      # Should be in same format as _base_options below
+    SUMMARY = "A brief summary of the program goes here."
+    COMMAND = "app"
+    USAGE   = "[options]"
+    USE_CONNECTIONS      = 1  # Set to 1 if the program uses dbdrivers
+    USE_DATABASE_OPTIONS = 0  # Also implies USE_CONNECTIONS = 1
+    USE_RPC_OPTIONS      = 0
 
 
-  # More options, but won't be changed unless this is a non-GNUe app using
-  # GNUe-Common
-  AUTHOR         = "GNU Enterprise Project"
-  EMAIL          = "address@hidden"
-  REPORT_BUGS_TO = "Please report any bugs to address@hidden"
-  CONFIGFILE     = "gnue.conf"
+    # More options, but won't be changed unless this is a non-GNUe app using
+    # GNUe-Common
+    AUTHOR         = "GNU Enterprise Project"
+    EMAIL          = "address@hidden"
+    REPORT_BUGS_TO = "Please report any bugs to address@hidden"
+    CONFIGFILE     = "gnue.conf"
 
 
-  # Attributes that will be set by GClientApp after __init__ has run
-  OPTIONS     = {}    # Will contain a hash containing command line options
-  ARGUMENTS   = []    # Will contain an array of command line arguments
-  connections = None  # Will contain a GConnection object
+    # Attributes that will be set by GClientApp after __init__ has run
+    OPTIONS     = {}    # Will contain a hash containing command line options
+    ARGUMENTS   = []    # Will contain an array of command line arguments
+    connections = None  # Will contain a GConnection object
 
-  # ---------------------------------------------------------------------------
-  # Create a new GNUe Application
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Create a new GNUe Application
+    # -------------------------------------------------------------------------
 
-  def __init__ (self, connections = None, application = 'common',
-      defaults = None):
-    """
-    @param connections:
-    @param application:
-    @param defaults:
-    """
+    def __init__(self, connections=None, application='common', defaults=None):
+        """
+        @param connections:
+        @param application:
+        @param defaults:
+        """
 
-    self.configDefaults = defaults
-    
-    sys.excepthook = self.excepthook
+        self.configDefaults = defaults
 
-    # Basic options
-    self._base_options = [
-      ##
-      ## Base options
-      ##
-      CommandOption ('version', category = "base", action = self.doVersion,
-        help = u_('Displays the version information for this program.')),
+        sys.excepthook = self.excepthook
 
-      CommandOption ('debug-level', category = "base", default = 0,
-        argument = u_("level"),
-        help = u_('Enables debugging messages.  Argument specifies the '
-                  'level of messages to display (e.g., "--debug-level 5" '
-                  'displays all debugging messages at level 5 or below.)')),
+        # Basic options
+        self._base_options = [
+          ##
+          ## Base options
+          ##
+          CommandOption('version', category="base", action=self.doVersion,
+            help=u_('Displays the version information for this program.')),
 
-      CommandOption ('debug-file', category = "base", argument = 
u_("filename"),
-        help = u_('Sends all debugging messages to a specified file '
-                  '(e.g., "--debug-file trace.log" sends all output to '
-                  '"trace.log")')),
-      
-      # This is actually handled during the initial GDebug import but is added
-      # here so that applications won't abort with an unknown option.
-      CommandOption ('debug-imports', category = "dev",
-        help = u_('All python imports are logged to stdout')),
+          CommandOption('debug-level', category="base", default=0,
+            argument=u_("level"),
+            help=u_('Enables debugging messages.  Argument specifies the '
+                    'level of messages to display (e.g., "--debug-level 5" '
+                    'displays all debugging messages at level 5 or below.)')),
 
-      CommandOption ('silent', category = "base",
-        help = u_('Displays no output at all.')),
+          CommandOption('debug-file', category="base", argument=u_("filename"),
+            help = u_('Sends all debugging messages to a specified file '
+                      '(e.g., "--debug-file trace.log" sends all output to '
+                      '"trace.log")')),
 
-      CommandOption ('help', category = "base", action = self.printHelp,
-        help = u_('Displays this help screen.')),
+          # This is actually handled during the initial GDebug import but is
+          # added here so that applications won't abort with an unknown
+          # option.
+          CommandOption('debug-imports', category="dev",
+            help=u_('All python imports are logged to stdout')),
 
-      CommandOption ('help-config', category = "base",
-        action = self.doHelpConfig,
-        help = u_('Displays a list of valid configuration file entries, their '
-                  'purpose, and their default values.')),
+          CommandOption('silent', category="base",
+            help=u_('Displays no output at all.')),
 
-      ##
-      ## Developer options
-      ##
+          CommandOption('help', category="base", action=self.printHelp,
+            help=u_('Displays this help screen.')),
 
-      CommandOption ('help-dev', category = "base", action = self.printHelpDev,
-        help = u_('Display all options of interest to core developers. ')),
+          CommandOption('help-config', category="base",
+            action=self.doHelpConfig,
+            help=u_('Displays a list of valid configuration file entries, '
+                    'their purpose, and their default values.')),
 
-      CommandOption ('selfdoc', category = "dev", action = self.doSelfDoc,
-        argument = u_("type[,subtype]"),
-        help = u_('Generates self-documentation.')),
+          ##
+          ## Developer options
+          ##
 
-      CommandOption ('selfdoc-format', category = "dev",
-        argument = u_("format"),
-        help = u_('Format to output the self-documentation in. Supported '
-                  'formats are dependent on the type of selfdoc being '
-                  'created.')),
+          CommandOption('help-dev', category="base", action=self.printHelpDev,
+            help=u_('Display all options of interest to core developers. ')),
 
-      CommandOption ('selfdoc-file', category = "dev",
-        argument = u_("filename"),
-        help = u_('Specifies the filename that selfdoc should write to. If not 
'
-                  'provided, output is sent to stdout.')),
+          CommandOption('selfdoc', category="dev", action=self.doSelfDoc,
+            argument=u_("type[,subtype]"),
+            help=u_('Generates self-documentation.')),
 
-      CommandOption ('selfdoc-options', category = "dev",
-        argument = u_("options"),
-        help = u_('Options specific to individual selfdoc types.')),
+          CommandOption('selfdoc-format', category="dev",
+            argument=u_("format"),
+            help=u_('Format to output the self-documentation in. Supported '
+                    'formats are dependent on the type of selfdoc being '
+                    'created.')),
 
-      CommandOption ('profile', category = "dev",
-        help = u_("Run Python's built-in profiler and display the resulting "
-                  "run statistics.")),
+          CommandOption('selfdoc-file', category="dev",
+            argument=u_("filename"),
+            help=u_('Specifies the filename that selfdoc should write to. If '
+                    'not provided, output is sent to stdout.')),
 
-      CommandOption ('interactive-debugger', category = "dev",
-        help = u_("Run the app inside Python's built-in debugger ")),
+          CommandOption('selfdoc-options', category="dev",
+            argument=u_("options"),
+            help=u_('Options specific to individual selfdoc types.')),
 
-      CommandOption ('debug-gc', 'g', 'debug-gc', True, None, "logfile",
-          category = "dev", action = self.__installGCHandler,
-          help = u_("Debug Python's garbage collection on a SIGUSR1. If the "
-                    "argument is empty 'garbage.log' will be used as "
-                    "logfile.")),
+          CommandOption('profile', category="dev",
+            help=u_("Run Python's built-in profiler and display the resulting "
+                    "run statistics.")),
 
-      #CommandOption ('garbagelog', 'l'
-    ]
+          CommandOption('interactive-debugger', category="dev",
+            help=u_("Run the app inside Python's built-in debugger ")),
 
-    if self.USE_DATABASE_OPTIONS:
-      self.USE_CONNECTIONS = 1
-      self._base_options.extend ([ \
-        CommandOption ('username', category = "connections", default = '',
-          argument = u_('name'),
-          help = u_('Username used to log into the database.  Note that if '
-                    'specified, this will be used for all databases.  If not '
-                    'supplied, the program will prompt for username.')),
+          CommandOption('debug-gc', 'g', 'debug-gc', True, None, "logfile",
+              category="dev", action=self.__installGCHandler,
+              help=u_("Debug Python's garbage collection on a SIGUSR1. If the "
+                      "argument is empty 'garbage.log' will be used as "
+                      "logfile.")),
+        ]
 
-        CommandOption ('password', category = "connections", default = '',
-          argument = u_('passwd'),
-          help = u_('Password used to log into the database.  Note that if '
-                    'specified, this will be used for all databases.  If not '
-                    'supplied, the program will prompt for password if needed.'
-                    '\nNOTE: SUPPLYING A PASSWORD VIA THE COMMAND LINE MAY BE '
-                    'CONSIDERED A SECURITY RISK AND IS NOT RECOMMENDED.'))])
+        if self.USE_DATABASE_OPTIONS:
+            self.USE_CONNECTIONS = 1
+            self._base_options.extend([ \
+              CommandOption('username', category="connections", default='',
+                argument=u_('name'),
+                help=u_('Username used to log into the database.  Note that if 
'
+                        'specified, this will be used for all databases.  If '
+                        'not supplied, the program will prompt for 
username.')),
 
-    if self.USE_CONNECTIONS:
-      self._base_options += [
-        CommandOption ('help-connections', category = "base",
-          action = self.printHelpConn,
-          help = u_('Display help information related to database '
-                    'connections, including a list of available drivers.')),
+              CommandOption('password', category="connections", default='',
+                argument=u_('passwd'),
+                help=u_('Password used to log into the database.  Note that '
+                        'if specified, this will be used for all databases. '
+                        'If not supplied, the program will prompt for '
+                        'password if needed.\nNOTE: SUPPLYING A PASSWORD VIA '
+                        'THE COMMAND LINE MAY BE CONSIDERED A SECURITY RISK '
+                        'AND IS NOT RECOMMENDED.'))])
 
-        CommandOption ('connections', category = "connections",
-          argument = u_("location"),
-          help = u_('Specifies the location of the connection definition file. 
'
-                    '<location> may specify a file name '
-                    '(/usr/local/gnue/etc/connections.conf),'
-                    'or a URL location '
-                    '(http://localhost/connections.conf).'
-                    'If this option is not specified, the environent variable '
-                    'GNUE_CONNECTIONS is checked.'
-                    'If neither of them is set, "%s" is used as a default.') %
-             os.path.join (paths.config, "connections.conf")) ]
+        if self.USE_CONNECTIONS:
+            self._base_options += [
+              CommandOption('help-connections', category="base",
+                action=self.printHelpConn,
+                help=u_('Display help information related to database '
+                        'connections, including a list of available 
drivers.')),
 
-    # Python version check
-    if not hasattr (sys, 'hexversion') or sys.hexversion < 0x02030000:
-      msg = u_("This application requires Python 2.3 or greater.")
-      if hasattr (sys, 'version'):
-        msg = u_("This application requires Python 2.3 or greater. "
-                 "You are running Python %s") % sys.version [:5]
+              CommandOption('connections', category="connections",
+                argument=u_("location"),
+                help=u_('Specifies the location of the connection definition '
+                        'file. <location> may specify a file name '
+                        '(/usr/local/gnue/etc/connections.conf),'
+                        'or a URL location '
+                        '(http://localhost/connections.conf).'
+                        'If this option is not specified, the environent '
+                        'variable GNUE_CONNECTIONS is checked.'
+                        'If neither of them is set, "%s" is used as a '
+                        'default.') %
+                   os.path.join(paths.config, "connections.conf")) ]
 
-      raise errors.AdminError, msg
+        # Python version check
+        if not hasattr(sys, 'hexversion') or sys.hexversion < 0x02030000:
+            msg = u_("This application requires Python 2.3 or greater.")
+            if hasattr(sys, 'version'):
+                msg = u_("This application requires Python 2.3 or greater. "
+                         "You are running Python %s") % sys.version[:5]
 
+            raise errors.AdminError, msg
 
-    #
-    # Get all command line options and arguments
-    #
-    shortoptions = ""
-    longoptions  = []
-    lookup       = {}
-    actions      = {}
 
-    # Convert old-style options to new-style
-    if self.COMMAND_OPTIONS and \
-        isinstance (self.COMMAND_OPTIONS [0], types.ListType):
-      options = self.COMMAND_OPTIONS
-      self.COMMAND_OPTIONS = []
-      for option in options:
-        self.COMMAND_OPTIONS.append (CommandOption (*option))
+        #
+        # Get all command line options and arguments
+        #
+        shortoptions = ""
+        longoptions  = []
+        lookup       = {}
+        actions      = {}
 
-    for optionset in [self._base_options, self.COMMAND_OPTIONS]:
-      for option in optionset:
-        self.OPTIONS[option.name] = option.default
-        if option.shortOption:
-          shortoptions += option.shortOption
-          lookup["-" + option.shortOption] = option.name
-        lookup["--" + option.longOption] = option.name
-        if option.action:
-          actions["--" + option.longOption] = option.action
-        lo = option.longOption
-        if option.acceptsArgument:
-          lo += '='
-          shortoptions += ':'
-        longoptions.append(lo)
+        # Convert old-style options to new-style
+        if self.COMMAND_OPTIONS and \
+            isinstance(self.COMMAND_OPTIONS[0], types.ListType):
+            options = self.COMMAND_OPTIONS
+            self.COMMAND_OPTIONS = []
+            for option in options:
+                self.COMMAND_OPTIONS.append(CommandOption(*option))
 
+        for optionset in [self._base_options, self.COMMAND_OPTIONS]:
+            for option in optionset:
+                self.OPTIONS[option.name] = option.default
+                if option.shortOption:
+                    shortoptions += option.shortOption
+                    lookup["-" + option.shortOption] = option.name
+                lookup["--" + option.longOption] = option.name
+                if option.action:
+                    actions["--" + option.longOption] = option.action
+                lo = option.longOption
+                if option.acceptsArgument:
+                    lo += '='
+                    shortoptions += ':'
+                longoptions.append(lo)
 
-    # mod_python apps don't have an argv
-    # so create an empty one.
-    # TODO: This class needs adjusted to
-    #       be more efficent in mod_python cases
-    #       But not this close to a release :)
-    if not sys.__dict__.has_key('argv'):
-      sys.argv = []
 
-    try:
-      opt, self.ARGUMENTS = getopt.getopt (sys.argv[1:], shortoptions,
-                                           longoptions)
-    except getopt.error, msg:
-      raise StartupError, "%s" % msg
+        # mod_python apps don't have an argv
+        # so create an empty one.
+        # TODO: This class needs adjusted to
+        #       be more efficent in mod_python cases
+        #       But not this close to a release :)
+        if not sys.__dict__.has_key('argv'):
+            sys.argv = []
 
-    pendingActions = []
-    for o in opt:
-      if len(o[1]):
-        self.OPTIONS[lookup[o[0]]] = o[1]
-      else:
-        self.OPTIONS[lookup[o[0]]] = True
+        try:
+            opt, self.ARGUMENTS = getopt.getopt(sys.argv[1:], shortoptions,
+                                                 longoptions)
+        except getopt.error, msg:
+            raise StartupError, "%s" % msg
 
-      # Add any actions to our list
-      try:
-        pendingActions.append(actions[o[0]])
-      except KeyError:
-        pass
+        pendingActions = []
+        for o in opt:
+            if len(o[1]):
+                self.OPTIONS[lookup[o[0]]] = o[1]
+            else:
+                self.OPTIONS[lookup[o[0]]] = True
 
-    for task in pendingActions:
-      task()
+            # Add any actions to our list
+            try:
+                pendingActions.append(actions[o[0]])
+            except KeyError:
+                pass
 
-    self._run = self.run
+        for task in pendingActions:
+            task()
 
-    # Are we silent?
-    if self.OPTIONS['silent']:
-      # our file objects (/dev/null and nul) has no encoding, unlike stdout...
-      import __builtin__
-      __builtin__.__dict__['u_'] = __builtin__.__dict__['_']
-      if os.name == 'posix':
-        sout = open('/dev/null','w')
-        serr = open('/dev/null','w')
-      elif os.name == 'nt':
-        sout = open('nul', 'w')
-        serr = open('nul', 'w')
+        self._run = self.run
 
-      try:
-        os.close(sys.stdout.fileno())
-        sys.stdout = sout
-        os.close(sys.stderr.fileno())
-        sys.stderr = serr
+        # Are we silent?
+        if self.OPTIONS['silent']:
+            # our file objects (/dev/null and nul) has no encoding, unlike
+            # stdout...
+            import __builtin__
+            __builtin__.__dict__['u_'] = __builtin__.__dict__['_']
+            if os.name == 'posix':
+                sout = open('/dev/null','w')
+                serr = open('/dev/null','w')
+            elif os.name == 'nt':
+                sout = open('nul', 'w')
+                serr = open('nul', 'w')
 
-      except:
-        pass
+            try:
+                os.close(sys.stdout.fileno())
+                sys.stdout = sout
+                os.close(sys.stderr.fileno())
+                sys.stderr = serr
 
-    # Should we profile?
-    if self.OPTIONS['profile']:
-      self.run = self._profile
+            except:
+                pass
 
-    # Setup debugging
-    # Should we run in debugger?
-    elif self.OPTIONS['interactive-debugger']:
-      self.run = self._debugger
+        # Should we profile?
+        if self.OPTIONS['profile']:
+            self.run = self._profile
 
-    try:
-      GDebug.setDebug ("%s" % self.OPTIONS ['debug-level'],
-                       self.OPTIONS ['debug-file'])
-    except ValueError:
-       raise StartupError, \
-           u_('The debug_level option ("-d") expects numerical values.')
+        # Setup debugging
+        # Should we run in debugger?
+        elif self.OPTIONS['interactive-debugger']:
+            self.run = self._debugger
 
-    assert gDebug (2, "Python %s" % sys.version)
-    assert gDebug (2, "Run Options: %s" % opt)
-    assert gDebug (2, "Run Arguments: %s" % self.ARGUMENTS)
+        try:
+            GDebug.setDebug("%s" % self.OPTIONS['debug-level'],
+                             self.OPTIONS['debug-file'])
+        except ValueError:
+            raise StartupError, \
+                u_('The debug_level option ("-d") expects numerical values.')
 
-    # Read the config files
-    if application:
-      try:
-        self.configurationManager = GConfig.GConfig (application,
-                         self.configDefaults, configFilename = self.CONFIGFILE)
+        assert gDebug(2, "Python %s" % sys.version)
+        assert gDebug(2, "Run Options: %s" % opt)
+        assert gDebug(2, "Run Arguments: %s" % self.ARGUMENTS)
 
-      except ConfigParser.NoSectionError, msg:
-        raise errors.AdminError, \
-            u_("The gnue.conf file is incomplete:\n   %s") % msg
+        # Read the config files
+        if application:
+            try:
+                self.configurationManager = GConfig.GConfig(application,
+                                 self.configDefaults,
+                                 configFilename=self.CONFIGFILE)
 
-    # Add custom import to python's namespace
-    try:
-      extrapaths = gConfig('ImportPath')
-    except:
-      extrapaths = ""
-    if extrapaths:
-      for path in extrapaths.split(','):
-        p = path.strip()
-        if not p in sys.path:
-          sys.path.append(p)
+            except ConfigParser.NoSectionError, msg:
+                raise errors.AdminError, \
+                    u_("The gnue.conf file is incomplete:\n   %s") % msg
 
-    # Get the connection definitions
-    if connections != None:
-      assert gDebug(7,"Reusing connections instance")
-      self.connections = connections
-    elif self.USE_CONNECTIONS:
+        # Add custom import to python's namespace
+        try:
+            extrapaths = gConfig('ImportPath')
+        except:
+            extrapaths = ""
 
-      # Check for default username/password
-      lhOptions = {}
-      if self.USE_DATABASE_OPTIONS:
-        if self.OPTIONS['username']:
-          lhOptions['_username'] = self.OPTIONS['username']
-        if self.OPTIONS['password']:
-          lhOptions['_password'] = self.OPTIONS['password']
+        if extrapaths:
+            for path in extrapaths.split(','):
+                p = path.strip()
+                if not p in sys.path:
+                    sys.path.append(p)
 
-      if self.OPTIONS['connections']:
-        self.connections_file = self.OPTIONS['connections']
-      elif os.environ.has_key('GNUE_CONNECTIONS'):
-        self.connections_file = os.environ['GNUE_CONNECTIONS']
-      else:
-        self.connections_file = os.path.join (paths.config, "connections.conf")
+        # Get the connection definitions
+        if connections != None:
+            assert gDebug(7,"Reusing connections instance")
+            self.connections = connections
+        elif self.USE_CONNECTIONS:
 
-      assert gDebug(2, 'Connection Definition: "%s"' % self.connections_file)
+            # Check for default username/password
+            lhOptions = {}
+            if self.USE_DATABASE_OPTIONS:
+                if self.OPTIONS['username']:
+                    lhOptions['_username'] = self.OPTIONS['username']
+                if self.OPTIONS['password']:
+                    lhOptions['_password'] = self.OPTIONS['password']
 
-      try:
-        self.connections = GConnections.GConnections (self.connections_file,
-                                                      loginOptions = lhOptions)
-      except GConnections.InvalidFormatError, msg:
-        raise errors.AdminError, \
-            u_("Unable to load the connections definition file.\n\n"
-               "The connections file is in an invalid format.\n%s") % msg
+            if self.OPTIONS['connections']:
+                self.connections_file = self.OPTIONS['connections']
+            elif os.environ.has_key('GNUE_CONNECTIONS'):
+                self.connections_file = os.environ['GNUE_CONNECTIONS']
+            else:
+                self.connections_file = os.path.join(paths.config,
+                        "connections.conf")
 
-      except IOError:
-        raise StartupError, \
-            u_("Unable to load the connections definition file: %s.") \
-            % self.connections_file
+            assert gDebug(2, 'Connection Definition: "%s"' %
+                    self.connections_file)
 
+            try:
+                self.connections = GConnections.GConnections( \
+                        self.connections_file, loginOptions = lhOptions)
 
-  # ---------------------------------------------------------------------------
-  # Run the program
-  # ---------------------------------------------------------------------------
+            except GConnections.InvalidFormatError, msg:
+                raise errors.AdminError, \
+                    u_("Unable to load the connections definition file.\n\n"
+                       "The connections file is in an invalid format.\n%s") \
+                               % msg
 
-  def run(self):
-    """
-    Run the program. This function will be overriden by a descendant.
-    """
+            except IOError:
+                raise StartupError, \
+                    u_("Unable to load the connections definition file: %s.") \
+                    % self.connections_file
 
-    pass
 
+    # -------------------------------------------------------------------------
+    # Run the program
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Add a new option to the program
-  # ---------------------------------------------------------------------------
+    def run(self):
+        """
+        Run the program. This function will be overriden by a descendant.
+        """
 
-  def addCommandOption(self, *args, **parms):
-    """
-    Create a new command option and add it to the options sequence.
+        pass
 
-    @param args: positional arguments for the command option's constructor
-    @param parms: keyword arguments for the command option's constructor
-    """
 
-    self.COMMAND_OPTIONS.append (CommandOption (*args, **parms))
+    # -------------------------------------------------------------------------
+    # Add a new option to the program
+    # -------------------------------------------------------------------------
 
+    def addCommandOption(self, *args, **parms):
+        """
+        Create a new command option and add it to the options sequence.
 
-  # ---------------------------------------------------------------------------
-  # Display version information for this application
-  # ---------------------------------------------------------------------------
+        @param args: positional arguments for the command option's constructor
+        @param parms: keyword arguments for the command option's constructor
+        """
 
-  def printVersion (self):
-    """
-    Display version information for this application
-    """
+        self.COMMAND_OPTIONS.append(CommandOption(*args, **parms))
 
-    from gnue.common import VERSION as commonVersion
-    print o(u_("\n%(name)s\nVersion %(version)s\n") \
-             % {'name': self.NAME, 'version': self.VERSION})
-    print o(u_("GNUe Common Version %s\n") % commonVersion)
 
+    # -------------------------------------------------------------------------
+    # Display version information for this application
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Build help options
-  # ---------------------------------------------------------------------------
+    def printVersion(self):
+        """
+        Display version information for this application
+        """
 
-  def buildHelpOptions (self, category = None):
-    """
-    Build 'help text' for all options of the given category. If no category is
-    given all options except the 'dev' options will be included.
+        from gnue.common import VERSION as commonVersion
+        print o(u_("\n%(name)s\nVersion %(version)s\n") \
+                 % {'name': self.NAME, 'version': self.VERSION})
+        print o(u_("GNUe Common Version %s\n") % commonVersion)
 
-    @param category: if not None only options of this category will be 
included.
 
-    @return: string with the help text for all matching options.
-    """
+    # -------------------------------------------------------------------------
+    # Build help options
+    # -------------------------------------------------------------------------
 
-    allOptions  = {}
-    descriptors = {}
-    maxLength   = 0
+    def buildHelpOptions(self, category=None):
+        """
+        Build 'help text' for all options of the given category. If no category
+        is given all options except the 'dev' options will be included.
 
-    for optionset in [self._base_options, self.COMMAND_OPTIONS]:
-      for option in optionset:
-        # Limit this to the correct category. A category of None implies all
-        # options except "dev".
-        if not (  ( category is None and \
-                    option.category != "dev" ) or \
-                  ( category == option.category ) ):
-          continue
+        @param category: if not None only options of this category will be
+            included.
 
-        allOptions [option.longOption.upper ()] = option
+        @return: string with the help text for all matching options.
+        """
 
-        if option.acceptsArgument:
-          descr = '--%s <%s>' % (option.longOption, option.argumentName)
-        else:
-          descr = '--%s' % (option.longOption)
-        if option.shortOption:
-          descr += ', -%s' % option.shortOption
+        allOptions  = {}
+        descriptors = {}
+        maxLength   = 0
 
-        descriptors [option.longOption.upper()] = descr
+        for optionset in [self._base_options, self.COMMAND_OPTIONS]:
+            for option in optionset:
+                # Limit this to the correct category. A category of None
+                # implies all options except "dev".
+                if not ((category is None and \
+                         option.category != "dev") or \
+                        (category == option.category)):
+                    continue
 
-        maxLength = max(len (descr), maxLength)
+                allOptions[option.longOption.upper()] = option
 
-    maxLength = min(10, maxLength)
+                if option.acceptsArgument:
+                    descr = '--%s <%s>' % (option.longOption,
+                                           option.argumentName)
+                else:
+                    descr = '--%s' % (option.longOption)
+                if option.shortOption:
+                    descr += ', -%s' % option.shortOption
 
-    sorted = allOptions.keys ()
-    sorted.sort ()
+                descriptors[option.longOption.upper()] = descr
 
-    dispOptions = u""
+                maxLength = max(len(descr), maxLength)
 
-    for optionKey in sorted:
-      margin = maxLength + 4
-      width  = 78 - margin
-      pos    = 0
+        maxLength = min(10, maxLength)
 
-      if len (descriptors [optionKey]) > maxLength:
-        dispOptions += "\n  %s\n%s" % (descriptors [optionKey], " " * margin)
-      else:
-        dispOptions += "\n  %s  %s" % (descriptors [optionKey],
-               " " * (maxLength - len (descriptors [optionKey])))
+        sorted = allOptions.keys()
+        sorted.sort()
 
-      for word in allOptions [optionKey].help.split():
-        if (len (word) + pos) > width:
-          pos = 0
-          dispOptions += "\n" + " " * margin
+        dispOptions = u""
 
-        pos = pos + len (word) + 1
+        for optionKey in sorted:
+            margin = maxLength + 4
+            width  = 78 - margin
+            pos    = 0
 
-        dispOptions += word + " "
+            if len(descriptors[optionKey]) > maxLength:
+                dispOptions += "\n  %s\n%s" % (descriptors[optionKey],
+                        " " * margin)
+            else:
+                dispOptions += "\n  %s  %s" % (descriptors[optionKey],
+                       " " * (maxLength - len(descriptors[optionKey])))
 
-      dispOptions +=  "\n"
+            for word in allOptions[optionKey].help.split():
+                if (len(word) + pos) > width:
+                    pos = 0
+                    dispOptions += "\n" + " " * margin
 
-    return dispOptions
+                pos = pos + len(word) + 1
 
+                dispOptions += word + " "
 
-  # ---------------------------------------------------------------------------
-  # Print a usage header
-  # ---------------------------------------------------------------------------
+            dispOptions +=  "\n"
 
-  def printHelpHeader(self):
-    """
-    Print version information and the usage header
-    """
+        return dispOptions
 
-    self.printVersion ()
-    print o(u_("Usage:  ") + self.COMMAND + ' ' + self.USAGE)
-    print
 
+    # -------------------------------------------------------------------------
+    # Print a usage header
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Print help footer
-  # ---------------------------------------------------------------------------
+    def printHelpHeader(self):
+        """
+        Print version information and the usage header
+        """
 
-  def printHelpFooter(self):
-    """
-    Print the help footer including the address for bug reports.
-    """
+        self.printVersion()
+        print o(u_("Usage:  ") + self.COMMAND + ' ' + self.USAGE)
+        print
 
-    print
-    print o("%s\n" % self.REPORT_BUGS_TO)
 
+    # -------------------------------------------------------------------------
+    # Print help footer
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Display help information for this program
-  # ---------------------------------------------------------------------------
+    def printHelpFooter(self):
+        """
+        Print the help footer including the address for bug reports.
+        """
 
-  def printHelp (self):
-    """
-    Print help information for this application and quit the program. This
-    includes the version, the usage, the application's summary and all
-    available command options (without the 'developer' options).
-    """
+        print
+        print o("%s\n" % self.REPORT_BUGS_TO)
 
-    self.printHelpHeader ()
-    print o("\n" + self.SUMMARY + '\n')
 
-    print o(u_('Available command line options:'))
-    print o(self.buildHelpOptions ())
-    self.printHelpFooter ()
+    # -------------------------------------------------------------------------
+    # Display help information for this program
+    # -------------------------------------------------------------------------
 
-    sys.exit ()
+    def printHelp(self):
+        """
+        Print help information for this application and quit the program. This
+        includes the version, the usage, the application's summary and all
+        available command options (without the 'developer' options).
+        """
 
+        self.printHelpHeader()
+        print o("\n" + self.SUMMARY + '\n')
 
-  # ---------------------------------------------------------------------------
-  # Display dev help information for this program
-  # ---------------------------------------------------------------------------
+        print o(u_('Available command line options:'))
+        print o(self.buildHelpOptions())
+        self.printHelpFooter()
 
-  def printHelpDev (self):
-    """
-    Print help information for this application and quit the program. This
-    includes the version, usage and all available developer's command options.
-    """
+        sys.exit()
 
-    self.printHelpHeader ()
 
-    print o(u_("The following options are mainly of interest to GNUe "
-               "developers."))
-    print o(u_("To view general help, run this command with the --help "
-               "option."))
-    print
-    print o(u_('Developer-specific command line options:'))
-    print o(self.buildHelpOptions ("dev"))
-    self.printHelpFooter ()
+    # -------------------------------------------------------------------------
+    # Display dev help information for this program
+    # -------------------------------------------------------------------------
 
-    sys.exit ()
+    def printHelpDev(self):
+        """
+        Print help information for this application and quit the program. This
+        includes the version, usage and all available developer's command
+        options.
+        """
 
+        self.printHelpHeader()
 
-  # ---------------------------------------------------------------------------
-  # Print connection-specific help information
-  # ---------------------------------------------------------------------------
+        print o(u_("The following options are mainly of interest to GNUe "
+                   "developers."))
+        print o(u_("To view general help, run this command with the --help "
+                   "option."))
+        print
+        print o(u_('Developer-specific command line options:'))
+        print o(self.buildHelpOptions("dev"))
+        self.printHelpFooter()
 
-  def printHelpConn (self):
-    """
-    Print connection/database-related help information and quit the program.
-    """
+        sys.exit()
 
-    self.printHelpHeader ()
 
-    print o(u_("The following connection/database-related options are "
-               "available."))
-    print o(u_("To view general help, run this command with the --help "
-               "option."))
-    print
-    print o(u_('Database/connection command line options:'))
-    print o(self.buildHelpOptions ("connections"))
-    print
-    print o(u_('The following database drivers are installed on your system:'))
-    print "   TODO\n"
-    # print self.connections.getAvailableDrivers()
-    self.printHelpFooter ()
+    # -------------------------------------------------------------------------
+    # Print connection-specific help information
+    # -------------------------------------------------------------------------
 
-    sys.exit ()
+    def printHelpConn(self):
+        """
+        Print connection/database-related help information and quit the 
program.
+        """
 
+        self.printHelpHeader()
 
-  # ---------------------------------------------------------------------------
-  # Run the self-documentation for a program
-  # ---------------------------------------------------------------------------
+        print o(u_("The following connection/database-related options are "
+                   "available."))
+        print o(u_("To view general help, run this command with the --help "
+                   "option."))
+        print
+        print o(u_('Database/connection command line options:'))
+        print o(self.buildHelpOptions("connections"))
+        print
+        print o(u_('The following database drivers are installed on ' \
+                   'your system:'))
+        print "   TODO\n"
+        # print self.connections.getAvailableDrivers()
+        self.printHelpFooter()
 
-  def selfdoc (self, command, handle, format = None, options = {}):
-    """
-    Run the self-documentation for an application. Currently only the command
-    'manpage' is supported.
+        sys.exit()
 
-    @param command: can be 'manpage' only atm
-    @param handle: file-like object to write the documentation contents to.
-        This file handle must be already opened for writing.
-    @param format: not used in the current version
-    @param options: not used in the current version
-    """
 
-    if command == 'manpage':
-      import manpage
-      manpage.ManPage (self, handle, format, options)
+    # -------------------------------------------------------------------------
+    # Run the self-documentation for a program
+    # -------------------------------------------------------------------------
 
+    def selfdoc(self, command, handle, format = None, options = {}):
+        """
+        Run the self-documentation for an application. Currently only the
+        command 'manpage' is supported.
 
-  # ---------------------------------------------------------------------------
-  # 
-  # ---------------------------------------------------------------------------
+        @param command: can be 'manpage' only atm
+        @param handle: file-like object to write the documentation contents to.
+            This file handle must be already opened for writing.
+        @param format: not used in the current version
+        @param options: not used in the current version
+        """
 
-  def getCommandLineParameters (self, paramList):
-    """
-    Convert a sequence of parameters (i.e. '--foo=bar') into a parameter
-    dictionary, where the paramter ('--foo') is the key and it's argument
-    ('bar') is the value.
+        if command == 'manpage':
+            import manpage
+            manpage.ManPage(self, handle, format, options)
 
-    @param paramList: sequence of parameters (usually from self.ARGUMENTS)
-    @return: dictionary of parameters, splitted by the first '='
 
-    @raises StartupError: if a parameter has no value assigned
-    """
+    # -------------------------------------------------------------------------
+    # Convert parameter sequence into dictionary
+    # -------------------------------------------------------------------------
 
-    parameters = {}
-    for param in [unicode(p, locale.getpreferredencoding()) for p in 
paramList]:
-      psplit = param.split('=', 1)
-      if len (psplit) == 1:
-        raise StartupError, \
-            'Parameter "%s" specified, but no value supplied.' % psplit [0]
-      parameters [psplit [0].lower()] = psplit [1]
+    def getCommandLineParameters(self, paramList):
+        """
+        Convert a sequence of parameters (i.e. '--foo=bar') into a parameter
+        dictionary, where the paramter ('--foo') is the key and it's argument
+        ('bar') is the value.
 
-      assert gDebug (2,'Param "%s"="%s" ' % (psplit [0].lower(), psplit [1]))
+        @param paramList: sequence of parameters (usually from self.ARGUMENTS)
+        @return: dictionary of parameters, splitted by the first '='
 
-    return parameters
+        @raises StartupError: if a parameter has no value assigned
+        """
 
+        parameters = {}
+        for param in [unicode(p, locale.getpreferredencoding()) \
+                      for p in paramList]:
+            psplit = param.split('=', 1)
+            if len(psplit) == 1:
+                raise StartupError, \
+                    'Parameter "%s" specified, but no value supplied.' \
+                    % psplit[0]
+            parameters[psplit[0].lower()] = psplit[1]
 
-  # ---------------------------------------------------------------------------
-  # Display a startup error and exit gracefully
-  # ---------------------------------------------------------------------------
+            assert gDebug(2,'Param "%s"="%s" ' % (psplit[0].lower(), 
psplit[1]))
 
-  def handleStartupError (self, msg):
-    """
-    Display a startup error and exit gracefully. This function is depreciated.
-    Descendants should use the concpet of exceptions instead, which will be
-    handled by the exception hook installed by this class.
-    """
+        return parameters
 
-    self.printVersion ()
 
-    # if msg is multiline, then surround with dashes to set it apart
-    if ("%s" % msg).find("\n") + 1:
-      print '-' * 60
+    # -------------------------------------------------------------------------
+    # Display a startup error and exit gracefully
+    # -------------------------------------------------------------------------
 
-    print o(u_("Error: %s") % msg)
-    if ("%s" % msg).find("\n") + 1:
-      print '-' * 60
+    def handleStartupError(self, msg):
+        """
+        Display a startup error and exit gracefully. This function is
+        depreciated.  Descendants should use the concpet of exceptions instead,
+        which will be handled by the exception hook installed by this class.
+        """
 
-    print o(u_("\nFor help, type:\n   %s --help\n") % self.COMMAND)
+        self.printVersion()
 
-    sys.exit ()
+        # if msg is multiline, then surround with dashes to set it apart
+        if ("%s" % msg).find("\n") + 1:
+            print '-' * 60
 
+        print o(u_("Error: %s") % msg)
+        if ("%s" % msg).find("\n") + 1:
+            print '-' * 60
 
-  # ---------------------------------------------------------------------------
-  # Display version information
-  # ---------------------------------------------------------------------------
+        print o(u_("\nFor help, type:\n   %s --help\n") % self.COMMAND)
 
-  def doVersion (self):
-    """
-    Display the version information and quit the program.
-    """
+        sys.exit()
 
-    self.printVersion ()
-    sys.exit ()
 
+    # -------------------------------------------------------------------------
+    # Display version information
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Run the self documentation
-  # ---------------------------------------------------------------------------
+    def doVersion(self):
+        """
+        Display the version information and quit the program.
+        """
 
-  def doSelfDoc (self):
-    """
-    Run the self documentation. If a documentation file is specified the
-    contents will be written to that file, otherwise it will be printed to
-    stdout.
-    """
+        self.printVersion()
+        sys.exit()
 
-    if self.OPTIONS ['selfdoc-file']:
-      doprint = False
-      handle  = open (self.OPTIONS ['selfdoc-file'], 'w')
-    else:
-      doprint = True
-      import StringIO
-      handle = StringIO.StringIO
 
-    try:
-      self.selfdoc (self.OPTIONS ['selfdoc'], handle,
-                    self.OPTIONS ['selfdoc-format'],
-                    self.OPTIONS ['selfdoc-options'])
-      if doprint:
-        handle.seek (0)
-        print o(handle.read ())
+    # -------------------------------------------------------------------------
+    # Run the self documentation
+    # -------------------------------------------------------------------------
 
-    finally:
-      handle.close ()
+    def doSelfDoc(self):
+        """
+        Run the self documentation. If a documentation file is specified the
+        contents will be written to that file, otherwise it will be printed to
+        stdout.
+        """
 
-    sys.exit ()
+        if self.OPTIONS['selfdoc-file']:
+            doprint = False
+            handle  = open(self.OPTIONS['selfdoc-file'], 'w')
+        else:
+            doprint = True
+            import StringIO
+            handle = StringIO.StringIO
 
+        try:
+            self.selfdoc(self.OPTIONS['selfdoc'], handle,
+                          self.OPTIONS['selfdoc-format'],
+                          self.OPTIONS['selfdoc-options'])
+            if doprint:
+                handle.seek(0)
+                print o(handle.read())
 
-  # ---------------------------------------------------------------------------
-  # Display information about the configuration settings
-  # ---------------------------------------------------------------------------
+        finally:
+            handle.close()
 
-  def doHelpConfig (self):
-    """
-    Display all configuration settings and their default values and quit the
-    program.
-    """
+        sys.exit()
 
-    self.printHelpHeader ()
-    print o(GConfig.printableConfigOptions (self.configDefaults))
 
-    sys.exit ()
+    # -------------------------------------------------------------------------
+    # Display information about the configuration settings
+    # -------------------------------------------------------------------------
 
+    def doHelpConfig(self):
+        """
+        Display all configuration settings and their default values and quit
+        the program.
+        """
 
-  # ---------------------------------------------------------------------------
-  # Catch an exception
-  # ---------------------------------------------------------------------------
+        self.printHelpHeader()
+        print o(GConfig.printableConfigOptions(self.configDefaults))
 
-  def excepthook (self, etype, value, traceback):
-    """
-    This function catches an exception and evaluates it using getException ().
-    The exception-tuple is then passed to showException (), which might get
-    overriden by a descendant.
-    """
-    sys.excepthook = sys.__excepthook__
-    log.excepthook(etype, value, traceback)
-    self._showException (*errors.getException (None, etype, value, traceback))
-    sys.excepthook = self.excepthook
+        sys.exit()
 
 
-  # ---------------------------------------------------------------------------
-  # Used when interactive debugger in use
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Catch an exception
+    # -------------------------------------------------------------------------
 
-  def _debugger (self):
-    """
-    Run the application in the python debugger.
-    """
+    def excepthook(self, etype, value, traceback):
+        """
+        This function catches an exception and evaluates it using
+        getException().  The exception-tuple is then passed to showException(),
+        which might get overriden by a descendant.
+        """
+        sys.excepthook = sys.__excepthook__
+        log.excepthook(etype, value, traceback)
+        self._showException(*errors.getException(None, etype, value, 
traceback))
+        sys.excepthook = self.excepthook
 
-    import pdb
 
-    debugger = pdb.Pdb ()
-    GDebug.setDebugger (debugger)
-    debugger.runctx ('self._run ()', globals (), locals ())
+    # -------------------------------------------------------------------------
+    # Used when interactive debugger in use
+    # -------------------------------------------------------------------------
 
+    def _debugger(self):
+        """
+        Run the application in the python debugger.
+        """
 
-  # ---------------------------------------------------------------------------
-  # Used when profiling
-  # ---------------------------------------------------------------------------
+        import pdb
 
-  def _profile (self):
-    """
-    Run the application through the python profiler and print some statistics
-    afterwards.
-    """
+        debugger = pdb.Pdb()
+        GDebug.setDebugger(debugger)
+        debugger.runctx('self._run()', globals(), locals())
 
-    import profile
-    prof = profile.Profile ()
-    prof.runctx ('self._run ()', globals (), locals ())
 
-    import pstats
-    p = pstats.Stats (prof)
-    p.sort_stats ('time').print_stats (50)
-    p.sort_stats ('cumulative').print_stats (50)
-    p.sort_stats ('calls').print_stats (50)
+    # -------------------------------------------------------------------------
+    # Used when profiling
+    # -------------------------------------------------------------------------
 
+    def _profile(self):
+        """
+        Run the application through the python profiler and print some
+        statistics afterwards.
+        """
 
-  # ---------------------------------------------------------------------------
-  # Show an exception
-  # ---------------------------------------------------------------------------
+        import profile
+        prof = profile.Profile()
+        prof.runctx('self._run()', globals(), locals())
 
-  def _showException (self, group, name, message, detail):
-    """
-    This function shows an exception specified by the given parameters.
-    @param group: Exception group ('system', 'admin', 'application', 'user')
-    @param name: Name of the exception
-    @param message: Message of the exception
-    @param detail: Detail of the exception (usually holding a traceback)
-    """
+        import pstats
+        p = pstats.Stats(prof)
+        p.sort_stats('time').print_stats(50)
+        p.sort_stats('cumulative').print_stats(50)
+        p.sort_stats('calls').print_stats(50)
 
-    if group in ['user', 'admin']:
-      sys.__stderr__.write ("%s: %s\n" % (self.COMMAND, o(message)))
-      sys.__stderr__.write ("%s\n" % \
-                           o(u_("For help, type: %s --help") % self.COMMAND))
-    else:
-      sys.stderr.write ("%s\n" % o(detail))
 
+    # -------------------------------------------------------------------------
+    # Show an exception
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Install a signal handler for SIGUSR1
-  # ---------------------------------------------------------------------------
+    def _showException(self, group, name, message, detail):
+        """
+        This function shows an exception specified by the given parameters.
+        @param group: Exception group('system', 'admin', 'application', 'user')
+        @param name: Name of the exception
+        @param message: Message of the exception
+        @param detail: Detail of the exception(usually holding a traceback)
+        """
 
-  def __installGCHandler (self):
-    """
-    Install a signal handler for SIGUSR1, which actually performs the 
debugging.
-    """
+        if group in ['user', 'admin']:
+            sys.__stderr__.write("%s: %s\n" % (self.COMMAND, o(message)))
+            sys.__stderr__.write("%s\n" % \
+                          o(u_("For help, type: %s --help") % self.COMMAND))
+        else:
+            sys.stderr.write("%s\n" % o(detail))
 
-    signal.signal (signal.SIGUSR1, self.debugGarbageCollection)
 
+    # -------------------------------------------------------------------------
+    # Install a signal handler for SIGUSR1
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Debug Python's garbage collection
-  # ---------------------------------------------------------------------------
+    def __installGCHandler(self):
+        """
+        Install a signal handler for SIGUSR1, which actually performs the
+        debugging.
+        """
 
-  def debugGarbageCollection (self, signal, frame):
-    """
-    Debug Python's garbage collection.
+        signal.signal(signal.SIGUSR1, self.debugGarbageCollection)
 
-    @param signal: signal number caught by this handler (=SIGUSR1)
-    @param frame: the current stack frame or None
-    """
 
-    filename = "garbage.log"
-    if isinstance (self.OPTIONS ['debug-gc'], basestring):
-      filename = self.OPTIONS ['debug-gc']
+    # -------------------------------------------------------------------------
+    # Debug Python's garbage collection
+    # -------------------------------------------------------------------------
 
-    log = open (filename, 'w')
-    try:
-      # If we are interested in the objects collected by the garbage collection
-      # set the debug level to gc.DEBUG_LEAK. In this case gc.garbage contains
-      # all objects, collectable and uncollectable as well and we are able to
-      # inspect those cycles and objects.
-      gc.collect ()
+    def debugGarbageCollection(self, signal, frame):
+        """
+        Debug Python's garbage collection.
 
-      self.__gcLog (log, "Number of unreachable objects: %d" % len 
(gc.garbage))
-      if not gc.garbage:
-        return
+        @param signal: signal number caught by this handler (=SIGUSR1)
+        @param frame: the current stack frame or None
+        """
 
-      try:
-        self.__gcLog (log, "Dump of gc.garbage sequence:")
-        self.__gcLog (log, "-" * 70)
+        filename = "garbage.log"
+        if isinstance(self.OPTIONS['debug-gc'], basestring):
+            filename = self.OPTIONS['debug-gc']
 
-        for item in gc.garbage:
-          try:
-            itemrep = "%s: %s" % (type (item), repr (item))
-          except:
-            itemrep = "No representation available for object (weakref/proxy?)"
+        log = open(filename, 'w')
+        try:
+            # If we are interested in the objects collected by the garbage
+            # collection set the debug level to gc.DEBUG_LEAK. In this case
+            # gc.garbage contains all objects, collectable and uncollectable as
+            # well and we are able to inspect those cycles and objects.
+            gc.collect()
 
-          self.__gcLog (log, "%s" % itemrep)
+            self.__gc_log(log, "Number of unreachable objects: %d" % \
+                    len(gc.garbage))
+            if not gc.garbage:
+                return
 
-        for item in gc.garbage:
-          cycle = self.findCycle (item, item, None, [], {})
+            try:
+                self.__gc_log(log, "Dump of gc.garbage sequence:")
+                self.__gc_log(log, "-" * 70)
 
-          if cycle:
-            self.__gcLog (log, "-" * 70)
+                for item in gc.garbage:
+                    try:
+                        itemrep = "%s: %s" % (type(item), repr(item))
+                    except:
+                        itemrep = "No representation available for " \
+                                  "object(weakref/proxy?)"
 
-            for line in self.analyzeCycle (cycle):
-              self.__gcLog (log, line)
+                    self.__gc_log(log, "%s" % itemrep)
 
-        self.__gcLog (log, "-" * 70)
+                for item in gc.garbage:
+                    cycle = self.findCycle(item, item, None, [], {})
 
-      finally:
-        del gc.garbage [:]
+                    if cycle:
+                        self.__gc_log(log, "-" * 70)
 
-    finally:
-      log.close ()
+                        for line in self.analyzeCycle(cycle):
+                            self.__gc_log(log, line)
 
+                self.__gc_log(log, "-" * 70)
 
-  # ---------------------------------------------------------------------------
+            finally:
+                del gc.garbage[:]
 
-  def __gcLog (self, filehandle, message):
+        finally:
+            log.close()
 
-    filehandle.write ("%s%s" % (message, os.linesep))
-    print o(message)
 
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Find a reference cycle starting from a given object
-  # ---------------------------------------------------------------------------
+    def __gc_log(self, filehandle, message):
 
-  def findCycle (self, search, current, last, path, seen):
-    """
-    Find a reference cycle starting from a given object (current) and ending
-    with a given object (search). The result is either None if no such cycle
-    exists, or a sequence of tuples (repr, propertyname) describing the
-    reference cycle. 'repr' is either a string representation of an object
-    holding the reference or None. 'propertyname' could be one of the
-    following:
-      - 'name':   name of the property within 'repr' holding the reference
-      - '[n]':    the reference is the n-th element of a sequence
-      - '[name]': the reference is the value of key 'name' in a dictionary
-      - '{}':     the reference is a key in a dictionary
+        filehandle.write("%s%s" % (message, os.linesep))
+        print o(message)
 
-    The latter three variants could be cumulative (i.e. [1][3]['foo']) and the
-    corresponding propertyname is the last one encountered.
 
-    @return: None or sequence of tuples (repr, propertyname)
-    """
+    # -------------------------------------------------------------------------
+    # Find a reference cycle starting from a given object
+    # -------------------------------------------------------------------------
 
-    if last is not None:
-      path = path + [last]
+    def findCycle(self, search, current, last, path, seen):
+        """
+        Find a reference cycle starting from a given object(current) and ending
+        with a given object(search). The result is either None if no such cycle
+        exists, or a sequence of tuples (repr, propertyname) describing the
+        reference cycle. 'repr' is either a string representation of an object
+        holding the reference or None. 'propertyname' could be one of the
+        following:
+          - 'name':   name of the property within 'repr' holding the reference
+          - '[n]':    the reference is the n-th element of a sequence
+          - '[name]': the reference is the value of key 'name' in a dictionary
+          - '{}':     the reference is a key in a dictionary
 
-    currentId = id (current)
+        The latter three variants could be cumulative (i.e. [1][3]['foo']) and
+        the corresponding propertyname is the last one encountered.
 
-    # If we have already visited this object, no need to do further processing
-    if seen.has_key (currentId):
-      return None
+        @return: None or sequence of tuples (repr, propertyname)
+        """
 
-    seen [currentId] = path
+        if last is not None:
+            path = path + [last]
 
-    # If the current object has a __dict__ property, iterate over all it's
-    # properties
-    if hasattr (current, '__dict__'):
-      for (name, attr) in current.__dict__.items ():
-        prop = (repr (current), name)
+        currentId = id(current)
 
-        if attr == search:
-          return path + [prop]
+        # If we have already visited this object, no need to do further
+        # processing
+        if seen.has_key(currentId):
+            return None
 
-        else:
-          newpath = self.findCycle (search, attr, prop, path, seen)
-          if newpath:
-            return newpath
+        seen[currentId] = path
 
-    # A bound method has a reference to self
-    elif isinstance (current, types.MethodType):
-      if current.im_self == search:
-        return path + [(repr (current), "im_self")]
+        # If the current object has a __dict__ property, iterate over all it's
+        # properties
+        if hasattr(current, '__dict__'):
+            for (name, attr) in current.__dict__.items():
+                prop = (repr(current), name)
 
-    # For Sequences or Tuples iterate over all elements
-    elif isinstance (current, types.ListType) or \
-         isinstance (current, types.TupleType):
+                if attr == search:
+                    return path + [prop]
 
-      for (index, element) in enumerate (current):
-        prop = (None, "[%d]" % index)
-        if element == search:
-          return path + [prop]
+                else:
+                    newpath = self.findCycle(search, attr, prop, path, seen)
+                    if newpath:
+                        return newpath
 
-        else:
-          newpath = self.findCycle (search, element, prop, path, seen)
-          if newpath:
-            return newpath
+        # A bound method has a reference to self
+        elif isinstance(current, types.MethodType):
+            if current.im_self == search:
+                return path + [(repr(current), "im_self")]
 
-    # For dictionaries iterate over all items
-    elif isinstance (current, types.DictType):
-      for (key, element) in current.items ():
-        prop = (None, "[%s]" % repr (key))
+        # For Sequences or Tuples iterate over all elements
+        elif isinstance(current, types.ListType) or \
+             isinstance(current, types.TupleType):
 
-        if element == search:
-          return path + [prop]
+            for (index, element) in enumerate(current):
+                prop = (None, "[%d]" % index)
+                if element == search:
+                    return path + [prop]
 
-        elif  key == search:
-          return path + [(None, "{}")]
+                else:
+                    newpath = self.findCycle(search, element, prop, path, seen)
+                    if newpath:
+                        return newpath
 
-        else:
-          newpath = self.findCycle (search, element, prop, path, seen)
-          if newpath:
-            return newpath
+        # For dictionaries iterate over all items
+        elif isinstance(current, types.DictType):
+            for (key, element) in current.items():
+                prop = (None, "[%s]" % repr(key))
 
-    # a generator keeps has always reference to self, so we have to iterate
-    # it's local namespace
-    elif isinstance (current, types.GeneratorType):
-      for (key, element) in current.gi_frame.f_locals.items ():
-        prop = (None, "[%s]" % key)
-        if element == search:
-          return path + [prop]
+                if element == search:
+                    return path + [prop]
 
-        elif key == search:
-          return path + [(None, "{}")]
+                elif  key == search:
+                    return path + [(None, "{}")]
 
-        else:
-          newpath = self.findCycle (search, element, prop, path, seen)
-          if newpath:
-            return newpath
+                else:
+                    newpath = self.findCycle(search, element, prop, path, seen)
+                    if newpath:
+                        return newpath
 
-    return None
+        # a generator keeps has always reference to self, so we have to iterate
+        # it's local namespace
+        elif isinstance(current, types.GeneratorType):
+            for (key, element) in current.gi_frame.f_locals.items():
+                prop = (None, "[%s]" % key)
+                if element == search:
+                    return path + [prop]
 
+                elif key == search:
+                    return path + [(None, "{}")]
 
-  # ---------------------------------------------------------------------------
-  # Analyze a given reference cycle
-  # ---------------------------------------------------------------------------
+                else:
+                    newpath = self.findCycle(search, element, prop, path, seen)
+                    if newpath:
+                        return newpath
 
-  def analyzeCycle (self, cycle):
-    """
-    Return a generator for iterating a given reference cycle.
+        return None
 
-    @param cycle: None or a sequence of tuples (repr, propertyname)
-    @return: iterator
-    """
 
-    if cycle:
-      for (index, (rep, name)) in enumerate (cycle):
-        if index == 0:
-          yield 'self = %s' % rep
-          lastname = 'self.%s' % name
-        else:
-          if rep is not None:
-            yield '%s = %s' % (lastname, rep)
-            jsymb = '.'
-          else:
-            jsymb = ' '
+    # -------------------------------------------------------------------------
+    # Analyze a given reference cycle
+    # -------------------------------------------------------------------------
 
-          lastname = jsymb.join ([lastname, name])
+    def analyzeCycle(self, cycle):
+        """
+        Return a generator for iterating a given reference cycle.
 
-      yield '%s = self' % lastname
+        @param cycle: None or a sequence of tuples (repr, propertyname)
+        @return: iterator
+        """
 
+        if cycle:
+            for (index, (rep, name)) in enumerate(cycle):
+                if index == 0:
+                    yield 'self = %s' % rep
+                    lastname = 'self.%s' % name
+                else:
+                    if rep is not None:
+                        yield '%s = %s' % (lastname, rep)
+                        jsymb = '.'
+                    else:
+                        jsymb = ' '
+
+                    lastname = jsymb.join([lastname, name])
+
+            yield '%s = self' % lastname

Modified: trunk/gnue-common/src/apps/GDebug.py
===================================================================
--- trunk/gnue-common/src/apps/GDebug.py        2007-09-27 08:57:00 UTC (rev 
9785)
+++ trunk/gnue-common/src/apps/GDebug.py        2007-09-27 12:37:18 UTC (rev 
9786)
@@ -28,7 +28,7 @@
 
 import sys, os
 if '--debug-imports' in sys.argv or os.environ.has_key('GNUE_DEBUG_IMPORT'):
-  from gnue.common.apps import GImportLogger
+    from gnue.common.apps import GImportLogger
 
 import __builtin__
 import inspect
@@ -38,6 +38,7 @@
 import time
 import traceback
 import types
+import logging
 
 from gnue.common.base import log
 
@@ -58,14 +59,14 @@
 # -----------------------------------------------------------------------------
 
 def __noDebug (level, message):
-  return True
-  
+    return True
 
+
 def __noEnter (level = 1):
-  return True
+    return True
 
 def __noLeave (level = 1, *result):
-  return True
+    return True
 
 # Initialize builtin dictionary with placeholders until setDebug is called
 __builtin__.__dict__ ['gDebug'] = __noDebug
@@ -78,121 +79,121 @@
 # -----------------------------------------------------------------------------
 
 def gDebug (level, message, *args):
-  """
-  Write a message to the debug-output. This function is available in the
-  global namespace.
+    """
+    Write a message to the debug-output. This function is available in the
+    global namespace.
 
-  @param level: the debug-level the message will be logged in
-  @param message: the message to be logged
-  @return: Always true so it can be filtered out via assert
-  """
+    @param level: the debug-level the message will be logged in
+    @param message: the message to be logged
+    @return: Always true so it can be filtered out via assert
+    """
 
-  if level in _DEBUG_LEVELS:
-    log.debug_n(inspect.stack()[1][0].f_globals['__name__'], message)
+    if level in _DEBUG_LEVELS:
+        log.debug_n(inspect.stack()[1][0].f_globals['__name__'], message)
 
-  return True
+    return True
 
 # -----------------------------------------------------------------------------
 # Add a function-signature to the debug output
 # -----------------------------------------------------------------------------
 
 def gEnter (level = 1):
-  """
-  Write information about the current function and its parameters to
-  debug-output. This function is available in the global namespace.
+    """
+    Write information about the current function and its parameters to
+    debug-output. This function is available in the global namespace.
 
-  assert gEnter is intended to be called at the begin of a function.
+    assert gEnter is intended to be called at the begin of a function.
 
-  @param level: the debug-level the message will be logged in
-  @return: Always true so it can be filtered out via assert
-  """
+    @param level: the debug-level the message will be logged in
+    @return: Always true so it can be filtered out via assert
+    """
 
-  if not level in _DEBUG_LEVELS:
-    return True
+    if not level in _DEBUG_LEVELS:
+        return True
 
-  # Get the caller's frame
-  frame = sys._getframe (1)
+    # Get the caller's frame
+    frame = sys._getframe (1)
 
-  try:
-    (args, vargs, vkw, flocals) = inspect.getargvalues (frame)
+    try:
+        (args, vargs, vkw, flocals) = inspect.getargvalues (frame)
 
-    # If the function has a 'self' argument we add the class referenced by self
-    # to the name of the function
-    funcName = frame.f_code.co_name
-    if 'self' in args:
-      funcName = "%s.%s" % (flocals ['self'].__class__, funcName)
+        # If the function has a 'self' argument we add the class referenced by
+        # self to the name of the function
+        funcName = frame.f_code.co_name
+        if 'self' in args:
+            funcName = "%s.%s" % (flocals ['self'].__class__, funcName)
 
-    params = []
+        params = []
 
-    # First add all 'normal' arguments
-    params = [repr (flocals [item]) for item in args]
+        # First add all 'normal' arguments
+        params = [repr (flocals [item]) for item in args]
 
-    # Next, add all variable arguments (*arg)
-    if vargs:
-      params.extend ([repr (i) for i in flocals [vargs]])
+        # Next, add all variable arguments (*arg)
+        if vargs:
+            params.extend ([repr (i) for i in flocals [vargs]])
 
-    # and finally add all keyword arguments (**kwarg)
-    if vkw is not None:
-      params.extend (["%s = %s" % (repr (k), repr (v)) \
-                      for (k, v) in flocals [vkw].items ()])
+        # and finally add all keyword arguments (**kwarg)
+        if vkw is not None:
+            params.extend (["%s = %s" % (repr (k), repr (v)) \
+                            for (k, v) in flocals [vkw].items ()])
 
-    message  = "Entering function %s (%s)" % (funcName,
-                                              string.join (params, ", "))
+        message  = "Entering function %s (%s)" % (funcName,
+                                                  string.join (params, ", "))
 
-    log.debug_n(inspect.stack()[1][0].f_globals['__name__'], message)
+        log.debug_n(inspect.stack()[1][0].f_globals['__name__'], message)
 
-  finally:
-    # Make sure to release the reference to the frame object. This keeps
-    # garbage collection doing a fine job :)
-    del frame
-  
-  return True
+    finally:
+        # Make sure to release the reference to the frame object. This keeps
+        # garbage collection doing a fine job :)
+        del frame
 
+    return True
 
+
 # -----------------------------------------------------------------------------
 # Add a line to debug-output describing the end of a function call
 # -----------------------------------------------------------------------------
 
 def gLeave (level = 1, *result):
-  """
-  Write information about the current function and its return value to
-  debug-output. This function is available in the global namespace.
+    """
+    Write information about the current function and its return value to
+    debug-output. This function is available in the global namespace.
 
-  gLeave is intended to be called at the end of a function.
+    gLeave is intended to be called at the end of a function.
 
-  @param level: debug-level to send the message to
-  @param result: the function's result (if any)
-  @return: True
-  """
+    @param level: debug-level to send the message to
+    @param result: the function's result (if any)
+    @return: True
+    """
 
-  if not level in _DEBUG_LEVELS:
-    return True
+    if not level in _DEBUG_LEVELS:
+        return True
 
-  # Get the caller's frame
-  frame = sys._getframe (1)
+    # Get the caller's frame
+    frame = sys._getframe (1)
 
-  try:
-    (args, vargs, vkw, flocals) = inspect.getargvalues (frame)
+    try:
+        (args, vargs, vkw, flocals) = inspect.getargvalues (frame)
 
-    # If the function has a 'self' argument we add the class referenced by self
-    # to the name of the function
-    fName = frame.f_code.co_name
-    hId   = ''
-    if 'self' in args:
-      fName = "%s.%s" % (flocals ['self'].__class__, fName)
-      hId   = repr (hex (id (flocals ['self'])))
+        # If the function has a 'self' argument we add the class referenced by
+        # self to the name of the function
+        fName = frame.f_code.co_name
+        hId   = ''
+        if 'self' in args:
+            fName = "%s.%s" % (flocals ['self'].__class__, fName)
+            hId   = repr (hex (id (flocals ['self'])))
 
-    resStr  = len (result) and ' == %s' % repr (result [0]) or ''
-    message = "Leaving function %s (%s)%s" % (fName, hId, resStr)
+        resStr  = len (result) and ' == %s' % repr (result [0]) or ''
+        message = "Leaving function %s (%s)%s" % (fName, hId, resStr)
 
-    log.debug_n(inspect.stack()[1][0].f_globals['__name__'], message)
+        log.debug_n(inspect.stack()[1][0].f_globals['__name__'], message)
 
-  finally:
-    # Make sure to release the reference to the frame object. This keeps
-    # garbage collection doing a fine job :)
-    del frame
+    finally:
+        # Make sure to release the reference to the frame object. This keeps
+        # garbage collection doing a fine job :)
+        del frame
 
-  return True
+    return True
 
 
 # -----------------------------------------------------------------------------
@@ -200,40 +201,45 @@
 # -----------------------------------------------------------------------------
 
 def setDebug (level, file = None):
-  """
-  Initialize and configure the debug message system
+    """
+    Initialize and configure the debug message system
 
-  @param level: A string with the debug levels to output, e.g. "0-3,5,7"
-  @param file: Filename to output debug messages to (instead of stderr)
-  """
+    @param level: A string with the debug levels to output, e.g. "0-3,5,7"
+    @param file: Filename to output debug messages to (instead of stderr)
+    """
 
-  global _DEBUG_LEVELS, printMesg
+    global _DEBUG_LEVELS, printMesg
 
-  # Find out debug levels
-  levels = []
-  for entry in level.split(','):
-    values=entry.split('-')
-    if len(values) > 1:
-      levels+=range(int(values[0]),int(values[1])+1)
-    else:
-      levels+=[int(entry)]
+    # Find out debug levels
+    levels = []
+    for entry in level.split(','):
+        values=entry.split('-')
+        if len(values) > 1:
+            levels+=range(int(values[0]),int(values[1])+1)
+        else:
+            levels+=[int(entry)]
 
-  _DEBUG_LEVELS=levels
+    _DEBUG_LEVELS=levels
 
-  # If debug levels are given, we must replace the empty placeholder functions
-  # with a function that actually does something
-  if _DEBUG_LEVELS != []:
-    __builtin__.__dict__ ['gDebug'] = gDebug
-    __builtin__.__dict__ ['gEnter'] = gEnter
-    __builtin__.__dict__ ['gLeave'] = gLeave
+    # If debug levels are given, we must replace the empty placeholder
+    # functions with a function that actually does something
+    if _DEBUG_LEVELS != []:
+        __builtin__.__dict__ ['gDebug'] = gDebug
+        __builtin__.__dict__ ['gEnter'] = gEnter
+        __builtin__.__dict__ ['gLeave'] = gLeave
 
+        if file is not None:
+            lgr = logging.getLogger('gnue')
+            lgr.addHandler(logging.FileHandler(file, 'a+'))
+            lgr.setLevel(logging.DEBUG)
 
+
 # -----------------------------------------------------------------------------
 # Deprecated, for compatibility
 # -----------------------------------------------------------------------------
 
 def printMesg (level, message):
-  """
-  This function is deprecated - use gDebug instead
-  """
-  __builtin__.__dict__ ['gDebug'] (level, message)
+    """
+    This function is deprecated - use gDebug instead
+    """
+    __builtin__.__dict__ ['gDebug'] (level, message)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]