aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Larson <chris_larson@mentor.com>2010-03-30 20:06:07 -0700
committerChris Larson <chris_larson@mentor.com>2010-03-30 20:06:09 -0700
commit424d7e267b009cc19b8503eadab782736d9597d0 (patch)
treeaeba768adb121e1f562bd6b39e6c7e2897d701e5
parent97da0cebbaf4dd1b46e58bd2e80cab6c007ae7c9 (diff)
downloadbitbake-424d7e267b009cc19b8503eadab782736d9597d0.tar.gz
Consolidate the exec/eval bits, switch anonfunc to better_exec, etc
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. Signed-off-by: Chris Larson <chris_larson@mentor.com>
-rw-r--r--lib/bb/build.py8
-rw-r--r--lib/bb/data_smart.py8
-rw-r--r--lib/bb/event.py9
-rw-r--r--lib/bb/methodpool.py10
-rw-r--r--lib/bb/parse/ast.py36
-rw-r--r--lib/bb/utils.py18
6 files changed, 36 insertions, 53 deletions
diff --git a/lib/bb/build.py b/lib/bb/build.py
index 1c713bf8..913d4835 100644
--- a/lib/bb/build.py
+++ b/lib/bb/build.py
@@ -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()
diff --git a/lib/bb/data_smart.py b/lib/bb/data_smart.py
index 55a6f314..77f18613 100644
--- a/lib/bb/data_smart.py
+++ b/lib/bb/data_smart.py
@@ -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
diff --git a/lib/bb/event.py b/lib/bb/event.py
index afd5bf57..8559858f 100644
--- a/lib/bb/event.py
+++ b/lib/bb/event.py
@@ -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
diff --git a/lib/bb/methodpool.py b/lib/bb/methodpool.py
index f43c4a05..1485b135 100644
--- a/lib/bb/methodpool.py
+++ b/lib/bb/methodpool.py
@@ -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
diff --git a/lib/bb/parse/ast.py b/lib/bb/parse/ast.py
index 59aa44be..d2ae09a4 100644
--- a/lib/bb/parse/ast.py
+++ b/lib/bb/parse/ast.py
@@ -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)
diff --git a/lib/bb/utils.py b/lib/bb/utils.py
index ad0aa68b..de0f3d34 100644
--- a/lib/bb/utils.py
+++ b/lib/bb/utils.py
@@ -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]+)(.*)$')
@@ -152,13 +159,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
@@ -181,7 +188,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()
@@ -203,6 +210,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