Skip to content

Commit 37c7473

Browse files
authored
Merge pull request SCons#4529 from mwichmann/maint/Variables-list
Variables cleanup: ListVariable
2 parents 103866d + bb7d8f9 commit 37c7473

File tree

3 files changed

+54
-38
lines changed

3 files changed

+54
-38
lines changed

SCons/Variables/ListVariable.py

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2222
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2323

24-
"""Variable type for list Variables.
24+
"""Variable type for List Variables.
2525
26-
A 'list' option may either be 'all', 'none' or a list of names
27-
separated by comma. After the option has been processed, the option
26+
A list variable may given as 'all', 'none' or a list of names
27+
separated by comma. After the variable has been processed, the variable
2828
value holds either the named list elements, all list elements or no
2929
list elements at all.
3030
@@ -41,7 +41,7 @@
4141
elems=list_of_libs,
4242
)
4343
)
44-
...
44+
env = Environment(variables=opts)
4545
for lib in list_of_libs:
4646
if lib in env['shared']:
4747
env.SharedObject(...)
@@ -53,14 +53,21 @@
5353
# since elements can occur twice.
5454

5555
import collections
56-
from typing import Tuple, Callable
56+
from typing import Callable, List, Optional, Tuple, Union
5757

5858
import SCons.Util
5959

6060
__all__ = ['ListVariable',]
6161

6262

6363
class _ListVariable(collections.UserList):
64+
"""Internal class holding the data for a List Variable.
65+
66+
The initializer accepts two arguments, the list of actual values
67+
given, and the list of allowable values. Not normally instantiated
68+
by hand, but rather by the ListVariable converter function.
69+
"""
70+
6471
def __init__(self, initlist=None, allowedElems=None) -> None:
6572
if initlist is None:
6673
initlist = []
@@ -88,19 +95,18 @@ def __lt__(self, other):
8895
return NotImplemented
8996

9097
def __str__(self) -> str:
91-
if not len(self):
98+
if not self.data:
9299
return 'none'
93100
self.data.sort()
94101
if self.data == self.allowedElems:
95102
return 'all'
96-
else:
97-
return ','.join(self)
103+
return ','.join(self)
98104

99105
def prepare_to_store(self):
100-
return self.__str__()
106+
return str(self)
101107

102108
def _converter(val, allowedElems, mapdict) -> _ListVariable:
103-
""" """
109+
"""Convert list variables."""
104110
if val == 'none':
105111
val = []
106112
elif val == 'all':
@@ -111,39 +117,57 @@ def _converter(val, allowedElems, mapdict) -> _ListVariable:
111117
notAllowed = [v for v in val if v not in allowedElems]
112118
if notAllowed:
113119
raise ValueError(
114-
"Invalid value(s) for option: %s" % ','.join(notAllowed)
120+
f"Invalid value(s) for option: {','.join(notAllowed)}"
115121
)
116122
return _ListVariable(val, allowedElems)
117123

118124

119125
# def _validator(key, val, env) -> None:
120126
# """ """
121-
# # TODO: write validator for pgk list
127+
# # TODO: write validator for list variable
122128
# pass
123129

124130

125-
def ListVariable(key, help, default, names, map={}) -> Tuple[str, str, str, None, Callable]:
126-
"""Return a tuple describing a list SCons Variable.
127-
128-
The input parameters describe a 'list' option. Returns
129-
a tuple including the correct converter and validator.
130-
The result is usable for input to :meth:`Add`.
131-
132-
*help* will have text appended indicating the legal values
133-
(not including any extra names from *map*).
134-
135-
*map* can be used to map alternative names to the ones in *names* -
136-
that is, a form of alias.
137-
138-
A 'list' option may either be 'all', 'none' or a list of
139-
names (separated by commas).
131+
# lint: W0622: Redefining built-in 'help' (redefined-builtin)
132+
# lint: W0622: Redefining built-in 'map' (redefined-builtin)
133+
def ListVariable(
134+
key,
135+
help: str,
136+
default: Union[str, List[str]],
137+
names: List[str],
138+
map: Optional[dict] = None,
139+
) -> Tuple[str, str, str, None, Callable]:
140+
"""Return a tuple describing a list variable.
141+
142+
The input parameters describe a list variable, where the values
143+
can be one or more from *names* plus the special values ``all``
144+
and ``none``.
145+
146+
Arguments:
147+
key: the name of the list variable.
148+
help: the basic help message. Will have text appended indicating
149+
the allowable values (not including any extra names from *map*).
150+
default: the default value(s) for the list variable. Can be
151+
given as string (possibly comma-separated), or as a list of strings.
152+
``all`` or ``none`` are allowed as *default*.
153+
names: the allowable values. Must be a list of strings.
154+
map: optional dictionary to map alternative names to the ones in
155+
*names*, providing a form of alias. The converter will make
156+
the replacement, names from *map* are not stored and will
157+
not appear in the help message.
158+
159+
Returns:
160+
A tuple including the correct converter and validator. The
161+
result is usable as input to :meth:`~SCons.Variables.Variables.Add`.
140162
"""
141-
names_str = 'allowed names: %s' % ' '.join(names)
163+
if map is None:
164+
map = {}
165+
names_str = f"allowed names: {' '.join(names)}"
142166
if SCons.Util.is_List(default):
143167
default = ','.join(default)
144168
help = '\n '.join(
145169
(help, '(all|none|comma-separated list of names)', names_str))
146-
return (key, help, default, None, lambda val: _converter(val, names, map))
170+
return key, help, default, None, lambda val: _converter(val, names, map)
147171

148172
# Local Variables:
149173
# tab-width:4

SCons/Variables/ListVariableTests.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,8 @@ def test_converter(self) -> None:
101101
x = o.converter('three,ONE,TWO')
102102
assert str(x) == 'all', x
103103

104-
caught = None
105-
try:
104+
with self.assertRaises(ValueError):
106105
x = o.converter('no_match')
107-
except ValueError:
108-
caught = 1
109-
assert caught, "did not catch expected ValueError"
110106

111107
def test_copy(self) -> None:
112108
"""Test copying a ListVariable like an Environment would"""

test/Variables/ListVariable.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,6 @@ def check(expect):
149149

150150
test.run(arguments='shared=foo,x11,,,bar', stderr=expect_stderr, status=2)
151151

152-
153-
154152
test.write('SConstruct', """
155153
from SCons.Variables import ListVariable
156154
@@ -174,8 +172,6 @@ def check(expect):
174172
scons: Nothing to be done for `dummy'.
175173
"""))
176174

177-
178-
179175
test.pass_test()
180176

181177
# Local Variables:

0 commit comments

Comments
 (0)