]> code.ossystems Code Review - openembedded-core.git/commitdiff
Consolidate the exec/eval bits, switch anonfunc to better_exec, etc
authorChris Larson <chris_larson@mentor.com>
Wed, 31 Mar 2010 03:06:07 +0000 (20:06 -0700)
committerRichard Purdie <rpurdie@linux.intel.com>
Fri, 2 Jul 2010 14:41:31 +0000 (15:41 +0100)
The methodpool, ${@} expansions, anonymous python functions, event handlers
now all run with the same global context, ensuring a consistent environment
for them.  Added a bb.utils.better_eval function which does an eval() with the
same globals as better_exec.

(Bitbake rev: 424d7e267b009cc19b8503eadab782736d9597d0)

Signed-off-by: Chris Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
bitbake/lib/bb/build.py
bitbake/lib/bb/data_smart.py
bitbake/lib/bb/event.py
bitbake/lib/bb/methodpool.py
bitbake/lib/bb/parse/ast.py
bitbake/lib/bb/utils.py

index 43dbfc1363b86de178dc186c74c86660194b926b..16d69281f1a0504121306f96c2ade1077cc0fe2f 100644 (file)
@@ -203,16 +203,14 @@ def exec_func_python(func, d, runfile, logfile):
     import re, os
 
     bbfile = bb.data.getVar('FILE', d, 1)
-    tmp  = "def " + func + "():\n%s" % data.getVar(func, d)
-    tmp += '\n' + func + '()'
+    tmp  = "def " + func + "(d):\n%s" % data.getVar(func, d)
+    tmp += '\n' + func + '(d)'
 
     f = open(runfile, "w")
     f.write(tmp)
     comp = utils.better_compile(tmp, func, bbfile)
-    g = {} # globals
-    g['d'] = d
     try:
-        utils.better_exec(comp, g, tmp, bbfile)
+        utils.better_exec(comp, {"d": d}, tmp, bbfile)
     except:
         (t,value,tb) = sys.exc_info()
 
index 55a6f3143cc397e80451bff5d40c0d3246325d82..77f1861381f42ccfce1d0da01efe512bc387aab8 100644 (file)
@@ -50,12 +50,6 @@ class DataSmart:
         self._seen_overrides = seen
 
         self.expand_cache = {}
-        self.expand_globals = {
-            "os": os,
-            "bb": bb,
-            "time": time,
-            "d": self
-        }
 
     def expand(self,s, varname):
         def var_sub(match):
@@ -72,7 +66,7 @@ class DataSmart:
         def python_sub(match):
             code = match.group()[3:-1]
             codeobj = compile(code.strip(), varname or "<expansion>", "eval")
-            s = eval(codeobj, self.expand_globals, {})
+            s = utils.better_eval(codeobj, {"d": self})
             if type(s) == types.IntType: s = str(s)
             return s
 
index afd5bf57c1e3573b1cb12217483c94c755dce28d..8559858f0428fd88b28a9bcd309989c4e08b2b8a 100644 (file)
@@ -48,13 +48,18 @@ _handlers = {}
 _ui_handlers = {}
 _ui_handler_seq = 0
 
+# For compatibility
+bb.utils._context["NotHandled"] = NotHandled
+bb.utils._context["Handled"] = Handled
+
 def fire_class_handlers(event, d):
     for handler in _handlers:
         h = _handlers[handler]
         event.data = d
         if type(h).__name__ == "code":
-            exec(h)
-            tmpHandler(event)
+            locals = {"e": event}
+            exec h in bb.utils._context, locals
+            bb.utils.better_eval("tmpHandler(e)", locals)
         else:
             h(event)
         del event.data
index f43c4a0580da653834728a1e958cde046adaf68a..1485b1357d8341bc87eeed421d6354c3e1d2dbdf 100644 (file)
@@ -27,7 +27,7 @@
     a method pool to do this task.
 
     This pool will be used to compile and execute the functions. It
-    will be smart enough to 
+    will be smart enough to
 """
 
 from bb.utils import better_compile, better_exec
@@ -43,8 +43,8 @@ def insert_method(modulename, code, fn):
     Add code of a module should be added. The methods
     will be simply added, no checking will be done
     """
-    comp = better_compile(code, "<bb>", fn )
-    better_exec(comp, __builtins__, code, fn)
+    comp = better_compile(code, modulename, fn )
+    better_exec(comp, None, code, fn)
 
     # now some instrumentation
     code = comp.co_names
@@ -59,7 +59,7 @@ def insert_method(modulename, code, fn):
 def check_insert_method(modulename, code, fn):
     """
     Add the code if it wasnt added before. The module
-    name will be used for that 
+    name will be used for that
 
     Variables:
         @modulename a short name e.g. base.bbclass
@@ -81,4 +81,4 @@ def get_parsed_dict():
     """
     shortcut
     """
-    return _parsed_methods    
+    return _parsed_methods
index 59aa44bee0b76683cf7779594f033139c5e412ac..d2ae09a4a447a815a27956f548394c7cbcd7869f 100644 (file)
@@ -122,12 +122,8 @@ class MethodNode:
 
     def eval(self, data):
         if self.func_name == "__anonymous":
-            funcname = ("__anon_%s_%s" % (self.lineno, self.fn.translate(string.maketrans('/.+-', '____'))))
-            if not funcname in bb.methodpool._parsed_fns:
-                text = "def %s(d):\n" % (funcname) + '\n'.join(self.body)
-                bb.methodpool.insert_method(funcname, text, self.fn)
             anonfuncs = bb.data.getVar('__BBANONFUNCS', data) or []
-            anonfuncs.append(funcname)
+            anonfuncs.append((self.fn, "\n".join(self.body)))
             bb.data.setVar('__BBANONFUNCS', anonfuncs, data)
         else:
             bb.data.setVarFlag(self.func_name, "func", 1, data)
@@ -143,7 +139,7 @@ class PythonMethodNode(AstNode):
         # Note we will add root to parsedmethods after having parse
         # 'this' file. This means we will not parse methods from
         # bb classes twice
-        if not self.root  in __parsed_methods__:
+        if not bb.methodpool.parsed_module(self.root):
             text = '\n'.join(self.body)
             bb.methodpool.insert_method(self.root, text, self.fn)
 
@@ -301,32 +297,12 @@ def finalise(fn, d):
 
     bb.data.expandKeys(d)
     bb.data.update_data(d)
-    anonqueue = bb.data.getVar("__anonqueue", d, 1) or []
-    body = [x['content'] for x in anonqueue]
-    flag = { 'python' : 1, 'func' : 1 }
-    bb.data.setVar("__anonfunc", "\n".join(body), d)
-    bb.data.setVarFlags("__anonfunc", flag, d)
-    from bb import build
-    try:
-        t = bb.data.getVar('T', d)
-        bb.data.setVar('T', '${TMPDIR}/anonfunc/', d)
-        anonfuncs = bb.data.getVar('__BBANONFUNCS', d) or []
-        code = ""
-        for f in anonfuncs:
-            code = code + "    %s(d)\n" % f
-        bb.data.setVar("__anonfunc", code, d)        
-        build.exec_func("__anonfunc", d)
-        bb.data.delVar('T', d)
-        if t:
-            bb.data.setVar('T', t, d)
-    except Exception, e:
-        bb.msg.debug(1, bb.msg.domain.Parsing, "Exception when executing anonymous function: %s" % e)
-        raise
-    bb.data.delVar("__anonqueue", d)
-    bb.data.delVar("__anonfunc", d)
+    for fn, func in bb.data.getVar("__BBANONFUNCS", d) or []:
+        funcdef = "def __anonfunc(d):\n%s\n__anonfunc(d)" % func.rstrip()
+        bb.utils.better_exec(funcdef, {"d": d}, funcdef, fn)
     bb.data.update_data(d)
 
-    all_handlers = {} 
+    all_handlers = {}
     for var in bb.data.getVar('__BBHANDLERS', d) or []:
         # try to add the handler
         handler = bb.data.getVar(var,d)
index 86b9c724edd54cf9874974c92bb7ecad43bb6210..50e9402a2ba1ba946054f9e1f516153be18b78bd 100644 (file)
@@ -21,9 +21,16 @@ BitBake Utility Functions
 
 separators = ".-"
 
-import re, fcntl, os, types, bb, string, stat, shutil
+import re, fcntl, os, types, bb, string, stat, shutil, time
 from commands import getstatusoutput
 
+# Context used in better_exec, eval
+_context = {
+    "os": os,
+    "bb": bb,
+    "time": time,
+}
+
 def explode_version(s):
     r = []
     alpha_regexp = re.compile('^([a-zA-Z]+)(.*)$')
@@ -164,13 +171,13 @@ def _print_trace(body, line):
         bb.msg.error(bb.msg.domain.Util, "\t%.4d:%s" % (i, body[i-1]) )
 
 
-def better_compile(text, file, realfile):
+def better_compile(text, file, realfile, mode = "exec"):
     """
     A better compile method. This method
     will print  the offending lines.
     """
     try:
-        return compile(text, file, "exec")
+        return compile(text, file, mode)
     except Exception, e:
         import bb,sys
 
@@ -193,7 +200,7 @@ def better_exec(code, context, text, realfile):
     """
     import bb,sys
     try:
-        exec code in context
+        exec code in _context, context
     except:
         (t,value,tb) = sys.exc_info()
 
@@ -215,6 +222,9 @@ def better_exec(code, context, text, realfile):
         
         raise
 
+def better_eval(source, locals):
+    return eval(source, _context, locals)
+
 def Enum(*names):
    """
    A simple class to give Enum support