From 98df366e9ed2c4cb18cb31ab82b773044d12854f Mon Sep 17 00:00:00 2001 From: stevenknight Date: Fri, 26 Mar 2004 22:09:41 +0000 Subject: [PATCH] Refactor env.Append() and env.Prepend(). git-svn-id: http://scons.tigris.org/svn/scons/trunk@931 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/CHANGES.txt | 3 + src/RELEASE.txt | 28 +++++- src/engine/SCons/Environment.py | 128 +++++++++++++++++++-------- src/engine/SCons/EnvironmentTests.py | 12 +-- 4 files changed, 128 insertions(+), 43 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index c421d120..637f9592 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -27,6 +27,9 @@ RELEASE 0.96 - XXX - Fix use of $MSVS_IGNORE_IDE_PATHS, which was broken when we added support for $MSVS_USE_MFC_DIRS last release. + - Make env.Append() and env.Prepend() act like the underlying Python + behavior when the variable being appended to is a UserList object. + From Gary Oberbrunner: - Add a --debug=presub option to print actions prior to substitution. diff --git a/src/RELEASE.txt b/src/RELEASE.txt index e75da89b..3ccb4cd7 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -25,6 +25,32 @@ RELEASE 0.96 - XXX This is the seventh beta release of SCons. Please consult the CHANGES.txt file for a list of specific changes since last release. + Please note the following important changes since release 0.95: + + - The behavior of the env.Append() and env.Prepend() methods has + changed when appending a string value to a UserList. They now + behave like normal Python addition of a string to a UserList. + Given an initialization like: + + env = Environment(VARIABLE = UserList(['foo'])) + + An Append() call like: + + env.Append(VARIABLE = 'bar') + + Will now yield a $VARIABLE value of ['foo', 'b', 'a', 'r']. + This is because Python UserList objects treat added strings as + sequences of letters. + + The old behavior of yielding a $VARIABLE value of ['foo', 'bar'] + now requires that the appended variable be a list (when the original + variable is a UserList object): + + env.Append(VARIABLE = ['bar']) + + Note that the behavior when appending to normal lists has *not* + changed. + Please note the following important changes since release 0.94: - The internal Python function used by the Zip Builder in Python @@ -62,7 +88,7 @@ RELEASE 0.96 - XXX the ATL and MFC directories to the INCLUDE and LIB environment variables by default. This default behavior will be changed in a future release; the current plan is to change it for the 0.97 - release (two releases from now). + release (next release). Whether or not the ATL and MFC directories are added to these environment variables is now controlled by a new MSVS_USE_MFC_DIRS diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index dc52ee12..1d61ae81 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -454,26 +454,53 @@ class Base: in an Environment. """ kw = our_deepcopy(kw) - for key in kw.keys(): - if not self._dict.has_key(key): - self._dict[key] = kw[key] - elif SCons.Util.is_List(self._dict[key]) and not \ - SCons.Util.is_List(kw[key]): - if kw[key]: - self._dict[key] = self._dict[key] + [ kw[key] ] - #self._dict[key] = map(None, self._dict[key] + [ kw[key] ]) - elif SCons.Util.is_List(kw[key]) and not \ - SCons.Util.is_List(self._dict[key]): - if self._dict[key]: - self._dict[key] = [ self._dict[key] ] + kw[key] - else: - self._dict[key] = kw[key] - #self._dict[key] = map(None, self._dict[key] + [ kw[key] ]) - elif SCons.Util.is_Dict(self._dict[key]) and \ - SCons.Util.is_Dict(kw[key]): - self._dict[key].update(kw[key]) + for key, val in kw.items(): + try: + orig = self._dict[key] + except KeyError: + # No existing variable in the environment, so just set + # it to the new value. + self._dict[key] = val + continue + + try: + # Most straightforward: just try to add them together. + # This will work in most cases, when the original and + # new values are of compatible types. + self._dict[key] = orig + val + continue + except TypeError: + pass + + try: + # Try to update a dictionary value with another. + # If orig isn't a dictionary, it won't have an + # update() method; if val isn't a dictionary, it + # won't have a keys() method. Either way, it's + # an AttributeError. + orig.update(val) + continue + except AttributeError: + pass + + try: + # Check if the original is a list. + add_to_orig = orig.append + except AttributeError: + pass else: - self._dict[key] = self._dict[key] + kw[key] + # The original is a list, so append the new value to it + # (if there's a value to append). + if val: + add_to_orig(val) + continue + + # The original isn't a list, but the new value is (by process + # of elimination), so insert the original in the new value + # (if there's one to insert) and replace the variable with it. + if orig: + val.insert(0, orig) + self._dict[key] = val def AppendENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep): """Append path elements to the path 'name' in the 'ENV' @@ -662,24 +689,53 @@ class Base: in an Environment. """ kw = our_deepcopy(kw) - for key in kw.keys(): - if not self._dict.has_key(key): - self._dict[key] = kw[key] - elif SCons.Util.is_List(self._dict[key]) and not \ - SCons.Util.is_List(kw[key]): - if kw[key]: - self._dict[key] = [ kw[key] ] + self._dict[key] - elif SCons.Util.is_List(kw[key]) and not \ - SCons.Util.is_List(self._dict[key]): - if self._dict[key]: - self._dict[key] = kw[key] + [ self._dict[key] ] - else: - self._dict[key] = kw[key] - elif SCons.Util.is_Dict(self._dict[key]) and \ - SCons.Util.is_Dict(kw[key]): - self._dict[key].update(kw[key]) + for key, val in kw.items(): + try: + orig = self._dict[key] + except KeyError: + # No existing variable in the environment, so just set + # it to the new value. + self._dict[key] = val + continue + + try: + # Most straightforward: just try to add them together. + # This will work in most cases, when the original and + # new values are of compatible types. + self._dict[key] = val + orig + continue + except TypeError: + pass + + try: + # Try to update a dictionary value with another. + # If orig isn't a dictionary, it won't have an + # update() method; if val isn't a dictionary, it + # won't have a keys() method. Either way, it's + # an AttributeError. + orig.update(val) + continue + except AttributeError: + pass + + try: + # Check if the added value is a list. + add_to_val = val.append + except AttributeError: + pass else: - self._dict[key] = kw[key] + self._dict[key] + # The added value is a list, so append the original to it + # (if there's a value to append). + if orig: + add_to_val(orig) + self._dict[key] = val + continue + + # The added value isn't a list, but the original is (by + # process of elimination), so insert the the new value in + # the original (if there's one to insert). + if val: + orig.insert(0, val) def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep): """Prepend path elements to the path 'name' in the 'ENV' diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 0576f837..11fd0d8c 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -875,7 +875,7 @@ class EnvironmentTestCase(unittest.TestCase): ['e7'], [''], ['e7', ''], ['e8'], UL(['']), UL(['e8', '']), - UL(['i1']), 'I1', UL(['i1', 'I1']), + UL(['i1']), 'I1', UL(['i1', 'I', '1']), UL(['i2']), ['I2'], UL(['i2', 'I2']), UL(['i3']), UL(['I3']), UL(['i3', 'I3']), UL(['i4']), '', UL(['i4']), @@ -902,7 +902,7 @@ class EnvironmentTestCase(unittest.TestCase): [], [''], [''], [], UL(['']), UL(['']), - UL([]), 'O1', ['O1'], + UL([]), 'O1', ['O', '1'], UL([]), ['O2'], ['O2'], UL([]), UL(['O3']), UL(['O3']), UL([]), '', UL([]), @@ -920,7 +920,7 @@ class EnvironmentTestCase(unittest.TestCase): [''], [''], ['', ''], [''], UL(['']), UL(['', '']), - UL(['']), 'Q1', ['', 'Q1'], + UL(['']), 'Q1', ['', 'Q', '1'], UL(['']), ['Q2'], ['', 'Q2'], UL(['']), UL(['Q3']), UL(['', 'Q3']), UL(['']), '', UL(['']), @@ -1297,7 +1297,7 @@ class EnvironmentTestCase(unittest.TestCase): ['e7'], [''], ['', 'e7'], ['e8'], UL(['']), UL(['', 'e8']), - UL(['i1']), 'I1', UL(['I1', 'i1']), + UL(['i1']), 'I1', UL(['I', '1', 'i1']), UL(['i2']), ['I2'], UL(['I2', 'i2']), UL(['i3']), UL(['I3']), UL(['I3', 'i3']), UL(['i4']), '', UL(['i4']), @@ -1324,7 +1324,7 @@ class EnvironmentTestCase(unittest.TestCase): [], [''], [''], [], UL(['']), UL(['']), - UL([]), 'O1', UL(['O1']), + UL([]), 'O1', UL(['O', '1']), UL([]), ['O2'], UL(['O2']), UL([]), UL(['O3']), UL(['O3']), UL([]), '', UL([]), @@ -1342,7 +1342,7 @@ class EnvironmentTestCase(unittest.TestCase): [''], [''], ['', ''], [''], UL(['']), UL(['', '']), - UL(['']), 'Q1', UL(['Q1', '']), + UL(['']), 'Q1', UL(['Q', '1', '']), UL(['']), ['Q2'], UL(['Q2', '']), UL(['']), UL(['Q3']), UL(['Q3', '']), UL(['']), '', UL(['']), -- 2.26.2