diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 4 | ||||
-rw-r--r-- | src/RELEASE.txt | 29 | ||||
-rw-r--r-- | src/engine/SCons/Action.py | 13 | ||||
-rw-r--r-- | src/engine/SCons/ActionTests.py | 12 | ||||
-rw-r--r-- | src/engine/SCons/Builder.py | 16 | ||||
-rw-r--r-- | src/engine/SCons/BuilderTests.py | 145 | ||||
-rw-r--r-- | src/engine/SCons/Environment.py | 60 | ||||
-rw-r--r-- | src/engine/SCons/EnvironmentTests.py | 59 | ||||
-rw-r--r-- | src/engine/SCons/SConf.py | 4 | ||||
-rw-r--r-- | src/engine/SCons/Util.py | 13 |
10 files changed, 191 insertions, 164 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 6550064..1c1829d 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -148,6 +148,10 @@ RELEASE 0.96 - XXX - Don't blow up with stack trace when the external $PATH environment variable isn't set. + - Make Builder calls return lists all the time, even if there's only + one target. This keeps things consistent and easier to program to + across platforms. + From Chris Murray: - Add a .win32 attribute to force file names to expand with diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 2228a83..0e63771 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -27,6 +27,33 @@ RELEASE 0.96 - XXX Please note the following important changes since release 0.95: + - All Builder calls (both built-in like Program(), Library(), + etc. and customer Builders) now always return a list of target + Nodes. If the Builder only builds one target, the Builder + call will now return a list containing that target Node, not + the target Node itself as it used to do. + + This change should be invisibile to most normal uses of the + return values from Builder calls. It will cause an error if the + SConscript file was performing some direct manipulation of the + returned Node value. For example, an attempt to print the name + of a target returned by the Object() Builder: + + target = Object('foo.c') + # OLD WAY + print target + + Will now need to access the first element in the list returned by + the Object() call: + + target = Object('foo.c') + # NEW AY + print target[0] + + This change was introduced to make the data type returned by Builder + calls consistent (always a list), regardless of platform or number + of returned targets. + - The SConsignFile() function now uses an internally-supplied SCons.dblite module as the default DB scheme for the .sconsign file. If you are using the SConsignFile() function without an explicitly @@ -58,7 +85,7 @@ RELEASE 0.96 - XXX FortranScan.add_skey('.x') => env.Append(FORTRANSUFFIXES = ['.x']) - The internal "node_factory" keyword argument has been removed; - the seperate and more flexible "target_factory" and "source_factory" + the separate and more flexible "target_factory" and "source_factory" keywords should be used instead. - SCons now treats file "extensions" that contain all digits (for diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 6a90c76..8306791 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -358,6 +358,7 @@ class CommandAction(ActionBase): # it is a path list, because that's a pretty # common list like value to stick in an environment # variable: + value = SCons.Util.flatten(value) ENV[key] = string.join(map(str, value), os.pathsep) elif not SCons.Util.is_String(value): # If it isn't a string or a list, then @@ -494,13 +495,13 @@ class FunctionAction(ActionBase): return "unknown_python_function" def strfunction(self, target, source, env): - def quote(s): - return '"' + str(s) + '"' - def array(a, q=quote): - return '[' + string.join(map(lambda x, q=q: q(x), a), ", ") + ']' + def array(a): + def quote(s): + return '"' + str(s) + '"' + return '[' + string.join(map(quote, a), ", ") + ']' name = self.function_name() - tstr = len(target) == 1 and quote(target[0]) or array(target) - sstr = len(source) == 1 and quote(source[0]) or array(source) + tstr = array(target) + sstr = array(source) return "%s(%s, %s)" % (name, tstr, sstr) def __str__(self): diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 9a89623..4c1649c 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -374,7 +374,7 @@ class ActionBaseTestCase(unittest.TestCase): result = a("out", "in", env) assert result == 7, result s = sio.getvalue() - assert s == 'execfunc("out", "in")\n', s + assert s == 'execfunc(["out"], ["in"])\n', s SCons.Action.execute_actions = 0 @@ -383,7 +383,7 @@ class ActionBaseTestCase(unittest.TestCase): result = a("out", "in", env) assert result == 0, result s = sio.getvalue() - assert s == 'execfunc("out", "in")\n', s + assert s == 'execfunc(["out"], ["in"])\n', s SCons.Action.print_actions_presub = 1 @@ -392,14 +392,14 @@ class ActionBaseTestCase(unittest.TestCase): result = a("out", "in", env) assert result == 0, result s = sio.getvalue() - assert s == 'execfunc("out", "in")\n', s + assert s == 'execfunc(["out"], ["in"])\n', s sio = StringIO.StringIO() sys.stdout = sio result = a("out", "in", env, presub=1) assert result == 0, result s = sio.getvalue() - assert s == 'Building out with action(s):\n execfunc(env, target, source)\nexecfunc("out", "in")\n', s + assert s == 'Building out with action(s):\n execfunc(env, target, source)\nexecfunc(["out"], ["in"])\n', s a2 = SCons.Action.Action(execfunc) @@ -408,14 +408,14 @@ class ActionBaseTestCase(unittest.TestCase): result = a2("out", "in", env) assert result == 0, result s = sio.getvalue() - assert s == 'Building out with action(s):\n execfunc(env, target, source)\nexecfunc("out", "in")\n', s + assert s == 'Building out with action(s):\n execfunc(env, target, source)\nexecfunc(["out"], ["in"])\n', s sio = StringIO.StringIO() sys.stdout = sio result = a2("out", "in", env, presub=0) assert result == 0, result s = sio.getvalue() - assert s == 'execfunc("out", "in")\n', s + assert s == 'execfunc(["out"], ["in"])\n', s sio = StringIO.StringIO() sys.stdout = sio diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 57f50c9..e6e7822 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -547,13 +547,11 @@ class BuilderBase: if len(tlist) == 1: builder = self - result = tlist[0] else: builder = ListBuilder(self, env, tlist) - result = tlist _init_nodes(builder, env, overwarn.data, tlist, slist) - return result + return tlist def __call__(self, env, target = None, source = _null, **kw): return self._execute(env, target, source, OverrideWarner(kw)) @@ -711,16 +709,14 @@ class MultiStepBuilder(BuilderBase): final_sources.append(snode) else: tgt = subsidiary_builder._execute(env, None, snode, overwarn) - # Only supply the builder with sources it is capable - # of building. - if SCons.Util.is_List(tgt): + # If the subsidiary Builder returned more than one target, + # then filter out any sources that this Builder isn't + # capable of building. + if len(tgt) > 1: tgt = filter(lambda x, self=self, suf=src_suffixes: self.splitext(SCons.Util.to_String(x))[1] in suf, tgt) - if not SCons.Util.is_List(tgt): - final_sources.append(tgt) - else: - final_sources.extend(tgt) + final_sources.extend(tgt) return BuilderBase._execute(self, env, target, final_sources, overwarn) diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index 57e9f28..5a605ec 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -214,15 +214,15 @@ class BuilderTestCase(unittest.TestCase): assert n1.executor, "no executor found" assert not hasattr(n2, 'env') - target = builder(env, target = 'n3', source = 'n4') + target = builder(env, target = 'n3', source = 'n4')[0] assert target.name == 'n3' assert target.sources[0].name == 'n4' - target = builder(env, target = 'n4 n5', source = ['n6 n7']) + target = builder(env, target = 'n4 n5', source = ['n6 n7'])[0] assert target.name == 'n4 n5' assert target.sources[0].name == 'n6 n7' - target = builder(env, target = ['n8 n9'], source = 'n10 n11') + target = builder(env, target = ['n8 n9'], source = 'n10 n11')[0] assert target.name == 'n8 n9' assert target.sources[0].name == 'n10 n11' @@ -240,12 +240,12 @@ class BuilderTestCase(unittest.TestCase): uni = unicode target = builder(env, target = uni('n12 n13'), - source = [uni('n14 n15')]) + source = [uni('n14 n15')])[0] assert target.name == uni('n12 n13') assert target.sources[0].name == uni('n14 n15') target = builder(env, target = [uni('n16 n17')], - source = uni('n18 n19')) + source = uni('n18 n19'))[0] assert target.name == uni('n16 n17') assert target.sources[0].name == uni('n18 n19') @@ -262,7 +262,7 @@ class BuilderTestCase(unittest.TestCase): source_factory=MyNode, prefix='p-', suffix='.s') - target = builder(env, source='n21') + target = builder(env, source='n21')[0] assert target.name == 'p-n21.s', target def test_mistaken_variables(self): @@ -395,19 +395,19 @@ class BuilderTestCase(unittest.TestCase): assert builder.get_prefix(env) == 'lib.' builder = SCons.Builder.Builder(prefix = 'lib') assert builder.get_prefix(env) == 'lib' - tgt = builder(env, target = 'tgt1', source = 'src1') + tgt = builder(env, target = 'tgt1', source = 'src1')[0] assert tgt.path == 'libtgt1', \ "Target has unexpected name: %s" % tgt.path - tgt = builder(env, target = 'tgt2a tgt2b', source = 'src2') + tgt = builder(env, target = 'tgt2a tgt2b', source = 'src2')[0] assert tgt.path == 'libtgt2a tgt2b', \ "Target has unexpected name: %s" % tgt.path - tgt = builder(env, source = 'src3') + tgt = builder(env, source = 'src3')[0] assert tgt.path == 'libsrc3', \ "Target has unexpected name: %s" % tgt.path - tgt = builder(env, source = 'lib/src4') + tgt = builder(env, source = 'lib/src4')[0] assert tgt.path == os.path.join('lib', 'libsrc4'), \ "Target has unexpected name: %s" % tgt.path - tgt = builder(env, target = 'lib/tgt5', source = 'lib/src5') + tgt = builder(env, target = 'lib/tgt5', source = 'lib/src5')[0] assert tgt.path == os.path.join('lib', 'libtgt5'), \ "Target has unexpected name: %s" % tgt.path @@ -427,17 +427,17 @@ class BuilderTestCase(unittest.TestCase): '.x' : 'y-', '$FOO' : 'foo-', '.zzz' : my_emit}) - tgt = builder(my_env, source = 'f1') + tgt = builder(my_env, source = 'f1')[0] assert tgt.path == 'default-f1', tgt.path - tgt = builder(my_env, source = 'f2.c') + tgt = builder(my_env, source = 'f2.c')[0] assert tgt.path == 'default-f2', tgt.path - tgt = builder(my_env, source = 'f3.in') + tgt = builder(my_env, source = 'f3.in')[0] assert tgt.path == 'out-f3', tgt.path - tgt = builder(my_env, source = 'f4.x') + tgt = builder(my_env, source = 'f4.x')[0] assert tgt.path == 'y-f4', tgt.path - tgt = builder(my_env, source = 'f5.foo') + tgt = builder(my_env, source = 'f5.foo')[0] assert tgt.path == 'foo-f5', tgt.path - tgt = builder(my_env, source = 'f6.zzz') + tgt = builder(my_env, source = 'f6.zzz')[0] assert tgt.path == 'emit-f6', tgt.path def test_src_suffix(self): @@ -451,11 +451,11 @@ class BuilderTestCase(unittest.TestCase): b1 = SCons.Builder.Builder(src_suffix = '.c') assert b1.src_suffixes(env) == ['.c'], b1.src_suffixes(env) - tgt = b1(env, target = 'tgt2', source = 'src2') + tgt = b1(env, target = 'tgt2', source = 'src2')[0] assert tgt.sources[0].path == 'src2.c', \ "Source has unexpected name: %s" % tgt.sources[0].path - tgt = b1(env, target = 'tgt3', source = 'src3a src3b') + tgt = b1(env, target = 'tgt3', source = 'src3a src3b')[0] assert len(tgt.sources) == 1 assert tgt.sources[0].path == 'src3a src3b.c', \ "Unexpected tgt.sources[0] name: %s" % tgt.sources[0].path @@ -485,13 +485,13 @@ class BuilderTestCase(unittest.TestCase): assert builder.get_suffix(env) == '.o', builder.get_suffix(env) builder = SCons.Builder.Builder(suffix = 'o') assert builder.get_suffix(env) == '.o', builder.get_suffix(env) - tgt = builder(env, target = 'tgt3', source = 'src3') + tgt = builder(env, target = 'tgt3', source = 'src3')[0] assert tgt.path == 'tgt3.o', \ "Target has unexpected name: %s" % tgt.path - tgt = builder(env, target = 'tgt4a tgt4b', source = 'src4') + tgt = builder(env, target = 'tgt4a tgt4b', source = 'src4')[0] assert tgt.path == 'tgt4a tgt4b.o', \ "Target has unexpected name: %s" % tgt.path - tgt = builder(env, source = 'src5') + tgt = builder(env, source = 'src5')[0] assert tgt.path == 'src5.o', \ "Target has unexpected name: %s" % tgt.path @@ -511,17 +511,17 @@ class BuilderTestCase(unittest.TestCase): '.x' : '.y', '$BAR' : '.new', '.zzz' : my_emit}) - tgt = builder(my_env, source = 'f1') + tgt = builder(my_env, source = 'f1')[0] assert tgt.path == 'f1.default', tgt.path - tgt = builder(my_env, source = 'f2.c') + tgt = builder(my_env, source = 'f2.c')[0] assert tgt.path == 'f2.default', tgt.path - tgt = builder(my_env, source = 'f3.in') + tgt = builder(my_env, source = 'f3.in')[0] assert tgt.path == 'f3.out', tgt.path - tgt = builder(my_env, source = 'f4.x') + tgt = builder(my_env, source = 'f4.x')[0] assert tgt.path == 'f4.y', tgt.path - tgt = builder(my_env, source = 'f5.bar') + tgt = builder(my_env, source = 'f5.bar')[0] assert tgt.path == 'f5.new', tgt.path - tgt = builder(my_env, source = 'f6.zzz') + tgt = builder(my_env, source = 'f6.zzz')[0] assert tgt.path == 'f6.emit', tgt.path def test_single_source(self): @@ -541,11 +541,11 @@ class BuilderTestCase(unittest.TestCase): builder = SCons.Builder.Builder(action=SCons.Action.Action(func,None), single_source = 1, suffix='.out') env['CNT'] = [0] - tgt = builder(env, target=outfiles[0], source=infiles[0]) + tgt = builder(env, target=outfiles[0], source=infiles[0])[0] tgt.prepare() tgt.build() assert env['CNT'][0] == 1, env['CNT'][0] - tgt = builder(env, outfiles[1], infiles[1]) + tgt = builder(env, outfiles[1], infiles[1])[0] tgt.prepare() tgt.build() assert env['CNT'][0] == 2 @@ -629,14 +629,15 @@ class BuilderTestCase(unittest.TestCase): src_builder = builder1, src_suffix = '.foo') - tgt = builder2(env, target='baz', source=['test.bar', 'test2.foo', 'test3.txt']) + tgt = builder2(env, target='baz', + source=['test.bar', 'test2.foo', 'test3.txt'])[0] assert str(tgt.sources[0]) == 'test.foo', str(tgt.sources[0]) assert str(tgt.sources[0].sources[0]) == 'test.bar', \ str(tgt.sources[0].sources[0]) assert str(tgt.sources[1]) == 'test2.foo', str(tgt.sources[1]) assert str(tgt.sources[2]) == 'test3.txt', str(tgt.sources[2]) - tgt = builder2(env, 'aaa.bar') + tgt = builder2(env, 'aaa.bar')[0] assert str(tgt) == 'aaa', str(tgt) assert str(tgt.sources[0]) == 'aaa.foo', str(tgt.sources[0]) assert str(tgt.sources[0].sources[0]) == 'aaa.bar', \ @@ -658,7 +659,7 @@ class BuilderTestCase(unittest.TestCase): src_builder=builder5, suffix='.exe', src_suffix='.obj') - tgt = builder6(env, 'test', 'test.i') + tgt = builder6(env, 'test', 'test.i')[0] assert str(tgt) == 'test.exe', str(tgt) assert str(tgt.sources[0]) == 'test_wrap.obj', str(tgt.sources[0]) assert str(tgt.sources[0].sources[0]) == 'test_wrap.c', \ @@ -679,14 +680,14 @@ class BuilderTestCase(unittest.TestCase): assert isinstance(builder, SCons.Builder.CompositeBuilder) assert isinstance(builder.action, SCons.Action.CommandGeneratorAction) - tgt = builder(env, target='test1', source='test1.foo') + tgt = builder(env, target='test1', source='test1.foo')[0] assert isinstance(tgt.builder, SCons.Builder.BuilderBase) assert tgt.builder.action is builder.action - tgt = builder(env, target='test2', source='test1.bar') + tgt = builder(env, target='test2', source='test1.bar')[0] assert isinstance(tgt.builder, SCons.Builder.BuilderBase) assert tgt.builder.action is builder.action flag = 0 - tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo']) + tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo'])[0] try: tgt.build() except SCons.Errors.UserError, e: @@ -695,7 +696,7 @@ class BuilderTestCase(unittest.TestCase): match = str(e) == "While building `['test3']' from `test1.foo': Cannot build multiple sources with different extensions: .bar, .foo" assert match, e - tgt = builder(env, target='test4', source=['test4.BAR2']) + tgt = builder(env, target='test4', source=['test4.BAR2'])[0] assert isinstance(tgt.builder, SCons.Builder.BuilderBase) try: tgt.build() @@ -707,7 +708,7 @@ class BuilderTestCase(unittest.TestCase): env['FOO_SUFFIX'] = '.BAR2' builder.add_action('$NEW_SUFFIX', func_action) flag = 0 - tgt = builder(env, target='test5', source=['test5.BAR2']) + tgt = builder(env, target='test5', source=['test5.BAR2'])[0] try: tgt.build() except SCons.Errors.UserError: @@ -726,10 +727,10 @@ class BuilderTestCase(unittest.TestCase): assert isinstance(builder, SCons.Builder.CompositeBuilder) assert isinstance(builder.action, SCons.Action.CommandGeneratorAction) - tgt = builder(env, target='t1', source='t1a.ina t1b.ina') + tgt = builder(env, target='t1', source='t1a.ina t1b.ina')[0] assert isinstance(tgt.builder, SCons.Builder.BuilderBase) - tgt = builder(env, target='t2', source='t2a.foo t2b.ina') + tgt = builder(env, target='t2', source='t2a.foo t2b.ina')[0] assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder), tgt.builder.__dict__ bar_bld = SCons.Builder.Builder(action = 'a-bar', @@ -743,14 +744,14 @@ class BuilderTestCase(unittest.TestCase): builder.add_action('.bar', 'bar') - tgt = builder(env, target='t3-foo', source='t3a.foo t3b.ina') + tgt = builder(env, target='t3-foo', source='t3a.foo t3b.ina')[0] assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder) - tgt = builder(env, target='t3-bar', source='t3a.bar t3b.inb') + tgt = builder(env, target='t3-bar', source='t3a.bar t3b.inb')[0] assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder) flag = 0 - tgt = builder(env, target='t5', source=['test5a.foo', 'test5b.inb']) + tgt = builder(env, target='t5', source=['test5a.foo', 'test5b.inb'])[0] try: tgt.build() except SCons.Errors.UserError, e: @@ -760,7 +761,7 @@ class BuilderTestCase(unittest.TestCase): assert match, e flag = 0 - tgt = builder(env, target='t6', source=['test6a.bar', 'test6b.ina']) + tgt = builder(env, target='t6', source=['test6a.bar', 'test6b.ina'])[0] try: tgt.build() except SCons.Errors.UserError, e: @@ -770,7 +771,7 @@ class BuilderTestCase(unittest.TestCase): assert match, e flag = 0 - tgt = builder(env, target='t4', source=['test4a.ina', 'test4b.inb']) + tgt = builder(env, target='t4', source=['test4a.ina', 'test4b.inb'])[0] try: tgt.build() except SCons.Errors.UserError, e: @@ -780,7 +781,7 @@ class BuilderTestCase(unittest.TestCase): assert match, e flag = 0 - tgt = builder(env, target='t7', source=['test7']) + tgt = builder(env, target='t7', source=['test7'])[0] try: tgt.build() except SCons.Errors.UserError, e: @@ -790,7 +791,7 @@ class BuilderTestCase(unittest.TestCase): assert match, e flag = 0 - tgt = builder(env, target='t8', source=['test8.unknown']) + tgt = builder(env, target='t8', source=['test8.unknown'])[0] try: tgt.build() except SCons.Errors.UserError, e: @@ -809,7 +810,7 @@ class BuilderTestCase(unittest.TestCase): env = Environment() builder = SCons.Builder.Builder(target_scanner=tscan, source_scanner=sscan) - tgt = builder(env, target='foo2', source='bar') + tgt = builder(env, target='foo2', source='bar')[0] assert tgt.target_scanner == tscan, tgt.target_scanner assert tgt.source_scanner == sscan, tgt.source_scanner @@ -820,7 +821,7 @@ class BuilderTestCase(unittest.TestCase): src_builder = builder1, target_scanner = tscan, source_scanner = tscan) - tgt = builder2(env, target='baz2', source='test.bar test2.foo test3.txt') + tgt = builder2(env, target='baz2', source='test.bar test2.foo test3.txt')[0] assert tgt.target_scanner == tscan, tgt.target_scanner assert tgt.source_scanner == tscan, tgt.source_scanner @@ -838,7 +839,7 @@ class BuilderTestCase(unittest.TestCase): # With no scanner specified, source_scanner and # backup_source_scanner are None. env1 = Environment() - tgt = builder(env1, target='foo1.x', source='bar.y') + tgt = builder(env1, target='foo1.x', source='bar.y')[0] src = tgt.sources[0] assert tgt.target_scanner != scanner, tgt.target_scanner assert src.source_scanner is None, src.source_scanner @@ -848,7 +849,7 @@ class BuilderTestCase(unittest.TestCase): # has a scanner must still set the scanner. env2 = Environment() env2.scanner = scanner - tgt = builder(env2, target='foo2.x', source='bar.y') + tgt = builder(env2, target='foo2.x', source='bar.y')[0] src = tgt.sources[0] assert tgt.target_scanner != scanner, tgt.target_scanner assert src.source_scanner is None, src.source_scanner @@ -864,7 +865,7 @@ class BuilderTestCase(unittest.TestCase): env=Environment(CC='cc') builder = SCons.Builder.Builder(action=buildFunc) - tgt = builder(env, target='foo', source='bar', foo=1, bar=2, CC='mycc') + tgt = builder(env, target='foo', source='bar', foo=1, bar=2, CC='mycc')[0] tgt.build() assert self.foo == 1, self.foo assert self.bar == 2, self.bar @@ -890,7 +891,7 @@ class BuilderTestCase(unittest.TestCase): emitter=emit, target_factory=MyNode, source_factory=MyNode) - tgt = builder(env, target='foo2', source='bar') + tgt = builder(env, target='foo2', source='bar')[0] assert str(tgt) == 'foo2', str(tgt) assert str(tgt.sources[0]) == 'bar', str(tgt.sources[0]) @@ -899,7 +900,7 @@ class BuilderTestCase(unittest.TestCase): assert 'foo3' in map(str, tgt), map(str, tgt) assert 'bar1' in map(str, tgt), map(str, tgt) - tgt = builder(env, target='foo4', source='bar', bar=1) + tgt = builder(env, target='foo4', source='bar', bar=1)[0] assert str(tgt) == 'foo4', str(tgt) assert len(tgt.sources) == 2, len(tgt.sources) assert 'baz' in map(str, tgt.sources), map(str, tgt.sources) @@ -911,7 +912,7 @@ class BuilderTestCase(unittest.TestCase): target_factory=MyNode, source_factory=MyNode) - tgt = builder2(env2, target='foo5', source='bar') + tgt = builder2(env2, target='foo5', source='bar')[0] assert str(tgt) == 'foo5', str(tgt) assert str(tgt.sources[0]) == 'bar', str(tgt.sources[0]) @@ -920,7 +921,7 @@ class BuilderTestCase(unittest.TestCase): assert 'foo6' in map(str, tgt), map(str, tgt) assert 'bar2' in map(str, tgt), map(str, tgt) - tgt = builder2(env2, target='foo7', source='bar', bar=1) + tgt = builder2(env2, target='foo7', source='bar', bar=1)[0] assert str(tgt) == 'foo7', str(tgt) assert len(tgt.sources) == 2, len(tgt.sources) assert 'baz' in map(str, tgt.sources), map(str, tgt.sources) @@ -947,7 +948,7 @@ class BuilderTestCase(unittest.TestCase): emitter=emit3, target_factory=MyNode, source_factory=MyNode) - tgt = builder3(env, target=node, source='bar') + tgt = builder3(env, target=node, source='bar')[0] assert tgt is new_node, tgt assert tgt.builder is builder3, tgt.builder assert node.builder is new_builder, node.builder @@ -967,11 +968,11 @@ class BuilderTestCase(unittest.TestCase): '.4b':emit4b}, target_factory=MyNode, source_factory=MyNode) - tgt = builder4(env, source='aaa.4a') + tgt = builder4(env, source='aaa.4a')[0] assert str(tgt) == 'emit4a-aaa', str(tgt) - tgt = builder4(env, source='bbb.4b') + tgt = builder4(env, source='bbb.4b')[0] assert str(tgt) == 'emit4b-bbb', str(tgt) - tgt = builder4(env, source='ccc.4c') + tgt = builder4(env, source='ccc.4c')[0] assert str(tgt) == 'ccc', str(tgt) def emit4c(target, source, env): @@ -979,7 +980,7 @@ class BuilderTestCase(unittest.TestCase): target = map(lambda x: 'emit4c-' + x[:-3], source) return (target, source) builder4.add_emitter('.4c', emit4c) - tgt = builder4(env, source='ccc.4c') + tgt = builder4(env, source='ccc.4c')[0] assert str(tgt) == 'emit4c-ccc', str(tgt) # Test a list of emitter functions. @@ -1024,51 +1025,51 @@ class BuilderTestCase(unittest.TestCase): env = Environment() b = SCons.Builder.Builder(action='foo', suffix='.o') - tgt = b(env, 'aaa') + tgt = b(env, 'aaa')[0] assert str(tgt) == 'aaa.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'aaa', map(str, tgt.sources) - tgt = b(env, 'bbb.c') + tgt = b(env, 'bbb.c')[0] assert str(tgt) == 'bbb.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'bbb.c', map(str, tgt.sources) - tgt = b(env, 'ccc.x.c') + tgt = b(env, 'ccc.x.c')[0] assert str(tgt) == 'ccc.x.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'ccc.x.c', map(str, tgt.sources) - tgt = b(env, ['d0.c', 'd1.c']) + tgt = b(env, ['d0.c', 'd1.c'])[0] assert str(tgt) == 'd0.o', str(tgt) assert len(tgt.sources) == 2, map(str, tgt.sources) assert str(tgt.sources[0]) == 'd0.c', map(str, tgt.sources) assert str(tgt.sources[1]) == 'd1.c', map(str, tgt.sources) - tgt = b(env, source='eee') + tgt = b(env, source='eee')[0] assert str(tgt) == 'eee.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'eee', map(str, tgt.sources) - tgt = b(env, source='fff.c') + tgt = b(env, source='fff.c')[0] assert str(tgt) == 'fff.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'fff.c', map(str, tgt.sources) - tgt = b(env, source='ggg.x.c') + tgt = b(env, source='ggg.x.c')[0] assert str(tgt) == 'ggg.x.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'ggg.x.c', map(str, tgt.sources) - tgt = b(env, source=['h0.c', 'h1.c']) + tgt = b(env, source=['h0.c', 'h1.c'])[0] assert str(tgt) == 'h0.o', str(tgt) assert len(tgt.sources) == 2, map(str, tgt.sources) assert str(tgt.sources[0]) == 'h0.c', map(str, tgt.sources) assert str(tgt.sources[1]) == 'h1.c', map(str, tgt.sources) - w = b(env, target='i0.w', source=['i0.x']) - y = b(env, target='i1.y', source=['i1.z']) - tgt = b(env, source=[w, y]) + w = b(env, target='i0.w', source=['i0.x'])[0] + y = b(env, target='i1.y', source=['i1.z'])[0] + tgt = b(env, source=[w, y])[0] assert str(tgt) == 'i0.o', str(tgt) assert len(tgt.sources) == 2, map(str, tgt.sources) assert str(tgt.sources[0]) == 'i0.w', map(str, tgt.sources) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 0e79eb4..8e0c5ee 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -338,7 +338,9 @@ class Base: if not args: return [] - if not SCons.Util.is_List(args): + if SCons.Util.is_List(args): + args = SCons.Util.flatten(args) + else: args = [args] nodes = [] @@ -354,10 +356,16 @@ class Base: n = self.subst(n, raw=1) if node_factory: n = node_factory(n) - nodes.append(n) + try: + nodes.extend(n) + except TypeError: + nodes.append(n) elif node_factory: - v = self.subst(v, raw=1) - nodes.append(node_factory(v)) + v = node_factory(self.subst(v, raw=1)) + try: + nodes.extend(v) + except TypeError: + nodes.append(v) else: nodes.append(v) @@ -964,20 +972,14 @@ class Base: s = self.arg2nodes(s, self.fs.Entry) for t in tlist: AliasBuilder(self, t, s) - if len(tlist) == 1: - tlist = tlist[0] return tlist def AlwaysBuild(self, *targets): tlist = [] for t in targets: tlist.extend(self.arg2nodes(t, self.fs.File)) - for t in tlist: t.set_always_build() - - if len(tlist) == 1: - tlist = tlist[0] return tlist def BuildDir(self, build_dir, src_dir, duplicate=1): @@ -1042,9 +1044,6 @@ class Base: dlist = self.arg2nodes(dependency, self.fs.Entry) for t in tlist: t.add_dependency(dlist) - - if len(tlist) == 1: - tlist = tlist[0] return tlist def Dir(self, name, *args, **kw): @@ -1072,10 +1071,11 @@ class Base: return SCons.Node.FS.find_file(file, nodes, self.fs.File) def GetBuildPath(self, files): - ret = map(str, self.arg2nodes(files, self.fs.Entry)) - if len(ret) == 1: - return ret[0] - return ret + result = map(str, self.arg2nodes(files, self.fs.Entry)) + if SCons.Util.is_List(files): + return result + else: + return result[0] def Ignore(self, target, dependency): """Ignore a dependency.""" @@ -1083,9 +1083,6 @@ class Base: dlist = self.arg2nodes(dependency, self.fs.Entry) for t in tlist: t.add_ignore(dlist) - - if len(tlist) == 1: - tlist = tlist[0] return tlist def Install(self, dir, source): @@ -1105,21 +1102,17 @@ class Base: for dnode in dnodes: for src in sources: target = self.fs.File(src.name, dnode) - tgt.append(InstallBuilder(self, target, src)) - if len(tgt) == 1: - tgt = tgt[0] + tgt.extend(InstallBuilder(self, target, src)) return tgt def InstallAs(self, target, source): """Install sources as targets.""" sources = self.arg2nodes(source, self.fs.File) targets = self.arg2nodes(target, self.fs.File) - ret = [] + result = [] for src, tgt in map(lambda x, y: (x, y), sources, targets): - ret.append(InstallBuilder(self, tgt, src)) - if len(ret) == 1: - ret = ret[0] - return ret + result.extend(InstallBuilder(self, tgt, src)) + return result def Literal(self, string): return SCons.Util.Literal(string) @@ -1140,12 +1133,8 @@ class Base: tlist = [] for t in targets: tlist.extend(self.arg2nodes(t, self.fs.Entry)) - for t in tlist: t.set_precious() - - if len(tlist) == 1: - tlist = tlist[0] return tlist def Repository(self, *dirs, **kw): @@ -1181,18 +1170,13 @@ class Base: self.Precious(side_effect) for target in targets: target.side_effects.append(side_effect) - if len(side_effects) == 1: - return side_effects[0] - else: - return side_effects + return side_effects def SourceCode(self, entry, builder): """Arrange for a source code builder for (part of) a tree.""" entries = self.arg2nodes(entry, self.fs.Entry) for entry in entries: entry.set_src_builder(builder) - if len(entries) == 1: - return entries[0] return entries def SourceSignatures(self, type): diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index c65fb03..1b2ceec 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -1733,31 +1733,31 @@ class EnvironmentTestCase(unittest.TestCase): """Test the Alias() method""" env = Environment(FOO='kkk', BAR='lll', EA='export_alias') - tgt = env.Alias('new_alias') + tgt = env.Alias('new_alias')[0] assert str(tgt) == 'new_alias', tgt assert tgt.sources == [], tgt.sources - tgt = env.Alias('None_alias', None) + tgt = env.Alias('None_alias', None)[0] assert str(tgt) == 'None_alias', tgt assert tgt.sources == [], tgt.sources - tgt = env.Alias('empty_list', []) + tgt = env.Alias('empty_list', [])[0] assert str(tgt) == 'empty_list', tgt assert tgt.sources == [], tgt.sources - tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ]) + tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])[0] assert str(tgt) == 'export_alias', tgt assert len(tgt.sources) == 2, map(str, tgt.sources) assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources) assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources) - n = env.Alias(tgt, source = ['$BAR', 'asrc4']) + n = env.Alias(tgt, source = ['$BAR', 'asrc4'])[0] assert n is tgt, n assert len(tgt.sources) == 4, map(str, tgt.sources) assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources) assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources) - n = env.Alias('$EA', 'asrc5') + n = env.Alias('$EA', 'asrc5')[0] assert n is tgt, n assert len(tgt.sources) == 5, map(str, tgt.sources) assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources) @@ -1880,7 +1880,7 @@ class EnvironmentTestCase(unittest.TestCase): """Test the Command() method.""" env = Environment() t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'], - action='buildfoo $target $source') + action='buildfoo $target $source')[0] assert not t.builder is None assert t.builder.action.__class__.__name__ == 'CommandAction' assert t.builder.action.cmd_list == 'buildfoo $target $source' @@ -1889,7 +1889,7 @@ class EnvironmentTestCase(unittest.TestCase): sub = SCons.Node.FS.default_fs.Dir('sub') t = env.Command(target='bar.out', source='sub', - action='buildbar $target $source') + action='buildbar $target $source')[0] assert 'sub' in map(lambda x: x.path, t.sources) def testFunc(env, target, source): @@ -1897,7 +1897,7 @@ class EnvironmentTestCase(unittest.TestCase): assert 'foo1.in' in map(str, source) and 'foo2.in' in map(str, source), map(str, source) return 0 t = env.Command(target='foo.out', source=['foo1.in','foo2.in'], - action=testFunc) + action=testFunc)[0] assert not t.builder is None assert t.builder.action.__class__.__name__ == 'FunctionAction' t.build() @@ -1910,7 +1910,7 @@ class EnvironmentTestCase(unittest.TestCase): env = Environment(TEST2 = test2) t = env.Command(target='baz.out', source='baz.in', action='${TEST2(XYZ)}', - XYZ='magic word') + XYZ='magic word')[0] assert not t.builder is None t.build() assert x[0] == 'magic word', x @@ -1951,7 +1951,8 @@ class EnvironmentTestCase(unittest.TestCase): env.Dir('dir2') env.File('xxx.py') env.File('yyy.py') - t = env.Depends(target='EnvironmentTest.py', dependency='Environment.py') + t = env.Depends(target='EnvironmentTest.py', + dependency='Environment.py')[0] assert t.__class__.__name__ == 'Entry', t.__class__.__name__ assert t.path == 'EnvironmentTest.py' assert len(t.depends) == 1 @@ -1959,7 +1960,7 @@ class EnvironmentTestCase(unittest.TestCase): assert d.__class__.__name__ == 'Entry', d.__class__.__name__ assert d.path == 'Environment.py' - t = env.Depends(target='${FOO}.py', dependency='${BAR}.py') + t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')[0] assert t.__class__.__name__ == 'File', t.__class__.__name__ assert t.path == 'xxx.py' assert len(t.depends) == 1 @@ -1967,7 +1968,7 @@ class EnvironmentTestCase(unittest.TestCase): assert d.__class__.__name__ == 'File', d.__class__.__name__ assert d.path == 'yyy.py' - t = env.Depends(target='dir1', dependency='dir2') + t = env.Depends(target='dir1', dependency='dir2')[0] assert t.__class__.__name__ == 'Dir', t.__class__.__name__ assert t.path == 'dir1' assert len(t.depends) == 1 @@ -2061,7 +2062,7 @@ class EnvironmentTestCase(unittest.TestCase): env.File('yyyzzz') env.File('zzzyyy') - t = env.Ignore(target='targ.py', dependency='dep.py') + t = env.Ignore(target='targ.py', dependency='dep.py')[0] assert t.__class__.__name__ == 'Entry', t.__class__.__name__ assert t.path == 'targ.py' assert len(t.ignore) == 1 @@ -2069,7 +2070,7 @@ class EnvironmentTestCase(unittest.TestCase): assert i.__class__.__name__ == 'Entry', i.__class__.__name__ assert i.path == 'dep.py' - t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO') + t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')[0] assert t.__class__.__name__ == 'File', t.__class__.__name__ assert t.path == 'yyyzzz' assert len(t.ignore) == 1 @@ -2077,7 +2078,7 @@ class EnvironmentTestCase(unittest.TestCase): assert i.__class__.__name__ == 'File', i.__class__.__name__ assert i.path == 'zzzyyy' - t = env.Ignore(target='dir1', dependency='dir2') + t = env.Ignore(target='dir1', dependency='dir2')[0] assert t.__class__.__name__ == 'Dir', t.__class__.__name__ assert t.path == 'dir1' assert len(t.ignore) == 1 @@ -2146,7 +2147,7 @@ class EnvironmentTestCase(unittest.TestCase): for tnode in tgt: assert tnode.builder == InstallBuilder - tgt = env.InstallAs(target='${FOO}.t', source='${BAR}.s') + tgt = env.InstallAs(target='${FOO}.t', source='${BAR}.s')[0] assert tgt.path == 'iii.t' assert tgt.sources[0].path == 'jjj.s' assert tgt.builder == InstallBuilder @@ -2282,9 +2283,9 @@ class EnvironmentTestCase(unittest.TestCase): env.File('mylll.pdb') env.Dir('mymmm.pdb') - foo = env.Object('foo.obj', 'foo.cpp') - bar = env.Object('bar.obj', 'bar.cpp') - s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj']) + foo = env.Object('foo.obj', 'foo.cpp')[0] + bar = env.Object('bar.obj', 'bar.cpp')[0] + s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])[0] assert s.__class__.__name__ == 'Entry', s.__class__.__name__ assert s.path == 'mylib.pdb' assert s.side_effect @@ -2293,9 +2294,9 @@ class EnvironmentTestCase(unittest.TestCase): assert s.depends_on([bar]) assert s.depends_on([foo]) - fff = env.Object('fff.obj', 'fff.cpp') - bbb = env.Object('bbb.obj', 'bbb.cpp') - s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj']) + fff = env.Object('fff.obj', 'fff.cpp')[0] + bbb = env.Object('bbb.obj', 'bbb.cpp')[0] + s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])[0] assert s.__class__.__name__ == 'File', s.__class__.__name__ assert s.path == 'mylll.pdb' assert s.side_effect @@ -2304,9 +2305,9 @@ class EnvironmentTestCase(unittest.TestCase): assert s.depends_on([bbb]) assert s.depends_on([fff]) - ggg = env.Object('ggg.obj', 'ggg.cpp') - ccc = env.Object('ccc.obj', 'ccc.cpp') - s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj']) + ggg = env.Object('ggg.obj', 'ggg.cpp')[0] + ccc = env.Object('ccc.obj', 'ccc.cpp')[0] + s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])[0] assert s.__class__.__name__ == 'Dir', s.__class__.__name__ assert s.path == 'mymmm.pdb' assert s.side_effect @@ -2318,18 +2319,18 @@ class EnvironmentTestCase(unittest.TestCase): def test_SourceCode(self): """Test the SourceCode() method.""" env = Environment(FOO='mmm', BAR='nnn') - e = env.SourceCode('foo', None) + e = env.SourceCode('foo', None)[0] assert e.path == 'foo' s = e.src_builder() assert s is None, s b = Builder() - e = env.SourceCode(e, b) + e = env.SourceCode(e, b)[0] assert e.path == 'foo' s = e.src_builder() assert s is b, s - e = env.SourceCode('$BAR$FOO', None) + e = env.SourceCode('$BAR$FOO', None)[0] assert e.path == 'nnnmmm' s = e.src_builder() assert s is None, s diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index 8087136..3aac882 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -268,7 +268,7 @@ class SConf: source = self.confdir.File(f + extension) sourceNode = self.env.SConfSourceBuilder(target=source, source=None) - nodesToBeBuilt.append(sourceNode) + nodesToBeBuilt.extend(sourceNode) else: source = None @@ -335,7 +335,7 @@ class SConf: pname = str(prog) output = SConfFS.File(pname+'.out') node = self.env.Command(output, prog, [ [ pname, ">", "${TARGET}"] ]) - ok = self.BuildNodes([node]) + ok = self.BuildNodes(node) if ok: outputStr = output.get_contents() return( 1, outputStr) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 261d73c..25cea2f 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -953,6 +953,19 @@ else: def is_String(e): return type(e) is types.StringType or isinstance(e, UserString) +def is_Scalar(e): + return is_String(e) or not is_List(e) + +def flatten(sequence, scalarp=is_Scalar, result=None): + if result is None: + result = [] + for item in sequence: + if scalarp(item): + result.append(item) + else: + flatten(item, scalarp, result) + return result + class Proxy: """A simple generic Proxy class, forwarding all calls to subject. So, for the benefit of the python newbie, what does |