Skip to content

Commit 16523d0

Browse files
authored
Merge branch 'master' into py36-depr
2 parents 84c3011 + 3e6a7ac commit 16523d0

26 files changed

+872
-542
lines changed

CHANGES.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ NOTE: 4.3.0 now requires Python 3.6.0 and above. Python 3.5.x is no longer suppo
99

1010
RELEASE VERSION/DATE TO BE FILLED IN LATER
1111

12+
From Thaddeus Crews:
13+
- GetSConsVersion() to grab the latest SCons version without needing to
14+
access SCons internals.
15+
1216
From Raymond Li:
1317
- Fix issue #3935: OSErrors are now no longer hidden during execution of
1418
Actions. All exceptions during the execution of an Action are now
@@ -18,6 +22,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
1822
expected exceptions (whereas previously many of these were silently
1923
caught and suppressed by the SCons Action exection code).
2024

25+
From Ryan Carsten Schmidt:
26+
- Teach ParseFlags to put a --stdlib=libname argument into CXXFLAGS.
27+
If placed in CCFLAGS (the default location), it could be fed to the
28+
C compiler (gcc, clang) where it is not applicable and causes a
29+
warning message.
30+
2131
From Mats Wichmann:
2232
- Updated Value Node docs and tests.
2333
- Python 3.13 compat: re.sub deprecated count, flags as positional args,
@@ -32,6 +42,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
3242
ones in parent NodeInfoBase and can just be inherited.
3343
- Update manpage for Tools, and for TOOL, which also gets a minor
3444
tweak for how it's handled (should be more accurate in a few situations).
45+
- Test framework now uses a subdirectory named "scons" below the base
46+
temporary directory. This gives something invariant to tell antivirus
47+
to ignore without having to exclude tmpdir itself. Fixes #4509.
48+
- MSVS "live" tests of project files adjusted to look for the generated
49+
executable with an exe sufffix
3550
- Documentation build now properly passes through skipping the PDF
3651
(and EPUB) builds of manpage and user guide; this can also be done
3752
manually if directly calling doc/man/SConstruct and doc/user/SConstruct
@@ -41,6 +56,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
4156
- Add the ability to print a Variables object for debugging purposes
4257
(provides a __str__ method in the class).
4358
- Mark Python 3.6 support as deprecated.
59+
- Clean up Variables: more consistently call them variables (finish the
60+
old change from Options) in docstrings, etc.; some typing and other
61+
tweaks. Update manpage and user guide for Variables usage.
4462

4563

4664
RELEASE 4.7.0 - Sun, 17 Mar 2024 17:22:20 -0700

RELEASE.txt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Here is a summary of the changes since 4.7.0:
1616
NEW FUNCTIONALITY
1717
-----------------
1818

19-
- List new features (presumably why a checkpoint is being released)
19+
- GetSConsVersion() added to retrieve the SCons version.
2020

2121
DEPRECATED FUNCTIONALITY
2222
------------------------
@@ -40,6 +40,10 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
4040
NOTE: With this change, user created Actions should now catch and handle
4141
expected exceptions (whereas previously many of these were silently caught
4242
and suppressed by the SCons Action exection code).
43+
- ParseFlags now sorts a --stdlib=libname argument into CXXFLAGS instead
44+
of CCFLAGS; the latter variable could cause a compiler warning.
45+
- The implementation of Variables was slightly refactored, there should
46+
not be user-visible changes.
4347

4448
FIXES
4549
-----
@@ -49,9 +53,9 @@ FIXES
4953
IMPROVEMENTS
5054
------------
5155

52-
- List improvements that wouldn't be visible to the user in the
53-
documentation: performance improvements (describe the circumstances
54-
under which they would be observed), or major code cleanups
56+
- Make the testing framework a little more resilient: the temporary
57+
directory for tests now includes a component named "scons" which can
58+
be given to antivirus software to exclude.
5559

5660
PACKAGING
5761
---------
@@ -64,6 +68,7 @@ DOCUMENTATION
6468

6569
- Updated Value Node docs.
6670
- Update manpage for Tools, and for the TOOL variable.
71+
- Update manpage and user guide for Variables usage.
6772

6873

6974

SCons/Environment.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -881,11 +881,11 @@ def ParseFlags(self, *flags) -> dict:
881881
'RPATH' : [],
882882
}
883883

884-
def do_parse(arg) -> None:
885-
# if arg is a sequence, recurse with each element
884+
def do_parse(arg: Union[str, Sequence]) -> None:
886885
if not arg:
887886
return
888887

888+
# if arg is a sequence, recurse with each element
889889
if not is_String(arg):
890890
for t in arg: do_parse(t)
891891
return
@@ -902,7 +902,7 @@ def append_define(name, mapping=mapping) -> None:
902902
else:
903903
mapping['CPPDEFINES'].append([t[0], '='.join(t[1:])])
904904

905-
# Loop through the flags and add them to the appropriate option.
905+
# Loop through the flags and add them to the appropriate variable.
906906
# This tries to strike a balance between checking for all possible
907907
# flags and keeping the logic to a finite size, so it doesn't
908908
# check for some that don't occur often. It particular, if the
@@ -926,6 +926,8 @@ def append_define(name, mapping=mapping) -> None:
926926
append_next_arg_to = None # for multi-word args
927927
for arg in params:
928928
if append_next_arg_to:
929+
# these are the second pass for options where the
930+
# option-argument follows as a second word.
929931
if append_next_arg_to == 'CPPDEFINES':
930932
append_define(arg)
931933
elif append_next_arg_to == '-include':
@@ -1022,6 +1024,8 @@ def append_define(name, mapping=mapping) -> None:
10221024
else:
10231025
key = 'CFLAGS'
10241026
mapping[key].append(arg)
1027+
elif arg.startswith('-stdlib='):
1028+
mapping['CXXFLAGS'].append(arg)
10251029
elif arg[0] == '+':
10261030
mapping['CCFLAGS'].append(arg)
10271031
mapping['LINKFLAGS'].append(arg)

SCons/Environment.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2687,6 +2687,7 @@ and added to the following construction variables:
26872687
-openmp CCFLAGS, LINKFLAGS
26882688
-pthread CCFLAGS, LINKFLAGS
26892689
-std= CFLAGS
2690+
-stdlib= CXXFLAGS
26902691
-Wa, ASFLAGS, CCFLAGS
26912692
-Wl,-rpath= RPATH
26922693
-Wl,-R, RPATH

SCons/EnvironmentTests.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,7 @@ def test_ParseFlags(self) -> None:
822822
"-DFOO -DBAR=value -D BAZ "
823823
"-fsanitize=memory "
824824
"-fsanitize-address-use-after-return "
825+
"-stdlib=libc++"
825826
)
826827

827828
d = env.ParseFlags(s)
@@ -841,7 +842,7 @@ def test_ParseFlags(self) -> None:
841842
'+DD64',
842843
'-fsanitize=memory',
843844
'-fsanitize-address-use-after-return'], repr(d['CCFLAGS'])
844-
assert d['CXXFLAGS'] == ['-std=c++0x'], repr(d['CXXFLAGS'])
845+
assert d['CXXFLAGS'] == ['-std=c++0x', '-stdlib=libc++'], repr(d['CXXFLAGS'])
845846
assert d['CPPDEFINES'] == ['FOO', ['BAR', 'value'], 'BAZ'], d['CPPDEFINES']
846847
assert d['CPPFLAGS'] == ['-Wp,-cpp'], d['CPPFLAGS']
847848
assert d['CPPPATH'] == ['/usr/include/fum',

SCons/Script/SConscript.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import sys
4646
import traceback
4747
import time
48+
from typing import Tuple
4849

4950
class SConscriptReturn(Exception):
5051
pass
@@ -385,7 +386,7 @@ class SConsEnvironment(SCons.Environment.Base):
385386
# Private methods of an SConsEnvironment.
386387
#
387388
@staticmethod
388-
def _get_major_minor_revision(version_string):
389+
def _get_major_minor_revision(version_string: str) -> Tuple[int, int, int]:
389390
"""Split a version string into major, minor and (optionally)
390391
revision parts.
391392
@@ -484,15 +485,22 @@ def Default(self, *targets) -> None:
484485
SCons.Script._Set_Default_Targets(self, targets)
485486

486487
@staticmethod
487-
def EnsureSConsVersion(major, minor, revision: int=0) -> None:
488+
def GetSConsVersion() -> Tuple[int, int, int]:
489+
"""Return the current SCons version.
490+
491+
.. versionadded:: 4.8.0
492+
"""
493+
return SConsEnvironment._get_major_minor_revision(SCons.__version__)
494+
495+
@staticmethod
496+
def EnsureSConsVersion(major: int, minor: int, revision: int = 0) -> None:
488497
"""Exit abnormally if the SCons version is not late enough."""
489498
# split string to avoid replacement during build process
490499
if SCons.__version__ == '__' + 'VERSION__':
491500
SCons.Warnings.warn(SCons.Warnings.DevelopmentVersionWarning,
492501
"EnsureSConsVersion is ignored for development version")
493502
return
494-
scons_ver = SConsEnvironment._get_major_minor_revision(SCons.__version__)
495-
if scons_ver < (major, minor, revision):
503+
if SConsEnvironment.GetSConsVersion() < (major, minor, revision):
496504
if revision:
497505
scons_ver_string = '%d.%d.%d' % (major, minor, revision)
498506
else:

SCons/Script/SConscript.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,19 @@ EnsureSConsVersion(0,96,90)
136136
</summary>
137137
</scons_function>
138138

139+
<scons_function name="GetSConsVersion">
140+
<arguments signature="global">
141+
()
142+
</arguments>
143+
<summary>
144+
<para>
145+
Returns the current SCons version in the form of a Tuple[int, int, int],
146+
representing the major, minor, and revision values respectively.
147+
<emphasis>Added in 4.7.1</emphasis>.
148+
</para>
149+
</summary>
150+
</scons_function>
151+
139152
<scons_function name="Exit">
140153
<arguments signature="global">
141154
([value])

SCons/Script/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ def Variables(files=None, args=ARGUMENTS):
297297
#
298298
# Static functions that do not trigger initialization of
299299
# DefaultEnvironment() and don't use its state.
300+
GetSConsVersion = _SConscript.SConsEnvironment.GetSConsVersion
300301
EnsureSConsVersion = _SConscript.SConsEnvironment.EnsureSConsVersion
301302
EnsurePythonVersion = _SConscript.SConsEnvironment.EnsurePythonVersion
302303
Exit = _SConscript.SConsEnvironment.Exit

SCons/Variables/BoolVariable.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
2828
opts = Variables()
2929
opts.Add(BoolVariable('embedded', 'build for an embedded system', False))
30-
...
30+
env = Environment(variables=opts)
3131
if env['embedded']:
3232
...
3333
"""
@@ -54,13 +54,13 @@ def _text2bool(val: str) -> bool:
5454
Raises:
5555
ValueError: if *val* cannot be converted to boolean.
5656
"""
57-
5857
lval = val.lower()
5958
if lval in TRUE_STRINGS:
6059
return True
6160
if lval in FALSE_STRINGS:
6261
return False
63-
raise ValueError("Invalid value for boolean option: %s" % val)
62+
# TODO: leave this check to validator?
63+
raise ValueError(f"Invalid value for boolean variable: {val!r}")
6464

6565

6666
def _validator(key, val, env) -> None:
@@ -73,23 +73,25 @@ def _validator(key, val, env) -> None:
7373
Raises:
7474
KeyError: if *key* is not set in *env*
7575
UserError: if the value of *key* is not ``True`` or ``False``.
76-
"""
77-
if not env[key] in (True, False):
78-
raise SCons.Errors.UserError(
79-
'Invalid value for boolean option %s: %s' % (key, env[key])
80-
)
8176
77+
"""
78+
if env[key] not in (True, False):
79+
msg = f'Invalid value for boolean variable {key!r}: {env[key]}'
80+
raise SCons.Errors.UserError(msg) from None
8281

83-
def BoolVariable(key, help, default) -> Tuple[str, str, str, Callable, Callable]:
82+
# lint: W0622: Redefining built-in 'help' (redefined-builtin)
83+
def BoolVariable(key, help: str, default) -> Tuple[str, str, str, Callable, Callable]:
8484
"""Return a tuple describing a boolean SCons Variable.
8585
86-
The input parameters describe a boolean option. Returns a tuple
87-
including the correct converter and validator.
88-
The *help* text will have ``(yes|no)`` automatically appended to show the
89-
valid values. The result is usable as input to :meth:`Add`.
86+
The input parameters describe a boolean variable, using a string
87+
value as described by :const:`TRUE_STRINGS` and :const:`FALSE_STRINGS`.
88+
Returns a tuple including the correct converter and validator.
89+
The *help* text will have ``(yes|no)`` automatically appended to
90+
show the valid values. The result is usable as input to
91+
:meth:`~SCons.Variables.Variables.Add`.
9092
"""
91-
help = '%s (yes|no)' % help
92-
return (key, help, default, _validator, _text2bool)
93+
help = f'{help} (yes|no)'
94+
return key, help, default, _validator, _text2bool
9395

9496
# Local Variables:
9597
# tab-width:4

SCons/Variables/BoolVariableTests.py

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,14 @@ def test_converter(self) -> None:
6767

6868
for t in true_values:
6969
x = o.converter(t)
70-
assert x, "converter returned false for '%s'" % t
70+
assert x, f"converter returned False for {t!r}"
7171

7272
for f in false_values:
7373
x = o.converter(f)
74-
assert not x, "converter returned true for '%s'" % f
74+
assert not x, f"converter returned True for {f!r}"
7575

76-
caught = False
77-
try:
76+
with self.assertRaises(ValueError):
7877
o.converter('x')
79-
except ValueError:
80-
caught = True
81-
assert caught, "did not catch expected ValueError for 'x'"
8278

8379
def test_validator(self) -> None:
8480
"""Test the BoolVariable validator"""
@@ -98,19 +94,11 @@ def test_validator(self) -> None:
9894
o.validator('F', 0, env)
9995

10096
# negative checks
101-
caught = False
102-
try:
97+
with self.assertRaises(SCons.Errors.UserError):
10398
o.validator('N', 0, env)
104-
except SCons.Errors.UserError:
105-
caught = True
106-
assert caught, "did not catch expected UserError for value %s" % env['N']
10799

108-
caught = False
109-
try:
100+
with self.assertRaises(KeyError):
110101
o.validator('NOSUCHKEY', 0, env)
111-
except KeyError:
112-
caught = True
113-
assert caught, "did not catch expected KeyError for 'NOSUCHKEY'"
114102

115103

116104
if __name__ == "__main__":

0 commit comments

Comments
 (0)