From 31615ed4df11661975191af901f33d54989f8a91 Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Thu, 14 Jan 2010 07:02:42 +0000 Subject: Fix use of varlist in CommandGeneratorAction, ListAction and LazyAction by adding a .get_varlist() accessor method that lets those wrapping classes fetch the varlist from their wrapped Action object(s). --- src/engine/SCons/Action.py | 18 ++++++++- src/engine/SCons/ActionTests.py | 90 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index da041c6..41c73ad 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -430,7 +430,7 @@ class ActionBase: # This should never happen, as the Action() factory should wrap # the varlist, but just in case an action is created directly, # we duplicate this check here. - vl = self.varlist + vl = self.get_varlist(target, source, env) if is_String(vl): vl = (vl,) for v in vl: result.append(env.subst('${'+v+'}')) @@ -454,6 +454,9 @@ class ActionBase: self.presub_env = None # don't need this any more return lines + def get_varlist(self, target, source, env, executor=None): + return self.varlist + def get_targets(self, env, executor): """ Returns the type of targets ($TARGETS, $CHANGED_TARGETS) used @@ -897,6 +900,9 @@ class CommandGeneratorAction(ActionBase): def get_implicit_deps(self, target, source, env, executor=None): return self._generate(target, source, env, 1, executor).get_implicit_deps(target, source, env) + def get_varlist(self, target, source, env, executor=None): + return self._generate(target, source, env, 1, executor).get_varlist(target, source, env, executor) + def get_targets(self, env, executor): return self._generate(None, None, env, 1, executor).get_targets(env, executor) @@ -958,6 +964,9 @@ class LazyAction(CommandGeneratorAction, CommandAction): c = self.get_parent_class(env) return c.get_presig(self, target, source, env) + def get_varlist(self, target, source, env, executor=None): + c = self.get_parent_class(env) + return c.get_varlist(self, target, source, env, executor) class FunctionAction(_ActionAction): @@ -1139,6 +1148,13 @@ class ListAction(ActionBase): result.extend(act.get_implicit_deps(target, source, env)) return result + def get_varlist(self, target, source, env, executor=None): + result = SCons.Util.OrderedDict() + for act in self.list: + for var in act.get_varlist(target, source, env, executor): + result[var] = True + return result.keys() + class ActionCaller: """A class for delaying calling an Action function with specific (positional and keyword) arguments until the Action is actually diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index b3f5221..4c2198b 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -1485,6 +1485,55 @@ class CommandGeneratorActionTestCase(unittest.TestCase): c = a.get_contents(target=[], source=[], env=env) assert c == "guux FFF BBB test", c + def test_get_contents_of_function_action(self): + """Test contents of a CommandGeneratorAction-generated FunctionAction + """ + + def LocalFunc(): + pass + + func_matches = [ + "0,0,0,0,(),(),(d\000\000S),(),()", + "0,0,0,0,(),(),(d\x00\x00S),(),()", + ] + + meth_matches = [ + "1,1,0,0,(),(),(d\000\000S),(),()", + "1,1,0,0,(),(),(d\x00\x00S),(),()", + ] + + def f_global(target, source, env, for_signature): + return SCons.Action.Action(GlobalFunc) + + def f_local(target, source, env, for_signature): + return SCons.Action.Action(LocalFunc) + + env = Environment(XYZ = 'foo') + + a = self.factory(f_global) + c = a.get_contents(target=[], source=[], env=env) + assert c in func_matches, repr(c) + + a = self.factory(f_local) + c = a.get_contents(target=[], source=[], env=env) + assert c in func_matches, repr(c) + + def f_global(target, source, env, for_signature): + return SCons.Action.Action(GlobalFunc, varlist=['XYZ']) + + def f_local(target, source, env, for_signature): + return SCons.Action.Action(LocalFunc, varlist=['XYZ']) + + matches_foo = map(lambda x: x + "foo", func_matches) + + a = self.factory(f_global) + c = a.get_contents(target=[], source=[], env=env) + assert c in matches_foo, repr(c) + + a = self.factory(f_local) + c = a.get_contents(target=[], source=[], env=env) + assert c in matches_foo, repr(c) + class FunctionActionTestCase(unittest.TestCase): @@ -1808,6 +1857,47 @@ class LazyActionTestCase(unittest.TestCase): c = a.get_contents(target=[], source=[], env=env) assert c == "This is a test", c + def test_get_contents_of_function_action(self): + """Test fetching the contents of a lazy-evaluation FunctionAction + """ + + def LocalFunc(): + pass + + func_matches = [ + "0,0,0,0,(),(),(d\000\000S),(),()", + "0,0,0,0,(),(),(d\x00\x00S),(),()", + ] + + meth_matches = [ + "1,1,0,0,(),(),(d\000\000S),(),()", + "1,1,0,0,(),(),(d\x00\x00S),(),()", + ] + + def factory(act, **kw): + return SCons.Action.FunctionAction(act, kw) + + + a = SCons.Action.Action("${FOO}") + + env = Environment(FOO = factory(GlobalFunc)) + c = a.get_contents(target=[], source=[], env=env) + assert c in func_matches, repr(c) + + env = Environment(FOO = factory(LocalFunc)) + c = a.get_contents(target=[], source=[], env=env) + assert c in func_matches, repr(c) + + matches_foo = map(lambda x: x + "foo", func_matches) + + env = Environment(FOO = factory(GlobalFunc, varlist=['XYZ'])) + c = a.get_contents(target=[], source=[], env=env) + assert c in func_matches, repr(c) + + env['XYZ'] = 'foo' + c = a.get_contents(target=[], source=[], env=env) + assert c in matches_foo, repr(c) + class ActionCallerTestCase(unittest.TestCase): def test___init__(self): """Test creation of an ActionCaller""" -- cgit v0.12