From 77a494e893032d420ea18c6ad6235c609050facd Mon Sep 17 00:00:00 2001 From: stevenknight Date: Fri, 18 Mar 2005 13:37:06 +0000 Subject: [PATCH] Fix a regression in handling overridden construction variables when the substitution is called from an Environment.Base class. git-svn-id: http://scons.tigris.org/svn/scons/trunk@1257 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/engine/SCons/Environment.py | 7 +- src/engine/SCons/EnvironmentTests.py | 162 ++++++++++++++++++++++----- 2 files changed, 140 insertions(+), 29 deletions(-) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 405243c3..9b93e12d 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -1402,7 +1402,7 @@ class Base(SubstitutionEnvironment): """ return SCons.Node.Python.Value(value) -class OverrideEnvironment(SubstitutionEnvironment): +class OverrideEnvironment(Base): """A proxy that overrides variables in a wrapped construction environment by returning values from an overrides dictionary in preference to values from the underlying subject environment. @@ -1464,6 +1464,11 @@ class OverrideEnvironment(SubstitutionEnvironment): return 1 except KeyError: return self.__dict__['__subject'].has_key(key) + def Dictionary(self): + """Emulates the items() method of dictionaries.""" + d = self.__dict__['__subject'].Dictionary().copy() + d.update(self.__dict__['overrides']) + return d def items(self): """Emulates the items() method of dictionaries.""" return self.Dictionary().items() diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 0e5da860..37a2dca7 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -2833,11 +2833,19 @@ f5: \ class OverrideEnvironmentTestCase(unittest.TestCase): + def setUp(self): + env = Environment() + env._dict = {'XXX' : 'x', 'YYY' : 'y'} + env2 = OverrideEnvironment(env, {'XXX' : 'x2'}) + env3 = OverrideEnvironment(env2, {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}) + self.envs = [ env, env2, env3 ] + + def checkpath(self, node, expect): + return str(node) == os.path.normpath(expect) + def test___init__(self): """Test OverrideEnvironment initialization""" - env = Environment(XXX = 'x', YYY = 'y') - env2 = OverrideEnvironment(env, {'XXX' : 'x2'}) - env3 = OverrideEnvironment(env2, {'XXX' : 'x3', 'YYY' : 'y3'}) + env, env2, env3 = self.envs assert env['XXX'] == 'x', env['XXX'] assert env2['XXX'] == 'x2', env2['XXX'] assert env3['XXX'] == 'x3', env3['XXX'] @@ -2847,9 +2855,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase): def test_get(self): """Test the OverrideEnvironment get() method""" - env = Environment(XXX = 'x', YYY = 'y') - env2 = OverrideEnvironment(env, {'XXX' : 'x2'}) - env3 = OverrideEnvironment(env2, {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}) + env, env2, env3 = self.envs assert env.get('XXX') == 'x', env.get('XXX') assert env2.get('XXX') == 'x2', env2.get('XXX') assert env3.get('XXX') == 'x3', env3.get('XXX') @@ -2862,9 +2868,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase): def test_has_key(self): """Test the OverrideEnvironment has_key() method""" - env = Environment(XXX = 'x', YYY = 'y') - env2 = OverrideEnvironment(env, {'XXX' : 'x2'}) - env3 = OverrideEnvironment(env2, {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}) + env, env2, env3 = self.envs assert env.has_key('XXX'), env.has_key('XXX') assert env2.has_key('XXX'), env2.has_key('XXX') assert env3.has_key('XXX'), env3.has_key('XXX') @@ -2875,47 +2879,52 @@ class OverrideEnvironmentTestCase(unittest.TestCase): assert not env2.has_key('ZZZ'), env2.has_key('ZZZ') assert env3.has_key('ZZZ'), env3.has_key('ZZZ') + def test_items(self): + """Test the OverrideEnvironment Dictionary() method""" + env, env2, env3 = self.envs + items = env.Dictionary() + assert items == {'XXX' : 'x', 'YYY' : 'y'}, items + items = env2.Dictionary() + assert items == {'XXX' : 'x2', 'YYY' : 'y'}, items + items = env3.Dictionary() + assert items == {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, items + def test_items(self): """Test the OverrideEnvironment items() method""" - env = Environment(WWW = 'w', XXX = 'x', YYY = 'y') - env2 = OverrideEnvironment(env, {'XXX' : 'x2'}) - env3 = OverrideEnvironment(env2, {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}) + env, env2, env3 = self.envs items = env.items() - assert items == {'WWW' : 'w', 'XXX' : 'x', 'YYY' : 'y'}, items + items.sort() + assert items == [('XXX', 'x'), ('YYY', 'y')], items items = env2.items() - assert items == {'WWW' : 'w', 'XXX' : 'x2', 'YYY' : 'y'}, items + items.sort() + assert items == [('XXX', 'x2'), ('YYY', 'y')], items items = env3.items() - assert items == {'WWW' : 'w', 'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, items + items.sort() + assert items == [('XXX', 'x3'), ('YYY', 'y3'), ('ZZZ', 'z3')], items def test_gvars(self): """Test the OverrideEnvironment gvars() method""" - env = Environment(XXX = 'x', YYY = 'y') - env2 = OverrideEnvironment(env, {'xxx' : 'x2'}) - env3 = OverrideEnvironment(env2, {'XXX' : 'x3', 'YYY' : 'y3'}) + env, env2, env3 = self.envs gvars = env.gvars() assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars gvars = env2.gvars() - assert gvars == {'XXX' : 'x2', 'YYY' : 'y'}, gvars + assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars gvars = env3.gvars() - assert gvars == {'XXX' : 'x3', 'YYY' : 'y3'}, gvars + assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars def test_lvars(self): """Test the OverrideEnvironment lvars() method""" - env = Environment(XXX = 'x', YYY = 'y') - env2 = OverrideEnvironment(env, {'xxx' : 'x2'}) - env3 = OverrideEnvironment(env2, {'xxx' : 'x3', 'YYY' : 'y3'}) + env, env2, env3 = self.envs lvars = env.lvars() assert lvars == {}, lvars lvars = env2.lvars() - assert lvars == {'XXX' : 'x2', 'YYY' : 'y'}, lvars + assert lvars == {'XXX' : 'x2'}, lvars lvars = env3.lvars() - assert lvars == {'XXX' : 'x3', 'YYY' : 'y3'}, lvars + assert lvars == {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, lvars def test_Replace(self): """Test the OverrideEnvironment Replace() method""" - env = Environment(XXX = 'x', YYY = 'y') - env2 = OverrideEnvironment(env, {'xxx' : 'x2'}) - env3 = OverrideEnvironment(env2, {'xxx' : 'x3', 'YYY' : 'y3'}) + env, env2, env3 = self.envs assert env['XXX'] == 'x', env['XXX'] assert env2['XXX'] == 'x2', env2['XXX'] assert env3['XXX'] == 'x3', env3['XXX'] @@ -2932,6 +2941,102 @@ class OverrideEnvironmentTestCase(unittest.TestCase): assert env2['YYY'] == 'y4', env2['YYY'] assert env3['YYY'] == 'y3', env3['YYY'] + # Tests a number of Base methods through an OverrideEnvironment to + # make sure they handle overridden constructionv variables properly. + # + # The following Base methods also call self.subst(), and so could + # theoretically be subject to problems with evaluating overridden + # variables, but they're never really called that way in the rest + # of our code, so we won't worry about them (at least for now): + # + # ParseConfig() + # ParseDepends() + # Platform() + # Tool() + # + # Action() + # Alias() + # Builder() + # CacheDir() + # Configure() + # Environment() + # FindFile() + # Scanner() + # SourceSignatures() + # TargetSignatures() + + # It's unlikely Copy() will ever be called this way, so let the + # other methods test that handling overridden values works. + #def test_Copy(self): + # """Test the OverrideEnvironment Copy() method""" + # pass + + def test_FindIxes(self): + """Test the OverrideEnvironment FindIxes() method""" + env, env2, env3 = self.envs + x = env.FindIxes(['xaaay'], 'XXX', 'YYY') + assert x == 'xaaay', x + x = env2.FindIxes(['x2aaay'], 'XXX', 'YYY') + assert x == 'x2aaay', x + x = env3.FindIxes(['x3aaay3'], 'XXX', 'YYY') + assert x == 'x3aaay3', x + + def test_ReplaceIxes(self): + """Test the OverrideEnvironment ReplaceIxes() method""" + env, env2, env3 = self.envs + x = env.ReplaceIxes('xaaay', 'XXX', 'YYY', 'YYY', 'XXX') + assert x == 'yaaax', x + x = env2.ReplaceIxes('x2aaay', 'XXX', 'YYY', 'YYY', 'XXX') + assert x == 'yaaax2', x + x = env3.ReplaceIxes('x3aaay3', 'XXX', 'YYY', 'YYY', 'XXX') + assert x == 'y3aaax3', x + + # It's unlikely WhereIs() will ever be called this way, so let the + # other methods test that handling overridden values works. + #def test_WhereIs(self): + # """Test the OverrideEnvironment WhereIs() method""" + # pass + + def test_Dir(self): + """Test the OverrideEnvironment Dir() method""" + env, env2, env3 = self.envs + x = env.Dir('ddir/$XXX') + assert self.checkpath(x, 'ddir/x'), str(x) + x = env2.Dir('ddir/$XXX') + assert self.checkpath(x, 'ddir/x2'), str(x) + x = env3.Dir('ddir/$XXX') + assert self.checkpath(x, 'ddir/x3'), str(x) + + def test_Entry(self): + """Test the OverrideEnvironment Entry() method""" + env, env2, env3 = self.envs + x = env.Entry('edir/$XXX') + assert self.checkpath(x, 'edir/x'), str(x) + x = env2.Entry('edir/$XXX') + assert self.checkpath(x, 'edir/x2'), str(x) + x = env3.Entry('edir/$XXX') + assert self.checkpath(x, 'edir/x3'), str(x) + + def test_File(self): + """Test the OverrideEnvironment File() method""" + env, env2, env3 = self.envs + x = env.File('fdir/$XXX') + assert self.checkpath(x, 'fdir/x'), str(x) + x = env2.File('fdir/$XXX') + assert self.checkpath(x, 'fdir/x2'), str(x) + x = env3.File('fdir/$XXX') + assert self.checkpath(x, 'fdir/x3'), str(x) + + def test_Split(self): + """Test the OverrideEnvironment Split() method""" + env, env2, env3 = self.envs + env['AAA'] = '$XXX $YYY $ZZZ' + x = env.Split('$AAA') + assert x == ['x', 'y'], x + x = env2.Split('$AAA') + assert x == ['x2', 'y'], x + x = env3.Split('$AAA') + assert x == ['x3', 'y3', 'z3'], x @@ -3041,6 +3146,7 @@ if __name__ == "__main__": suite = unittest.TestSuite() tclasses = [ SubstitutionTestCase, BaseTestCase, + OverrideEnvironmentTestCase, NoSubstitutionProxyTestCase ] for tclass in tclasses: names = unittest.getTestCaseNames(tclass, 'test_') -- 2.26.2