commit-gnue
[Top][All Lists]
Advanced

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

[gnue] r7058 - in trunk/gnue-appserver/src: . classrep language


From: johannes
Subject: [gnue] r7058 - in trunk/gnue-appserver/src: . classrep language
Date: Wed, 23 Feb 2005 10:54:25 -0600 (CST)

Author: johannes
Date: 2005-02-23 10:54:24 -0600 (Wed, 23 Feb 2005)
New Revision: 7058

Modified:
   trunk/gnue-appserver/src/classrep/Base.py
   trunk/gnue-appserver/src/data.py
   trunk/gnue-appserver/src/geasInstance.py
   trunk/gnue-appserver/src/geasList.py
   trunk/gnue-appserver/src/geasRpcServer.py
   trunk/gnue-appserver/src/geasSession.py
   trunk/gnue-appserver/src/language/Object.py
   trunk/gnue-appserver/src/language/ObjectList.py
   trunk/gnue-appserver/src/language/Session.py
Log:
Some improvements and fixes of memory leaks


Modified: trunk/gnue-appserver/src/classrep/Base.py
===================================================================
--- trunk/gnue-appserver/src/classrep/Base.py   2005-02-23 16:53:58 UTC (rev 
7057)
+++ trunk/gnue-appserver/src/classrep/Base.py   2005-02-23 16:54:24 UTC (rev 
7058)
@@ -25,7 +25,6 @@
 import helpers
 from gnue import appserver
 from gnue.common.apps import errors
-from gnue.appserver.language.Object import Object
 
 # =============================================================================
 # Exceptions
@@ -390,7 +389,7 @@
     """
 
     if self.__object is None:
-      self.__object = Object (self._session, self.classname, self.gnue_id)
+      self.__object = self._session.get (self.classname, self.gnue_id)
 
     result = self.__object
 

Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py    2005-02-23 16:53:58 UTC (rev 7057)
+++ trunk/gnue-appserver/src/data.py    2005-02-23 16:54:24 UTC (rev 7058)
@@ -528,9 +528,17 @@
 def _createResultSet (connections, database, content, conditions, order):
 
   datasource = _createDatasource (connections, database, content, order)
-  return datasource.createResultSet (_conditionTree (conditions))
+  condition  = _conditionTree (conditions)
+  try:
+    return datasource.createResultSet (condition)
 
+  finally:
+    # If we have a condition, make sure to have all it's elements collectable
+    # by the garbage collector
+    if condition is not None:
+      condition.breakReferences ()
 
+
 # -----------------------------------------------------------------------------
 # Create a condition tree of a given condition
 # -----------------------------------------------------------------------------

Modified: trunk/gnue-appserver/src/geasInstance.py
===================================================================
--- trunk/gnue-appserver/src/geasInstance.py    2005-02-23 16:53:58 UTC (rev 
7057)
+++ trunk/gnue-appserver/src/geasInstance.py    2005-02-23 16:54:24 UTC (rev 
7058)
@@ -320,47 +320,52 @@
       for name in [x.encode ('ascii') for x in params.keys ()]:
         paramDef = proceduredef.parameters [name]
         parameters [name] = self.__convert (params [name], paramDef,
-                                            ParameterValueError)
+                                              ParameterValueError)
 
     engine = getLanguageAdapter (proceduredef.gnue_language)
 
     cx = engine.createNewContext ()
 
-    # describe the context
-    cx.shortname   = '%s.%s' % (self.__classdef.fullName, 
proceduredef.fullName)
-    cx.description = proceduredef.gnue_comment
+    try:
+      # describe the context
+      cx.shortname = '%s.%s' % (self.__classdef.fullName, 
proceduredef.fullName)
+      cx.description = proceduredef.gnue_comment
 
-    # the object itself and the session
-    cx.bindObject ('self', obj)
-    cx.bindObject ('session', sess)
+      # the object itself and the session
+      cx.bindObject ('self', obj)
+      cx.bindObject ('session', sess)
 
-    if namespace is not None:
-      for (key, value) in namespace.items ():
-        cx.bindObject (key, value)
+      if namespace is not None:
+        for (key, value) in namespace.items ():
+          cx.bindObject (key, value)
 
-    # language interface, session functions
-    cx.bindFunction ('find',       sess.find)
-    cx.bindFunction ('setcontext', sess.setcontext)
-    cx.bindFunction ('new',        sess.new)
-    cx.bindFunction ('message',    sess.message)
+      # language interface, session functions
+      cx.bindFunction ('find',       sess.find)
+      cx.bindFunction ('setcontext', sess.setcontext)
+      cx.bindFunction ('new',        sess.new)
+      cx.bindFunction ('message',    sess.message)
 
-    # direct access to RPC API func.
-    cx.bindFunction ('direct_request', self.__session.request)
-    cx.bindFunction ('direct_fetch',   self.__session.fetch)
-    cx.bindFunction ('direct_load',    self.__session.load)
-    cx.bindFunction ('direct_store',   self.__session.store)
-    cx.bindFunction ('direct_call',    self.__session.call)
+      # direct access to RPC API func.
+      cx.bindFunction ('direct_request', self.__session.request)
+      cx.bindFunction ('direct_fetch',   self.__session.fetch)
+      cx.bindFunction ('direct_load',    self.__session.load)
+      cx.bindFunction ('direct_store',   self.__session.store)
+      cx.bindFunction ('direct_call',    self.__session.call)
 
-    # set context for the procedure
-    sess.setcontext (proceduredef.module.gnue_name)
+      # set context for the procedure
+      sess.setcontext (proceduredef.module.gnue_name)
 
-    method = cx.buildFunction (proceduredef.gnue_name, proceduredef.gnue_code,
-                               parameters)
-    result = method (**parameters)
-    if (proceduredef.gnue_type is None) != (result is None):
-      if result is not None or not proceduredef.gnue_nullable:
-        raise ResultTypeError, (proceduredef.fullName, proceduredef.gnue_type,
-                                result)
+      method = cx.buildFunction (proceduredef.gnue_name, 
proceduredef.gnue_code,
+                                 parameters)
+      result = method (**parameters)
+      if (proceduredef.gnue_type is None) != (result is None):
+        if result is not None or not proceduredef.gnue_nullable:
+          raise ResultTypeError, (proceduredef.fullName, 
proceduredef.gnue_type,
+                                  result)
+    finally:
+      method._context = None
+      cx.release ()
+
     return result
 
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-appserver/src/geasList.py
===================================================================
--- trunk/gnue-appserver/src/geasList.py        2005-02-23 16:53:58 UTC (rev 
7057)
+++ trunk/gnue-appserver/src/geasList.py        2005-02-23 16:54:24 UTC (rev 
7058)
@@ -281,7 +281,11 @@
     self.__instances  = []
     self.__unsorted   = []
 
+    if self.__condition is not None:
+      self.__condition.breakReferences ()
+      self.__condition = None
 
+
   # ---------------------------------------------------------------------------
   # Evaluate an exist condition for an instance
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-appserver/src/geasRpcServer.py
===================================================================
--- trunk/gnue-appserver/src/geasRpcServer.py   2005-02-23 16:53:58 UTC (rev 
7057)
+++ trunk/gnue-appserver/src/geasRpcServer.py   2005-02-23 16:54:24 UTC (rev 
7058)
@@ -25,6 +25,7 @@
 import os
 import sys
 import signal
+import gc
 
 import gnue.paths
 
@@ -38,6 +39,9 @@
 from gnue.appserver import geasSessionManager
 from gnue.appserver import geasConfiguration
 
+
+_GC_DEBUG = True   # Set this to True to activate garbage collection debugging
+
 # =============================================================================
 # RPC application class
 # =============================================================================
@@ -215,8 +219,13 @@
     # Daemonize (if appropriate)
     GServerApp.run (self)
 
+    if _GC_DEBUG:
+      gc.enable ()
+      gc.set_debug (gc.DEBUG_LEAK)
+
     try:
       signal.signal (signal.SIGHUP, self._hangupServer)
+      signal.signal (signal.SIGUSR1, self._gcCheck)
       
     except AttributeError:
       pass
@@ -262,7 +271,51 @@
     if self.sm:
       self.sm.updateRepository ()
 
+  # ---------------------------------------------------------------------------
+  # Check the current state of the garbage collection
+  # ---------------------------------------------------------------------------
 
+  def _gcCheck (self, signal, frame):
+    """
+    This function starts a garbage collection, and lists all unreachable
+    objects not collected.
+    """
+
+    if not _GC_DEBUG:
+      print o(u_("Debugging garbage collection not activated."))
+      return
+
+    r = gc.collect ()
+
+    gf = open ('garbage.log', 'w')
+
+    print "=" * 70
+    print "GARBAGE:", r, ":"
+    gf.write ('GARBAGE: %d\n' % r)
+
+    n = 0
+    for x in gc.garbage:
+      n += 1
+      s = str(x)
+      if len(s) > 75: s = s[:75]
+      print type(x),"\n  ", s
+      gf.write ("%s: %s\n" % (type (x), repr (x)))
+
+      from gnue.common.datasources import GConditions
+      if isinstance (x, GConditions.GCondition):
+        gf.write ("Referrer of: %s\n" % x)
+        for y in gc.get_referrers (x):
+          gf.write ("--> %s: %s\n" % (type (y), y))
+
+        gf.write ("%s\n" % ("-" * 70))
+
+    gf.close ()
+    del gc.garbage [:]
+
+    print "-" * 70
+    print "GC dump done", n
+
+
   # ---------------------------------------------------------------------------
   # Self test
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-appserver/src/geasSession.py
===================================================================
--- trunk/gnue-appserver/src/geasSession.py     2005-02-23 16:53:58 UTC (rev 
7057)
+++ trunk/gnue-appserver/src/geasSession.py     2005-02-23 16:54:24 UTC (rev 
7058)
@@ -265,10 +265,10 @@
     if self.locale:
       i18n.setcurrentlocale (self.locale)
 
-    for item in self.__lists.values ():
-      item.close ()
+    for key in self.__lists.keys ():
+      self.__lists [key].close ()
+      del self.__lists [key]
 
-    self.__lists          = {}
     self.__dirtyInstances = {}
     self.filters          = {}
 
@@ -728,6 +728,8 @@
       else:
         asTrees.append (tree)
 
+    cTree.breakReferences ()
+
     # now create the final trees
     dbCond = None
     asCond = None

Modified: trunk/gnue-appserver/src/language/Object.py
===================================================================
--- trunk/gnue-appserver/src/language/Object.py 2005-02-23 16:53:58 UTC (rev 
7057)
+++ trunk/gnue-appserver/src/language/Object.py 2005-02-23 16:54:24 UTC (rev 
7058)
@@ -49,18 +49,18 @@
   # Constructor
   # -------------------------------------------------------------------------
 
-  def __init__ (self, session, classname, objectId = None):
+  def __init__ (self, session, classname, objectId = None, definition = None):
     # we won't trigger __setattr__ here ...
-    self.__dict__ ['objectId']          = objectId
-    self.__dict__ ['_Object__session']  = session
-    self.__dict__ ['_Object__class']    = classname
-    self.__dict__ ['_Object__sm']       = session.getSessionManager ()
-    self.__dict__ ['_Object__sid']      = session.getSessionId ()
-    self.__dict__ ['_Object__datatype'] = {}
+    self.__dict__ ['objectId']            = objectId
+    self.__dict__ ['_Object__session']    = session
+    self.__dict__ ['_Object__class']      = classname
+    self.__dict__ ['_Object__sid']        = session.getSessionId ()
+    self.__dict__ ['_Object__definition'] = definition or {}
 
     if self.objectId is None:
       # Create new object
-      res = self.__sm.store (self.__sid, self.__class, [None], [], [[]])
+      sm  = session.getSessionManager ()
+      res = sm.store (self.__sid, self.__class, [None], [], [[]])
       self.objectId = res [0]
 
     self.__dict__ ['gnue_id'] = self.objectId
@@ -75,20 +75,20 @@
     gBeginFunc (6)
 
     name = self.__session.qualify (attr)
+    key  = name.lower ()
 
-    if name == "gnue_id":
+    if key == "gnue_id":
       result = self.objectId
       gEndFunc (6, result)
       return result
 
+    sm = self.__session.getSessionManager ()
+
     try:
-      # TODO: move the datatype-dictionary into the session, but keep a
-      # per-instance pointer to it. This way we could reduce the amount of
-      # loads to a per-class/per-session minimum
-      if not self.__datatype.has_key (name):
-        self.__datatype [name] = self.__sm.load (self.__sid, self.__class,
-                                                 [''], [name]) [0][0]
-      datatype = self.__datatype [name]
+      if not self.__definition.has_key (key):
+        self.__definition [key] = sm.load (self.__sid, self.__class, [''],
+                                           [name]) [0][0]
+      datatype = self.__definition [key]
 
     except KeyError:
       raise MemberNotFoundError, (self.__class, name)
@@ -97,16 +97,18 @@
       result = Procedure (self.__session, self.objectId, self.__class, name)
 
     else:
-      res = self.__sm.load (self.__sid, self.__class, [self.objectId], [name])
+      res = sm.load (self.__sid, self.__class, [self.objectId], [name])
       value = res [0][0]
 
       # Convert reference fields to object references
       if '_' in datatype and value is not None:
-        result = Object (self.__session, datatype, value)
+        cDef   = self.__session.getClassDefinition (datatype)
+        result = Object (self.__session, datatype, value, cDef)
 
       elif value is None:
         if '_' in datatype:
-          result = NullObject (self.__session, datatype)
+          cDef   = self.__session.getClassDefinition (datatype)
+          result = NullObject (self.__session, datatype, cDef)
         else:
           result = None
 
@@ -114,6 +116,7 @@
         result = value
 
     gEndFunc (6, result)
+
     return result
 
 
@@ -133,14 +136,16 @@
       elif attr == 'gnue_id':
         self.__dict__ ['objectId'] = value
 
-    if not self.__dict__.has_key (attr) or attr == 'gnue_id':
+    if not self.__dict__.has_key (attr) or attr.lower () == 'gnue_id':
       name = self.__session.qualify (attr)
+      key  = name.lower ()
+      sm   = self.__session.getSessionManager ()
 
       try:
-        if not self.__datatype.has_key (name):
-          self.__datatype [name] = self.__sm.load (self.__sid, self.__class,
+        if not self.__definition.has_key (key):
+          self.__definition [key] = sm.load (self.__sid, self.__class,
                                                    [''], [name]) [0][0]
-        datatype = self.__datatype [name]
+        datatype = self.__definition [key]
 
       except KeyError:
         raise MemberNotFoundError, (self.__class, name)
@@ -154,8 +159,7 @@
       else:
         __value = value
 
-      self.__sm.store (self.__sid, self.__class, [self.objectId], [name],
-                       [[__value]])
+      sm.store (self.__sid, self.__class, [self.objectId], [name], [[__value]])
 
     gEndFunc (6, hasResult = False)
 
@@ -214,7 +218,8 @@
 
     gBeginFunc (6)
 
-    self.__sm.delete (self.__sid, self.__class, [self.objectId])
+    sm = self.__session.getSessionManager ()
+    sm.delete (self.__sid, self.__class, [self.objectId])
     self.objectId = None
 
     gEndFunc (6, hasResult = False)
@@ -231,13 +236,12 @@
   # Constructor
   # ---------------------------------------------------------------------------
 
-  def __init__ (self, session, classname):
+  def __init__ (self, session, classname, definition):
 
-    self.__session  = session
-    self.__class    = classname
-    self.__sm       = session.getSessionManager ()
-    self.__sid      = session.getSessionId ()
-    self.__datatype = {}
+    self.__session    = session
+    self.__class      = classname
+    self.__sid        = session.getSessionId ()
+    self.__definition = definition
 
 
   # ---------------------------------------------------------------------------
@@ -257,11 +261,15 @@
     gBeginFunc (6)
 
     name = self.__session.qualify (attr)
-    if not self.__datatype.has_key (name):
-      self.__datatype [name] = self.__sm.load (self.__sid, self.__class,
+    key  = name.lower ()
+    if not self.__definition.has_key (key):
+      sm = self.__session.getSessionManager ()
+      self.__definition [key] = sm.load (self.__sid, self.__class,
                                                [''], [name]) [0][0]
-    if '_' in self.__datatype [name]:
-      self.__class = self.__datatype [name]
+    if '_' in self.__definition [key]:
+      self.__class      = self.__definition [key]
+      self.__definition = self.__session.getClassDefinition (self.__class)
+
       result = self
     else:
       result = None

Modified: trunk/gnue-appserver/src/language/ObjectList.py
===================================================================
--- trunk/gnue-appserver/src/language/ObjectList.py     2005-02-23 16:53:58 UTC 
(rev 7057)
+++ trunk/gnue-appserver/src/language/ObjectList.py     2005-02-23 16:54:24 UTC 
(rev 7058)
@@ -34,11 +34,12 @@
   # -------------------------------------------------------------------------
   # Constructor
   # -------------------------------------------------------------------------
-  def __init__ (self, session, classname, cond, sort, properties):
+  def __init__ (self, session, classname, cond, sort, properties, definition):
     self.classname   = classname
     self.conditions  = cond
     self.sortOrder   = sort
     self.properties  = properties
+    self.definition  = definition
 
     self.__session   = session
     self.__list      = []
@@ -117,7 +118,7 @@
 
     rset = sm.fetch (sid, self.__list_id, len (self.__list), 
self.__cacheStep,0)
     for row in rset:
-      obj = Object (self.__session, self.classname, row [0])
+      obj = Object (self.__session, self.classname, row [0], self.definition)
       self.__list.append (obj)
 
     # We double the cache-size for the next call to fetch (). This boosts

Modified: trunk/gnue-appserver/src/language/Session.py
===================================================================
--- trunk/gnue-appserver/src/language/Session.py        2005-02-23 16:53:58 UTC 
(rev 7057)
+++ trunk/gnue-appserver/src/language/Session.py        2005-02-23 16:54:24 UTC 
(rev 7058)
@@ -42,59 +42,134 @@
     msg = u_("Message '%s' not found") % message
     errors.ApplicationError.__init__ (self, msg)
 
+
 # ===========================================================================
 # CLASS session: implement a session of the language interface
 # ===========================================================================
+
 class Session:
 
   # -------------------------------------------------------------------------
   # Constructor
   # -------------------------------------------------------------------------
+
   def __init__ (self, sessionManager, sessionId, params = {}):
+    """
+    Create an instance of a language interface session
+
+    @param sessionManager: the session manager to be used
+    @param sessionId: id of the session encapsulated by the instance
+    @param params: dictionary of session parameters
+    """
+
     self.__sm         = sessionManager
     self.__session_id = sessionId
     self.__context    = None
     self.parameters   = params
+    self.classdefs    = {}
 
 
   # -------------------------------------------------------------------------
   # Get the session's sessionManager
   # -------------------------------------------------------------------------
+
   def getSessionManager (self):
+    """
+    This function returns the session manager this session is bound to
+    @return: session manager instance
+    """
+
     return self.__sm
 
+
   # -------------------------------------------------------------------------
   # Get the session's id
   # -------------------------------------------------------------------------
+
   def getSessionId (self):
+    """
+    This function returns the id of this session in the session manager.
+    @return: id of the session
+    """
+
     return self.__session_id
 
+
   # -------------------------------------------------------------------------
+  # Get or created the class definition dictionary for a given class
+  # -------------------------------------------------------------------------
+
+  def getClassDefinition (self, classname):
+    """
+    This function returns the class definition dictionary for a given
+    classname. If it does not exist it will be created. Such a dictionary
+    contains the datatype per class-element (property/procedure).
+
+    @param classname: name of the class to return a definition dictionary for
+    @return: class definition dictionary for the requested class
+    """
+
+    return {}
+
+    key = classname.lower ()
+    if not self.classdefs.has_key (key):
+      self.classdefs [key] = {}
+
+    return self.classdefs [key]
+
+
+  # -------------------------------------------------------------------------
   # Set the default context
   # -------------------------------------------------------------------------
+
   def setcontext (self, context):
+    """
+    This function specifies the current context of the session. All subsequent
+    calls to qualify using an unqualified name will be extended with this
+    context.
+
+    @param context: context to set
+    """
+
     self.__context = context
 
+
   # -------------------------------------------------------------------------
   # Ensure the given name is fully qualified using the current context
   # -------------------------------------------------------------------------
+
   def qualify (self, name):
+    """
+    This function returns a fully qualified named. If the given name isn't
+    already qualified the current context will be added. If no such context is
+    available a NoContextError exception will be raised.
 
+    @param name: name to be returned as fully qulified name
+    @return: fully qualified name
+    """
+
+    # Although the 'in'-operation is an expensive operation, it's still faster
+    # than using string.find () here
     if '_' in name:
-      result = name
+      return name
+
     else:
       if self.__context is None:
         raise NoContextError (name)
       else:
-        result = "%s_%s" % (self.__context, name)
+        # This looks a bit ugly but it's faster than using "%s_%s" % (...)
+        return self.__context + "_" + name
 
-    return result
 
 
   # -------------------------------------------------------------------------
   # Close the session 
   # -------------------------------------------------------------------------
+
   def close (self):
+    """
+    This function closes the encapsulated session on the session manager.
+    """
 
     gBeginFunc (6)
 
@@ -108,7 +183,11 @@
   # -------------------------------------------------------------------------
   # Commit the current transaction
   # -------------------------------------------------------------------------
+
   def commit (self):
+    """
+    This function commits all pending changes of the session.
+    """
 
     gBeginFunc (6)
 
@@ -121,7 +200,11 @@
   # -------------------------------------------------------------------------
   # Revoke the current transaction
   # -------------------------------------------------------------------------
+
   def rollback (self):
+    """
+    This function revokes all pending changes of the current session.
+    """
 
     gBeginFunc (6)
 
@@ -130,39 +213,111 @@
 
     gEndFunc (6, hasResult = False)
 
+
   # -------------------------------------------------------------------------
   # Return a collection of 'classname' matching the given arguments
   # -------------------------------------------------------------------------
+
   def find (self, classname, conditions = None,
             sortorder = [('gnue_id', False)], properties = []):
+    """
+    This function returns a new collection of classes matching the given
+    conditions, having a given order and using a given set of 'preloaded'
+    properties.
 
+    @param classname: name of the class to be fetched
+    @param conditions: condition which must be matched. This could be a
+        dictionary, a sequence in prefix notation or a GCondition tree
+    @param sortorder: order to sort the instances. This is a sequence of
+        sort-elements where such an element could be a name, a tuple/triple or 
a
+        dictionary with the keys 'name, descending, ignorecase'
+    @param properties: sequence of propertynames to be loaded for each instance
+        in the collection
+
+    @return: ObjectList instance with all matching instances of the given class
+    """
+
     gBeginFunc (6)
-    result = ObjectList (self, self.qualify (classname), conditions, sortorder,
-                       properties)
+
+    name = self.qualify (classname)
+    cdef = self.getClassDefinition (name)
+
+    result = ObjectList (self, name, conditions, sortorder, properties, cdef)
+
     gEndFunc (6, result)
+
     return result
 
+
   # -------------------------------------------------------------------------
   # Create a new instance of classname
   # -------------------------------------------------------------------------
+
   def new (self, classname):
+    """
+    This function creates a new instance of a given class.
+    @param classname: name of the class to create an instance of
 
+    @return: Object instance of the requested class
+    """
+
     gBeginFunc (6)
-    result = Object (self, self.qualify (classname))
+
+    result = self.get (classname)
+
     gEndFunc (6, result)
+
     return result
 
 
   # -------------------------------------------------------------------------
+  # Get an instance of a class having a given objectId
+  # -------------------------------------------------------------------------
+
+  def get (self, classname, objectId = None):
+    """
+    This function returns an instance of a given class having the specified
+    objectId. If the objectId is None, a new one will be generated.
+
+    @param classname: name of the class to create an instance for
+    @param objectId: gnue_id of the instance or None to create a new one
+
+    @return: Object instance of the requested class
+    """
+
+    gBeginFunc (6)
+
+    name = self.qualify (classname)
+    cDef = self.getClassDefinition (name)
+
+    result = Object (self, name, objectId, cDef)
+
+    gEndFunc (6, result)
+
+    return result
+
+
+  # -------------------------------------------------------------------------
   # Get a message from the message catalogue
   # -------------------------------------------------------------------------
 
   def message (self, messageName, *args):
+    """
+    This function returns a message from the message catalogue using the given
+    arguments. If the session has a '_language' parameter this language(s) are
+    treated with higher priority.
 
+    @param messageName: name of the message to be returned
+    @param args: variable arguments applied to the messaged
+
+    @return: the message as unicode string
+    """
+
     gBeginFunc (6)
 
     languages = ['C']
     current = self.parameters.get ('_language', 'C')
+
     if '_' in current:
       add = current.split ('_') [0]
       if not add in languages:





reply via email to

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