Refactor env.Append() and env.Prepend().
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 26 Mar 2004 22:09:41 +0000 (22:09 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 26 Mar 2004 22:09:41 +0000 (22:09 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@931 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/RELEASE.txt
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py

index c421d120152a2494eb25a95c475c883e627b5769..637f9592298dcec23c974a57386b9625e1921164 100644 (file)
@@ -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.
index e75da89bec66b8904863803e30946eec0e472ec8..3ccb4cd7bf0df4b13a04b3d64bc41af4ca157f65 100644 (file)
@@ -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
index dc52ee1253119824f567fcf4a3df412640457bed..1d61ae813c3a44170f8dea13f35f67863f55c3ae 100644 (file)
@@ -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'
index 0576f83717c0587afb225a757b944e9d4c7c1b76..11fd0d8c5e1373d0e66b7580677b83c0c6364f36 100644 (file)
@@ -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(['']),