commit-gnue
[Top][All Lists]
Advanced

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

[gnue] r8415 - in trunk/gnue-common/src/logic: . adapters


From: reinhard
Subject: [gnue] r8415 - in trunk/gnue-common/src/logic: . adapters
Date: Tue, 18 Apr 2006 10:59:20 -0500 (CDT)

Author: reinhard
Date: 2006-04-18 10:59:19 -0500 (Tue, 18 Apr 2006)
New Revision: 8415

Modified:
   trunk/gnue-common/src/logic/adapters/Base.py
   trunk/gnue-common/src/logic/adapters/__init__.py
   trunk/gnue-common/src/logic/adapters/ecmascript.py
   trunk/gnue-common/src/logic/adapters/python.py
   trunk/gnue-common/src/logic/language.py
Log:
It's just a spring-clean for the may queen.


Modified: trunk/gnue-common/src/logic/adapters/Base.py
===================================================================
--- trunk/gnue-common/src/logic/adapters/Base.py        2006-04-18 13:04:25 UTC 
(rev 8414)
+++ trunk/gnue-common/src/logic/adapters/Base.py        2006-04-18 15:59:19 UTC 
(rev 8415)
@@ -1,4 +1,7 @@
+# GNU Enterprise Common Library - Base classes for language adapter plugins
 #
+# Copyright 2000-2006 Free Software Foundation
+#
 # This file is part of GNU Enterprise.
 #
 # GNU Enterprise is free software; you can redistribute it
@@ -16,205 +19,235 @@
 # write to the Free Software Foundation, Inc., 59 Temple Place
 # - Suite 330, Boston, MA 02111-1307, USA.
 #
-# Copyright 2001-2006 Free Software Foundation
+# $Id$
 #
-# $Id$
+# We use * and ** magic on purpose
+# pylint: disable-msg=W0142
 
+"""
+Base classes for language adapter plugins.
+
+Language adapters are python modules that allow external, user provided code in
+a given language to be executed within Python. In GNU Enterprise, language
+adapters are used to execute L{actions}, L{GTrigger} triggers, and server side
+methods in GNUe-AppServer.
+
+Each language adapter implements this feature for a specific language. An
+implementation of a language adapter consists of three classes that are derived
+from the three base classes in this module.
+"""
+
 import types
 
 from gnue.common.logic.language import ImplementationError, AbortRequest
-from gnue.common.logic.NamespaceCore import NamespaceElement
 
+__all__ = ['LanguageAdapter', 'ExecutionContext', 'Function']
 
+
 # =============================================================================
 # Base class for LanguageAdapters
 # =============================================================================
 
-class BaseLanguageAdapter:
-  """
-  This is the base class for language adapters. A language adapter has to
-  provide a public function for creation of new execution contexts.
-  """
+class LanguageAdapter:
+    """
+    Base class for language adapters.
 
-  # ---------------------------------------------------------------------------
-  # Create and return a new execution context
-  # ---------------------------------------------------------------------------
-
-  def createNewContext (self):
+    Descendants must implement the L{createNewContext} function.
     """
-    Abstract: Create a new execution context.
-    """
-    raise ImplementationError, (self.__class__, 'createNewContext ()')
 
+    # -------------------------------------------------------------------------
+    # Create and return a new execution context
+    # -------------------------------------------------------------------------
 
+    def createNewContext(self):
+        """
+        Create a new execution context in which user provided code can run.
 
+        @return: Execution context object.
+        @rtype: L{ExecutionContext}
+        """
+        raise ImplementationError, (self.__class__, 'createNewContext()')
+
+
 # =============================================================================
 # Base class for execution contexts
 # =============================================================================
 
-class BaseExecutionContext:
-  """
-  An execution context provides an environment where code can be transformed
-  and executed.
-  """
+class ExecutionContext:
+    """
+    An environment in which user defined code can be compiled and executed.
+    """
 
-  # ---------------------------------------------------------------------------
-  # Constructor
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Constructor
+    # -------------------------------------------------------------------------
 
-  def __init__ (self, runtime = None):
-    self._runtime    = runtime
-    self.shortname   = "unknown_executioncontext"
-    self.description = "There is no description provided"
+    def __init__(self):
 
+        self.shortname   = "unknown_executioncontext"
+        self.description = "There is no description provided"
 
-  # ---------------------------------------------------------------------------
-  # Merge a namespace into the execution contexts namespace
-  # ---------------------------------------------------------------------------
 
-  def defineNamespace (self, addNS, asGlobal = False):
-    """
-    Merge the given namespace @addNS into the execution context. This function
-    is doing this using bindFunction () and bindObject () depeding on the
-    namespace elements type.
-    """
-    for (name, value) in addNS.items ():
-      if name is not None:
-        if isinstance (value, types.MethodType):
-          self.bindFunction (name, value, asGlobal)
+    # -------------------------------------------------------------------------
+    # Define the namespace
+    # -------------------------------------------------------------------------
 
-        if isinstance (value, NamespaceElement):
-          self.bindObject (name, value, asGlobal)
+    def defineNamespace(self, addNS, asGlobal = False):
+        """
+        Define the namespace for this execution context.
 
+        Merge the given namespace into the execution context. This function
+        is doing this using L{bindFunction} and L{bindObject} methods depeding
+        on the namespace elements type.
+        """
+        for (name, value) in addNS.items():
+            if name is not None:
+                if isinstance(value, types.MethodType):
+                    self.bindFunction(name, value, asGlobal)
+                else:
+                    self.bindObject(name, value, asGlobal)
 
-  # ---------------------------------------------------------------------------
-  # Bind an object into the contexts namespace using the given name
-  # ---------------------------------------------------------------------------
 
-  def bindObject (self, name, aObject, asGlobal = False):
-    """
-    Abstract: A descendant overrides this function to bind a given object into
-    the local or global namespace.
-    """
-    raise ImplementationError, (self.__class__, 'bindObject ()')
+    # -------------------------------------------------------------------------
+    # Bind an object into the contexts namespace using the given name
+    # -------------------------------------------------------------------------
 
+    def bindObject(self, name, aObject, asGlobal = False):
+        """
+        Bind an object into the namespace.
 
-  # ---------------------------------------------------------------------------
-  # Bind a function into the contexts namespace using the given name
-  # ---------------------------------------------------------------------------
+        A descendant overrides this function to bind a given object into the
+        local or global namespace.
+        """
+        raise ImplementationError, (self.__class__, 'bindObject()')
 
-  def bindFunction (self, name, aFunction, asGlobal = False):
-    """
-    Abstract: A descendant overrides this function to bind a given function 
-    with into the local or global namespace.
-    """
-    raise ImplementationError, (self.__class__, 'bindFunction ()')
 
+    # -------------------------------------------------------------------------
+    # Bind a function into the contexts namespace using the given name
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Bind an element into the contexts builtin-namespace
-  # ---------------------------------------------------------------------------
+    def bindFunction(self, name, aFunction, asGlobal = False):
+        """
+        Bind a function into the namespace.
 
-  def bindBuiltin (self, name, anElement):
-    """
-    Abstract: A descendant overrides this function to bind a given element into
-    the builtin-namespace of the context.
-    """
+        A descendant overrides this function to bind a given function into the
+        local or global namespace.
+        """
+        raise ImplementationError, (self.__class__, 'bindFunction()')
 
-    raise ImplementationError, (self.__class__, 'bindBuiltin ()')
 
+    # -------------------------------------------------------------------------
+    # Bind an element into the contexts builtin-namespace
+    # -------------------------------------------------------------------------
 
-  # ---------------------------------------------------------------------------
-  # Create a new function instance 
-  # ---------------------------------------------------------------------------
+    def bindBuiltin(self, name, anElement):
+        """
+        Bind a builtin function into the namespace.
 
-  def buildFunction (self, name, code, parameters = {}):
-    """
-    Abstract: Create a new instance of a virtual function and prepare it's 
-    code.
-    """
-    raise ImplementationError, (self.__class__, 'buildFunction ()')
+        A descendant overrides this function to bind a given element into the
+        builtin-namespace of the context.
+        """
+        raise ImplementationError, (self.__class__, 'bindBuiltin()')
 
 
-  # ---------------------------------------------------------------------------
-  # Release an execution context
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Create a new function instance 
+    # -------------------------------------------------------------------------
 
-  def release (self):
-    """
-    Release an execution context: remove references in the namespace and the
-    like.
-    """
+    def buildFunction(self, name, code, parameters = None):
+        """
+        Create a new instance of a L{Function} and compile its code.
 
-    pass
+        Descendants must implement this.
+        """
+        raise ImplementationError, (self.__class__, 'buildFunction()')
 
 
+    # -------------------------------------------------------------------------
+    # Release an execution context
+    # -------------------------------------------------------------------------
 
+    def release (self):
+        """
+        Release an execution context: remove references in the namespace and
+        the like.
+        """
+        pass
+
+
 # =============================================================================
-# Base class of a virtual function
+# Base class of a function
 # =============================================================================
 
-class VirtualFunction:
-  """
-  This is the base class of virtual functions. Such an instance must be able to
-  prepare a sourcecode and to execute it.
-  """
+class Function:
+    """
+    Function holding user provided code.
 
-  # ---------------------------------------------------------------------------
-  # Constructor
-  # ---------------------------------------------------------------------------
+    Descendants of this class implement compiling and running functions with
+    user provided program code.
+    """
 
-  def __init__ (self, context, name, code, parameters):
-    self._context    = context
-    self._name       = name
-    self._code       = code
-    self._parameters = parameters
-    self._prepare ()
+    # -------------------------------------------------------------------------
+    # Constructor
+    # -------------------------------------------------------------------------
 
+    def __init__(self, context, name, code, parameters):
+        self._context    = context
+        self._name       = name
+        self._code       = code
 
-  # ---------------------------------------------------------------------------
-  # Execute the function using the given arguments
-  # ---------------------------------------------------------------------------
+        if parameters is not None:
+            self._parameters = parameters
+        else:
+            self._parameters = {}
+        self._prepare()
 
-  def execute (self, *args, **params):
-    """
-    Execute the function using the given arguments. A descendant must override
-    this function.
-    """
-    raise ImplementationError, (self.__class__, 'execute ()')
 
+    # -------------------------------------------------------------------------
+    # Execute the function using the given arguments
+    # -------------------------------------------------------------------------
 
+    def execute(self, *args, **params):
+        """
+        Execute the function using the given arguments. A descendant must
+        override this function.
+        """
+        raise ImplementationError, (self.__class__, 'execute()')
 
-  # ---------------------------------------------------------------------------
-  # Generate a user requested abort 
-  # ---------------------------------------------------------------------------
 
-  def requestAbort (self, message):
-    """
-    Abstract: Generate a user abort request.  Linked into the execution
-    namespace so that scripts can request an abort.
-    """
-    raise AbortRequest(message)
+    # -------------------------------------------------------------------------
+    # Generate a user requested abort 
+    # -------------------------------------------------------------------------
+
+    def requestAbort(self, message):
+        """
+        Generate an L{AbortRequest} exception.
+        
+        Linked into the execution namespace so that scripts can request an
+        abort.
+        """
+        raise AbortRequest(message)
+
   
-  # ---------------------------------------------------------------------------
-  # redirect a call of an instance to the execute () function.
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # redirect a call of an instance to the execute () function.
+    # -------------------------------------------------------------------------
 
-  def __call__ (self, *args, **params):
-    """
-    If an instance gets called, redirect this call to the execute () function.
-    """
-    return apply (self.execute, args, params)
+    def __call__(self, *args, **params):
+        """
+        If an instance gets called, redirect this call to the execute()
+        function.
+        """
+        return self.execute(*args, **params)
 
 
-  # ---------------------------------------------------------------------------
-  # Prepare the given source code
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Prepare the given source code
+    # -------------------------------------------------------------------------
 
-  def _prepare (self):
-    """
-    This function gets called on constructing an instance at could be used by a
-    descendant to prepare the sourcecode, i.e. compile it.
-    """
-    pass
-
+    def _prepare(self):
+        """
+        This function gets called on constructing an instance at could be used
+        by a descendant to prepare the sourcecode, i.e. compile it.
+        """
+        pass

Modified: trunk/gnue-common/src/logic/adapters/__init__.py
===================================================================
--- trunk/gnue-common/src/logic/adapters/__init__.py    2006-04-18 13:04:25 UTC 
(rev 8414)
+++ trunk/gnue-common/src/logic/adapters/__init__.py    2006-04-18 15:59:19 UTC 
(rev 8415)
@@ -0,0 +1,26 @@
+# GNU Enterprise Common Library - Language adapter plugins
+#
+# Copyright 2000-2006 Free Software Foundation
+#
+# This file is part of GNU Enterprise.
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+
+"""
+Language adapter plugins for the various languages.
+"""

Modified: trunk/gnue-common/src/logic/adapters/ecmascript.py
===================================================================
--- trunk/gnue-common/src/logic/adapters/ecmascript.py  2006-04-18 13:04:25 UTC 
(rev 8414)
+++ trunk/gnue-common/src/logic/adapters/ecmascript.py  2006-04-18 15:59:19 UTC 
(rev 8415)
@@ -37,7 +37,7 @@
 from gnue.common.logic.adapters import Base
 from gnue.common.logic.NamespaceCore import NamespaceElement
 
-class LanguageAdapter(Base.BaseLanguageAdapter):
+class LanguageAdapter(Base.LanguageAdapter):
   def __init__(self):
     # Import down here so module remains importable (for eypdoc)
     try:
@@ -51,8 +51,9 @@
   def createNewContext(self):
     return ExecutionContext(self._rt)
 
-class ExecutionContext(Base.BaseExecutionContext):
+class ExecutionContext(Base.ExecutionContext):
   def __init__(self, runtime):
+    Base.ExecutionContext.__init__(self)
     self._cx = runtime.new_context()
     self._cx.bind_class(NamespaceElement)
 
@@ -75,11 +76,10 @@
   def buildFunction(self, name, code, parameters={}):
     return ECMAscriptFunction(self, name, code, parameters)
 
-#class ECMAscriptMethod (Base.VirtualMethod):
-class ECMAscriptMethod (Base.VirtualFunction):  # a rename to fix it for the 
moment
+class ECMAscriptMethod (Base.Function):  # a rename to fix it for the moment
 
   def __init__(self, context, name, code, parameters):
-    Base.VirtualFunction.__init__(self, context, name, code, parameters)
+    Base.Function.__init__(self, context, name, code, parameters)
     # Take care of special names
     self._name = string.replace(self._name,'-','_')
     self._cx=context._cx
@@ -139,9 +139,9 @@
   def rebind(self, obj, name):
     pass
 
-class ECMAscriptFunction(Base.VirtualFunction):
+class ECMAscriptFunction(Base.Function):
   def __init__(self, context, name, code, parameters):
-    Base.VirtualFunction.__init__(self, context, name, code, parameters)
+    Base.Function.__init__(self, context, name, code, parameters)
     # Take care of special names
     self._name = string.replace(self._name,'-','_')
     self._cx=context._cx

Modified: trunk/gnue-common/src/logic/adapters/python.py
===================================================================
--- trunk/gnue-common/src/logic/adapters/python.py      2006-04-18 13:04:25 UTC 
(rev 8414)
+++ trunk/gnue-common/src/logic/adapters/python.py      2006-04-18 15:59:19 UTC 
(rev 8415)
@@ -1,4 +1,7 @@
+# GNU Enterprise Common Library - Python language adapter plugin
 #
+# Copyright 2000-2006 Free Software Foundation
+#
 # This file is part of GNU Enterprise.
 #
 # GNU Enterprise is free software; you can redistribute it
@@ -16,12 +19,15 @@
 # write to the Free Software Foundation, Inc., 59 Temple Place
 # - Suite 330, Boston, MA 02111-1307, USA.
 #
-# Copyright 2001-2006 Free Software Foundation
-#
 # $Id$
+#
+# We use * and ** magic on purpose
+# pylint: disable-msg=W0142
 
+"""
+Language adapter plugin for Python.
+"""
 
-import string
 import re
 import copy
 
@@ -29,265 +35,255 @@
 from gnue.common.logic import language
 from gnue.common.logic.adapters import Base
 
+__all__ = ['LanguageAdapter', 'ExecutionContext', 'Function']
+
+
 # =============================================================================
 # Implementation of a language adapter for python
 # =============================================================================
 
-class LanguageAdapter (Base.BaseLanguageAdapter):
-  """
-  Implementation of a language engine for python
-  """
-
-  # ---------------------------------------------------------------------------
-  # Create a new execution context
-  # ---------------------------------------------------------------------------
-
-  def createNewContext (self):
+class LanguageAdapter(Base.LanguageAdapter):
     """
-    Create a python execution context
+    Implementation of a language engine for python
     """
-    return PythonExecutionContext ()
 
+    # -------------------------------------------------------------------------
+    # Create a new execution context
+    # -------------------------------------------------------------------------
 
+    def createNewContext(self):
+        """
+        Create a python execution context
+        """
+        return ExecutionContext()
+
+
 # =============================================================================
 # Python Execution Context
 # =============================================================================
 
-class PythonExecutionContext (Base.BaseExecutionContext):
-  """
-  This class implements an ExecutionContext for Python.
-  """
+class ExecutionContext(Base.ExecutionContext):
+    """
+    This class implements an ExecutionContext for Python.
+    """
 
-  # ---------------------------------------------------------------------------
-  # Constructor
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Constructor
+    # -------------------------------------------------------------------------
 
-  def __init__ (self, runtime = None):
-    Base.BaseExecutionContext.__init__ (self, runtime)
+    def __init__(self):
 
-    self._globalNS = {}
-    self._localNS  = {}
-    self._builtins = {}
+        Base.ExecutionContext.__init__(self)
 
+        self._globalNS = {}
+        self._localNS  = {}
+        self._builtins = {}
 
-  # ---------------------------------------------------------------------------
-  # Replace the local or global namespace
-  # ---------------------------------------------------------------------------
 
-  def defineNamespace (self, addNS, asGlobal = False):
-    """
-    This function replaces the local or global namespace with @addNS.
-    """
-    if asGlobal:
-      self._globalNS = addNS
-    else:
-      self._localNS = addNS
+    # -------------------------------------------------------------------------
+    # Add an object to the namespace
+    # -------------------------------------------------------------------------
 
+    def bindObject(self, name, aObject, asGlobal = False):
+        """
+        Add an object to the local or global namespace.
+        """
+        if asGlobal:
+            self._globalNS[name] = aObject
+        else:
+            self._localNS[name] = aObject
 
-  # ---------------------------------------------------------------------------
-  # Add an object to the namespace
-  # ---------------------------------------------------------------------------
 
-  def bindObject (self, name, aObject, asGlobal = False):
-    """
-    Add @aObject as @name to the local or global namespace.
-    """
-    if asGlobal:
-      self._globalNS [name] = aObject
-    else:
-      self._localNS [name] = aObject
+    # -------------------------------------------------------------------------
+    # Add a function to the namespace
+    # -------------------------------------------------------------------------
 
+    def bindFunction(self, name, aFunction, asGlobal = False):
+        """
+        Add a function to the local or global namespace.
+        """
+        if asGlobal:
+            self._globalNS[name] = aFunction
+        else:
+            self._localNS[name] = aFunction
 
-  # ---------------------------------------------------------------------------
-  # Add a function to the namespace
-  # ---------------------------------------------------------------------------
 
-  def bindFunction (self, name, aFunction, asGlobal = False):
-    """
-    Add @aFunction as @name to the local or global namespace.
-    """
-    if asGlobal:
-      self._globalNS [name] = aFunction
-    else:
-      self._localNS [name] = aFunction
+    # -------------------------------------------------------------------------
+    # Bind an element into the contexts builtin-namespace
+    # -------------------------------------------------------------------------
 
+    def bindBuiltin(self, name, anElement):
+        """
+        Bind the given element into the builtin-namespace.
+        @param name: name of the element within the builtin-namespace
+        @param anElement: element to be bound into the builtin-namespace
+        """
+        self._builtins[name] = anElement
 
-  # ---------------------------------------------------------------------------
-  # Bind an element into the contexts builtin-namespace
-  # ---------------------------------------------------------------------------
 
-  def bindBuiltin (self, name, anElement):
-    """
-    Bind the given element into the builtin-namespace.
-    @param name: name of the element within the builtin-namespace
-    @param anElement: element to be bound into the builtin-namespace
-    """
+    # -------------------------------------------------------------------------
+    # Create a function
+    # -------------------------------------------------------------------------
 
-    self._builtins [name] = anElement
+    def buildFunction(self, name, code, parameters = None):
+        return Function(self, name, code, parameters)
 
-
-  # ---------------------------------------------------------------------------
-  # Create a function
-  # ---------------------------------------------------------------------------
-
-  def buildFunction (self, name, code, parameters = {}):
-    return PythonFunction (self, name, code, parameters)
-
   
-  # ---------------------------------------------------------------------------
-  # Release the namespace of an execution context
-  # ---------------------------------------------------------------------------
+    # -------------------------------------------------------------------------
+    # Release the namespace of an execution context
+    # -------------------------------------------------------------------------
 
-  def release (self):
-    """
-    This function releases all references held by the namespace of an execution
-    context.
-    """
+    def release (self):
+        """
+        This function releases all references held by the namespace of an
+        execution context.
+        """
+        self._globalNS.clear()
+        self._localNS.clear()
+        self._builtins.clear()
 
-    self._globalNS.clear ()
-    self._localNS.clear ()
-    self._builtins.clear ()
 
-
 # =============================================================================
 # This class implements a virtual function using python
 # =============================================================================
 
-class PythonFunction (Base.VirtualFunction):
-  """
-  Implementation of a virtual function using Python.
-  """
-
-  # ---------------------------------------------------------------------------
-  # Prepare a python function
-  # ---------------------------------------------------------------------------
-
-  def _prepare (self):
+class Function(Base.Function):
     """
-    Preparing a sourcecode for python means compiling. This function compiles
-    the code.
+    Implementation of a virtual function using Python.
     """
-    # The function name may only contain ascii characters and underscores.
-    self.funcName = self.__identifier (self._name)
-    if not self.funcName:
-      self.funcName = 'unnamed'
 
-    paramlist = string.join (['__namespace', '__builtins'] + \
-           [self.__identifier (key) for key in self._parameters.keys ()], ", ")
-    text      = self._code.rstrip ()
+    # -------------------------------------------------------------------------
+    # Prepare a python function
+    # -------------------------------------------------------------------------
 
-    try:
-      tabPos = text.find ('\t')
-      if tabPos > -1:
-        raise errors.ApplicationError, \
-           u_("Sourcecode contains tab character at position %d") % tabPos
+    def _prepare(self):
+        """
+        Preparing a sourcecode for python means compiling. This function 
compiles
+        the code.
+        """
 
+        # The function name may only contain ascii characters and underscores.
+        function_name = self.__identifier(self._name)
+        if not function_name:
+            function_name = 'unnamed'
 
-      # get the indentation level of the first line
-      indent = 0
-      for line in text.splitlines ():
-        if len (line.strip ()) and line.lstrip () [0] != "#":
-          indent = len (line) - len (line.lstrip ())
-          break
+        paramlist = ", ".join(['__namespace', '__builtins'] + \
+                [self.__identifier(key) for key in self._parameters.keys()])
+        text = self._code.rstrip()
 
-      # add the functions header
-      revisedCode  = "# -*- coding: utf-8 -*-\n"
-      revisedCode += "import __builtin__\n"
-      revisedCode += "def %s (%s):\n" % (self.funcName, paramlist)
+        try:
+            tab_pos = text.find ('\t')
+            if tab_pos > -1:
+                raise errors.ApplicationError, u_(
+                        "Sourcecode contains tab character at position %d") \
+                                % tab_pos
 
-      # add the namespace transformation loop
-      revisedCode += "  for __add in __namespace.keys ():\n"
-      revisedCode += "    exec '%s = __namespace [\"%s\"]' % (__add, __add) in 
globals(), locals()\n"
-      revisedCode += "  for (name, item) in __builtins.items ():\n"
-      revisedCode += "    __builtin__.__dict__ [name] = item\n"
-      revisedCode += "  del __add, __namespace, __builtins\n\n"
+            # get the indentation level of the first line
+            indent = 0
+            for line in text.splitlines():
+                if len (line.strip()) and line.lstrip()[0] != "#":
+                    indent = len(line) - len(line.lstrip())
+                    break
 
-      # add the original code
-      for line in text.splitlines ():
-        revisedCode += "  %s\n" % line [indent:]
+            # add the functions header
+            revised_code  = "# -*- coding: utf-8 -*-\n"
+            revised_code += "import __builtin__\n"
+            revised_code += "def %s (%s):\n" % (function_name, paramlist)
 
-      # and finalize the function by a call to it
-      revisedCode += "  pass\n\n"
-      revisedCode += "__result = %s (%s)\n" % (self.funcName, paramlist)
+            # add the namespace transformation loop
+            revised_code += "  for __add in __namespace.keys ():\n"
+            revised_code += "    exec '%s = __namespace [\"%s\"]' % "
+            revised_code += "(__add, __add) in globals(), locals()\n"
+            revised_code += "  for (name, item) in __builtins.items ():\n"
+            revised_code += "    __builtin__.__dict__ [name] = item\n"
+            revised_code += "  del __add, __namespace, __builtins\n\n"
 
-      self._compiled = compile (revisedCode.encode ('utf-8'),
-                     '<%s>' % self._context.shortname.encode ('utf-8'), 'exec')
-    except:
-      (group, name, message, detail) = errors.getException (1)
-      if group == 'system':
-        group = 'application'
-      raise language.CompileError, (group, name, message, detail)
+            # add the original code
+            for line in text.splitlines():
+                revised_code += "  %s\n" % line[indent:]
 
+            # and finalize the function by a call to it
+            revised_code += "  pass\n\n"
+            revised_code += "__result = %s (%s)\n" % (function_name, paramlist)
 
-  # ---------------------------------------------------------------------------
-  # Execute the function
-  # ---------------------------------------------------------------------------
+            self.__compiled = compile(revised_code.encode('utf-8'),
+                    '<%s>' % self._context.shortname.encode('utf-8'), 'exec')
+        except:
+            (group, name, message, detail) = errors.getException(1)
+            if group == 'system':
+                group = 'application'
+            raise language.CompileError, (group, name, message, detail)
 
-  def execute (self, *args, **params):
-    """
-    This function creates a local namespace as a copy from the execution
-    context's local namespace, adds all parameters to this namespace and
-    executes the code.
-    """
 
-    try:
-      localNS = copy.copy (self._context._localNS)
-      localNS.update (params)
-      localNS ['__namespace'] = localNS
-      localNS ['__builtins'] = copy.copy (self._context._builtins)
-      # We do not use the context's bindBuiltin () method here to avoid another
-      # non-collectable reference
-      localNS ['__builtins'] ['abort'] = self.requestAbort
+    # -------------------------------------------------------------------------
+    # Execute the function
+    # -------------------------------------------------------------------------
 
-      try:
+    def execute(self, *args, **params):
+        """
+        This function creates a local namespace as a copy from the execution
+        context's local namespace, adds all parameters to this namespace and
+        executes the code.
+        """
 
-        # make sure we only use safe identifiers in our namespace
-        self.__makeSafeNamespace (localNS)
+        try:
+            local_namespace = copy.copy(self._context._localNS)
+            local_namespace.update(params)
+            local_namespace['__namespace'] = local_namespace
+            local_namespace['__builtins'] = copy.copy(self._context._builtins)
+            # We do not use the context's bindBuiltin() method here to avoid
+            # another non-collectable reference
+            local_namespace['__builtins']['abort'] = self.requestAbort
 
-        exec self._compiled in self._context._globalNS, localNS
+            try:
+                # make sure we only use safe identifiers in our namespace
+                self.__make_safe_namespace(local_namespace)
 
-        return localNS.get ('__result')
+                exec self.__compiled in self._context._globalNS, 
local_namespace
 
-      finally:
-        # It's very importaint to release all references from the cloned
-        # namespace here, otherwise garbage collection won't work very well !
-        localNS.clear ()
+                return local_namespace.get('__result')
 
-    except language.AbortRequest:
-      # Pass through AbortRequests unchanged
-      raise
+            finally:
+                # It's very important to release all references from the cloned
+                # namespace here, otherwise garbage collection won't work very
+                # well !
+                local_namespace.clear()
 
-    except:
-      # All others raise a RuntimeError
-      (group, name, message, detail) = errors.getException (2)
-      if group == 'system':
-        group = 'application'
-      raise language.RuntimeError, (group, name, message, detail)
+        except language.AbortRequest:
+            # Pass through AbortRequests unchanged
+            raise
 
+        except:
+            # All others raise a RuntimeError
+            (group, name, message, detail) = errors.getException (2)
+            if group == 'system':
+                group = 'application'
+            raise language.RuntimeError, (group, name, message, detail)
 
-  # ---------------------------------------------------------------------------
-  # Make sure we use proper identifiers
-  # ---------------------------------------------------------------------------
 
-  def __identifier (self, name):
-    """
-    This function translates @name to a valid python identifier, which means
-    all non-letter characters are replaced by an underscore.
-    """
-    return re.sub ('[^a-zA-Z0-9]', '_', name)
+    # -------------------------------------------------------------------------
+    # Make sure the given Namespace has no invalid identifiers
+    # -------------------------------------------------------------------------
 
+    def __make_safe_namespace(self, namespace):
+        """
+        This function replaces all invalid keys in the dict. @namespace by
+        appropriate identifiers.
+        """
+        for key in namespace.keys():
+            safe_id = self.__identifier(key)
+            if safe_id != key:
+                namespace[safe_id] = namespace[key]
+                del namespace[key]
 
-  # ---------------------------------------------------------------------------
-  # Make sure the given Namespace has no invalid identifiers
-  # ---------------------------------------------------------------------------
 
-  def __makeSafeNamespace (self, namespace):
-    """
-    This function replaces all invalid keys in the dict. @namespace by
-    appropriate identifiers.
-    """
-    for key in namespace.keys ():
-      safeId = self.__identifier (key)
-      if safeId != key:
-        namespace [safeId] = namespace [key]
-        del namespace [key]
+    # -------------------------------------------------------------------------
+    # Make sure we use proper identifiers
+    # -------------------------------------------------------------------------
+
+    def __identifier(self, name):
+        """
+        This function translates @name to a valid python identifier, which
+        means all non-letter characters are replaced by an underscore.
+        """
+        return re.sub('[^a-zA-Z0-9]', '_', name)

Modified: trunk/gnue-common/src/logic/language.py
===================================================================
--- trunk/gnue-common/src/logic/language.py     2006-04-18 13:04:25 UTC (rev 
8414)
+++ trunk/gnue-common/src/logic/language.py     2006-04-18 15:59:19 UTC (rev 
8415)
@@ -1,4 +1,7 @@
+# GNU Enterprise Common Library - Interface to language adapters
 #
+# Copyright 2000-2006 Free Software Foundation
+#
 # This file is part of GNU Enterprise.
 #
 # GNU Enterprise is free software; you can redistribute it
@@ -16,127 +19,151 @@
 # write to the Free Software Foundation, Inc., 59 Temple Place
 # - Suite 330, Boston, MA 02111-1307, USA.
 #
-# Copyright 2001-2006 Free Software Foundation
+# $Id$
 #
-# $Id$
+# We redefine builtin RuntimeError
+# pylint: disable-msg=W0622
+#
+# We use * and ** magic on purpose
+# pylint: disable-msg=W0142
 
-import string
+"""
+Interface to language adapters.
 
+This module contains classes necessary to access the language adapters, which
+are used to execute user provided code in GNUe applications.
+"""
+
 from gnue.common.apps import errors
 from gnue.common.utils.FileUtils import dyn_import
 
-adapters = {}
+__all__ = ['AdapterNotFoundError', 'ImplementationError', 'CompileError',
+        'RuntimeError', 'AbortRequest', 'getLanguageAdapter']
 
+__adapters = {}
 
-# =============================================================================
-# Exceptions
-# =============================================================================
 
 # -----------------------------------------------------------------------------
-# Python module not available
+# Exceptions
 # -----------------------------------------------------------------------------
 
-class AdapterNotFoundError (errors.AdminError):
-  """
-  The language adapter for the requested language cannot be imported.
-  """
-  def __init__ (self, language):
-    msg = u_("No adapter available for language '%s'") % language
-    errors.AdminError.__init__ (self, msg)
+class AdapterNotFoundError(errors.AdminError):
+    """
+    Language adapter not found.
+    """
+    def __init__(self, language):
+        errors.AdminError.__init__(self,
+                u_("No adapter available for language '%s'") % language)
 
-
 # -----------------------------------------------------------------------------
-# Abstract method not implemented
-# -----------------------------------------------------------------------------
 
-class ImplementationError (errors.SystemError):
-  """
-  Exception raised if an abstract method isn't implemented by a descendant.
-  """
-  def __init__ (self, classname, method):
-    msg = u_("The class '%(class)s' has no implementation for '%(method)s'") \
-           % {"class" : classname,
-              "method": method}
-    errors.SystemError.__init__ (self, msg)
+class ImplementationError(errors.SystemError):
+    """
+    Method not implemented in language adapter.
+    """
+    def __init__(self, classname, methodname):
+        errors.SystemError.__init__(self,
+                u_("The class '%(class)s' has no implementation for "
+                   "'%(method)s'") \
+                % {"class" : classname, "method": methodname})
 
 # -----------------------------------------------------------------------------
-# Code failed on compilation
-# -----------------------------------------------------------------------------
 
-class CompileError (errors.RemoteError):
-  pass
+class CompileError(errors.RemoteError):
+    """
+    Error in user code compilation.
 
+    An error occured when trying to compile user code. Details of the error are
+    available through the L{getName}, {getDatail}, and {getMessage} methods.
+    """
+    pass
+
 # -----------------------------------------------------------------------------
-# Code failed on execution
-# -----------------------------------------------------------------------------
 
-class RuntimeError (errors.RemoteError):
-  pass
+class RuntimeError(errors.RemoteError):
+    """
+    Error in user code execution.
 
+    An error occured when trying to execute user code. Details of the error are
+    available through the L{getName}, {getDatail}, and {getMessage} methods.
+    """
+    pass
+
 # -----------------------------------------------------------------------------
-# Abort the current execution
-# -----------------------------------------------------------------------------
 
-class AbortRequest (errors.UserError):
-  pass
+class AbortRequest(errors.UserError):
+    """
+    Call to abort().
 
+    User code called the abort() function.
+    """
+    pass
+
 # -----------------------------------------------------------------------------
 # Get or create an instance of a given language adapter
 # -----------------------------------------------------------------------------
 
-def getLanguageAdapter (language):
-  """
-  This function returns an execution context factory for the given language.
-  AdapterNotFoundError will be raised, if the language adapter cannot be
-  imported.
-  """
-  global adapters
-  lang = str(language.lower ())
+def getLanguageAdapter(language):
+    """
+    Return a language adapter object for the given language.
+
+    This function returns an execution context factory for the given language.
+
+    @param language: The language to return the language adapter object for.
+    @type language: string or unicode
+
+    @return: Language adapter object
+    @rtype: L{adapters.Base.LanguageAdapter}
+
+    @raise L{AdapterNotFoundError}: There is no language adapter available for
+        the given language.
+    """
+
+    lang = str(language.lower())
   
-  if not adapters.has_key (lang):
-    try:
-      adapter = dyn_import ('gnue.common.logic.adapters.%s' % lang)
-      adapters [lang] = adapter.LanguageAdapter ()
+    if not __adapters.has_key(lang):
+        try:
+            module = dyn_import('gnue.common.logic.adapters.%s' % lang)
+        except ImportError:
+            raise AdapterNotFoundError, language
+        __adapters[lang] = module.LanguageAdapter()
 
-    except ImportError:
-      raise AdapterNotFoundError, language
+    return __adapters[lang]
 
-  return adapters [lang]
 
-
 # =============================================================================
 # Self test code
 # =============================================================================
 
 if __name__ == '__main__':
 
-  print "Creating language adapter for 'python' ..."
-  adapter = getLanguageAdapter ('python')
+    print "Creating language adapter for 'python' ..."
+    adapter = getLanguageAdapter('python')
 
-  print "Creating new execution environment ..."
-  environ = adapter.createNewContext ()
-  environ.shortname   = "testing"
-  environ.description = "Execution context for self testing"
+    print "Creating new execution environment ..."
+    environ = adapter.createNewContext()
+    environ.shortname   = "testing"
+    environ.description = "Execution context for self testing"
 
-  code = """
+    code = """
 print "Hello World!"
 print "My name is %s." % name
 print foobar
 return value * 2
 """
 
-  print "Creating a new virtual code object ..."
-  method = environ.buildFunction ('myFunctionName', code,
-                        {'name': "", 'value': 0})
+    print "Creating a new virtual code object ..."
+    method = environ.buildFunction('myFunctionName', code,
+            {'name': "", 'value': 0})
 
-  params = {'name': 'foo', 'value': 'bar'}
-  print "Calling function with: %s" % params
-  res = method (**params)
-  print "   result:", repr (res)
+    params = {'name': 'foo', 'value': 'bar'}
+    print "Calling function with: %s" % params
+    res = method(**params)
+    print "   result:", repr(res)
 
-  params = {'name': 'fooBar', 'value': 4}
-  print "Calling function with: %s" % params
-  res = method (**params)
-  print "   result:", repr (res)
+    params = {'name': 'fooBar', 'value': 4}
+    print "Calling function with: %s" % params
+    res = method(**params)
+    print "   result:", repr(res)
 
-  print "Thank's for playing."
+    print "Thank's for playing."





reply via email to

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