[Top][All Lists]
[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."
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r8415 - in trunk/gnue-common/src/logic: . adapters,
reinhard <=