commit-gnue
[Top][All Lists]
Advanced

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

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


From: reinhard
Subject: [gnue] r8417 - in trunk/gnue-common/src/logic: . adapters
Date: Tue, 18 Apr 2006 15:47:45 -0500 (CDT)

Author: reinhard
Date: 2006-04-18 15:47:44 -0500 (Tue, 18 Apr 2006)
New Revision: 8417

Modified:
   trunk/gnue-common/src/logic/adapters/Base.py
   trunk/gnue-common/src/logic/adapters/python.py
   trunk/gnue-common/src/logic/language.py
Log:
Added a straightforward and easy-to-use interface to language adapters. The old
interface will be depreciated with gnue-common 0.7 and removed with gnue-common
0.8.


Modified: trunk/gnue-common/src/logic/adapters/Base.py
===================================================================
--- trunk/gnue-common/src/logic/adapters/Base.py        2006-04-18 19:49:14 UTC 
(rev 8416)
+++ trunk/gnue-common/src/logic/adapters/Base.py        2006-04-18 20:47:44 UTC 
(rev 8417)
@@ -37,11 +37,12 @@
 from the three base classes in this module.
 """
 
+import re
 import types
 
 from gnue.common.logic.language import ImplementationError, AbortRequest
 
-__all__ = ['LanguageAdapter', 'ExecutionContext', 'Function']
+__all__ = ['LanguageAdapter', 'ExecutionContext']
 
 
 # =============================================================================
@@ -70,6 +71,19 @@
 
 
 # =============================================================================
+# Helper function to raise an AbortRequest exception
+# =============================================================================
+
+def _abort(self, message):
+    """
+    Raise an L{language.AbortRequest} exception.
+
+    This function will be available for user code under the name "abort".
+    """
+    raise AbortRequest, message
+
+
+# =============================================================================
 # Base class for execution contexts
 # =============================================================================
 
@@ -82,20 +96,113 @@
     # Constructor
     # -------------------------------------------------------------------------
 
-    def __init__(self):
+    def __init__(self, name, local_namespace, global_namespace,
+            builtin_namespace):
+        """
+        Initialize an execution context object.
 
-        self.shortname   = "unknown_executioncontext"
-        self.description = "There is no description provided"
+        Descendants must overwrite the constructor and do something useful with
+        the parameters.
 
+        @param name: Name of the execution context. This will be used in error
+            messages.
+        @type name: string or unicode
+        @param local_namespace: Dictionary with the local namespace. Keys are
+            variable names or function names, values are the objects or the
+            functions respectively. Identifiers defined here will look like
+            locally defined identifiers to the user code.
+        @type local_namespace: dict
+        @param global_namespace: Dictionary with the global namespace. Keys are
+            variable names or function names, values are the objects or the
+            functions respectively. Identifiers defined here will look like
+            globally defined identifiers to the user code.
+        @type global_namespace: dict
+        @param builtin_namespace: Dictionary with the builtin namespace. Keys
+            are variable names or function names, values are the objects or the
+            functions respectively. Identifiers defined here will look like
+            builtins to the user code, which means that they can even be
+            accessed from modules that are imported into the user code.
+        @type builtin_namespace: dict
+        """
 
+        builtin_namespace['abort'] = _abort
+
+
     # -------------------------------------------------------------------------
-    # Define the namespace
+    # Build a function
     # -------------------------------------------------------------------------
 
+    def build_function(self, name, parameters, code):
+        """
+        Create an executable object containing the user provided code.
+
+        @param name: Function name
+        @type name: string or unicode
+        @param parameters: List of paramete names
+        @type parameters: list of strings or unicodes
+        @param code: Function code
+        @type code: string or unicode
+        """
+
+        checktype(name, basestring)
+        checktype(parameters, list)
+        for parameters_item in parameters:
+            checktype(parameters_item, basestring)
+        checktype(code, basestring)
+
+        # Make sure name is not empty
+        if not name:
+            name = "unnamed"
+
+        # Make sure the function name and the parameter names are clean
+        # identifiers
+        name = self._identifier_(name)
+        parameters = [self._identifier_(param) for param in parameters]
+
+        return self._build_function_(name, parameters, code)
+
+
+    # -------------------------------------------------------------------------
+    # Virtual methods
+    # -------------------------------------------------------------------------
+
+    def _build_function_(self, name, parameters, code):
+        """
+        Create an executable object containing the user provided code.
+
+        Descendants must implement this function.
+        """
+        raise ImplementationError, (self.__class__, '_build_function_()')
+
+    # -------------------------------------------------------------------------
+
+    def _identifier_(self, name):
+        """
+        Convert any name into an identifier valid for this programming
+        language.
+        
+        By default, this function changes all non-alphanumeric characters into
+        an underscore and adds an underscore at the beginning if the name
+        starts with a number. Descendants can overwrite or extend this.
+        """
+        result = re.sub('[^a-zA-Z0-9]', '_', name)
+        if re.match('[0-9]', result):
+            result = '_' + result
+        return result
+
+
+    # -------------------------------------------------------------------------
+    # Depreciated methods
+    # -------------------------------------------------------------------------
+
     def defineNamespace(self, addNS, asGlobal = False):
         """
-        Define the namespace for this execution context.
+        Define the namespace for this execution context. DEPRECIATED.
 
+        This function will be depreciated in 0.7 and removed in 0.8.
+        Use L{language.create_execution_context} instead to define all
+        namespaces in one single step.
+
         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.
@@ -107,52 +214,52 @@
                 else:
                     self.bindObject(name, value, asGlobal)
 
-
     # -------------------------------------------------------------------------
-    # 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 an object into the namespace. DEPRECIATED.
 
+        This function will be depreciated in 0.7 and removed in 0.8.
+        Use L{language.create_execution_context} instead to define all
+        namespaces in one single step.
+
         A descendant overrides this function to bind a given object into the
         local or global namespace.
         """
         raise ImplementationError, (self.__class__, 'bindObject()')
 
-
     # -------------------------------------------------------------------------
-    # Bind a function into the contexts namespace using the given name
-    # -------------------------------------------------------------------------
 
     def bindFunction(self, name, aFunction, asGlobal = False):
         """
-        Bind a function into the namespace.
+        Bind a function into the namespace. DEPRECIATED.
 
+        This function will be depreciated in 0.7 and removed in 0.8.
+        Use L{language.create_execution_context} instead to define all
+        namespaces in one single step.
+
         A descendant overrides this function to bind a given function into the
         local or global namespace.
         """
         raise ImplementationError, (self.__class__, 'bindFunction()')
 
-
     # -------------------------------------------------------------------------
-    # Bind an element into the contexts builtin-namespace
-    # -------------------------------------------------------------------------
 
     def bindBuiltin(self, name, anElement):
         """
-        Bind a builtin function into the namespace.
+        Bind a builtin function into the namespace. DEPRECIATED.
 
+        This function will be depreciated in 0.7 and removed in 0.8.
+        Use L{language.create_execution_context} instead to define all
+        namespaces in one single step.
+
         A descendant overrides this function to bind a given element into the
         builtin-namespace of the context.
         """
         raise ImplementationError, (self.__class__, 'bindBuiltin()')
 
-
     # -------------------------------------------------------------------------
-    # Create a new function instance 
-    # -------------------------------------------------------------------------
 
     def buildFunction(self, name, code, parameters = None):
         """
@@ -160,94 +267,19 @@
 
         Descendants must implement this.
         """
-        raise ImplementationError, (self.__class__, 'buildFunction()')
+        if parameters is None:
+            params = []
+        else:
+            params = parameters.keys()
+        return self._build_function_(name, params, code)
 
-
     # -------------------------------------------------------------------------
-    # Release an execution context
-    # -------------------------------------------------------------------------
 
     def release (self):
         """
         Release an execution context: remove references in the namespace and
-        the like.
-        """
-        pass
+        the like. DEPRECIATED.
 
-
-# =============================================================================
-# Base class of a function
-# =============================================================================
-
-class Function:
-    """
-    Function holding user provided code.
-
-    Descendants of this class implement compiling and running functions with
-    user provided program code.
-    """
-
-    # -------------------------------------------------------------------------
-    # Constructor
-    # -------------------------------------------------------------------------
-
-    def __init__(self, context, name, code, parameters):
-        self._context    = context
-        self._name       = name
-        self._code       = code
-
-        if parameters is not None:
-            self._parameters = parameters
-        else:
-            self._parameters = {}
-        self._prepare()
-
-
-    # -------------------------------------------------------------------------
-    # Execute the function using the given arguments
-    # -------------------------------------------------------------------------
-
-    def execute(self, *args, **params):
+        This function is not necessary any more.
         """
-        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):
-        """
-        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.
-    # -------------------------------------------------------------------------
-
-    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
-    # -------------------------------------------------------------------------
-
-    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/python.py
===================================================================
--- trunk/gnue-common/src/logic/adapters/python.py      2006-04-18 19:49:14 UTC 
(rev 8416)
+++ trunk/gnue-common/src/logic/adapters/python.py      2006-04-18 20:47:44 UTC 
(rev 8417)
@@ -28,9 +28,6 @@
 Language adapter plugin for Python.
 """
 
-import re
-import copy
-
 from gnue.common.apps import errors
 from gnue.common.logic import language
 from gnue.common.logic.adapters import Base
@@ -55,7 +52,7 @@
         """
         Create a python execution context
         """
-        return ExecutionContext()
+        return ExecutionContext("unknown_executioncontext", {}, {}, {})
 
 
 # =============================================================================
@@ -64,53 +61,146 @@
 
 class ExecutionContext(Base.ExecutionContext):
     """
-    This class implements an ExecutionContext for Python.
+    This class implements an execution context for Python code.
     """
 
     # -------------------------------------------------------------------------
     # Constructor
     # -------------------------------------------------------------------------
 
-    def __init__(self):
+    def __init__(self, name, local_namespace, global_namespace,
+            builtin_namespace):
 
-        Base.ExecutionContext.__init__(self)
+        Base.ExecutionContext.__init__(self, name, local_namespace,
+                global_namespace, builtin_namespace)
 
-        self._globalNS = {}
-        self._localNS  = {}
-        self._builtins = {}
+        # TODO: Change this to self.__name with 0.8
+        self.shortname = name
+        self.__local_namespace = local_namespace
+        self.__global_namespace = global_namespace
+        self.__builtin_namespace = builtin_namespace
 
 
     # -------------------------------------------------------------------------
-    # Add an object to the namespace
+    # Create a function
     # -------------------------------------------------------------------------
 
+    def _build_function_(self, name, parameters, code):
+
+        # Strip trailing whitespace from code
+        text = code.rstrip()
+
+        # Refuse to run code with tab characters
+        tab_pos = text.find ('\t')
+        if tab_pos > -1:
+            raise errors.ApplicationError, u_(
+                    "Sourcecode contains tab character at position %d") \
+                                % tab_pos
+
+        # 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
+
+        # The whole code is enclosed into a pseudo function definition. This
+        # way, the code can contain "return" statements.
+
+        # Start with the function header
+        revised_code  = "# -*- coding: utf-8 -*-\n"
+        revised_code += "def %s(%s):\n" % (name,
+                ", ".join(['__namespace'] + parameters))
+
+        # Unpack the namepsace dictionary within the function, so the local
+        # namespace appears to be local *inside* the function
+        revised_code += "    __add = None\n"
+        revised_code += "    for __add in __namespace.keys():\n"
+        revised_code += "        exec '%s = __namespace[\"%s\"]' % "
+        revised_code += "(__add, __add) in globals(), locals()\n"
+        revised_code += "    del __add, __namespace\n\n"
+
+        # Add the actual code
+        for line in text.splitlines():
+            revised_code += "    %s\n" % line[indent:]
+
+        # End the function with a "pass" statement in case the function body is
+        # empty
+        revised_code += "    pass\n\n"
+
+        # Before calling the function, add the builtins
+        revised_code += "import __builtin__\n"
+        revised_code += "for (__key, __value) in __builtins.items():\n"
+        revised_code += "    __builtin__.__dict__[__key] = __value\n"
+
+        # And finally run the function and save the result
+        revised_code += "__result = %s(__namespace, **__parameters)\n" % name
+
+        try:
+            compiled_code = compile(revised_code.encode('utf-8'),
+                    '<%s>' % self.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)
+
+        # Make sure namespaces are clean
+        # TODO: This can be moved to Base.ExecutionContext.__init__() after all
+        # the depreciated functions are removed.
+        self.__make_safe_namespace(self.__builtin_namespace)
+        self.__make_safe_namespace(self.__local_namespace)
+        self.__make_safe_namespace(self.__global_namespace)
+
+        return Function(
+                compiled_code = compiled_code,
+                local_namespace = {
+                    '__builtins': self.__builtin_namespace,
+                    '__namespace': self.__local_namespace},
+                global_namespace = self.__global_namespace)
+
+
+    # -------------------------------------------------------------------------
+    # 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]
+
+
+    # -------------------------------------------------------------------------
+    # Depreciated functions
+    # -------------------------------------------------------------------------
+
     def bindObject(self, name, aObject, asGlobal = False):
         """
         Add an object to the local or global namespace.
         """
         if asGlobal:
-            self._globalNS[name] = aObject
+            self.__global_namespace[name] = aObject
         else:
-            self._localNS[name] = aObject
+            self.__local_namespace[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
+            self.__global_namespace[name] = aFunction
         else:
-            self._localNS[name] = aFunction
+            self.__local_namespace[name] = aFunction
 
-
     # -------------------------------------------------------------------------
-    # Bind an element into the contexts builtin-namespace
-    # -------------------------------------------------------------------------
 
     def bindBuiltin(self, name, anElement):
         """
@@ -118,137 +208,46 @@
         @param name: name of the element within the builtin-namespace
         @param anElement: element to be bound into the builtin-namespace
         """
-        self._builtins[name] = anElement
+        self.__builtin_namespace[name] = anElement
 
 
-    # -------------------------------------------------------------------------
-    # Create a function
-    # -------------------------------------------------------------------------
-
-    def buildFunction(self, name, code, parameters = None):
-        return Function(self, name, code, parameters)
-
-  
-    # -------------------------------------------------------------------------
-    # Release 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()
-
-
 # =============================================================================
-# This class implements a virtual function using python
+# Class encapsulating user provided Python code in a function
 # =============================================================================
 
-class Function(Base.Function):
+class Function:
     """
     Implementation of a virtual function using Python.
     """
 
     # -------------------------------------------------------------------------
-    # Prepare a python function
+    # Constructor
     # -------------------------------------------------------------------------
 
-    def _prepare(self):
-        """
-        Preparing a sourcecode for python means compiling. This function 
compiles
-        the code.
-        """
+    def __init__(self, compiled_code, local_namespace, global_namespace):
 
-        # The function name may only contain ascii characters and underscores.
-        function_name = self.__identifier(self._name)
-        if not function_name:
-            function_name = 'unnamed'
+        self.__compiled_code = compiled_code
+        self.__local_namespace = local_namespace
+        self.__global_namespace = global_namespace
 
-        paramlist = ", ".join(['__namespace', '__builtins'] + \
-                [self.__identifier(key) for key in self._parameters.keys()])
-        text = self._code.rstrip()
 
-        try:
-            tab_pos = text.find ('\t')
-            if tab_pos > -1:
-                raise errors.ApplicationError, u_(
-                        "Sourcecode contains tab character at position %d") \
-                                % tab_pos
-
-            # 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 functions header
-            revised_code  = "# -*- coding: utf-8 -*-\n"
-            revised_code += "import __builtin__\n"
-            revised_code += "def %s (%s):\n" % (function_name, 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"
-
-            # 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)
-
-            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)
-
-
     # -------------------------------------------------------------------------
     # Execute the function
     # -------------------------------------------------------------------------
 
-    def execute(self, *args, **params):
+    def __call__(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.
         """
 
+        self.__local_namespace['__parameters'] = params
+
         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_code \
+                    in self.__global_namespace, self.__local_namespace
 
-            try:
-                # make sure we only use safe identifiers in our namespace
-                self.__make_safe_namespace(local_namespace)
-
-                exec self.__compiled in self._context._globalNS, 
local_namespace
-
-                return local_namespace.get('__result')
-
-            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 language.AbortRequest:
             # Pass through AbortRequests unchanged
             raise
@@ -260,30 +259,4 @@
                 group = 'application'
             raise language.RuntimeError, (group, name, message, detail)
 
-
-    # -------------------------------------------------------------------------
-    # 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 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)
+        return self.__local_namespace.get('__result')

Modified: trunk/gnue-common/src/logic/language.py
===================================================================
--- trunk/gnue-common/src/logic/language.py     2006-04-18 19:49:14 UTC (rev 
8416)
+++ trunk/gnue-common/src/logic/language.py     2006-04-18 20:47:44 UTC (rev 
8417)
@@ -40,6 +40,9 @@
 __all__ = ['AdapterNotFoundError', 'ImplementationError', 'CompileError',
         'RuntimeError', 'AbortRequest', 'getLanguageAdapter']
 
+__plugins = {}                          # Cache for loaded plugins
+
+# for old function "getLanguageAdapter"
 __adapters = {}
 
 
@@ -99,16 +102,75 @@
     """
     pass
 
+
 # -----------------------------------------------------------------------------
+# Create an execution context
+# -----------------------------------------------------------------------------
+
+def create_execution_context(language, name, local_namespace, global_namespace,
+        builtin_namespace):
+    """
+    Create a new execution context.
+
+    An execution context defines the environment in which user provided code
+    runs. Most notably, the execution context handles the local and global
+    variables that can be accessed by user code.
+
+    @param language: Programming language.
+    @type language: string or unicode
+    @param name: Name of the execution context. This will be used in error
+        messages.
+    @type name: string or unicode
+    @param local_namespace: Dictionary with the local namespace. Keys are
+        variable names or function names, values are the objects or the
+        functions respectively. Identifiers defined here will look like locally
+        defined identifiers to the user code.
+    @type local_namespace: dict
+    @param global_namespace: Dictionary with the global namespace. Keys are
+        variable names or function names, values are the objects or the
+        functions respectively. Identifiers defined here will look like
+        globally defined identifiers to the user code.
+    @type global_namespace: dict
+    @param builtin_namespace: Dictionary with the builtin namespace. Keys are
+        variable names or function names, values are the objects or the
+        functions respectively. Identifiers defined here will look like
+        builtins to the user code, which means that they can even be accessed
+        from modules that are imported into the user code.
+    @type builtin_namespace: dict
+    @return The execution context that can be used to run user defined code.
+    @rtype L{adapters.Base.ExecutionContext}
+    """
+
+    checktype(language, basestring)
+    checktype(name, basestring)
+    checktype(local_namespace, dict)
+    checktype(global_namespace, dict)
+    checktype(builtin_namespace, dict)
+
+    lang = str(language.lower())
+  
+    if not __plugins.has_key(lang):
+        try:
+            __plugins[lang] = dyn_import('gnue.common.logic.adapters.%s' % 
lang)
+        except ImportError:
+            raise AdapterNotFoundError, language
+
+    return __plugins[lang].ExecutionContext(name, local_namespace,
+            global_namespace, builtin_namespace)
+
+
+# -----------------------------------------------------------------------------
 # Get or create an instance of a given language adapter
 # -----------------------------------------------------------------------------
 
 def getLanguageAdapter(language):
     """
-    Return a language adapter object for the given language.
+    Return a language adapter object for the given language. DEPRECIATED.
 
     This function returns an execution context factory for the given language.
 
+    This function will be depreciated in 0.7 and removed in 0.8.
+
     @param language: The language to return the language adapter object for.
     @type language: string or unicode
 
@@ -137,20 +199,22 @@
 
 if __name__ == '__main__':
 
+    code = """
+            print "Hello World!"
+            print "My name is %s %s." % (my_name, name)
+            return value * 2"""
+
+    print "*** Old (depreciated) interface ***"
+
     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"
+    environ.shortname = "testing"
 
-    code = """
-print "Hello World!"
-print "My name is %s." % name
-print foobar
-return value * 2
-"""
+    print "Setting up namespaces ..."
+    environ.bindObject('my_name', 'John')
 
     print "Creating a new virtual code object ..."
     method = environ.buildFunction('myFunctionName', code,
@@ -166,4 +230,31 @@
     res = method(**params)
     print "   result:", repr(res)
 
-    print "Thank's for playing."
+    print ""
+    print "*** New interface ***"
+
+    print "Creating execution context for Python..."
+    execution_context = create_execution_context(
+            language = 'Python',
+            name = 'test_context',
+            local_namespace = {'my_name': 'John'},
+            global_namespace = {},
+            builtin_namespace = {})
+
+    print "Compiling the code..."
+    function = execution_context.build_function(
+            name = 'myFunctionName',
+            parameters = ['name', 'value'],
+            code = code)
+
+    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)
+
+    print "Thank you for playing."





reply via email to

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