From 92bc9f3929e00394956aa7c976ab8696179f5586 Mon Sep 17 00:00:00 2001 From: stevenknight Date: Mon, 27 Sep 2004 21:24:20 +0000 Subject: [PATCH] Fix env.subst() stack trace on var containing ListAction. git-svn-id: http://scons.tigris.org/svn/scons/trunk@1108 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/CHANGES.txt | 3 +++ src/engine/SCons/Util.py | 28 ++++++++++++++++++++-------- src/engine/SCons/UtilTests.py | 28 ++++++++++++++++++++++++++++ test/actions.py | 20 ++++++++++++++++++++ 4 files changed, 71 insertions(+), 8 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 4f50aecc..7032d691 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -76,6 +76,9 @@ RELEASE 0.97 - XXX through "chdir" keyword arguments to Action and Builder creation and calls. + - Fix handling of Action ojects (and other callables that don't match + our calling arguments) in construction variable expansions. + From Clive Levinson: - Make ParseConfig() recognize and add -mno-cygwin to $LINKFLAGS and diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index afcaf112..984bb021 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -606,10 +606,16 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, dict=No r.append(self.conv(self.substitute(l, lvars))) return string.join(r) elif callable(s): - s = s(target=self.target, - source=self.source, - env=self.env, - for_signature=(self.mode != SUBST_CMD)) + try: + s = s(target=self.target, + source=self.source, + env=self.env, + for_signature=(self.mode != SUBST_CMD)) + except TypeError: + # This probably indicates that it's a callable + # object that doesn't match our calling arguments + # (like an Action). + s = str(s) return self.substitute(s, lvars) elif s is None: return '' @@ -753,10 +759,16 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, di self.substitute(a, lvars, 1) self.next_word() elif callable(s): - s = s(target=self.target, - source=self.source, - env=self.env, - for_signature=(self.mode != SUBST_CMD)) + try: + s = s(target=self.target, + source=self.source, + env=self.env, + for_signature=(self.mode != SUBST_CMD)) + except TypeError: + # This probably indicates that it's a callable + # object that doesn't match our calling arguments + # (like an Action). + s = str(s) self.substitute(s, lvars, within_list) elif s is None: self.this_word() diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 054d0b24..5ac6ec00 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -130,6 +130,14 @@ class UtilTestCase(unittest.TestCase): def is_literal(self): return 1 + class TestCallable: + def __init__(self, value): + self.value = value + def __call__(self): + pass + def __str__(self): + return self.value + def function_foo(arg): pass @@ -194,6 +202,9 @@ class UtilTestCase(unittest.TestCase): 'RECURSE' : 'foo $RECURSE bar', 'RRR' : 'foo $SSS bar', 'SSS' : '$RRR', + + # Test callables that don't match the calling arguments. + 'CALLABLE' : TestCallable('callable-1'), } env = DummyEnv(loc) @@ -307,6 +318,9 @@ class UtilTestCase(unittest.TestCase): # Bug reported by Christoph Wiedemann. cvt('$xxx/bin'), '/bin', + + # Tests callables that don't match our calling arguments. + '$CALLABLE', 'callable-1', ] kwargs = {'target' : target, 'source' : source} @@ -474,6 +488,14 @@ class UtilTestCase(unittest.TestCase): self.attribute.attr1 = 'attr$1-' + os.path.basename(name) self.attribute.attr2 = 'attr$2-' + os.path.basename(name) + class TestCallable: + def __init__(self, value): + self.value = value + def __call__(self): + pass + def __str__(self): + return self.value + target = [ MyNode("./foo/bar.exe"), MyNode("/bar/baz with spaces.obj"), MyNode("../foo/baz.obj") ] @@ -529,6 +551,9 @@ class UtilTestCase(unittest.TestCase): 'RECURSE' : 'foo $RECURSE bar', 'RRR' : 'foo $SSS bar', 'SSS' : '$RRR', + + # Test callable objects that don't match our calling arguments. + 'CALLABLE' : TestCallable('callable-2'), } env = DummyEnv(loc) @@ -660,6 +685,9 @@ class UtilTestCase(unittest.TestCase): '<$AAA', [['<', 'a']], '>$AAA', [['>', 'a']], '|$AAA', [['|', 'a']], + + # Test callables that don't match our calling arguments. + '$CALLABLE', [['callable-2']], ] kwargs = {'target' : target, 'source' : source} diff --git a/test/actions.py b/test/actions.py index 42b391cf..8a64a242 100644 --- a/test/actions.py +++ b/test/actions.py @@ -110,4 +110,24 @@ test.fail_test(test.read('foo.out') != "4\nfoo.in\n") test.up_to_date(arguments = '.') +# Make sure we can expand actions in substitutions. +test.write('SConstruct', """\ +def func(env, target, source): + pass +env = Environment(S = Action('foo'), + F = Action(func), + L = Action(['arg1', 'arg2'])) +print env.subst('$S') +print env.subst('$F') +print env.subst('$L') +""") + +test.run(arguments = '-Q .', stdout = """\ +foo +func(env, target, source) +arg1 +arg2 +scons: `.' is up to date. +""") + test.pass_test() -- 2.26.2