diff options
author | William Deegan <bill@baddogconsulting.com> | 2021-03-28 19:44:15 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-28 19:44:15 (GMT) |
commit | b7477f0274bfad9ed8e8b98c328ab4263f6bfb62 (patch) | |
tree | 7cceb3e058a3acfe49881e8beb9889ca4c6acd8f | |
parent | 485749728ff769dbe9148bd3a946ad03e3e4ee64 (diff) | |
parent | a256652f5b436d692ac0237d7f12a81a591fcb2a (diff) | |
download | SCons-b7477f0274bfad9ed8e8b98c328ab4263f6bfb62.zip SCons-b7477f0274bfad9ed8e8b98c328ab4263f6bfb62.tar.gz SCons-b7477f0274bfad9ed8e8b98c328ab4263f6bfb62.tar.bz2 |
Merge pull request #3916 from mwichmann/issue2399
Add a __iadd__ method to CLVar to support inplace adds
-rwxr-xr-x | CHANGES.txt | 2 | ||||
-rw-r--r-- | SCons/Util.py | 30 | ||||
-rw-r--r-- | SCons/UtilTests.py | 133 |
3 files changed, 101 insertions, 64 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index d400ceb..41ffe4e 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -45,6 +45,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Remove long-deprecated construction variables PDFCOM, WIN32_INSERT_DEF, WIN32DEFPREFIX, WIN32DEFSUFFIX, WIN32EXPPREFIX, WIN32EXPSUFFIX. All have been replaced by other names since at least 1.0. + - Add a __iadd__ method to the CLVar class so that inplace adds + (+=) also work as expected (issue 2399) - Remove local copy of CLVar in EnvironmentTests unittest file - should be testing against the production version, and they didn't really differ. diff --git a/SCons/Util.py b/SCons/Util.py index e614880..37107c9 100644 --- a/SCons/Util.py +++ b/SCons/Util.py @@ -1048,22 +1048,38 @@ def Split(arg): else: return [arg] + class CLVar(UserList): """A class for command-line construction variables. - This is a list that uses Split() to split an initial string along - white-space arguments, and similarly to split any strings that get - added. This allows us to Do the Right Thing with Append() and + Forces the use of a list of strings, matching individual arguments + that will be issued on the command line. Like UserList, + but the argument passed to __init__ will be processed by the + Split function, which includes special handling for string types - + they will be split into a list of words, not coereced directly + to a list. The same happens if adding a string, + which allows us to Do the Right Thing with Append() and Prepend() (as well as straight Python foo = env['VAR'] + 'arg1 arg2') regardless of whether a user adds a list or a string to a command-line construction variable. + + Side effect: spaces will be stripped from individual string + arguments. If you need spaces preserved, pass strings containing + spaces inside a list argument. """ - def __init__(self, seq = []): - UserList.__init__(self, Split(seq)) + + def __init__(self, seq=[]): + super().__init__(Split(seq)) + def __add__(self, other): - return UserList.__add__(self, CLVar(other)) + return super().__add__(CLVar(other)) + def __radd__(self, other): - return UserList.__radd__(self, CLVar(other)) + return super().__radd__(CLVar(other)) + + def __iadd__(self, other): + return super().__iadd__(CLVar(other)) + def __str__(self): return ' '.join(self.data) diff --git a/SCons/UtilTests.py b/SCons/UtilTests.py index 817ad02..8e39a16 100644 --- a/SCons/UtilTests.py +++ b/SCons/UtilTests.py @@ -550,101 +550,120 @@ class UtilTestCase(unittest.TestCase): def test_CLVar(self): """Test the command-line construction variable class""" - f = SCons.Util.CLVar('a b') - r = f + 'c d' + # input to CLVar is a string - should be split + f = SCons.Util.CLVar('aa bb') + + r = f + 'cc dd' assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', 'c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', 'cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + ' c d' + r = f + ' cc dd' assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', 'c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', 'cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + ['c d'] + r = f + ['cc dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', 'c d'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', 'cc dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + [' c d'] + r = f + [' cc dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', ' c d'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', ' cc dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + ['c', 'd'] + r = f + ['cc', 'dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', 'c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', 'cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + [' c', 'd'] + r = f + [' cc', 'dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', ' c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', ' cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - f = SCons.Util.CLVar(['a b']) + # input to CLVar is a list of one string, should not be split + f = SCons.Util.CLVar(['aa bb']) - r = f + 'c d' + r = f + 'cc dd' assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a b', 'c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa bb', 'cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + ' c d' + r = f + ' cc dd' assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a b', 'c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa bb', 'cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + ['c d'] + r = f + ['cc dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a b', 'c d'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa bb', 'cc dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + [' c d'] + r = f + [' cc dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a b', ' c d'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa bb', ' cc dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + ['c', 'd'] + r = f + ['cc', 'dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a b', 'c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa bb', 'cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + [' c', 'd'] + r = f + [' cc', 'dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a b', ' c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa bb', ' cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - f = SCons.Util.CLVar(['a', 'b']) + # input to CLVar is a list of strings + f = SCons.Util.CLVar(['aa', 'bb']) - r = f + 'c d' + r = f + 'cc dd' assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', 'c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', 'cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + ' c d' + r = f + ' cc dd' assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', 'c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', 'cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + ['c d'] + r = f + ['cc dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', 'c d'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', 'cc dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + [' c d'] + r = f + [' cc dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', ' c d'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', ' cc dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + ['c', 'd'] + r = f + ['cc', 'dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', 'c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', 'cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) - r = f + [' c', 'd'] + r = f + [' cc', 'dd'] assert isinstance(r, SCons.Util.CLVar), type(r) - assert r.data == ['a', 'b', ' c', 'd'], r.data - assert str(r) == 'a b c d', str(r) + assert r.data == ['aa', 'bb', ' cc', 'dd'], r.data + assert str(r) == 'aa bb cc dd', str(r) + + # make sure inplace adding a string works as well (issue 2399) + # UserList would convert the string to a list of chars + f = SCons.Util.CLVar(['aa', 'bb']) + f += 'cc dd' + assert isinstance(f, SCons.Util.CLVar), type(f) + assert f.data == ['aa', 'bb', 'cc', 'dd'], f.data + assert str(f) == 'aa bb cc dd', str(f) + + f = SCons.Util.CLVar(['aa', 'bb']) + f += ' cc dd' + assert isinstance(f, SCons.Util.CLVar), type(f) + assert f.data == ['aa', 'bb', 'cc', 'dd'], f.data + assert str(f) == 'aa bb cc dd', str(f) + def test_Selector(self): """Test the Selector class""" |