commit-gnue
[Top][All Lists]
Advanced

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

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


From: reinhard
Subject: [gnue] r7130 - trunk/gnue-common/src/apps
Date: Tue, 8 Mar 2005 13:47:40 -0600 (CST)

Author: reinhard
Date: 2005-03-08 13:47:39 -0600 (Tue, 08 Mar 2005)
New Revision: 7130

Modified:
   trunk/gnue-common/src/apps/GDebug.py
Log:
Code cleanup, added comments and docstrings.


Modified: trunk/gnue-common/src/apps/GDebug.py
===================================================================
--- trunk/gnue-common/src/apps/GDebug.py        2005-03-08 18:11:26 UTC (rev 
7129)
+++ trunk/gnue-common/src/apps/GDebug.py        2005-03-08 19:47:39 UTC (rev 
7130)
@@ -1,4 +1,4 @@
-# GNU Enterprise Common - Application Services - Debugging support
+# GNU Enterprise Common Library - Application Services - Debugging support
 #
 # Copyright 2001-2005 Free Software Foundation
 #
@@ -19,111 +19,110 @@
 # write to the Free Software Foundation, Inc., 59 Temple Place
 # - Suite 330, Boston, MA 02111-1307, USA.
 #
-# $Id: $
+# $Id$
 
-import string
-import sys
+# Do this at the very start so we lose as little time as possible
 import time
-from traceback import *
+__starttime = time.time ()
+
+import __builtin__
 import inspect
 import os
-import __builtin__
+import string
+import sys
+import traceback
+import types
 
-_fh = sys.__stderr__
-_conttest = 0
-_DEBUG_LEVELS = []
-_DEBUGGER = None
 
-__starttime = time.time ()
+# -----------------------------------------------------------------------------
+# Internal global variables
+# -----------------------------------------------------------------------------
 
+_fh = sys.__stderr__                    # Filehandle to write debug msgs to
+_DEBUG_LEVELS = []                      # Debug levels requested
+_DEBUGGER = None                        # Interactive debugger
+
+
+# =============================================================================
+# Support for redirecting error messages to a file
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# Class to catch the stderr stream
+# -----------------------------------------------------------------------------
+
 class _stderrcatcher:
-    def write(self, str):
-        global _fh, _conttest
-        for ch in str:
-            if (_conttest == 0):
-                _fh.write("DB000: ")
-                _conttest = 1
-            if ( ch != '\n'):
-                _fh.write(ch)
-            else:
-                _fh.write('\n')
-                _conttest = 0
+  """
+  sys.stderr is redirected to this class. It prepends "DB000: " in front of
+  each line and writes everything to the debug file or stderr.
+  """
 
-    def writelines(self, list):
-        for line in list:
-            self.write(str)
+  def __init__ (self, filehandle):
+    self.filehandle = filehandle
 
-def setDebugger(debugger):
-    global _DEBUGGER
-    _DEBUGGER = debugger
+  def write (self, str):
+    lines = string.split (str, "\n")
+    while lines [-1] == "":             # remove empty lines at the end
+      del (lines [-1])
+    self.filehandle.write (string.join (["DB000: " + s for s in lines], "\n"))
+    self.filehandle.write ("\n")
 
-def setDebug (level, file=None):
-  global _DEBUG_LEVELS, printMesg
+  def writelines (self, list):
+    for line in list:
+      self.write (str)
 
-  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
-      
-  if _DEBUG_LEVELS != []:
-    printMesg = _printMesg
-  if (file):
-    fh = open( file, 'w' )
-    catchStderr( fh )
-  else:
-    catchStderr( sys.__stderr__ )
-  __builtin__.__dict__['gDebug'] = printMesg
 
+# -----------------------------------------------------------------------------
+# redirect stderr and all debugging output to the given filehandle
+# -----------------------------------------------------------------------------
 
-def catchStderr(fh):
-    global _fh
-    _fh = fh
-    sys.stderr = _stderrcatcher()
+def catchStderr (filehandle):
 
+  global _fh
+  _fh = filehandle
+  sys.stderr = _stderrcatcher (filehandle)
 
-def handleException(exc_info):
-    #
-    # Not used at present
-    #
-    type, exception, traceback = exc_info
-    if (isinstance(exception, GETrace) ):
-        printMesg( exception.level, exception.message)
-    elif (not isinstance(exception, SystemExit)):
-        strings = format_exception(type, exception, traceback)
-        text = string.join(strings, '')
-        printMesg(0, text)
 
-#
-# We use _noPrintMesg and _printMesg assignment to printMesg
-# to speed things up when debug mode is not being used.  It's
-# assigned in setDebug()
-#
-def _noPrintMesg(level, message, dropToDebugger=0):
+# =============================================================================
+# Support for debugging messages
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# Placeholders for gDebug/gEnter/gLeave if no debug output is desired at all
+# -----------------------------------------------------------------------------
+
+def __noDebug (level, message, dropToDebugger = False):
   pass
 
-def _printMesg (level, message, dropToDebugger = 0):
-    if level in _DEBUG_LEVELS :
-      global _fh, _DEBUGGER
-      if type(message)==type(u''):
-          message=message.encode('utf-8')
-      caller = extract_stack()[-2]
-      try:
-        if caller[0][-3:] == '.py':
-          file = "[%s:%s] " % (string.split(caller[0][:-3],'/')[-1], caller[1])
-        else:
-          file = "[%s:%s] " % (string.split(caller[0],'/')[-1], caller[1])
-      except:
-        file = ""
+def __noEnter (level = 1):
+  pass
 
-      __dumpMessage (level, file, message, dropToDebugger)
+def __noLeave (level = 1, *result):
+  if len (result):
+    return result [0]
 
+# Initialize builtin dictionary with placeholders until setDebug is called
+__builtin__.__dict__ ['gDebug'] = __noDebug
+__builtin__.__dict__ ['gEnter'] = __noEnter
+__builtin__.__dict__ ['gLeave'] = __noLeave
 
+
 # -----------------------------------------------------------------------------
+# Set the debugger
+# -----------------------------------------------------------------------------
+
+def setDebugger (debugger):
+  """
+  This function informs the debug system about the use of Python's interactive
+  debugger. If this is called, subsequent calls to gDebug with the parameter
+  dropToDebugger set will switch the interactive debugger to trace mode.
+  """
+
+  global _DEBUGGER
+  _DEBUGGER = debugger
+
+
+# -----------------------------------------------------------------------------
 # Dump a message to the debug-output
 # -----------------------------------------------------------------------------
 
@@ -135,9 +134,12 @@
   @param level: the debug-level the message will be logged in
   @param filename: the filename the message originated from
   @param message: the message to be logged
-  @param dropToDebugger: if set to True, the message will be dropped to the
-      currently set debugger.
+  @param dropToDebugger: if set to True, Python's interactive debugger will be
+      switched to trace mode. This requires that setDebugger has been called
+      before.
   """
+
+  global _fh, _DEBUGGER
   
   s = time.time () - __starttime
   (m, s) = divmod (s, 60)
@@ -149,15 +151,44 @@
     _fh.write ("DB%03d: %s %s%s%s" % (level, stamp, filename, line, 
os.linesep))
 
   if dropToDebugger and _DEBUGGER:
-    _DEBUGGER.set_trace()
+    _DEBUGGER.set_trace ()
 
 
+# -----------------------------------------------------------------------------
+# Write debug message
+# -----------------------------------------------------------------------------
 
-printMesg = _noPrintMesg
+def gDebug (level, message, dropToDebugger = False):
+  """
+  This function writes a message to the debug-output. It is available in the
+  global namespace.
 
-__builtin__.__dict__['gDebug'] = printMesg
+  @param level: the debug-level the message will be logged in
+  @param message: the message to be logged
+  @param dropToDebugger: if set to True, Python's interactive debugger will be
+      switched to trace mode. This requires that setDebugger has been called
+      before.
+  """
 
+  if level in _DEBUG_LEVELS :
 
+    # Just to be sure...
+    if isinstance (message, types.UnicodeType):
+      message = message.encode ('utf-8')
+
+    # Find out the file from where we were called
+    caller = traceback.extract_stack()[-2]
+    try:
+      if caller[0][-3:] == '.py':
+        file = "[%s:%s] " % (string.split(caller[0][:-3],'/')[-1], caller[1])
+      else:
+        file = "[%s:%s] " % (string.split(caller[0],'/')[-1], caller[1])
+    except:
+      file = ""
+
+    __dumpMessage (level, file, message, dropToDebugger)
+
+
 # -----------------------------------------------------------------------------
 # Add a function-signature to the debug output
 # -----------------------------------------------------------------------------
@@ -165,7 +196,7 @@
 def gEnter (level = 1):
   """
   This function adds another line to the debug-output, describing the caller's
-  function with all it's arguments.
+  function with all it's arguments. It is available in the global namespace.
 
   @param level: the debug-level the message will be logged in
   """
@@ -227,7 +258,8 @@
 def gLeave (level = 1, *result):
   """
   This function adds a line to the debug-output describing the end of a
-  function call, optionally containing the function's result.
+  function call, optionally containing the function's result. It is available
+  in the global namespace.
 
   @param level: debug-level to send the message to
   @param result: the function's result (if any)
@@ -276,12 +308,61 @@
     return retVal
 
 
+# -----------------------------------------------------------------------------
+# Set debug levels to use and initialize debugging
+# -----------------------------------------------------------------------------
 
+def setDebug (level, file = None):
+  """
+  This function initializes and configures the debug message system.
 
-__builtin__.__dict__ ['gEnter'] = gEnter
-__builtin__.__dict__ ['gLeave'] = gLeave
+  @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
 
+  # 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
+      
+  # 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
+
+  # Redirect debugging and error output to a file if requested
+  if (file):
+    catchStderr (open (file, 'w'))
+  else:
+    catchStderr (sys.__stderr__)
+
+
+# -----------------------------------------------------------------------------
+# Deprecated, for compatibility
+# -----------------------------------------------------------------------------
+
+def printMesg (level, message, dropToDebugger = False):
+  """
+  This function is deprecated - use gDebug instead
+  """
+  __builtin__.__dict__ ['gDebug'] (level, message, dropToDebugger)
+
+
+# -----------------------------------------------------------------------------
+# FIXME: is it save to remove the following stuff?
+# -----------------------------------------------------------------------------
+
 class GETrace(Exception):
     #
     #Exception class representing a debug message
@@ -291,3 +372,15 @@
         Exception.__init__(self)
         self.level = level
         self.message = message
+
+def handleException(exc_info):
+    #
+    # Not used at present
+    #
+    type, exception, traceback = exc_info
+    if (isinstance(exception, GETrace) ):
+        printMesg( exception.level, exception.message)
+    elif (not isinstance(exception, SystemExit)):
+        strings = traceback.format_exception(type, exception, traceback)
+        text = string.join(strings, '')
+        printMesg(0, text)





reply via email to

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