[Top][All Lists]
[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)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r9786 - trunk/gnue-common/src/apps,
johannes <=