From 961ddffc1f598e37c1cf1e1316d6a79ae7d99fcc Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 11 Feb 2023 09:40:40 -0700 Subject: Tweak pseudo-builder in user guide [skip appveyor] Minor fiddling - example format, headers, wordings tweaks Signed-off-by: Mats Wichmann --- doc/user/add-method.xml | 73 ++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/doc/user/add-method.xml b/doc/user/add-method.xml index 7b5200e..86297de 100644 --- a/doc/user/add-method.xml +++ b/doc/user/add-method.xml @@ -1,4 +1,10 @@ + + %scons; @@ -18,43 +24,17 @@ xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd"> -Extending &SCons;: Pseudo-Builders and the AddMethod function - - +Extending &SCons;: Pseudo-Builders and the AddMethod function - The &AddMethod; function is used to add a method - to an environment. It's typically used to add a "pseudo-builder," - a function that looks like a &Builder; but - wraps up calls to multiple other &Builder;s + The &f-link-AddMethod; function is used to add a method + to an environment. It is typically used to add a "pseudo-builder," + a function that looks like a Builder but + wraps up calls to multiple other Builder's or otherwise processes its arguments - before calling one or more &Builder;s. + before calling one or more Builders. In the following example, we want to install the program into the standard /usr/bin directory hierarchy, @@ -69,10 +49,11 @@ def install_in_bin_dirs(env, source): """Install source in both bin dirs""" i1 = env.Install("$BIN", source) i2 = env.Install("$LOCALBIN", source) - return [i1[0], i2[0]] # Return a list, like a normal builder + return [i1[0], i2[0]] # Return a list, like a normal builder + env = Environment(BIN='__ROOT__/usr/bin', LOCALBIN='#install/bin') env.AddMethod(install_in_bin_dirs, "InstallInBinDirs") -env.InstallInBinDirs(Program('hello.c')) # installs hello in both bin dirs +env.InstallInBinDirs(Program('hello.c')) # installs hello in both bin dirs int main() { printf("Hello, world!\n"); } @@ -89,31 +70,35 @@ int main() { printf("Hello, world!\n"); } - As mentioned, a pseudo-builder also provides more flexibility - in parsing arguments than you can get with a &Builder;. + A pseudo-builder is useful because it provides more flexibility + in parsing arguments than you can get with a standard Builder method. The next example shows a pseudo-builder with a named argument that modifies the filename, and a separate argument for the resource file (rather than having the builder figure it out by file extension). This example also demonstrates using the global &AddMethod; function to add a method to the global Environment class, - so it will be used in all subsequently created environments. + so it will be available in all subsequently created environments. -def BuildTestProg(env, testfile, resourcefile, testdir="tests"): - """Build the test program; - prepends "test_" to src and target, - and puts target into testdir.""" - srcfile = "test_%s.c" % testfile - target = "%s/test_%s" % (testdir, testfile) - if env['PLATFORM'] == 'win32': +def BuildTestProg(env, testfile, resourcefile="", testdir="tests"): + """Build the test program. + + Prepends "test_" to src and target and puts the target into testdir. + If the build is running on Windows, also make use of a resource file, + if supplied. + """ + srcfile = f"test_{testfile}.c" + target = f"{testdir}/test_{testfile}" + if env['PLATFORM'] == 'win32' and resourcefile: resfile = env.RES(resourcefile) p = env.Program(target, [srcfile, resfile]) else: p = env.Program(target, srcfile) return p + AddMethod(Environment, BuildTestProg) env = Environment() -- cgit v0.12 From cdd4bb3ec9f665c13473792ee0f5f34f1261c76d Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 21 Feb 2023 08:59:41 -0700 Subject: Restore markup of Builder in PR 4299 [skip appveyor] The add-method chapter now has entity references to &Builder; back. The markup for &Builder; is changed from to , as used it's a concept, and there is no actual class named Builder anyway. Signed-off-by: Mats Wichmann --- doc/scons.mod | 4 ++-- doc/user/add-method.xml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/scons.mod b/doc/scons.mod index ea1decc..ebe0e6f 100644 --- a/doc/scons.mod +++ b/doc/scons.mod @@ -100,7 +100,7 @@ CommandAction"> FunctionAction"> ListAction"> -Builder"> +Builder"> BuilderBase"> CompositeBuilder"> MultiStepBuilder"> @@ -110,7 +110,7 @@ Parallel"> Node"> Node.FS"> -Scanner"> +Scanner"> Sig"> Signature"> Taskmaster"> diff --git a/doc/user/add-method.xml b/doc/user/add-method.xml index 86297de..d25ba9a 100644 --- a/doc/user/add-method.xml +++ b/doc/user/add-method.xml @@ -31,10 +31,10 @@ Copyright The SCons Foundation The &f-link-AddMethod; function is used to add a method to an environment. It is typically used to add a "pseudo-builder," - a function that looks like a Builder but - wraps up calls to multiple other Builder's + a function that looks like a &Builder; but + wraps up calls to multiple other &Builder;'s or otherwise processes its arguments - before calling one or more Builders. + before calling one or more &Builder;s. In the following example, we want to install the program into the standard /usr/bin directory hierarchy, @@ -71,7 +71,7 @@ int main() { printf("Hello, world!\n"); } A pseudo-builder is useful because it provides more flexibility - in parsing arguments than you can get with a standard Builder method. + in parsing arguments than you can get with a standard &Builder;. The next example shows a pseudo-builder with a named argument that modifies the filename, and a separate argument for the resource file (rather than having the builder figure it out -- cgit v0.12 From 959e35788a8a6aa418c97cb55221c70b9cc15fe5 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 22 Feb 2023 09:43:58 -0700 Subject: User Guide fixups [skip appveyor] For add-method chapter, plus the following scanners chapter, normalize usage a little: the first mention in any given section uses the marked-up form &Builder; and &Scanner;, which contain index references, subsequent ones do not. Only references to Scanner as a concept are capitalized, things like "scanner function" were left alone. Signed-off-by: Mats Wichmann --- doc/user/add-method.xml | 4 ++-- doc/user/scanners.xml | 62 ++++++++++++++++++++++++------------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/doc/user/add-method.xml b/doc/user/add-method.xml index d25ba9a..7c59bf2 100644 --- a/doc/user/add-method.xml +++ b/doc/user/add-method.xml @@ -32,9 +32,9 @@ Copyright The SCons Foundation The &f-link-AddMethod; function is used to add a method to an environment. It is typically used to add a "pseudo-builder," a function that looks like a &Builder; but - wraps up calls to multiple other &Builder;'s + wraps up calls to multiple other Builders or otherwise processes its arguments - before calling one or more &Builder;s. + before calling one or more Builders. In the following example, we want to install the program into the standard /usr/bin directory hierarchy, diff --git a/doc/user/scanners.xml b/doc/user/scanners.xml index b9a5084..1e22342 100644 --- a/doc/user/scanners.xml +++ b/doc/user/scanners.xml @@ -146,15 +146,16 @@ over the file scanning rather than being called for each input line: - &SCons; has built-in scanners that know how to look in + &SCons; has routines that know how to look in C/C++, Fortran, D, IDL, LaTeX, Python and SWIG source files for information about - other files that targets built from those files depend on--for example, - in the case of files that use the C preprocessor, + other files that targets built from those files depend on - + for example, in the case of files that use the C preprocessor, the .h files that are specified using #include lines in the source. + Such a routine is called a &Scanner;. You can use the same mechanisms that &SCons; uses to create - its built-in scanners to write scanners of your own for file types + its built-in Scanners to write Scanners of your own for file types that &SCons; does not know how to scan "out of the box." @@ -164,7 +165,7 @@ over the file scanning rather than being called for each input line: - Suppose, for example, that we want to create a simple scanner + Suppose, for example, that we want to create a simple &Scanner; for .foo files. A .foo file contains some text that will be processed, @@ -183,7 +184,7 @@ include filename.foo Scanning a file will be handled by a Python function that you must supply. Here is a function that will use the Python - re module + re module to scan for the include lines in our example: @@ -203,7 +204,7 @@ def kfile_scan(node, env, path, arg): It is important to note that you have to return a list of File nodes from the scanner function, simple strings for the file names won't do. As in the examples we are showing here, - you can use the &File; + you can use the &f-link-File; function of your current &consenv; in order to create nodes on the fly from a sequence of file names with relative paths. @@ -225,7 +226,7 @@ def kfile_scan(node, env, path, arg): - node + node @@ -233,8 +234,8 @@ def kfile_scan(node, env, path, arg): An &SCons; node object representing the file being scanned. The path name to the file can be used by converting the node to a string - using the str() function, - or an internal &SCons; get_text_contents() + using the str function, + or an internal &SCons; get_text_contents object method can be used to fetch the contents. @@ -242,7 +243,7 @@ def kfile_scan(node, env, path, arg): - env + env @@ -256,13 +257,13 @@ def kfile_scan(node, env, path, arg): - path + path A list of directories that form the search path for included files - for this scanner. + for this Scanner. This is how &SCons; handles the &cv-link-CPPPATH; and &cv-link-LIBPATH; variables. @@ -271,7 +272,7 @@ def kfile_scan(node, env, path, arg): - arg + arg @@ -288,10 +289,10 @@ def kfile_scan(node, env, path, arg): - A Scanner object is created using the &f-link-Scanner; function, + A scanner object is created using the &f-link-Scanner; function, which typically takes an skeys argument - to associate a file suffix with this scanner. - The Scanner object must then be associated with the + to associate a file suffix with this Scanner. + The scanner object must then be associated with the &cv-link-SCANNERS; &consvar; in the current &consenv;, typically by using the &f-link-Append; method: @@ -320,7 +321,6 @@ def kfile_scan(node, env, path): return env.File(includes) kscan = Scanner(function=kfile_scan, skeys=['.k']) - env = Environment(ENV={'PATH': '__ROOT__/usr/local/bin'}) env.Append(SCANNERS=kscan) @@ -364,21 +364,21 @@ cat
- Adding a search path to a scanner: &FindPathDirs; + Adding a search path to a Scanner: &FindPathDirs; If the build tool in question will use a path variable to search - for included files or other dependencies, then the Scanner will + for included files or other dependencies, then the &Scanner; will need to take that path variable into account as well - &cv-link-CPPPATH; and &cv-link-LIBPATH; are used this way, for example. The path to search is passed to your - scanner as the path argument. Path variables + Scanner as the path argument. Path variables may be lists of nodes, semicolon-separated strings, or even contain &consvars; which need to be expanded. &SCons; provides the &f-link-FindPathDirs; function which returns a callable to expand a given path (given as a SCons &consvar; - name) to a list of paths at the time the scanner is called. + name) to a list of paths at the time the Scanner is called. Deferring evaluation until that point allows, for instance, the path to contain &cv-link-TARGET; references which differ for each file scanned. @@ -390,7 +390,7 @@ cat Using &FindPathDirs; is quite easy. Continuing the above example, using KPATH as the &consvar; with the search path (analogous to &cv-link-CPPPATH;), we just modify the call to - the &Scanner; factory function to include a path keyword arg: + the &f-link-Scanner; factory function to include a path keyword arg: @@ -404,7 +404,7 @@ kscan = Scanner(function=kfile_scan, skeys=['.k'], path_function=FindPathDirs('K &FindPathDirs; returns a callable object that, when called, will essentially expand the elements in env['KPATH'] - and tell the scanner to search in those dirs. It will also properly + and tell the Scanner to search in those dirs. It will also properly add related repository and variant dirs to the search list. As a side note, the returned method stores the path in an efficient way so lookups are fast even when variable substitutions may be needed. @@ -418,9 +418,9 @@ kscan = Scanner(function=kfile_scan, skeys=['.k'], path_function=FindPathDirs('K - One approach for introducing scanners into the build is in - conjunction with a Builder. There are two relvant optional - parameters we can use when creating a builder: + One approach for introducing a &Scanner; into the build is in + conjunction with a &Builder;. There are two relvant optional + parameters we can use when creating a Builder: source_scanner and target_scanner. source_scanner is used for scanning @@ -459,16 +459,16 @@ env.Foo('file') An emitter function can modify the list of sources or targets - passed to the action function when the builder is triggered. + passed to the action function when the Builder is triggered. A scanner function will not affect the list of sources or targets - seen by the builder during the build action. The scanner function - will however affect if the builder should rebuild (if any of - the files sourced by the scanner have changed for example). + seen by the Builder during the build action. The scanner function + will however affect if the Builder should rebuild (if any of + the files sourced by the Scanner have changed for example).
-- cgit v0.12 From 7923bb984986831f6696ae966e3297cce7e96316 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 23 Feb 2023 10:15:26 -0700 Subject: UGuide; tweak Scanner intro again [skip appveyor] Put back the previous wording, now with glossary entry that also defines the plural form Scanners (there is still no actual glossary) Signed-off-by: Mats Wichmann --- doc/scons.mod | 13 ++++++++++--- doc/user/builders-writing.xml | 3 ++- doc/user/scanners.xml | 3 +-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/doc/scons.mod b/doc/scons.mod index ebe0e6f..2d3f5a4 100644 --- a/doc/scons.mod +++ b/doc/scons.mod @@ -92,15 +92,23 @@ zip"> + +Action"> +Builder"> +Builders"> +Scanner"> +Scanners"> + + -Action"> ActionBase"> BuildInfo"> CommandAction"> FunctionAction"> ListAction"> -Builder"> BuilderBase"> CompositeBuilder"> MultiStepBuilder"> @@ -110,7 +118,6 @@ Parallel"> Node"> Node.FS"> -Scanner"> Sig"> Signature"> Taskmaster"> diff --git a/doc/user/builders-writing.xml b/doc/user/builders-writing.xml index a53e70e..97ca36f 100644 --- a/doc/user/builders-writing.xml +++ b/doc/user/builders-writing.xml @@ -222,13 +222,14 @@ hello.c To be able to use both our own defined &Builder; objects and the default &Builder; objects in the same &consenv;, you can either add to the &cv-link-BUILDERS; variable - using the &Append; function: + using the &f-link-Append; function:
import os + env = Environment() env.AppendENVPath('PATH', os.getcwd()) bld = Builder(action='foobuild < $SOURCE > $TARGET') diff --git a/doc/user/scanners.xml b/doc/user/scanners.xml index 1e22342..9a0a1d3 100644 --- a/doc/user/scanners.xml +++ b/doc/user/scanners.xml @@ -146,14 +146,13 @@ over the file scanning rather than being called for each input line: - &SCons; has routines that know how to look in + &SCons; has built-in &Scanners; that know how to look in C/C++, Fortran, D, IDL, LaTeX, Python and SWIG source files for information about other files that targets built from those files depend on - for example, in the case of files that use the C preprocessor, the .h files that are specified using #include lines in the source. - Such a routine is called a &Scanner;. You can use the same mechanisms that &SCons; uses to create its built-in Scanners to write Scanners of your own for file types that &SCons; does not know how to scan "out of the box." -- cgit v0.12 From 4c835c49219361b08f03b71d1f944e2e74f23545 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 26 Feb 2023 08:52:04 -0700 Subject: Fix Configure tests on win32/msys2 If selecting tool 'mingw', and using an msys2 Python, paths constructed to run a compiled check ended up with forward slashes, which gave an error when executed through cmd.exe. Cygwin does not have the same problem, as it uses "sh" as the shell when executing the command. Signed-off-by: Mats Wichmann --- CHANGES.txt | 3 +++ RELEASE.txt | 3 +++ SCons/SConf.py | 6 ++++++ SCons/Tool/mingw.py | 3 ++- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6052a21..b2962d3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -145,6 +145,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER We take advantage that their order is now stable based on insertion order in Python 3.5+ - Added/modifed unit and system tests to verify these changes. + - Fixed: when using the mingw tool, if an msys2 Python is used (os.sep + is '/' rather than the Windows default '\'), certain Configure checks + could fail due to the construction of the path to run the compiled check. RELEASE 4.4.0 - Sat, 30 Jul 2022 14:08:29 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index 91dbb86..04590ab 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -113,6 +113,9 @@ FIXES of duplicate macros now works for both valued and unvalued forms. - Handling of CPPDEFINES macros via Prepend and PrependUnique now works (previously this was special-cased only for Append and AppendUnique). +- Fixed: when using the mingw tool, if an msys2 Python is used (os.sep + is '/' rather than the Windows default '\'), certain Configure checks + could fail due to the construction of the path to run the compiled check. IMPROVEMENTS ------------ diff --git a/SCons/SConf.py b/SCons/SConf.py index 136be27..7dc950a 100644 --- a/SCons/SConf.py +++ b/SCons/SConf.py @@ -714,6 +714,12 @@ class SConfBase: if ok: prog = self.lastTarget pname = prog.get_internal_path() + if sys.platform == "win32" and os.sep == "/": + # msys might have a Python where os.sep='/' on Windows. + # That builds a path in the env.Command below which breaks + # if the SHELL used is cmd because 'pname' will always have + # an os.sep in it. + pname = pname.replace(os.sep, os.altsep) output = self.confdir.File(os.path.basename(pname)+'.out') node = self.env.Command(output, prog, [ [ pname, ">", "${TARGET}"] ]) ok = self.BuildNodes(node) diff --git a/SCons/Tool/mingw.py b/SCons/Tool/mingw.py index 8e7ac2d..78b5a8d 100644 --- a/SCons/Tool/mingw.py +++ b/SCons/Tool/mingw.py @@ -48,7 +48,8 @@ mingw_base_paths = [ r'C:\msys64\mingw64\bin', r'C:\cygwin\bin', r'C:\msys', - r'C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin' + r'C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin', + os.path.expandvars(r'%LocalAppData%\Programs\msys64\usr\bin'), ] -- cgit v0.12 From 176711bd1fde814e9c441ae44132eb600063ec7a Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 13 Apr 2023 14:51:01 -0700 Subject: updated copyright and added csv results output to bench.py --- bench/bench.py | 113 +++++++++++++++++++++++++++++++++++++++------------ bench/lvars-gvars.py | 33 ++++++++++++--- 2 files changed, 116 insertions(+), 30 deletions(-) diff --git a/bench/bench.py b/bench/bench.py index aad0fb4..5adac23 100644 --- a/bench/bench.py +++ b/bench/bench.py @@ -1,34 +1,59 @@ #!/usr/bin/env python +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # -# A script for timing snippets of Python code. +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: # -# By default, this script will execute a single Python file specified on -# the command line and time any functions in a list named "FunctionList" -# set by the Python file under test, or (by default) time any functions -# in the file whose names begin with "Func". +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. # -# All functions are assumed to get passed the same arguments, and the -# inputs are specified in a list named "Data," each element of which -# is a list consisting of a tag name, a list of positional arguments, -# and a dictionary of keyword arguments. -# -# Each function is expected to test a single, comparable snippet of -# of Python code. IMPORTANT: We want to test the timing of the code -# itself, not Python function call overhead, so every function should -# put its code under test within the following block: -# -# for i in IterationList: -# -# This will allow (as much as possible) us to time just the code itself, -# not Python function call overhead. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +A script for timing snippets of Python code. + +By default, this script will execute a single Python file specified on +the command line and time any functions in a list named "FunctionList" +set by the Python file under test, or (by default) time any functions +in the file whose names begin with "Func". + +All functions are assumed to get passed the same arguments, and the +inputs are specified in a list named "Data," each element of which +is a list consisting of a tag name, a list of positional arguments, +and a dictionary of keyword arguments. + +Each function is expected to test a single, comparable snippet of +of Python code. IMPORTANT: We want to test the timing of the code +itself, not Python function call overhead, so every function should +put its code under test within the following block: + + for i in IterationList: + +This will allow (as much as possible) us to time just the code itself, +not Python function call overhead. +""" from __future__ import division, print_function import getopt +import os.path import sys import time import types +from pprint import pprint + Usage = """\ Usage: bench.py OPTIONS file.py @@ -105,6 +130,11 @@ if len(args) != 1: sys.stderr.write(Usage) sys.exit(1) + +(bench_name,_) = os.path.splitext(args[0]) +print(f"Bench: {bench_name} : {args[0]}") +results_filename = f"{bench_name}_results.csv" + with open(args[0], 'r') as f: exec(f.read()) @@ -118,6 +148,7 @@ except NameError: IterationList = [None] * Iterations + def timer(func, *args, **kw): results = [] for i in range(Runs): @@ -127,20 +158,52 @@ def timer(func, *args, **kw): results.append((finish - start) / Iterations) return results -def display(label, results): + +results_dict = {} + + +def display(func, result_label, results): total = 0.0 for r in results: total += r - print(" %8.3f" % ((total * 1e6) / len(results)), ':', label) + + test_result = (total * 1e6) / len(results) + print(" %8.3f" % (test_result), ':', result_label) + if results_dict.get(func.__doc__, False): + results_dict[func.__doc__][result_label] = test_result + else: + results_dict[func.__doc__] = { result_label: test_result} + for func in FunctionList: - if func.__doc__: d = ' (' + func.__doc__ + ')' - else: d = '' + if func.__doc__: + d = ' (' + func.__doc__ + ')' + else: + d = '' print(func.__name__ + d + ':') for label, args, kw in Data: r = timer(func, *args, **kw) - display(label, r) + # print(f"{label} {r}") + display(func, label, r) + +py_ver_string = "%d.%d"%(sys.version_info.major, sys.version_info.minor) + + +# pprint(results_dict) +# breakpoint() +tests = [label for label, args, kw in Data] +columns = ['Python Version', 'Implementation', 'Test'] + tests +with open(results_filename, 'a') as r: + print("Python Version,%s" % ".".join(columns), file=r) + # print("Python Version,%s" % ".".join(columns)) + + for implementation in results_dict.keys(): + for test in tests: + print(f'{py_ver_string},"{implementation}","{test}",%8.3f' % results_dict[implementation][test], file=r) + # print(f'{py_ver_string},"{implementation}","{test}",%8.3f' % results_dict[implementation][test]) + + # Local Variables: # tab-width:4 diff --git a/bench/lvars-gvars.py b/bench/lvars-gvars.py index 1511203..0a81337 100644 --- a/bench/lvars-gvars.py +++ b/bench/lvars-gvars.py @@ -1,9 +1,32 @@ -# __COPYRIGHT__ +# MIT License # -# Functions and data for timing different idioms for fetching a keyword -# value from a pair of dictionaries for localand global values. This was -# used to select how to most efficiently expand single $KEYWORD strings -# in src/engine/SCons/Subst.py. +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +Functions and data for timing different idioms for fetching a keyword +value from a pair of dictionaries for localand global values. This was +used to select how to most efficiently expand single $KEYWORD strings +in src/engine/SCons/Subst.py. +""" def Func1(var, gvars, lvars): """lvars try:-except:, gvars try:-except:""" -- cgit v0.12 From b3744e8862927899e3d0ebcb41297f9b4c142c63 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 22 Apr 2023 16:49:38 -0700 Subject: added --debug=json, which will dump object counts and memory into scons_stats.json in invocation directory --- SCons/Script/Main.py | 106 +++++++++-------------------- SCons/Script/SConsOptions.py | 2 +- SCons/Util/stats.py | 156 +++++++++++++++++++++++++++++++++++++++++++ SCons/__init__.py | 10 +-- 4 files changed, 192 insertions(+), 82 deletions(-) create mode 100644 SCons/Util/stats.py diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index d4228fa..ec34c12 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -37,7 +37,6 @@ deprecated_python_version = (3, 6, 0) import SCons.compat -import atexit import importlib.util import os import re @@ -63,6 +62,7 @@ import SCons.Taskmaster import SCons.Util import SCons.Warnings import SCons.Script.Interactive +from SCons.Util.stats import COUNT_STATS, MEMORY_STATS, ENABLE_JSON, WriteJsonFile from SCons import __version__ as SConsVersion @@ -82,10 +82,18 @@ num_jobs = None delayed_warnings = [] +display = SCons.Util.display +progress_display = SCons.Util.DisplayEngine() +ProgressObject = SCons.Util.Null() +_BuildFailures = [] + + def revert_io(): - # This call is added to revert stderr and stdout to the original - # ones just in case some build rule or something else in the system - # has redirected them elsewhere. + """ + This call is added to revert stderr and stdout to the original + ones just in case some build rule or something else in the system + has redirected them elsewhere. + """ sys.stderr = sys.__stderr__ sys.stdout = sys.__stdout__ @@ -94,10 +102,6 @@ class SConsPrintHelpException(Exception): pass -display = SCons.Util.display -progress_display = SCons.Util.DisplayEngine() - - class Progressor: prev = '' count = 0 @@ -150,7 +154,6 @@ class Progressor: self.erase_previous() self.func(node) -ProgressObject = SCons.Util.Null() def Progress(*args, **kw): global ProgressObject @@ -159,9 +162,6 @@ def Progress(*args, **kw): # Task control. # -_BuildFailures = [] - - def GetBuildFailures(): return _BuildFailures @@ -515,59 +515,8 @@ def ValidateOptions(throw_exception=False) -> None: def PrintHelp(file=None): OptionsParser.print_help(file=file) -class Stats: - def __init__(self): - self.stats = [] - self.labels = [] - self.append = self.do_nothing - self.print_stats = self.do_nothing - def enable(self, outfp): - self.outfp = outfp - self.append = self.do_append - self.print_stats = self.do_print - def do_nothing(self, *args, **kw): - pass -class CountStats(Stats): - def do_append(self, label): - self.labels.append(label) - self.stats.append(SCons.Debug.fetchLoggedInstances()) - def do_print(self): - stats_table = {} - for s in self.stats: - for n in [t[0] for t in s]: - stats_table[n] = [0, 0, 0, 0] - i = 0 - for s in self.stats: - for n, c in s: - stats_table[n][i] = c - i = i + 1 - self.outfp.write("Object counts:\n") - pre = [" "] - post = [" %s\n"] - l = len(self.stats) - fmt1 = ''.join(pre + [' %7s']*l + post) - fmt2 = ''.join(pre + [' %7d']*l + post) - labels = self.labels[:l] - labels.append(("", "Class")) - self.outfp.write(fmt1 % tuple([x[0] for x in labels])) - self.outfp.write(fmt1 % tuple([x[1] for x in labels])) - for k in sorted(stats_table.keys()): - r = stats_table[k][:l] + [k] - self.outfp.write(fmt2 % tuple(r)) - -count_stats = CountStats() - -class MemStats(Stats): - def do_append(self, label): - self.labels.append(label) - self.stats.append(SCons.Debug.memory()) - def do_print(self): - fmt = 'Memory %-32s %12d\n' - for label, stats in zip(self.labels, self.stats): - self.outfp.write(fmt % (label, stats)) - -memory_stats = MemStats() + # utility functions @@ -671,7 +620,7 @@ def _set_debug_values(options): enable_count = False if __debug__: enable_count = True if enable_count: - count_stats.enable(sys.stdout) + COUNT_STATS.enable(sys.stdout) SCons.Debug.track_instances = True else: msg = "--debug=count is not supported when running SCons\n" + \ @@ -685,7 +634,7 @@ def _set_debug_values(options): options.debug_includes = ("includes" in debug_values) print_memoizer = ("memoizer" in debug_values) if "memory" in debug_values: - memory_stats.enable(sys.stdout) + MEMORY_STATS.enable(sys.stdout) print_objects = ("objects" in debug_values) if print_objects: SCons.Debug.track_instances = True @@ -706,6 +655,8 @@ def _set_debug_values(options): SCons.Taskmaster.print_prepare = True if "duplicate" in debug_values: SCons.Node.print_duplicate = True + if "json" in debug_values: + SCons.Util.stats.ENABLE_JSON = True def _create_path(plist): path = '.' @@ -1039,8 +990,8 @@ def _main(parser): if not hasattr(sys.stderr, 'isatty') or not sys.stderr.isatty(): sys.stderr = SCons.Util.Unbuffered(sys.stderr) - memory_stats.append('before reading SConscript files:') - count_stats.append(('pre-', 'read')) + MEMORY_STATS.append('before reading SConscript files:') + COUNT_STATS.append(('pre-', 'read')) # And here's where we (finally) read the SConscript files. @@ -1066,8 +1017,8 @@ def _main(parser): progress_display("scons: done reading SConscript files.") - memory_stats.append('after reading SConscript files:') - count_stats.append(('post-', 'read')) + MEMORY_STATS.append('after reading SConscript files:') + COUNT_STATS.append(('post-', 'read')) # Re-{enable,disable} warnings in case they disabled some in # the SConscript file. @@ -1319,8 +1270,8 @@ def _build_targets(fs, options, targets, target_top): if msg: SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg) - memory_stats.append('before building targets:') - count_stats.append(('pre-', 'build')) + MEMORY_STATS.append('before building targets:') + COUNT_STATS.append(('pre-', 'build')) def jobs_postfunc( jobs=jobs, @@ -1348,8 +1299,8 @@ def _build_targets(fs, options, targets, target_top): progress_display("scons: " + opening_message) jobs.run(postfunc = jobs_postfunc) - memory_stats.append('after building targets:') - count_stats.append(('post-', 'build')) + MEMORY_STATS.append('after building targets:') + COUNT_STATS.append(('post-', 'build')) return nodes @@ -1437,8 +1388,8 @@ def main(): SCons.Script._SConscript.SConscript_exception() sys.exit(2) - memory_stats.print_stats() - count_stats.print_stats() + MEMORY_STATS.print_stats() + COUNT_STATS.print_stats() if print_objects: SCons.Debug.listLoggedInstances('*') @@ -1469,6 +1420,9 @@ def main(): print("Total SCons execution time: %f seconds"%scons_time) print("Total command execution time: %f seconds"%ct) + if SCons.Util.stats.ENABLE_JSON: + WriteJsonFile() + sys.exit(exit_status) # Local Variables: diff --git a/SCons/Script/SConsOptions.py b/SCons/Script/SConsOptions.py index 8391d62..25c6046 100644 --- a/SCons/Script/SConsOptions.py +++ b/SCons/Script/SConsOptions.py @@ -701,7 +701,7 @@ def Parser(version): debug_options = ["count", "duplicate", "explain", "findlibs", "includes", "memoizer", "memory", "objects", "pdb", "prepare", "presub", "stacktrace", - "time", "action-timestamps"] + "time", "action-timestamps", "json"] def opt_debug(option, opt, value__, parser, debug_options=debug_options, diff --git a/SCons/Util/stats.py b/SCons/Util/stats.py new file mode 100644 index 0000000..ccad165 --- /dev/null +++ b/SCons/Util/stats.py @@ -0,0 +1,156 @@ +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +This package provides a way to gather various statistics during a SCons run and dump that info in several formats + +Additionally, it probably makes sense to do stderr/stdout output of those statistics here as well + +There are basically two types of stats. +1. Timer (start/stop/time) for specific event. These events can be hierarchical. So you can record the children events of some parent. + Think program compile could contain the total Program builder time, which could include linking, and stripping the executable +2. Counter. Counting the number of events and/or objects created. This would likely only be reported at the end of a given SCons run, + though it might be useful to query during a run. + +""" +import json + +import SCons.Debug + +ALL_STATS = {} +ENABLE_JSON = False + + +def AddStatType(name, stat_object): + """ + Add a statistic type to the global collection + """ + if name in ALL_STATS: + raise UserWarning(f'Stat type {name} already exists') + else: + ALL_STATS[name] = stat_object + + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: +class Stats: + def __init__(self): + self.stats = [] + self.labels = [] + self.append = self.do_nothing + self.print_stats = self.do_nothing + self.enabled = False + + def do_append(self, label): + raise NotImplementedError + + def do_print(self): + raise NotImplementedError + + def enable(self, outfp): + self.outfp = outfp + self.append = self.do_append + self.print_stats = self.do_print + self.enabled = True + + def do_nothing(self, *args, **kw): + pass + + +class CountStats(Stats): + + def __init__(self): + super().__init__() + self.stats_table = {} + + def do_append(self, label): + self.labels.append(label) + self.stats.append(SCons.Debug.fetchLoggedInstances()) + + def do_print(self): + self.stats_table = {} + for s in self.stats: + for n in [t[0] for t in s]: + self.stats_table[n] = [0, 0, 0, 0] + i = 0 + for s in self.stats: + for n, c in s: + self.stats_table[n][i] = c + i = i + 1 + self.outfp.write("Object counts:\n") + pre = [" "] + post = [" %s\n"] + l = len(self.stats) + fmt1 = ''.join(pre + [' %7s'] * l + post) + fmt2 = ''.join(pre + [' %7d'] * l + post) + labels = self.labels[:l] + labels.append(("", "Class")) + self.outfp.write(fmt1 % tuple([x[0] for x in labels])) + self.outfp.write(fmt1 % tuple([x[1] for x in labels])) + for k in sorted(self.stats_table.keys()): + r = self.stats_table[k][:l] + [k] + self.outfp.write(fmt2 % tuple(r)) + + +class MemStats(Stats): + def do_append(self, label): + self.labels.append(label) + self.stats.append(SCons.Debug.memory()) + + def do_print(self): + fmt = 'Memory %-32s %12d\n' + for label, stats in zip(self.labels, self.stats): + self.outfp.write(fmt % (label, stats)) + + +COUNT_STATS = CountStats() +MEMORY_STATS = MemStats() + + +def WriteJsonFile(): + """ + + """ + print("DUMPING JSON FILE") + json_structure = {} + if COUNT_STATS.enabled: + json_structure['Object counts'] = {} + + oc = json_structure['Object counts'] + for c in COUNT_STATS.stats_table: + oc[c] = {} + for l, v in zip(COUNT_STATS.labels, COUNT_STATS.stats_table[c]): + oc[c][''.join(l)] = v + + if MEMORY_STATS.enabled: + json_structure['Memory'] = {} + + m = json_structure['Memory'] + for label, stats in zip(MEMORY_STATS.labels, MEMORY_STATS.stats): + m[label] =stats + + with open("scons_stats.json", 'w') as sf: + sf.write(json.dumps(json_structure)) diff --git a/SCons/__init__.py b/SCons/__init__.py index f53583b..9804f4f 100644 --- a/SCons/__init__.py +++ b/SCons/__init__.py @@ -1,9 +1,9 @@ -__version__="4.5.1" +__version__="4.5.2" __copyright__="Copyright (c) 2001 - 2023 The SCons Foundation" __developer__="bdbaddog" -__date__="Mon, 06 Mar 2023 23:32:38 -0400" -__buildsys__="M1DOG2021" -__revision__="49578b34582d9e92dac7d713a8e58599ae35aa63" -__build__="49578b34582d9e92dac7d713a8e58599ae35aa63" +__date__="Sat, 22 Apr 2023 16:48:09 -0700" +__buildsys__="M1Dog2021" +__revision__="176711bd1fde814e9c441ae44132eb600063ec7a" +__build__="176711bd1fde814e9c441ae44132eb600063ec7a" # make sure compatibility is always in place import SCons.compat # noqa \ No newline at end of file -- cgit v0.12 From 7ddeb166c05a68ebea9b4976373694337614c5ae Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 23 Mar 2023 09:28:54 -0600 Subject: yacc tool updates The yacc tool now recognizes the bison syntax of using --header, --defines and --graph options in YACCFLAGS without supplying an option argument. Note that byacc doesn't allow leaving off the option argument, and would error out in such cases. Fixes #4326 The yacc tool now recognizes -H as a partial synonym for --header. It only works in the no-option-argument form - giving an option argument will likely break things. Fixes #4327 Tests are expanded to cover these. The graph file name (-g) is now generated relative to the requested target file name, not to the source name, to match actual current behavior. This is rare case - only kicks in if target explicitly requested with a different base name than source - in this case SCons would emit a different name than bison produces. Unlikely to affect any real usage - you would have to set up the condition described, and additionally use the graph file as a source for some other build target. The default file suffix for graph files is set to .gv, which is current for Bison as of 3.8. The previous suffix for Bison, dating back to 2.4, was .dot, which is still the suffix byacc uses. Docs updated to better describe when you need to set this. The former default, .vcg, has not been used since 2006. Documentation updated for the two header suffix construction variables to better describe (I hope) what these mean and when to set them. Other doc updates as well. Signed-off-by: Mats Wichmann --- CHANGES.txt | 9 +++ SCons/Tool/Tool.xml | 26 +++++-- SCons/Tool/yacc.py | 35 ++++++---- SCons/Tool/yacc.xml | 92 +++++++++++++------------ test/YACC/BISONFLAGS.py | 49 ++++++++++++- test/YACC/YACCFLAGS-fixture/myyacc.py | 125 ++++++++++++++++++++++------------ test/YACC/YACCFLAGS.py | 2 +- 7 files changed, 230 insertions(+), 108 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d4ad973..2977fa8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -23,6 +23,15 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER calls dunder method __call__. Invoke instance directly." - Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1. Only used in msvs.py. Use base64.decodebytes instead. + - The yacc tool now understands the bison behavior of --header, + --defines and --graph being called without option-argument as being + synonyms for -d (first two) and -g. -H also recognized as a synonym + for -d. Default value for $YACCVCGFILESUFFIX changed to '.gv' + to match current bison default (since bison 3.8). The graph file name + (-g) is now generated relative to the requested target file name, + not to the source file name, to match actual current behavior (only + affects if target explicitly requested with a different base name + than source). Docs updated. Fixes #4326 and #4327. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Tool/Tool.xml b/SCons/Tool/Tool.xml index de71efb..d25d7a5 100644 --- a/SCons/Tool/Tool.xml +++ b/SCons/Tool/Tool.xml @@ -37,10 +37,19 @@ Example: # builds foo.c -env.CFile(target = 'foo.c', source = 'foo.l') +env.CFile(target='foo.c', source='foo.l') + # builds bar.c -env.CFile(target = 'bar', source = 'bar.y') +env.CFile(target='bar', source='bar.y') + + +Note that for yacc files, +the output file name is derived from target, +or from the source file name if a target is not specified; +the traditional yacc default name +y.tab.c is not used. + @@ -59,10 +68,19 @@ Example: # builds foo.cc -env.CXXFile(target = 'foo.cc', source = 'foo.ll') +env.CXXFile(target='foo.cc', source='foo.ll') + # builds bar.cc -env.CXXFile(target = 'bar', source = 'bar.yy') +env.CXXFile(target='bar', source='bar.yy') + + +Note that for yacc files, +the output file name is derived from target, +or from the source file name if a target is not specified; +the traditional yacc default name +y.tab.cc is not used. + diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index 67ecd86..d408e62 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -23,8 +23,11 @@ """Tool-specific initialization for yacc. -This tool should support multiple yacc implementations, -but is in actuality biased towards GNU Bison. +This tool should support multiple yacc implementations, but is in actuality +biased towards GNU Bison. In particular, it forces the output file name (thus +avoiding the default convention of y.tab.c or foo.tab.c), so the tool *must* +support the -o option, which pure POSIX yacc does not. byacc should be okay +as an alternative to bison. There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() @@ -64,15 +67,17 @@ def _yaccEmitter(target, source, env, ysuf, hsuf) -> tuple: target = [targetBase + ".m"] # the extension is ".m". # If -d is specified on the command line, yacc will emit a .h - # or .hpp file with the same name as the .c or .cpp output file. - if '-d' in flags: + # or .hpp file with the same base name as the .c or .cpp output file. + # if '-d' in flags: # add bison options -H, --header, --defines (obsolete) + if "-d" in flags or "-H" in flags or "--header" in flags or "--defines" in flags: target.append(targetBase + env.subst(hsuf, target=target, source=source)) - # If -g is specified on the command line, yacc will emit a .vcg - # file with the same base name as the .y, .yacc, .ym or .yy file. - if "-g" in flags: - base, ext = os.path.splitext(to_String(source[0])) - target.append(base + env.subst("$YACCVCGFILESUFFIX")) + # If -g is specified on the command line, yacc will emit a graph + # file with the same base name as the .c or .cpp output file. + # TODO: should this be handled like -v? i.e. a side effect, not target + # if "-g" in flags: # add bison option --graph + if "-g" in flags or "--graph" in flags: + target.append(targetBase + env.subst("$YACCVCGFILESUFFIX")) # If -v is specified yacc will create the output debug file # which is not really source for any process, but should @@ -82,11 +87,13 @@ def _yaccEmitter(target, source, env, ysuf, hsuf) -> tuple: env.Clean(target[0], targetBase + '.output') # With --defines and --graph, the file to write is defined by the option - # argument. Extract this and include in the list of targets. - # NOTE: a filename passed to the command this way is not modified by SCons, - # and so will be interpreted relative to the project top directory at - # execution time, while the name added to the target list will be + # argument, if present (the no-option-argument cases were caught above). + # Extract this and include in the list of targets. + # NOTE: a filename passed to the command this way is not modified by + # SCons, and so will be interpreted relative to the project top directory + # at execution time, while the name added to the target list will be # interpreted relative to the SConscript directory - a possible mismatch. + # Better to use YACC_HEADER_FILE and YACC_GRAPH_FILE to pass these. # # These are GNU bison-only options. # Since bison 3.8, --header is the preferred name over --defines @@ -185,7 +192,7 @@ def generate(env) -> None: env['YACCCOM'] = '$YACC $YACCFLAGS $_YACC_HEADER $_YACC_GRAPH -o $TARGET $SOURCES' env['YACCHFILESUFFIX'] = '.h' env['YACCHXXFILESUFFIX'] = '.hpp' - env['YACCVCGFILESUFFIX'] = '.vcg' + env['YACCVCGFILESUFFIX'] = '.gv' env['_YACC_HEADER'] = '${YACC_HEADER_FILE and "--header=" + str(YACC_HEADER_FILE)}' env['_YACC_GRAPH'] = '${YACC_GRAPH_FILE and "--graph=" + str(YACC_GRAPH_FILE)}' diff --git a/SCons/Tool/yacc.xml b/SCons/Tool/yacc.xml index 9ccc4e6..cf466a2 100644 --- a/SCons/Tool/yacc.xml +++ b/SCons/Tool/yacc.xml @@ -115,6 +115,7 @@ with the suffix defined by &cv-link-YACCHFILESUFFIX; if the yacc source file ends in a .y suffix, or a file with the suffix defined by &cv-link-YACCHXXFILESUFFIX; if the yacc source file ends in a .yy suffix. +The header will have the same base name as the requested target. @@ -131,22 +132,31 @@ with the suffix .output. Also recognized are GNU &bison; options - and its deprecated synonym -, + +(and its deprecated synonym ), which is similar to -but the output filename is named by the option argument; -and , +but gives the option to explicitly name the output header file +through an option argument; +and , which is similar to -but the output filename is named by the option argument. +but gives the option to explicitly name the output graph file +through an option argument. +The file suffixes described for + and above +are not applied if these are used in the option=argument form. Note that files specified by and may not be properly handled -by &SCons; in all situations. Consider using -&cv-link-YACC_HEADER_FILE; and &cv-link-YACC_GRAPH_FILE; instead. +by &SCons; in all situations, and using those in &cv-YACCFLAGS; +should be considered legacy support only. +Consider using &cv-link-YACC_HEADER_FILE; +and &cv-link-YACC_GRAPH_FILE; instead +if the files need to be explicitly named +(new in version 4.4.0). @@ -159,6 +169,7 @@ Will be emitted as a command-line option. Use this in preference to including in &cv-link-YACCFLAGS; directly. +New in version 4.4.0. @@ -171,6 +182,7 @@ Will be emitted as a command-line option. Use this in preference to including in &cv-link-YACCFLAGS; directly.
+New in version 4.4.0. @@ -179,14 +191,13 @@ command-line option. Use this in preference to including The suffix of the C header file generated by the parser generator -when the - -option is used. -Note that setting this variable does not cause -the parser generator to generate a header -file with the specified suffix, -it exists to allow you to specify -what suffix the parser generator will use of its own accord. +when the option +(or without an option-argument) +is used in &cv-link-YACCFLAGS;. +Note that setting this variable informs &SCons; +how to construct the header filename for tracking purposes, +it does not affect the actual generated filename. +Set this to match what your parser generator produces. The default value is .h. @@ -198,22 +209,14 @@ The default value is The suffix of the C++ header file generated by the parser generator -when the - -option is used. -Note that setting this variable does not cause -the parser generator to generate a header -file with the specified suffix, -it exists to allow you to specify -what suffix the parser generator will use of its own accord. -The default value is -.hpp, -except on Mac OS X, -where the default is -${TARGET.suffix}.h. -because the default &bison; parser generator just -appends .h -to the name of the generated C++ file. +when the option +(or without an option-argument) +is used in &cv-link-YACCFLAGS;. +Note that setting this variable informs &SCons; +how to construct the header filename for tracking purposes, +it does not affect the actual generated filename. +Set this to match what your parser generator produces. +The default value is .hpp. @@ -222,17 +225,22 @@ to the name of the generated C++ file. The suffix of the file -containing the VCG grammar automaton definition -when the - -option is used. -Note that setting this variable does not cause -the parser generator to generate a VCG -file with the specified suffix, -it exists to allow you to specify -what suffix the parser generator will use of its own accord. -The default value is -.vcg. +containing a graph of the grammar automaton +when the option +(or without an option-argument) +is used in &cv-link-YACCFLAGS;. +Note that setting this variable informs &SCons; +how to construct the graph filename for tracking purposes, +it does not affect the actual generated filename. +Various yacc tools have emitted various formats +at different times. +Set this to match what your parser generator produces. +The default value is .gv. + + +Changed in version 4.X.Y: the default value +changed from .vcg (&bison; stopped generating +.vcg output with version 2.4, in 2006). diff --git a/test/YACC/BISONFLAGS.py b/test/YACC/BISONFLAGS.py index cae673d..9b8cf03 100644 --- a/test/YACC/BISONFLAGS.py +++ b/test/YACC/BISONFLAGS.py @@ -47,12 +47,13 @@ test = TestSCons.TestSCons() test.subdir('sub1') test.subdir('sub2') +test.subdir('sub3') test.dir_fixture('YACCFLAGS-fixture') test.write('SConstruct', """\ DefaultEnvironment(tools=[]) -SConscript(dirs=['sub1', 'sub2']) +SConscript(dirs=['sub1', 'sub2', 'sub3']) """) # this SConscript is for the options-in-flags version @@ -90,8 +91,50 @@ env.CFile( """ % locals()) test.write(['sub2', 'aaa.y'], "aaa.y\nYACCFLAGS\n") +# this SConscript is to try various other flag combos +test.write(['sub3', 'SConscript'], """\ +import sys + +env = Environment( + YACC=r'%(_python_)s myyacc.py', + YACCFLAGS='-x --header=header.h --graph=graph.g', + tools=['yacc', '%(linker)s', '%(compiler)s'], +) + +def check(targets, expected): + t = [str(target) for target in targets] + assert t == expected, t + +targs1 = env.CFile('trg1', source='aaa.y', YACCFLAGS='-d') +check(targs1, ['trg1.c', 'trg1.h']) + +targs2 = env.CXXFile('trg2', source='aaa.yy', YACCFLAGS='-d') +check(targs2, ['trg2.cc', 'trg2.hpp']) + +targs3 = env.CFile('trg3', source='aaa.y', YACCFLAGS='--defines=zot.q') +check(targs3, ['trg3.c', 'zot.q']) + +targs4 = env.CFile('trg4', source='aaa.y', YACCFLAGS='--header') +check(targs4, ['trg4.c', 'trg4.h']) + +targs5 = env.CFile('trg5', source='aaa.y', YACCFLAGS='-H') +check(targs5, ['trg5.c', 'trg5.h']) + +targs6 = env.CFile('trg6', source='aaa.y', YACCFLAGS='-g') +check(targs6, ['trg6.c', 'trg6.gv']) + +targs7 = env.CFile('trg7', source='aaa.y', YACCFLAGS='-g -H') +check(targs7, ['trg7.c', 'trg7.h', 'trg7.gv']) + +targs8 = env.CFile('trg8', source='aaa.y', YACCFLAGS='--graph --header') +check(targs8, ['trg8.c', 'trg8.h', 'trg8.gv']) +""" % locals()) + +test.write(['sub3', 'aaa.y'], "aaa.y\nYACCFLAGS\n") +test.write(['sub3', 'aaa.yy'], "aaa.yy\nYACCFLAGS\n") + test.run('.', stderr=None) -test.must_match(['sub1', 'aaa.c'], "aaa.y\n -x --header=header.h --graph=graph.g\n") +test.must_match(['sub1', 'aaa.c'], "aaa.y\n-x --header=header.h --graph=graph.g\n") # NOTE: this behavior is "wrong" but we're keeping it for compat: # the generated files should go into 'sub1', not the topdir. @@ -109,7 +152,7 @@ test.must_match(['graph.g'], 'yacc graph\n') sub2 = Path('sub2') headerfile = sub2 / 'header.h' graphfile = sub2 / 'graph.g' -yaccflags = f"aaa.y\n -x --header={headerfile} --graph={graphfile}\n" +yaccflags = f"aaa.y\n-x --header={headerfile} --graph={graphfile}\n" test.must_match(['sub2', 'aaa.c'], yaccflags) test.must_match(['sub2', 'header.h'], 'yacc header\n') test.must_match(['sub2', 'graph.g'], 'yacc graph\n') diff --git a/test/YACC/YACCFLAGS-fixture/myyacc.py b/test/YACC/YACCFLAGS-fixture/myyacc.py index 3bc1375..8b793a1 100644 --- a/test/YACC/YACCFLAGS-fixture/myyacc.py +++ b/test/YACC/YACCFLAGS-fixture/myyacc.py @@ -1,65 +1,102 @@ -import getopt +#!/usr/bin/python +# +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +""" +Mock yacc/bison command for testing yacc tool with options +""" + +import argparse +import os import sys from pathlib import Path -def make_side_effect(path, text): +# Sentinels to make sure we pick the defaults +HEADER_DEFAULT = "_header_compute" +GRAPH_DEFAULT = "_graph_compute" +REPORT_DEFAULT = "_report_compute" + + +def make_side_effect(path, text, outfile): + if path == HEADER_DEFAULT: + file, ext = os.path.splitext(outfile) + if ext in [".y", ".yacc"]: + path = file + ".h" + elif ext in [".ym"]: + path = file + ".h.m" + elif ext in [".yy"]: + path = file + ".hpp" + else: # just guess + path = file + ".h" + if path == GRAPH_DEFAULT: + path = os.path.splitext(outfile)[0] + ".gv" + if path == REPORT_DEFAULT: + path = os.path.splitext(outfile)[0] + ".output" + p = Path(path) - if str(p.parent) != '.': + if str(p.parent) != ".": p.parent.mkdir(parents=True, exist_ok=True) with p.open(mode="wb") as f: f.write(text) def fake_yacc(): - make_header = None - make_graph = None + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument("-g", "--graph", nargs="?", const=GRAPH_DEFAULT) + parser.add_argument("-d", dest="graph", action="store_const", const=HEADER_DEFAULT) + parser.add_argument("-v", "--verbose", action="store_const", const=REPORT_DEFAULT) + parser.add_argument("-x", action="store_true") # accept, do nothing + parser.add_argument("-H", "--header", "--defines", nargs="?", const=HEADER_DEFAULT) + parser.add_argument("-o", "--output", dest="out", required=True) + parser.add_argument("-I", dest="i_arguments", default=[], action="append") + parser.add_argument("files", nargs="+") + args = parser.parse_args() + # print(f"DEBUG: {args}") - longopts = ["defines=", "header=", "graph="] - cmd_opts, args = getopt.getopt(sys.argv[1:], 'o:I:x', longopts) - opt_string = '' - i_arguments = '' - - for opt, arg in cmd_opts: - if opt == '-o': - out = arg - elif opt == '-I': - i_arguments = f'{i_arguments} {arg}' - elif opt in ('--defines', '--header'): - make_header = arg - opt_string = f'{opt_string} {opt}={arg}' - elif opt == '--graph': - make_graph = arg - opt_string = f'{opt_string} {opt}={arg}' + # Synthesize "opt_string", which, when this script used getopt, was + # collected in the arg processing loop - from some arguments. The tests + # expect this to be subbed in for YACCFLAGS in making the output file. + opt_list = [] + skip = False + for arg in sys.argv[1:]: + if skip: + skip = False + elif arg == "-o": + skip = True + elif arg.startswith("-I"): + pass else: - opt_string = f'{opt_string} {opt}' + opt_list.append(arg) + # The original didn't use the file argument(s) so we have to get rid of. + for file in args.files: + if file in opt_list: + opt_list.remove(file) + opt_string = " ".join(opt_list) + + # Now we need to do something similar for i_arguments, which is easier + i_arguments = " ".join(args.i_arguments) - with open(out, 'wb') as ofp: - for a in args: - with open(a, 'rb') as ifp: + with open(args.out, "wb") as ofp: + for file in args.files: + with open(file, "rb") as ifp: contents = ifp.read() - contents = contents.replace(b'YACCFLAGS', opt_string.encode()) - contents = contents.replace(b'YACC', b'myyacc.py') - contents = contents.replace(b'I_ARGS', i_arguments.encode()) + contents = contents.replace(b"YACCFLAGS", opt_string.encode()) + contents = contents.replace(b"YACC", b"myyacc.py") + contents = contents.replace(b"I_ARGS", i_arguments.encode()) ofp.write(contents) - # Extra bits: - if make_header: - make_side_effect(make_header, b"yacc header\n") - if make_graph: - make_side_effect(make_graph, b"yacc graph\n") + # Make extra output files + if args.header: + make_side_effect(args.header, b"yacc header\n", args.out) + if args.graph: + make_side_effect(args.graph, b"yacc graph\n", args.out) + if args.verbose: + make_side_effect(args.verbose, b"yacc debug\n", args.out) -if __name__ == '__main__': +if __name__ == "__main__": fake_yacc() sys.exit(0) - -# If -d is specified on the command line, yacc will emit a .h -# or .hpp file with the same name as the .c or .cpp output file. - -# If -g is specified on the command line, yacc will emit a .vcg -# file with the same base name as the .y, .yacc, .ym or .yy file. - -# If -v is specified yacc will create the output debug file -# which is not really source for any process, but should -# be noted and also be cleaned (issue #2558) diff --git a/test/YACC/YACCFLAGS.py b/test/YACC/YACCFLAGS.py index 1f3ad78..7a07072 100644 --- a/test/YACC/YACCFLAGS.py +++ b/test/YACC/YACCFLAGS.py @@ -56,7 +56,7 @@ env.CFile(target='out/aaa', source='in/aaa.y') test.write(['in', 'aaa.y'], "aaa.y\nYACCFLAGS\nI_ARGS\n") test.run('.', stderr=None) -test.must_match(['out', 'aaa.c'], "aaa.y\n -x\n out in\n") +test.must_match(['out', 'aaa.c'], "aaa.y\n-x\nout in\n") test.pass_test() -- cgit v0.12 From 2ef22690e2c81db7e82b0526bc935854e4e85e8e Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 6 May 2023 08:00:27 -0600 Subject: yacc changes: add RELEASE, drop doc note Per review requests Signed-off-by: Mats Wichmann --- RELEASE.txt | 9 ++++++--- SCons/Tool/Tool.xml | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/RELEASE.txt b/RELEASE.txt index c2244f2..e475755 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -26,13 +26,16 @@ DEPRECATED FUNCTIONALITY CHANGED/ENHANCED EXISTING FUNCTIONALITY --------------------------------------- -- List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug +- The yacc tool now understands the bison behavior of --header, --defines + and --graph being called without an option-argument as being synonyms + for -d (first two) and -g. -H also recognized as a synonym for -d. + Default value for $YACCVCGFILESUFFIX changed to '.gv' to match + current bison default (since bison 3.8). Set this variable to '.dot' + if using byacc. FIXES ----- - - Fixed: when using the mingw tool, if an msys2 Python is used (os.sep is '/' rather than the Windows default '\'), certain Configure checks could fail due to the construction of the path to run the compiled check. diff --git a/SCons/Tool/Tool.xml b/SCons/Tool/Tool.xml index d25d7a5..086d989 100644 --- a/SCons/Tool/Tool.xml +++ b/SCons/Tool/Tool.xml @@ -43,13 +43,13 @@ env.CFile(target='foo.c', source='foo.l') env.CFile(target='bar', source='bar.y') - + -- cgit v0.12 From 38453a39b4aedfa6ac2970d05cb6ee23527374b3 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 24 Feb 2023 11:43:27 -0700 Subject: pdb debugging now recognizes SConstruct/SConscript Make it possible (once the project path has been added to sys.path) to set/clear breakpoints using file paths that end in SConstruct and SConscript - specializing pdb.Pdb to override the need for all paths that are not absolute to end in .py. Man: tried to address some surprise that pdb can't find the SConstruct when you start up in debugger mode. Signed-off-by: Mats Wichmann --- CHANGES.txt | 3 +++ NEWS.d/changes/4306.bugfix | 5 +++++ SCons/Script/Main.py | 38 +++++++++++++++++++++++++++++++++++++- doc/man/scons.xml | 46 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 NEWS.d/changes/4306.bugfix diff --git a/CHANGES.txt b/CHANGES.txt index d4ad973..58a3840 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -23,6 +23,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER calls dunder method __call__. Invoke instance directly." - Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1. Only used in msvs.py. Use base64.decodebytes instead. + - When debugging (--debug=pdb), the filenames SConstruct and SConscript + are now recognized when manipulating breakpoints. Previously, only a + full pathname worked, as otherwise pdb required a .py extension on files. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/NEWS.d/changes/4306.bugfix b/NEWS.d/changes/4306.bugfix new file mode 100644 index 0000000..7ec2774 --- /dev/null +++ b/NEWS.d/changes/4306.bugfix @@ -0,0 +1,5 @@ + +When debugging (--debug=pdb), the filenames SConstruct and SConscript +are now recognized when manipulating breakpoints. Previously, only a +full pathname worked, as otherwise pdb required a .py extension on files. + diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index c3f31ca..ab4eedf 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -1390,7 +1390,42 @@ def _exec_main(parser, values) -> None: if isinstance(options.debug, list) and "pdb" in options.debug: import pdb - pdb.Pdb().runcall(_main, parser) + + class SConsPdb(pdb.Pdb): + """Specialization of Pdb to help find SConscript files.""" + + def lookupmodule(self, filename: str) -> Optional[str]: + """Helper function for break/clear parsing -- SCons version. + + Copy of the original, but recognizes common names for + SConstruct/SConscript without having to have them end in ``.py`` + + .. versionadded:: 4.5.0 + """ + if os.path.isabs(filename) and os.path.exists(filename): + return filename + f = os.path.join(sys.path[0], filename) + if os.path.exists(f) and self.canonic(f) == self.mainpyfile: + return f + root, ext = os.path.splitext(filename) + SCONSCRIPTS = ( + "SConstruct Sconstruct sconstruct SConscript sconscript".split() + ) + base = os.path.split(filename)[-1] + if ext == '' and base not in SCONSCRIPTS: + filename = filename + '.py' + if os.path.isabs(filename): + return filename + for dirname in sys.path: + while os.path.islink(dirname): + dirname = os.readlink(dirname) + fullname = os.path.join(dirname, filename) + if os.path.exists(fullname): + return fullname + return None + + SConsPdb().runcall(_main, parser) + elif options.profile_file: from cProfile import Profile @@ -1399,6 +1434,7 @@ def _exec_main(parser, values) -> None: prof.runcall(_main, parser) finally: prof.dump_stats(options.profile_file) + else: _main(parser) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index e79a267..a6294ac 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -959,9 +959,53 @@ of the various classes used internally by SCons. pdb -Re-run &scons; under the control of the +Run &scons; under control of the pdb &Python; debugger. + +$ scons --debug=pdb +> /usr/lib/python3.11/site-packages/SCons/Script/Main.py(869)_main() +-> options = parser.values +(Pdb) + + +pdb will stop at the +beginning of the &scons; main routine on startup. +The search path (sys.path) +at that point will include the location of the running &scons;, +but not of the project itself - +if you need to set breakpoints in your project files, +you will either need to add to the path, +or use absolute pathnames when referring to project files. +A .pdbrc file in the project root +can be used to add the current directory to the search path +to avoid having to enter it by hand, +along these lines: + + +sys.path.append('.') + + +Due to the implementation of the +pdb module, +the break, +tbreak +and clear +commands only understand references to filenames +which end in a .py suffix +(although that suffix does not have to be typed), +except if you use an absolute path. +As a special exception to that rule, the names +&SConstruct; and &SConscript; are recognized without +needing the .py extension. + + +Changed in version 4.5.0: +The names &SConstruct; and &SConscript; are now +recognized without needing to have a +.py suffix. + + -- cgit v0.12 From 0b96124b69b8e9b0440edf337e9123b2da67c194 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 7 May 2023 08:48:30 -0600 Subject: pdb: minor tweaks to doc [skip appveyor] Explanations of new "recognize sconscripts" behavior to debugger support are tweaked a bit to hopefully be more clear. Signed-off-by: Mats Wichmann --- CHANGES.txt | 5 +++-- RELEASE.txt | 6 ++++-- SCons/Script/Main.py | 11 +++++++---- doc/man/scons.xml | 14 +++++++------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 58a3840..60f5f96 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -24,8 +24,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1. Only used in msvs.py. Use base64.decodebytes instead. - When debugging (--debug=pdb), the filenames SConstruct and SConscript - are now recognized when manipulating breakpoints. Previously, only a - full pathname worked, as otherwise pdb required a .py extension on files. + are now recognized when manipulating breakpoints. Previously, + only a full pathname to an sconscript file worked, as pdb requires + a .py extension to open a file that is not an absolute path. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index c2244f2..0d931b7 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -26,8 +26,10 @@ DEPRECATED FUNCTIONALITY CHANGED/ENHANCED EXISTING FUNCTIONALITY --------------------------------------- -- List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug +- When debugging (--debug=pdb), the filenames SConstruct and SConscript + are now recognized when manipulating breakpoints. Previously, + only a full pathname to an sconscript file worked, as pdb requires + a .py extension to open a file that is not an absolute path. FIXES ----- diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index ab4eedf..79806ba 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -1397,10 +1397,13 @@ def _exec_main(parser, values) -> None: def lookupmodule(self, filename: str) -> Optional[str]: """Helper function for break/clear parsing -- SCons version. - Copy of the original, but recognizes common names for - SConstruct/SConscript without having to have them end in ``.py`` + translates (possibly incomplete) file or module name + into an absolute file name. - .. versionadded:: 4.5.0 + The SCons override recognizes common names for ``SConstruct`` + and ``SConscript`` without requiring a ``.py`` suffix. + + .. versionadded:: 4.6.0 """ if os.path.isabs(filename) and os.path.exists(filename): return filename @@ -1412,7 +1415,7 @@ def _exec_main(parser, values) -> None: "SConstruct Sconstruct sconstruct SConscript sconscript".split() ) base = os.path.split(filename)[-1] - if ext == '' and base not in SCONSCRIPTS: + if ext == '' and base not in SCONSCRIPTS: # SCons filename = filename + '.py' if os.path.isabs(filename): return filename diff --git a/doc/man/scons.xml b/doc/man/scons.xml index a6294ac..97a6131 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -973,8 +973,8 @@ $ scons --debug=pdb beginning of the &scons; main routine on startup. The search path (sys.path) at that point will include the location of the running &scons;, -but not of the project itself - -if you need to set breakpoints in your project files, +but not of the project itself. +If you need to set breakpoints in your project files, you will either need to add to the path, or use absolute pathnames when referring to project files. A .pdbrc file in the project root @@ -992,17 +992,17 @@ the break, tbreak and clear commands only understand references to filenames -which end in a .py suffix -(although that suffix does not have to be typed), +which have a .py extension. +(although the suffix itself can be omitted), except if you use an absolute path. As a special exception to that rule, the names &SConstruct; and &SConscript; are recognized without needing the .py extension.
-Changed in version 4.5.0: +Changed in version 4.6.0: The names &SConstruct; and &SConscript; are now -recognized without needing to have a +recognized without requiring .py suffix. @@ -4005,7 +4005,7 @@ it will not be added again. The default is False. library can be a list of library names, or None (the default if the argument is omitted). If the former, symbol is checked against -each library name in order, returning +each library name in order, returning (and reporting success) on the first successful test; if the latter, it is checked with the current value of &cv-LIBS; -- cgit v0.12 From aed512b9626a44e19b0368f241ca504cffa01a22 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 11 Nov 2021 15:12:01 -0700 Subject: Use pathlib in runtest In the past, there have been some mismatches between how tests are specified and how they are found. testlist files, excludelist files and command-line specifications should be agnostic to operating system conventions. For example, typing "runtest.py foo/bar" on windows will produce paths like foo/bar\test.py, which is hard to match and painful to read, it should obviously match discovered foo\bar\test.py. Test information should be output using the native path separator for consistency. Using pathlib lets these be normalized - stored in a common format and output in the expected format. Adding this normalization of course broke some tests, which either intentionally or through omission expected some portion of a path to be UNIX-style. Specifically these five: test\runtest\baseline\fail.py test\runtest\baseline\no_result.py test\runtest\simple\fail.py test\runtest\simple\no_result.py test\runtest\simple\pass.py test\runtest\testargv.py This was fixed and a general cleanup/reformat performed on the runtest tests. Signed-off-by: Mats Wichmann --- CHANGES.txt | 2 + runtest.py | 126 ++++++++++++++++++------------------- test/runtest/SCons.py | 17 +++-- test/runtest/baseline/combined.py | 29 ++++----- test/runtest/baseline/fail.py | 27 ++++---- test/runtest/baseline/no_result.py | 38 ++++++----- test/runtest/baseline/pass.py | 17 +++-- test/runtest/faillog.py | 17 +++-- test/runtest/no_faillog.py | 26 ++++---- test/runtest/print_time.py | 28 ++++----- test/runtest/python.py | 25 ++++---- test/runtest/retry.py | 22 ++++--- test/runtest/simple/combined.py | 28 ++++----- test/runtest/simple/fail.py | 25 ++++---- test/runtest/simple/no_result.py | 31 +++++---- test/runtest/simple/pass.py | 18 +++--- test/runtest/testargv.py | 42 ++++++------- test/runtest/testlistfile.py | 24 +++---- test/runtest/xml/output.py | 32 ++++------ 19 files changed, 281 insertions(+), 293 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d4ad973..5ad76b8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -23,6 +23,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER calls dunder method __call__. Invoke instance directly." - Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1. Only used in msvs.py. Use base64.decodebytes instead. + - SCons test runner now uses pathlib to normalize and compare paths + to test files. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/runtest.py b/runtest.py index a2ece7e..46cdc7b 100755 --- a/runtest.py +++ b/runtest.py @@ -14,22 +14,17 @@ This script adds SCons/ and testing/ directories to PYTHONPATH, performs test discovery and processes tests according to options. """ -# TODO: normalize requested and testlist/exclude paths for easier comparison. -# e.g.: "runtest foo/bar" on windows will produce paths like foo/bar\test.py -# this is hard to match with excludelists, and makes those both os.sep-specific -# and command-line-typing specific. - import argparse -import glob +import itertools import os -import stat import subprocess import sys import tempfile import threading import time from abc import ABC, abstractmethod -from pathlib import Path +from io import StringIO +from pathlib import Path, PurePath, PureWindowsPath from queue import Queue cwd = os.getcwd() @@ -39,7 +34,7 @@ scons = None catch_output = False suppress_output = False -script = os.path.basename(sys.argv[0]) +script = PurePath(sys.argv[0]).name usagestr = """\ %(script)s [OPTIONS] [TEST ...] """ % locals() @@ -388,11 +383,13 @@ else: class RuntestBase(ABC): """ Base class for tests """ - def __init__(self, path, num, spe=None): - self.path = path - self.num = num + _ids = itertools.count(1) # to geenerate test # automatically + + def __init__(self, path, spe=None): + self.path = str(path) + self.testno = next(self._ids) self.stdout = self.stderr = self.status = None - self.abspath = os.path.abspath(path) + self.abspath = path.absolute() self.command_args = [] self.command_str = "" self.test_time = self.total_time = 0 @@ -404,7 +401,7 @@ class RuntestBase(ABC): break @abstractmethod - def execute(self): + def execute(self, env): pass @@ -547,7 +544,7 @@ if sys.platform == 'win32': # Windows doesn't support "shebang" lines directly (the Python launcher # and Windows Store version do, but you have to get them launched first) # so to directly launch a script we depend on an assoc for .py to work. - # Some systems may have none, and in some cases IDE programs take over + # Some systems may have none, and in some cases IDE programs take over # the assoc. Detect this so the small number of tests affected can skip. try: python_assoc = get_template_command('.py') @@ -564,7 +561,7 @@ if '_JAVA_OPTIONS' in os.environ: # ---[ test discovery ]------------------------------------ -# This section figures which tests to run. +# This section figures out which tests to run. # # The initial testlist is made by reading from the testlistfile, # if supplied, or by looking at the test arguments, if supplied, @@ -587,10 +584,15 @@ if '_JAVA_OPTIONS' in os.environ: # Test exclusions, if specified, are then applied. -def scanlist(testlist): +def scanlist(testfile): """ Process a testlist file """ - tests = [t.strip() for t in testlist if not t.startswith('#')] - return [t for t in tests if t] + data = StringIO(testfile.read_text()) + tests = [t.strip() for t in data.readlines() if not t.startswith('#')] + # in order to allow scanned lists to work whether they use forward or + # backward slashes, first create the object as a PureWindowsPath which + # accepts either, then use that to make a Path object to use for + # comparisons like "file in scanned_list". + return [Path(PureWindowsPath(t)) for t in tests if t] def find_unit_tests(directory): @@ -602,7 +604,8 @@ def find_unit_tests(directory): continue for fname in filenames: if fname.endswith("Tests.py"): - result.append(os.path.join(dirpath, fname)) + result.append(Path(dirpath, fname)) + return sorted(result) @@ -617,79 +620,74 @@ def find_e2e_tests(directory): # Slurp in any tests in exclude lists excludes = [] if ".exclude_tests" in filenames: - p = Path(dirpath).joinpath(".exclude_tests") - # TODO simplify when Py3.5 dropped - if sys.version_info.major == 3 and sys.version_info.minor < 6: - excludefile = p.resolve() - else: - excludefile = p.resolve(strict=True) - with excludefile.open() as f: - excludes = scanlist(f) + excludefile = Path(dirpath, ".exclude_tests").resolve() + excludes = scanlist(excludefile) for fname in filenames: - if fname.endswith(".py") and fname not in excludes: - result.append(os.path.join(dirpath, fname)) + if fname.endswith(".py") and Path(fname) not in excludes: + result.append(Path(dirpath, fname)) return sorted(result) # initial selection: +# if we have a testlist file read that, else hunt for tests. unittests = [] endtests = [] if args.testlistfile: - with args.testlistfile.open() as f: - tests = scanlist(f) + tests = scanlist(args.testlistfile) else: testpaths = [] - if args.all: - testpaths = ['SCons', 'test'] - elif args.testlist: - testpaths = args.testlist - - for tp in testpaths: - # Clean up path so it can match startswith's below - # remove leading ./ or .\ - if tp.startswith('.') and tp[1] in (os.sep, os.altsep): - tp = tp[2:] - - for path in glob.glob(tp): - if os.path.isdir(path): - if path.startswith(('SCons', 'testing')): + if args.all: # -a flag + testpaths = [Path('SCons'), Path('test')] + elif args.testlist: # paths given on cmdline + testpaths = [Path(PureWindowsPath(t)) for t in args.testlist] + + for path in testpaths: + # Clean up path removing leading ./ or .\ + name = str(path) + if name.startswith('.') and name[1] in (os.sep, os.altsep): + path = path.with_name(tn[2:]) + + if path.exists(): + if path.is_dir(): + if path.parts[0] == "SCons" or path.parts[0] == "testing": unittests.extend(find_unit_tests(path)) - elif path.startswith('test'): + elif path.parts[0] == 'test': endtests.extend(find_e2e_tests(path)) + # else: TODO: what if user pointed to a dir outside scons tree? else: - if path.endswith("Tests.py"): + if path.match("*Tests.py"): unittests.append(path) - elif path.endswith(".py"): + elif path.match("*.py"): endtests.append(path) - tests = sorted(unittests + endtests) + tests = sorted(unittests + endtests) # Remove exclusions: if args.e2e_only: - tests = [t for t in tests if not t.endswith("Tests.py")] + tests = [t for t in tests if not t.match("*Tests.py")] if args.unit_only: - tests = [t for t in tests if t.endswith("Tests.py")] + tests = [t for t in tests if t.match("*Tests.py")] if args.excludelistfile: - with args.excludelistfile.open() as f: - excludetests = scanlist(f) + excludetests = scanlist(args.excludelistfile) tests = [t for t in tests if t not in excludetests] +# did we end up with any tests? if not tests: sys.stderr.write(parser.format_usage() + """ -error: no tests were found. - Tests can be specified on the command line, read from a file with - the -f/--file option, or discovered with -a/--all to run all tests. +error: no tests matching the specification were found. + See "Test selection options" in the help for details on + how to specify and/or exclude tests. """) sys.exit(1) # ---[ test processing ]----------------------------------- -tests = [Test(t, n + 1) for n, t in enumerate(tests)] +tests = [Test(t) for t in tests] if args.list_only: for t in tests: - sys.stdout.write(t.path + "\n") + print(t.path) sys.exit(0) if not args.python: @@ -702,7 +700,7 @@ os.environ["python_executable"] = args.python if args.print_times: def print_time(fmt, tm): - sys.stdout.write(fmt % tm) + print(fmt % tm) else: @@ -739,7 +737,7 @@ def log_result(t, io_lock=None): print(t.stdout) if t.stderr: print(t.stderr) - print_time("Test execution time: %.1f seconds\n", t.test_time) + print_time("Test execution time: %.1f seconds", t.test_time) finally: if io_lock: io_lock.release() @@ -778,8 +776,8 @@ def run_test(t, io_lock=None, run_async=True): if args.printcommand: if args.print_progress: t.headline += "%d/%d (%.2f%s) %s\n" % ( - t.num, total_num_tests, - float(t.num) * 100.0 / float(total_num_tests), + t.testno, total_num_tests, + float(t.testno) * 100.0 / float(total_num_tests), "%", t.command_str, ) @@ -843,7 +841,7 @@ else: # --- all tests are complete by the time we get here --- if tests: tests[0].total_time = time_func() - total_start_time - print_time("Total execution time for all tests: %.1f seconds\n", tests[0].total_time) + print_time("Total execution time for all tests: %.1f seconds", tests[0].total_time) passed = [t for t in tests if t.status == 0] fail = [t for t in tests if t.status == 1] diff --git a/test/runtest/SCons.py b/test/runtest/SCons.py index 20c4c64..fc4c3e0 100644 --- a/test/runtest/SCons.py +++ b/test/runtest/SCons.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that we find tests under the SCons/ tree only if they end @@ -46,17 +45,17 @@ test.write_passing_test(['SCons', 'passTests.py']) test.write_passing_test(['SCons', 'suite', 'pass.py']) test.write_passing_test(['SCons', 'suite', 'passTests.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(src_passTests_py)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {src_passTests_py} PASSING TEST STDOUT -%(pythonstring)s%(pythonflags)s %(src_suite_passTests_py)s +{pythonstring}{pythonflags} {src_suite_passTests_py} PASSING TEST STDOUT -""" % locals() +""" expect_stderr = """\ PASSING TEST STDERR PASSING TEST STDERR -""" % locals() +""" test.run(arguments='-k SCons', stdout=expect_stdout, stderr=expect_stderr) diff --git a/test/runtest/baseline/combined.py b/test/runtest/baseline/combined.py index 228d42d..00ce85b 100644 --- a/test/runtest/baseline/combined.py +++ b/test/runtest/baseline/combined.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test a combination of a passing test, failing test, and no-result @@ -42,27 +41,24 @@ test_pass_py = os.path.join('test', 'pass.py') test = TestRuntest.TestRuntest() test.subdir('test') - test.write_failing_test(['test', 'fail.py']) - test.write_no_result_test(['test', 'no_result.py']) - test.write_passing_test(['test', 'pass.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(test_fail_py)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_fail_py} FAILING TEST STDOUT -%(pythonstring)s%(pythonflags)s %(test_no_result_py)s +{pythonstring}{pythonflags} {test_no_result_py} NO RESULT TEST STDOUT -%(pythonstring)s%(pythonflags)s %(test_pass_py)s +{pythonstring}{pythonflags} {test_pass_py} PASSING TEST STDOUT Failed the following test: -\t%(test_fail_py)s +\t{test_fail_py} NO RESULT from the following test: -\t%(test_no_result_py)s -""" % locals() +\t{test_no_result_py} +""" expect_stderr = """\ FAILING TEST STDERR @@ -70,10 +66,7 @@ NO RESULT TEST STDERR PASSING TEST STDERR """ -test.run(arguments='-k -b . test', - status=1, - stdout=expect_stdout, - stderr=expect_stderr) +test.run(arguments='-k -b . test', status=1, stdout=expect_stdout, stderr=expect_stderr) test.pass_test() diff --git a/test/runtest/baseline/fail.py b/test/runtest/baseline/fail.py index e2aff4a..2268dce 100644 --- a/test/runtest/baseline/fail.py +++ b/test/runtest/baseline/fail.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,38 +22,39 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test how we handle a failing test specified on the command line. """ +import os + import TestRuntest pythonstring = TestRuntest.pythonstring pythonflags = TestRuntest.pythonflags +test_fail_py = os.path.join('test', 'fail.py') test = TestRuntest.TestRuntest() test.subdir('test') - test.write_failing_test(['test', 'fail.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s test/fail.py +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_fail_py} FAILING TEST STDOUT -""" % locals() +""" expect_stderr = """\ FAILING TEST STDERR """ -test.run(arguments='-k -b . test/fail.py', - status=1, - stdout=expect_stdout, - stderr=expect_stderr) +test.run( + arguments='-k -b . test/fail.py', + status=1, + stdout=expect_stdout, + stderr=expect_stderr, +) test.pass_test() diff --git a/test/runtest/baseline/no_result.py b/test/runtest/baseline/no_result.py index d00f536..ce6f20c 100644 --- a/test/runtest/baseline/no_result.py +++ b/test/runtest/baseline/no_result.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,43 +22,45 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test how we handle a no-results test specified on the command line. """ +import os + import TestRuntest pythonstring = TestRuntest.pythonstring pythonflags = TestRuntest.pythonflags +test_no_result_py = os.path.join('test', 'no_result.py') test = TestRuntest.TestRuntest() - test.subdir('test') - test.write_no_result_test(['test', 'no_result.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s test/no_result.py +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_no_result_py} NO RESULT TEST STDOUT -""" % locals() +""" expect_stderr = """\ NO RESULT TEST STDERR """ -test.run(arguments='--no-ignore-skips -k -b . test/no_result.py', - status=2, - stdout=expect_stdout, - stderr=expect_stderr) +test.run( + arguments='--no-ignore-skips -k -b . test/no_result.py', + status=2, + stdout=expect_stdout, + stderr=expect_stderr, +) -test.run(arguments='-k -b . test/no_result.py', - status=0, - stdout=expect_stdout, - stderr=expect_stderr) +test.run( + arguments='-k -b . test/no_result.py', + status=0, + stdout=expect_stdout, + stderr=expect_stderr, +) test.pass_test() diff --git a/test/runtest/baseline/pass.py b/test/runtest/baseline/pass.py index 481fc97..c31a6d6 100644 --- a/test/runtest/baseline/pass.py +++ b/test/runtest/baseline/pass.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test how we handle a passing test specified on the command line. @@ -42,18 +41,16 @@ test.subdir('test') test.write_passing_test(['test', 'pass.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(test_pass_py)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_pass_py} PASSING TEST STDOUT -""" % locals() +""" expect_stderr = """\ PASSING TEST STDERR """ -test.run(arguments='-k -b . test', - stdout=expect_stdout, - stderr=expect_stderr) +test.run(arguments='-k -b . test', stdout=expect_stdout, stderr=expect_stderr) test.pass_test() diff --git a/test/runtest/faillog.py b/test/runtest/faillog.py index e2ca67e..f23b90b 100644 --- a/test/runtest/faillog.py +++ b/test/runtest/faillog.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test a list of tests in failed_tests.log to run with the --retry option @@ -42,15 +41,15 @@ test.subdir('test') test.write_failing_test(test_fail_py) test.write_passing_test(test_pass_py) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(test_fail_py)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_fail_py} FAILING TEST STDOUT -%(pythonstring)s%(pythonflags)s %(test_pass_py)s +{pythonstring}{pythonflags} {test_pass_py} PASSING TEST STDOUT Failed the following test: -\t%(test_fail_py)s -""" % locals() +\t{test_fail_py} +""" expect_stderr = """\ FAILING TEST STDERR diff --git a/test/runtest/no_faillog.py b/test/runtest/no_faillog.py index db17c8e..174ab48 100644 --- a/test/runtest/no_faillog.py +++ b/test/runtest/no_faillog.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test a list of tests in failed_tests.log to run with the --retry option @@ -42,19 +41,22 @@ test.subdir('test') test.write_failing_test(test_fail_py) test.write_passing_test(test_pass_py) -test.write('failed_tests.log', """\ -%(test_fail_py)s -""" % locals()) +test.write( + 'failed_tests.log', + f"""\ +{test_fail_py} +""", +) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(test_fail_py)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_fail_py} FAILING TEST STDOUT -%(pythonstring)s%(pythonflags)s %(test_pass_py)s +{pythonstring}{pythonflags} {test_pass_py} PASSING TEST STDOUT Failed the following test: -\t%(test_fail_py)s -""" % locals() +\t{test_fail_py} +""" expect_stderr = """\ FAILING TEST STDERR diff --git a/test/runtest/print_time.py b/test/runtest/print_time.py index 834d2ae..3d49a97 100644 --- a/test/runtest/print_time.py +++ b/test/runtest/print_time.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test a combination of a passing test, failing test, and no-result @@ -41,30 +40,30 @@ test_fail_py = re.escape(os.path.join('test', 'fail.py')) test_no_result_py = re.escape(os.path.join('test', 'no_result.py')) test_pass_py = re.escape(os.path.join('test', 'pass.py')) -test = TestRuntest.TestRuntest(match = TestCmd.match_re) +test = TestRuntest.TestRuntest(match=TestCmd.match_re) test.subdir('test') test.write_failing_test(['test', 'fail.py']) test.write_no_result_test(['test', 'no_result.py']) test.write_passing_test(['test', 'pass.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(test_fail_py)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_fail_py} FAILING TEST STDOUT Test execution time: \\d+.\\d seconds -%(pythonstring)s%(pythonflags)s %(test_no_result_py)s +{pythonstring}{pythonflags} {test_no_result_py} NO RESULT TEST STDOUT Test execution time: \\d+.\\d seconds -%(pythonstring)s%(pythonflags)s %(test_pass_py)s +{pythonstring}{pythonflags} {test_pass_py} PASSING TEST STDOUT Test execution time: \\d+.\\d seconds Total execution time for all tests: \\d+.\\d seconds Failed the following test: -\t%(test_fail_py)s +\t{test_fail_py} NO RESULT from the following test: -\t%(test_no_result_py)s -""" % locals() +\t{test_no_result_py} +""" expect_stderr = """\ FAILING TEST STDERR @@ -72,10 +71,7 @@ NO RESULT TEST STDERR PASSING TEST STDERR """ -test.run(arguments='-k -t test', - status=1, - stdout=expect_stdout, - stderr=expect_stderr) +test.run(arguments='-k -t test', status=1, stdout=expect_stdout, stderr=expect_stderr) test.pass_test() diff --git a/test/runtest/python.py b/test/runtest/python.py index abd4f0c..dbb24ca 100644 --- a/test/runtest/python.py +++ b/test/runtest/python.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test that the -P option lets us specify a Python version to use. @@ -46,26 +45,26 @@ head, dir = os.path.split(head) # python version then in use, which could be different pythonflags = TestRuntest.pythonflags -# We have to normalize the python path here, because some installations don't like -# getting called with "/bin/../bin/python" as first argument, e.g. Fedora 17 Desktop. +# We have to normalize the python path here, because some installations +# don't like getting called with "/bin/../bin/python" as first argument, +# e.g. Fedora 17 Desktop. mypython = os.path.normpath(os.path.join(head, dir, os.path.pardir, dir, python)) test.subdir('test') - test.write_passing_test(['test', 'pass.py']) -expect_stdout = """\ -%(mypython)s%(pythonflags)s %(test_pass_py)s +expect_stdout = f"""\ +{mypython}{pythonflags} {test_pass_py} PASSING TEST STDOUT -""" % locals() +""" expect_stderr = """\ PASSING TEST STDERR """ -test.run(arguments=['-k','-P', mypython, 'test'], - stdout=expect_stdout, - stderr=expect_stderr) +test.run( + arguments=['-k', '-P', mypython, 'test'], stdout=expect_stdout, stderr=expect_stderr +) test.pass_test() diff --git a/test/runtest/retry.py b/test/runtest/retry.py index 4280152..0c5beb6 100644 --- a/test/runtest/retry.py +++ b/test/runtest/retry.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test a list of tests in failed_tests.log to run with the --retry option @@ -45,14 +44,17 @@ test.write_failing_test(['test', 'fail.py']) test.write_no_result_test(['test', 'no_result.py']) test.write_passing_test(['test', 'pass.py']) -test.write('failed_tests.log', """\ -%(test_fail_py)s -""" % locals()) +test.write( + 'failed_tests.log', + f"""\ +{test_fail_py} +""", +) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(test_fail_py)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_fail_py} FAILING TEST STDOUT -""" % locals() +""" expect_stderr = """\ FAILING TEST STDERR diff --git a/test/runtest/simple/combined.py b/test/runtest/simple/combined.py index a54e57c..e594c50 100644 --- a/test/runtest/simple/combined.py +++ b/test/runtest/simple/combined.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test a combination of a passing test, failing test, and no-result @@ -45,20 +44,20 @@ test.write_failing_test(test_fail_py) test.write_no_result_test(test_no_result_py) test.write_passing_test(test_pass_py) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(test_fail_py)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_fail_py} FAILING TEST STDOUT -%(pythonstring)s%(pythonflags)s %(test_no_result_py)s +{pythonstring}{pythonflags} {test_no_result_py} NO RESULT TEST STDOUT -%(pythonstring)s%(pythonflags)s %(test_pass_py)s +{pythonstring}{pythonflags} {test_pass_py} PASSING TEST STDOUT Failed the following test: -\t%(test_fail_py)s +\t{test_fail_py} NO RESULT from the following test: -\t%(test_no_result_py)s -""" % locals() +\t{test_no_result_py} +""" expect_stderr = """\ FAILING TEST STDERR @@ -66,12 +65,7 @@ NO RESULT TEST STDERR PASSING TEST STDERR """ -test.run( - arguments='-k test', - status=1, - stdout=expect_stdout, - stderr=expect_stderr -) +test.run(arguments='-k test', status=1, stdout=expect_stdout, stderr=expect_stderr) test.must_exist('failed_tests.log') test.must_contain('failed_tests.log', test_fail_py) diff --git a/test/runtest/simple/fail.py b/test/runtest/simple/fail.py index f26f00e..5e1979a 100644 --- a/test/runtest/simple/fail.py +++ b/test/runtest/simple/fail.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,38 +22,35 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test how we handle a failing test specified on the command line. """ +import os + import TestRuntest pythonstring = TestRuntest.pythonstring pythonflags = TestRuntest.pythonflags +test_fail_py = os.path.join('test', 'fail.py') test = TestRuntest.TestRuntest() - test.subdir('test') - test.write_failing_test(['test', 'fail.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s test/fail.py +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_fail_py} FAILING TEST STDOUT -""" % locals() +""" expect_stderr = """\ FAILING TEST STDERR """ -test.run(arguments='-k test/fail.py', - status=1, - stdout=expect_stdout, - stderr=expect_stderr) +test.run( + arguments='-k test/fail.py', status=1, stdout=expect_stdout, stderr=expect_stderr +) test.pass_test() diff --git a/test/runtest/simple/no_result.py b/test/runtest/simple/no_result.py index 33f28e4..beb82b0 100644 --- a/test/runtest/simple/no_result.py +++ b/test/runtest/simple/no_result.py @@ -27,35 +27,40 @@ Test how we handle a no-results test specified on the command line. """ +import os + import TestRuntest pythonstring = TestRuntest.pythonstring pythonflags = TestRuntest.pythonflags +test_no_result_py = os.path.join('test', 'no_result.py') test = TestRuntest.TestRuntest() - test.subdir('test') - test.write_no_result_test(['test', 'no_result.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s test/no_result.py +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_no_result_py} NO RESULT TEST STDOUT -""" % locals() +""" expect_stderr = """\ NO RESULT TEST STDERR """ -test.run(arguments='--no-ignore-skips -k test/no_result.py', - status=2, - stdout=expect_stdout, - stderr=expect_stderr) +test.run( + arguments='--no-ignore-skips -k test/no_result.py', + status=2, + stdout=expect_stdout, + stderr=expect_stderr, +) -test.run(arguments='-k test/no_result.py', - status=0, - stdout=expect_stdout, - stderr=expect_stderr) +test.run( + arguments='-k test/no_result.py', + status=0, + stdout=expect_stdout, + stderr=expect_stderr, +) test.pass_test() diff --git a/test/runtest/simple/pass.py b/test/runtest/simple/pass.py index 7ceb9a0..408ef4c 100644 --- a/test/runtest/simple/pass.py +++ b/test/runtest/simple/pass.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,29 +22,27 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test how we handle a passing test specified on the command line. """ +import os + import TestRuntest pythonstring = TestRuntest.pythonstring pythonflags = TestRuntest.pythonflags +test_pass_py = os.path.join('test', 'pass.py') test = TestRuntest.TestRuntest() - test.subdir('test') - test.write_passing_test(['test', 'pass.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s test/pass.py +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_pass_py} PASSING TEST STDOUT -""" % locals() +""" expect_stderr = """\ PASSING TEST STDERR diff --git a/test/runtest/testargv.py b/test/runtest/testargv.py index 22e57e8..20dcdc8 100644 --- a/test/runtest/testargv.py +++ b/test/runtest/testargv.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test subdir args for runtest.py, for example: @@ -38,34 +37,35 @@ import TestRuntest test = TestRuntest.TestRuntest() test.subdir('test', ['test', 'subdir']) -files = {} -files['pythonstring'] = TestRuntest.pythonstring -files['pythonflags'] = TestRuntest.pythonflags +pythonstring = TestRuntest.pythonstring +pythonflags = TestRuntest.pythonflags -files['one'] = os.path.join('test/subdir', 'test_one.py') -files['two'] = os.path.join('test/subdir', 'two.py') -files['three'] = os.path.join('test', 'test_three.py') +one = os.path.join('test', 'subdir', 'test_one.py') +two = os.path.join('test', 'subdir', 'two.py') +three = os.path.join('test', 'test_three.py') -test.write_passing_test(files['one']) -test.write_passing_test(files['two']) -test.write_passing_test(files['three']) +test.write_passing_test(['test', 'subdir', 'test_one.py']) +test.write_passing_test(['test', 'subdir', 'two.py']) +test.write_passing_test(['test', 'test_three.py']) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(one)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {one} PASSING TEST STDOUT -%(pythonstring)s%(pythonflags)s %(two)s +{pythonstring}{pythonflags} {two} PASSING TEST STDOUT -""" % files +""" expect_stderr = """\ PASSING TEST STDERR PASSING TEST STDERR """ -test.run(arguments = '--no-progress test/subdir', - status = 0, - stdout = expect_stdout, - stderr = expect_stderr) +test.run( + arguments='--no-progress test/subdir', + status=0, + stdout=expect_stdout, + stderr=expect_stderr, +) test.pass_test() diff --git a/test/runtest/testlistfile.py b/test/runtest/testlistfile.py index 5c956b8..e5d85b8 100644 --- a/test/runtest/testlistfile.py +++ b/test/runtest/testlistfile.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test a list of tests to run in a file specified with the -f option. @@ -46,15 +45,18 @@ test.write_failing_test(['test', 'fail.py']) test.write_no_result_test(['test', 'no_result.py']) test.write_passing_test(['test', 'pass.py']) -test.write('t.txt', """\ -#%(test_fail_py)s -%(test_pass_py)s -""" % locals()) +test.write( + 't.txt', + f"""\ +#{test_fail_py} +{test_pass_py} +""", +) -expect_stdout = """\ -%(pythonstring)s%(pythonflags)s %(test_pass_py)s +expect_stdout = f"""\ +{pythonstring}{pythonflags} {test_pass_py} PASSING TEST STDOUT -""" % locals() +""" expect_stderr = """\ PASSING TEST STDERR diff --git a/test/runtest/xml/output.py b/test/runtest/xml/output.py index cd20dbd..66ec656 100644 --- a/test/runtest/xml/output.py +++ b/test/runtest/xml/output.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test writing XML output to a file. @@ -34,8 +33,7 @@ import re import TestCmd import TestRuntest -test = TestRuntest.TestRuntest(match = TestCmd.match_re, - diff = TestCmd.diff_re) +test = TestRuntest.TestRuntest(match=TestCmd.match_re, diff=TestCmd.diff_re) pythonstring = re.escape(TestRuntest.pythonstring) pythonflags = TestRuntest.pythonflags @@ -44,22 +42,18 @@ test_no_result_py = re.escape(os.path.join('test', 'no_result.py')) test_pass_py = re.escape(os.path.join('test', 'pass.py')) test.subdir('test') - test.write_fake_scons_source_tree() - test.write_failing_test(['test', 'fail.py']) - test.write_no_result_test(['test', 'no_result.py']) - test.write_passing_test(['test', 'pass.py']) -test.run(arguments = '--xml xml.out test', status=1) +test.run(arguments='--xml xml.out test', status=1) -expect = """\ +expect = f"""\ - %(test_fail_py)s - %(pythonstring)s%(pythonflags)s %(test_fail_py)s + {test_fail_py} + {pythonstring}{pythonflags} {test_fail_py} 1 FAILING TEST STDOUT @@ -68,8 +62,8 @@ expect = """\ - %(test_no_result_py)s - %(pythonstring)s%(pythonflags)s %(test_no_result_py)s + {test_no_result_py} + {pythonstring}{pythonflags} {test_no_result_py} 2 NO RESULT TEST STDOUT @@ -78,8 +72,8 @@ expect = """\ - %(test_pass_py)s - %(pythonstring)s%(pythonflags)s %(test_pass_py)s + {test_pass_py} + {pythonstring}{pythonflags} {test_pass_py} 0 PASSING TEST STDOUT @@ -89,7 +83,7 @@ expect = """\ -""" % locals() +""" # Just strip carriage returns so the regular expression matching works. contents = test.read('xml.out') -- cgit v0.12 From c31c4d7032eede7eb7389c79a9a602da17487811 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 19 Apr 2023 08:40:20 -0600 Subject: runtest: add additional test of os.sep usage Make sure test lists with "foreign" separator still cause the correct discovery/usage. Signed-off-by: Mats Wichmann --- test/runtest/pathseps.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 test/runtest/pathseps.py diff --git a/test/runtest/pathseps.py b/test/runtest/pathseps.py new file mode 100644 index 0000000..10d86b2 --- /dev/null +++ b/test/runtest/pathseps.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +Make sure different path separators don't break things. +Backslashes should be okay on POSIX, forwards slashes on win32, +and combinations should cause no problems. +""" + +import os.path + +import TestRuntest + +# the "expected" paths are generated os-native +test_one_py = os.path.join('test', 'subdir', 'test1.py') +test_two_py = os.path.join('test', 'subdir', 'test2.py') +test_three_py = os.path.join('test', 'subdir', 'test3.py') +test_four_py = os.path.join('test', 'subdir', 'test4.py') + +test = TestRuntest.TestRuntest() +# create files for discovery +testdir = "test/subdir".split("/") +test.subdir(testdir[0], testdir) +test.write_passing_test(testdir + ['test1.py']) +test.write_passing_test(testdir + ['test2.py']) +test.write_passing_test(testdir + ['test3.py']) +test.write_passing_test(testdir + ['test4.py']) + +# discover tests using testlist file with various combinations of slashes +test.write( + 'testlist.txt', + r""" +test/subdir/test1.py +test\subdir/test2.py +test/subdir\test3.py +test\subdir\test4.py +""", +) + +# expect the discovered files to all be os-native +expect_stdout = f"""\ +{test_one_py} +{test_two_py} +{test_three_py} +{test_four_py} +""" + +test.run(arguments="-k -l -f testlist.txt", stdout=expect_stdout, stderr=None) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From faa271d1dd379d5fe46ca2742f5a83e54ea4f36c Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 8 May 2023 08:05:06 -0600 Subject: add RELEASE entry for runtest changes [skip ci] Signed-off-by: Mats Wichmann --- RELEASE.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RELEASE.txt b/RELEASE.txt index c2244f2..bafda47 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -64,7 +64,11 @@ DOCUMENTATION DEVELOPMENT ----------- -- List visible changes in the way SCons is developed +- SCons test runner now uses pathlib to normalize and compare paths + to test files, which allows test lists, exclude lists, and tests on + the command line to "not care" about the OS convention for pathname + separators. + Thanks to the following contributors listed below for their contributions to this release. ========================================================================================== -- cgit v0.12 From e327282f5086730fc045d99c5efbc7a2be0839b4 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 8 May 2023 09:23:46 -0600 Subject: Fixup usage of new mock yacc tool When the mock tool was revised to use argparse instead of getopt, it stumbled across the problem that argparse apparently doesn't deal with a single-letter option and its option-argument not having a space between them until Python 3.8 - 3.6 and 3.7 failed the test. Change to use the space in the test/mock tool. Signed-off-by: Mats Wichmann --- test/YACC/YACCFLAGS-fixture/myyacc.py | 2 +- test/YACC/YACCFLAGS.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/YACC/YACCFLAGS-fixture/myyacc.py b/test/YACC/YACCFLAGS-fixture/myyacc.py index 8b793a1..7461501 100644 --- a/test/YACC/YACCFLAGS-fixture/myyacc.py +++ b/test/YACC/YACCFLAGS-fixture/myyacc.py @@ -67,7 +67,7 @@ def fake_yacc(): elif arg == "-o": skip = True elif arg.startswith("-I"): - pass + skip = True else: opt_list.append(arg) # The original didn't use the file argument(s) so we have to get rid of. diff --git a/test/YACC/YACCFLAGS.py b/test/YACC/YACCFLAGS.py index 7a07072..f7a3cfb 100644 --- a/test/YACC/YACCFLAGS.py +++ b/test/YACC/YACCFLAGS.py @@ -48,7 +48,7 @@ test.write('SConstruct', """ DefaultEnvironment(tools=[]) env = Environment( YACC=r'%(_python_)s myyacc.py', - YACCFLAGS='-x -I${TARGET.dir} -I${SOURCE.dir}', + YACCFLAGS='-x -I ${TARGET.dir} -I ${SOURCE.dir}', tools=['yacc', '%(linker)s', '%(compiler)s'], ) env.CFile(target='out/aaa', source='in/aaa.y') -- cgit v0.12 From 34d0aedbec2df177264c023c554c2f5cbb966ccc Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 8 May 2023 12:20:08 -0600 Subject: yacc tool: further doc tweak [skip appveyor] Signed-off-by: Mats Wichmann --- SCons/Tool/yacc.py | 2 +- SCons/Tool/yacc.xml | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index d408e62..9751742 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -53,7 +53,7 @@ YaccAction = SCons.Action.Action("$YACCCOM", "$YACCCOMSTR") if sys.platform == 'win32': BINS = ['bison', 'yacc', 'win_bison'] else: - BINS = ["bison", "yacc"] + BINS = ["bison", "yacc", "byacc"] # for byacc, yacc is normally a link def _yaccEmitter(target, source, env, ysuf, hsuf) -> tuple: diff --git a/SCons/Tool/yacc.xml b/SCons/Tool/yacc.xml index cf466a2..cc70adb 100644 --- a/SCons/Tool/yacc.xml +++ b/SCons/Tool/yacc.xml @@ -48,7 +48,7 @@ See its __doc__ string for a discussion of the format. -Sets construction variables for the &yacc; parse generator. +Sets construction variables for the &yacc; parser generator. @@ -109,13 +109,19 @@ and adds those to the target list.
-If a option is present, +If the option is present in &cv-YACCFLAGS; &scons; assumes that the call will also create a header file with the suffix defined by &cv-link-YACCHFILESUFFIX; if the yacc source file ends in a .y suffix, or a file with the suffix defined by &cv-link-YACCHXXFILESUFFIX; if the yacc source file ends in a .yy suffix. The header will have the same base name as the requested target. +This is only correct if the executable is bison +(or win_bison). +If using Berkeley yacc (byacc), +y.tab.h is always written - +avoid the in this case and +use &cv-link-YACC_HEADER_FILE; instead. -- cgit v0.12 From d723812004c1e88c5bfab37b454b7164f5b4ae00 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 8 May 2023 12:55:27 -0600 Subject: Put back Builder entityref in UG add-method [skip appveyor] Entity reference &Builder;s was turned to plain text in a few places. Restored, this time using existing pluralized entity name &Builders;. Also twiddled a little wording in same User Guide chapter. Signed-off-by: Mats Wichmann --- doc/user/add-method.xml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/doc/user/add-method.xml b/doc/user/add-method.xml index 7c59bf2..179be95 100644 --- a/doc/user/add-method.xml +++ b/doc/user/add-method.xml @@ -32,9 +32,14 @@ Copyright The SCons Foundation The &f-link-AddMethod; function is used to add a method to an environment. It is typically used to add a "pseudo-builder," a function that looks like a &Builder; but - wraps up calls to multiple other Builders + wraps up calls to multiple other &Builders; or otherwise processes its arguments - before calling one or more Builders. + before calling one or more &Builders;. + + + + + In the following example, we want to install the program into the standard /usr/bin directory hierarchy, @@ -70,11 +75,11 @@ int main() { printf("Hello, world!\n"); } - A pseudo-builder is useful because it provides more flexibility - in parsing arguments than you can get with a standard &Builder;. + A pseudo-builder is useful because it gives you more flexibility + parsing arguments than you can get with a standard &Builder;. The next example shows a pseudo-builder with a - named argument that modifies the filename, and a separate argument - for the resource file (rather than having the builder figure it out + named argument that modifies the filename, and a separate optional + argument for a resource file (rather than having the builder figure it out by file extension). This example also demonstrates using the global &AddMethod; function to add a method to the global Environment class, so it will be available in all subsequently created environments. -- cgit v0.12 From 201be7ebc3e65094b189ff82d75cfef3fb695321 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 9 May 2023 08:45:34 -0600 Subject: yacc tool: comment out other doc note A review request suggested removing the note in CFile/CXXFile tool doc on yacc filenames. I removed only the CFile one, this does the CXXFile one as well. Signed-off-by: Mats Wichmann --- SCons/Tool/Tool.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SCons/Tool/Tool.xml b/SCons/Tool/Tool.xml index 086d989..25e4625 100644 --- a/SCons/Tool/Tool.xml +++ b/SCons/Tool/Tool.xml @@ -74,13 +74,13 @@ env.CXXFile(target='foo.cc', source='foo.ll') env.CXXFile(target='bar', source='bar.yy') - + -- cgit v0.12 From 58f731fa313dc05e3b567682760b7cff0c343e3a Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 9 May 2023 13:21:22 -0600 Subject: Move pdb-support SConscript list to top Define the list of recognized names for sconscript files for pdb to handle to the top, together with the existing list of names for SConstruct, to make it harder to miss any changes that should kept in sync. Signed-off-by: Mats Wichmann --- SCons/Script/Main.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 79806ba..a1ce5df 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -76,6 +76,16 @@ KNOWN_SCONSTRUCT_NAMES = [ 'sconstruct.py', ] +# list of names regognized by debugger as "SConscript files" (inc. SConstruct) +# files suffixed .py always work so don't need to be in this list. +KNOWN_SCONSCRIPTS = [ + "SConstruct", + "Sconstruct", + "sconstruct", + "SConscript", + "sconscript", +] + # Global variables first_command_start = None last_command_end = None @@ -1397,11 +1407,12 @@ def _exec_main(parser, values) -> None: def lookupmodule(self, filename: str) -> Optional[str]: """Helper function for break/clear parsing -- SCons version. - translates (possibly incomplete) file or module name - into an absolute file name. - - The SCons override recognizes common names for ``SConstruct`` - and ``SConscript`` without requiring a ``.py`` suffix. + Translates (possibly incomplete) file or module name + into an absolute file name. The "possibly incomplete" + means adding a ``.py`` suffix if not present, which breaks + picking breakpoints in sconscript files, which often don't + have a suffix. This version fixes for some known names of + sconscript files that don't have the suffix. .. versionadded:: 4.6.0 """ @@ -1411,11 +1422,8 @@ def _exec_main(parser, values) -> None: if os.path.exists(f) and self.canonic(f) == self.mainpyfile: return f root, ext = os.path.splitext(filename) - SCONSCRIPTS = ( - "SConstruct Sconstruct sconstruct SConscript sconscript".split() - ) base = os.path.split(filename)[-1] - if ext == '' and base not in SCONSCRIPTS: # SCons + if ext == '' and base not in KNOWN_SCONSCRIPTS: # SCons mod filename = filename + '.py' if os.path.isabs(filename): return filename -- cgit v0.12 From 73f05debff36d451eb966daefd5a1687521387fb Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 10 May 2023 08:33:33 -0600 Subject: Find choco msys mingw 4c835c4 introduced an effort to find mingw if installed as part of the msys2 chocolatey package. Unfortunately that change worked only for one specific user (me) who had set environment variable %ChocolateyToolsLocation% to a prefix in that path. Instead, reference the environment variable to try to find it. Usually we don't like environment variables, but this one actually makes the lookup *less* system-specific, as it extracts the best possible guess where chocolatey has put the files on that system. Also moved a CHANGES.txt entry that had gotten merged under an earlier release (submission of that PR had been before 4.5 went out) Signed-off-by: Mats Wichmann --- CHANGES.txt | 7 ++++--- SCons/Tool/mingw.py | 9 ++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 5ad76b8..a937ea2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -25,6 +25,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER Only used in msvs.py. Use base64.decodebytes instead. - SCons test runner now uses pathlib to normalize and compare paths to test files. + - Fixed: when using the mingw tool, if an msys2 Python is used (os.sep + is '/' rather than the Windows default '\'), certain Configure checks + could fail due to the construction of the path to run the compiled check. + - Added effort to find mingw if it comes from Chocolatey install of msys2. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 @@ -198,9 +202,6 @@ RELEASE 4.5.0 - Sun, 05 Mar 2023 14:08:29 -0700 We take advantage that their order is now stable based on insertion order in Python 3.5+ - Added/modifed unit and system tests to verify these changes. - - Fixed: when using the mingw tool, if an msys2 Python is used (os.sep - is '/' rather than the Windows default '\'), certain Configure checks - could fail due to the construction of the path to run the compiled check. RELEASE 4.4.0 - Sat, 30 Jul 2022 14:08:29 -0700 diff --git a/SCons/Tool/mingw.py b/SCons/Tool/mingw.py index 8d4f3ed..0119444 100644 --- a/SCons/Tool/mingw.py +++ b/SCons/Tool/mingw.py @@ -41,6 +41,8 @@ import SCons.Defaults import SCons.Tool import SCons.Util +# TODO: should this be synced with SCons/Platform/mingw.py:MINGW_DEFAULTPATHS +# i.e. either keep the same, or make sure there's only one? mingw_base_paths = [ r'c:\MinGW\bin', r'C:\cygwin64\bin', @@ -48,9 +50,14 @@ mingw_base_paths = [ r'C:\msys64\mingw64\bin', r'C:\cygwin\bin', r'C:\msys', + # Chocolatey mingw (pkg name for MinGW-w64) does not use ChocolateyToolsLocation r'C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin', - os.path.expandvars(r'%LocalAppData%\Programs\msys64\usr\bin'), ] +# Chocolatey msys2 uses envvar ChocolateyToolsLocation to base the install +# location (unless the user supplied additional params). Try to reproduce: +choco = os.environ.get('ChocolateyToolsLocation') +if choco: + mingw_base_paths.append(choco + r'\msys64\bin') def shlib_generator(target, source, env, for_signature): -- cgit v0.12 From 959e2d4c4b029890ed90327bf66a29ca1f515678 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 11 May 2023 07:01:32 -0600 Subject: Release blurb [skip ci] Signed-off-by: Mats Wichmann --- RELEASE.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/RELEASE.txt b/RELEASE.txt index bafda47..e90cdee 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -32,7 +32,6 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY FIXES ----- - - Fixed: when using the mingw tool, if an msys2 Python is used (os.sep is '/' rather than the Windows default '\'), certain Configure checks could fail due to the construction of the path to run the compiled check. @@ -45,9 +44,7 @@ FIXES IMPROVEMENTS ------------ -- List improvements that wouldn't be visible to the user in the - documentation: performance improvements (describe the circumstances - under which they would be observed), or major code cleanups +- Now tries to find mingw if it comes from Chocolatey install of msys2. PACKAGING --------- -- cgit v0.12 From d6c4a4236512d1310ca5cfe990bd0af71dfe89a9 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 16 May 2023 09:23:33 -0600 Subject: Doc fiddling - Alias, Action, Decider [skip appveyor] * Signature of Alias() now matches implementation to avoid problem if kwargs used * Case of Alias with no targets is mentioned in text (was already shown in example) * Now mention that Action([item]) does not return a ListAction - previously implied that if arg was a list, a ListAction was *always* returned * Mention default Decider and sort the names of available decider functions, and add version marking. * Minor fiddling with Alias.py docstrings. Signed-off-by: Mats Wichmann --- CHANGES.txt | 7 +++ RELEASE.txt | 7 +-- SCons/Action.py | 55 ++++++++++--------- SCons/Environment.xml | 142 ++++++++++++++++++++++++++++++-------------------- doc/man/scons.xml | 12 +++-- doc/user/caching.xml | 2 +- 6 files changed, 134 insertions(+), 91 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 5ad76b8..6e8e677 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -25,6 +25,13 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER Only used in msvs.py. Use base64.decodebytes instead. - SCons test runner now uses pathlib to normalize and compare paths to test files. + - Minor doc fixes: signature of Alias() now matches implementation + to avoid problem if kwargs used; case of Alias with no targets is + mentioned in text (was already shown in example); now mention that + Action([item]) does not return a ListAction - previously implied + that if arg was a list, a ListAction was *always* returned; mention + default Decider and sort the names of available decider functions, + and add a version marking. Minor fiddling with Alias.py docstrings. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index bafda47..5cef731 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -57,9 +57,10 @@ PACKAGING DOCUMENTATION ------------- -- List any significant changes to the documentation (not individual - typo fixes, even if they're mentioned in src/CHANGES.txt to give - the contributor credit) +- Aligned manpage signature for Alias function to match implementation - + if the previous *targets* parameter had been used as a keyword argument, + the results would be incorrect (does not apply to positional argument + usage, which had no problem). DEVELOPMENT ----------- diff --git a/SCons/Action.py b/SCons/Action.py index 3f1a24e..fcc6f3f 100644 --- a/SCons/Action.py +++ b/SCons/Action.py @@ -148,9 +148,8 @@ def default_exitstatfunc(s): strip_quotes = re.compile(r'^[\'"](.*)[\'"]$') -def _callable_contents(obj): - """Return the signature contents of a callable Python object. - """ +def _callable_contents(obj) -> bytearray: + """Return the signature contents of a callable Python object.""" try: # Test if obj is a method. return _function_contents(obj.__func__) @@ -170,7 +169,7 @@ def _callable_contents(obj): return _function_contents(obj) -def _object_contents(obj): +def _object_contents(obj) -> bytearray: """Return the signature contents of any Python object. We have to handle the case where object contains a code object @@ -210,8 +209,10 @@ def _object_contents(obj): # the best we can. return bytearray(repr(obj), 'utf-8') +# TODO: docstrings for _code_contents and _function_contents +# do not render well with Sphinx. Consider reworking. -def _code_contents(code, docstring=None): +def _code_contents(code, docstring=None) -> bytearray: r"""Return the signature contents of a code object. By providing direct access to the code object of the @@ -223,7 +224,7 @@ def _code_contents(code, docstring=None): recompilations from moving a Python function. See: - - https://docs.python.org/2/library/inspect.html + - https://docs.python.org/3/library/inspect.html - http://python-reference.readthedocs.io/en/latest/docs/code/index.html For info on what each co\_ variable provides @@ -243,7 +244,6 @@ def _code_contents(code, docstring=None): co_code - Returns a string representing the sequence of bytecode instructions. """ - # contents = [] # The code contents depends on the number of local variables @@ -281,8 +281,9 @@ def _code_contents(code, docstring=None): return contents -def _function_contents(func): - """ +def _function_contents(func) -> bytearray: + """Return the signature contents of a function. + The signature is as follows (should be byte/chars): < _code_contents (see above) from func.__code__ > ,( comma separated _object_contents for function argument defaults) @@ -293,11 +294,7 @@ def _function_contents(func): - func.__code__ - The code object representing the compiled function body. - func.__defaults__ - A tuple containing default argument values for those arguments that have defaults, or None if no arguments have a default value - func.__closure__ - None or a tuple of cells that contain bindings for the function's free variables. - - :Returns: - Signature contents of a function. (in bytes) """ - contents = [_code_contents(func.__code__, func.__doc__)] # The function contents depends on the value of defaults arguments @@ -439,16 +436,13 @@ def _do_create_keywords(args, kw): def _do_create_action(act, kw): - """This is the actual "implementation" for the - Action factory method, below. This handles the - fact that passing lists to Action() itself has - different semantics than passing lists as elements - of lists. - - The former will create a ListAction, the latter - will create a CommandAction by converting the inner - list elements to strings.""" + """The internal implementation for the Action factory method. + This handles the fact that passing lists to :func:`Action` itself has + different semantics than passing lists as elements of lists. + The former will create a :class:`ListAction`, the latter will create a + :class:`CommandAction by converting the inner list elements to strings. + """ if isinstance(act, ActionBase): return act @@ -491,13 +485,22 @@ def _do_create_action(act, kw): return None -def _do_create_list_action(act, kw): - """A factory for list actions. Convert the input list into Actions - and then wrap them in a ListAction.""" +# TODO: from __future__ import annotations once we get to Python 3.7 base, +# to avoid quoting the defined-later classname +def _do_create_list_action(act, kw) -> "ListAction": + """A factory for list actions. + + Convert the input list *act* into Actions and then wrap them in a + :class:`ListAction`. If *act* has only a single member, return that + member, not a *ListAction*. This is intended to allow a contained + list to specify a command action without being processed into a + list action. + """ acts = [] for a in act: aa = _do_create_action(a, kw) - if aa is not None: acts.append(aa) + if aa is not None: + acts.append(aa) if not acts: return ListAction([]) elif len(acts) == 1: diff --git a/SCons/Environment.xml b/SCons/Environment.xml index f87e883..2b4c4af 100644 --- a/SCons/Environment.xml +++ b/SCons/Environment.xml @@ -351,9 +351,9 @@ to be performed after the specified target has been built. -The specified action(s) may be +action may be an Action object, or anything that -can be converted into an Action object +can be converted into an Action object. See the manpage section "Action Objects" for a complete explanation. @@ -364,6 +364,13 @@ the action may be called multiple times, once after each action that generates one or more targets in the list. + + +foo = Program('foo.c') +# remove execute permission from binary: +AddPostAction(foo, Chmod('$TARGET', "a-x")) + + @@ -379,9 +386,9 @@ to be performed before the specified target is built. -The specified action(s) may be +action may be an Action object, or anything that -can be converted into an Action object +can be converted into an Action object. See the manpage section "Action Objects" for a complete explanation. @@ -426,21 +433,35 @@ file into an object file. -(alias, [targets, [action]]) +(alias, [source, [action]]) -Creates one or more phony targets that -expand to one or more other targets. -An optional +Creates a phony target (or targets) that +can be used as references to zero or more other targets, +as specified by the optional source +parameter. +alias and +source +may each be a string or Node object, +or a list of strings or Node objects; +if Nodes are used for +alias +they must be Alias nodes. +The optional action -(command) -or list of actions -can be specified that will be executed +parameter specifies an action or list of actions +that will be executed whenever the any of the alias targets are out-of-date. -Returns the Node object representing the alias, -which exists outside of any file system. -This Node object, or the alias name, + + + +Returns a list of Alias Node objects representing the alias(es), +which exist outside of any physical file system. + + + +The alias name, or an Alias Node object, may be used as a dependency of any other target, including another alias. &f-Alias; @@ -593,7 +614,7 @@ giving an easy way to enter multiple macros in one addition. Use an = to specify a valued macro. -A tuple is treated as a valued macro. +A tuple is treated as a valued macro. Use the value None if the macro should not have a value. It is an error to supply more than two elements in such a tuple. @@ -1238,8 +1259,8 @@ so you normally don't need to create directories by hand. -Creates a Configure object for integrated -functionality similar to GNU autoconf. +Creates a &Configure; object for integrated +functionality similar to GNU autoconf. See the manpage section "Configure Contexts" for a complete explanation of the arguments and behavior. @@ -1265,50 +1286,24 @@ that will be applied: -"timestamp-newer" - - -Specifies that a target shall be considered out of date and rebuilt -if the dependency's timestamp is newer than the target file's timestamp. -This is the behavior of the classic Make utility, -and -make -can be used a synonym for -timestamp-newer. - - - - -"timestamp-match" - - -Specifies that a target shall be considered out of date and rebuilt -if the dependency's timestamp is different than the -timestamp recorded the last time the target was built. -This provides behavior very similar to the classic Make utility -(in particular, files are not opened up so that their -contents can be checksummed) -except that the target will also be rebuilt if a -dependency file has been restored to a version with an -earlier -timestamp, such as can happen when restoring files from backup archives. - - - - "content" Specifies that a target shall be considered out of date and rebuilt if the dependency's content has changed since the last time the target was built, -as determined be performing an checksum -on the dependency's contents +as determined by performing a checksum +on the dependency's contents using the selected hash function, and comparing it to the checksum recorded the last time the target was built. -MD5 -can be used as a synonym for -content, but it is deprecated. +content is the default decider. + + +Changed in version 4.1: +The decider was renamed to content +since the hash function is now selectable. +The former name, MD5, +can still be used as a synonym, but is deprecated. @@ -1339,9 +1334,44 @@ that runs a build, updates a file, and runs the build again, all within a single second. -MD5-timestamp -can be used as a synonym for -content-timestamp, but it is deprecated. + + +Changed in version 4.1: +The decider was renamed to content-timestamp +since the hash function is now selectable. +The former name, MD5-timestamp, +can still be used as a synonym, but is deprecated. + + + + +"timestamp-newer" + + +Specifies that a target shall be considered out of date and rebuilt +if the dependency's timestamp is newer than the target file's timestamp. +This is the behavior of the classic Make utility, +and +make +can be used a synonym for +timestamp-newer. + + + + +"timestamp-match" + + +Specifies that a target shall be considered out of date and rebuilt +if the dependency's timestamp is different than the +timestamp recorded the last time the target was built. +This provides behavior very similar to the classic Make utility +(in particular, files are not opened up so that their +contents can be checksummed) +except that the target will also be rebuilt if a +dependency file has been restored to a version with an +earlier +timestamp, such as can happen when restoring files from backup archives. diff --git a/doc/man/scons.xml b/doc/man/scons.xml index e79a267..b070dcb 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -1216,7 +1216,7 @@ small block-size slows down the build considerably. The default value is to use a chunk size of 64 kilobytes, which should be appropriate for most uses. -New in version 4.2. +New in version 4.1. @@ -1256,7 +1256,7 @@ For example, uses a SConsign database named .sconsign_sha256.dblite. -New in version 4.2. +New in version 4.1. @@ -3961,7 +3961,7 @@ it will not be added again. The default is False. library can be a list of library names, or None (the default if the argument is omitted). If the former, symbol is checked against -each library name in order, returning +each library name in order, returning (and reporting success) on the first successful test; if the latter, it is checked with the current value of &cv-LIBS; @@ -6526,9 +6526,11 @@ env.Command( -The behavior of Chmod is limited on Windows, +The behavior of Chmod is limited on Windows +and on WebAssembly platforms, see the notes in the Python documentation for -os.chmod, which is the underlying function. + +os.chmod, which is the underlying function. diff --git a/doc/user/caching.xml b/doc/user/caching.xml index 69368d7..f00bd69 100644 --- a/doc/user/caching.xml +++ b/doc/user/caching.xml @@ -129,7 +129,7 @@ CacheDir('/usr/local/build_cache') A few inside details: &SCons; tracks two main kinds of cryptographic hashes: a &contentsig;, which is a hash of the contents of a file participating in the - build (depepdencies as well as targets); + build (dependencies as well as targets); and a &buildsig;, which is a hash of the elements needed to build a target, such as the command line, the contents of the sources, and possibly information about -- cgit v0.12 From 27132f89fa411aae71b931138561b00549a163f8 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 17 May 2023 18:57:26 -0700 Subject: Minor update to scanner description --- doc/user/scanners.xml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/user/scanners.xml b/doc/user/scanners.xml index 9a0a1d3..6538987 100644 --- a/doc/user/scanners.xml +++ b/doc/user/scanners.xml @@ -149,10 +149,13 @@ over the file scanning rather than being called for each input line: &SCons; has built-in &Scanners; that know how to look in C/C++, Fortran, D, IDL, LaTeX, Python and SWIG source files for information about - other files that targets built from those files depend on - - for example, in the case of files that use the C preprocessor, - the .h files that are specified - using #include lines in the source. + other files that targets built from those files depend on. + + For example, if you have a file format which uses #include + to specify files which should be included into the source file + when it is processed, you can use an existing scanner already + included in &SCons;. + You can use the same mechanisms that &SCons; uses to create its built-in Scanners to write Scanners of your own for file types that &SCons; does not know how to scan "out of the box." -- cgit v0.12 From 157c5f8354abc5ed247c84c424cdc5e171729021 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 17 May 2023 20:59:16 -0700 Subject: added YACC_GRAPH_FILE_SUFFIX to represent it's the graph file and not be tied to the suffix string. It will respect the previous value if it's not set. Added test for such --- CHANGES.txt | 4 +- RELEASE.txt | 5 +- SCons/Tool/yacc.py | 9 ++-- SCons/Tool/yacc.xml | 15 ++++++ test/YACC/YACC_GRAPH_FILE_SUFFIX.py | 96 +++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 test/YACC/YACC_GRAPH_FILE_SUFFIX.py diff --git a/CHANGES.txt b/CHANGES.txt index 2977fa8..367a498 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -23,10 +23,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER calls dunder method __call__. Invoke instance directly." - Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1. Only used in msvs.py. Use base64.decodebytes instead. + - Obsoleted YACCVCGFILESUFFIX, it's being replaced by YACC_GRAPH_FILE_SUFFIX. + If YACC_GRAPH_FILE_SUFFIX is not set, it will respect YACCVCGFILESUFFIX. - The yacc tool now understands the bison behavior of --header, --defines and --graph being called without option-argument as being synonyms for -d (first two) and -g. -H also recognized as a synonym - for -d. Default value for $YACCVCGFILESUFFIX changed to '.gv' + for -d. Default value for $YACC_GRAPH_FILE_SUFFIX changed to '.gv' to match current bison default (since bison 3.8). The graph file name (-g) is now generated relative to the requested target file name, not to the source file name, to match actual current behavior (only diff --git a/RELEASE.txt b/RELEASE.txt index e475755..095a85c 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -25,11 +25,12 @@ DEPRECATED FUNCTIONALITY CHANGED/ENHANCED EXISTING FUNCTIONALITY --------------------------------------- - +- Obsoleted YACCVCGFILESUFFIX, it's being replaced by YACC_GRAPH_FILE_SUFFIX. + If YACC_GRAPH_FILE_SUFFIX is not set, it will respect YACCVCGFILESUFFIX. - The yacc tool now understands the bison behavior of --header, --defines and --graph being called without an option-argument as being synonyms for -d (first two) and -g. -H also recognized as a synonym for -d. - Default value for $YACCVCGFILESUFFIX changed to '.gv' to match + Default value for $YACC_GRAPH_FILE_SUFFIX changed to '.gv' to match current bison default (since bison 3.8). Set this variable to '.dot' if using byacc. diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index 9751742..7a4ddfc 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -68,16 +68,18 @@ def _yaccEmitter(target, source, env, ysuf, hsuf) -> tuple: # If -d is specified on the command line, yacc will emit a .h # or .hpp file with the same base name as the .c or .cpp output file. - # if '-d' in flags: # add bison options -H, --header, --defines (obsolete) + # if '-d' in flags: + # or bison options -H, --header, --defines (obsolete) if "-d" in flags or "-H" in flags or "--header" in flags or "--defines" in flags: target.append(targetBase + env.subst(hsuf, target=target, source=source)) # If -g is specified on the command line, yacc will emit a graph # file with the same base name as the .c or .cpp output file. # TODO: should this be handled like -v? i.e. a side effect, not target - # if "-g" in flags: # add bison option --graph + # if "-g" in flags: + # or bison option --graph if "-g" in flags or "--graph" in flags: - target.append(targetBase + env.subst("$YACCVCGFILESUFFIX")) + target.append(targetBase + env.subst("$YACC_GRAPH_FILE_SUFFIX")) # If -v is specified yacc will create the output debug file # which is not really source for any process, but should @@ -193,6 +195,7 @@ def generate(env) -> None: env['YACCHFILESUFFIX'] = '.h' env['YACCHXXFILESUFFIX'] = '.hpp' env['YACCVCGFILESUFFIX'] = '.gv' + env['YACC_GRAPH_FILE_SUFFIX'] = '$YACCVCGFILESUFFIX' env['_YACC_HEADER'] = '${YACC_HEADER_FILE and "--header=" + str(YACC_HEADER_FILE)}' env['_YACC_GRAPH'] = '${YACC_GRAPH_FILE and "--graph=" + str(YACC_GRAPH_FILE)}' diff --git a/SCons/Tool/yacc.xml b/SCons/Tool/yacc.xml index cc70adb..3d4fa33 100644 --- a/SCons/Tool/yacc.xml +++ b/SCons/Tool/yacc.xml @@ -58,6 +58,7 @@ Sets construction variables for the &yacc; parser generator. YACCHFILESUFFIX YACCHXXFILESUFFIX YACCVCGFILESUFFIX +YACC_GRAPH_FILE_SUFFIX YACCCOMSTR @@ -230,6 +231,20 @@ The default value is .hpp. +Obsoleted. Use &cv-link-ACC_GRAPH_FILE_SUFFIX;. + + +Changed in version 4.X.Y + + + + + + + +Previously specified by &cv-link-YACCVCGFILESUFFIX;. + + The suffix of the file containing a graph of the grammar automaton when the option diff --git a/test/YACC/YACC_GRAPH_FILE_SUFFIX.py b/test/YACC/YACC_GRAPH_FILE_SUFFIX.py new file mode 100644 index 0000000..58e7628 --- /dev/null +++ b/test/YACC/YACC_GRAPH_FILE_SUFFIX.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +Test setting the YACC_GRAPH_FILE_SUFFIX variable. +Also that if both YACCVCGFILESUFFIX and YACC_GRAPH_FILE_SUFFIX are set, +then YACCVCGFILESUFFIX will be ignored. +""" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.write('myyacc.py', """\ +import getopt +import os.path +import sys + +vcg = None +opts, args = getopt.getopt(sys.argv[1:], 'go:') +for o, a in opts: + if o == '-g': + vcg = 1 + elif o == '-o': + outfile = open(a, 'wb') +for f in args: + with open(f, 'rb') as infile: + for l in [l for l in infile.readlines() if l != b'/*yacc*/\\n']: + outfile.write(l) +outfile.close() +if vcg: + base, ext = os.path.splitext(args[0]) + with open(base + '.graph_suffix', 'wb') as outfile: + outfile.write((" ".join(sys.argv) + '\\n').encode()) +sys.exit(0) +""") + +test.write('SConstruct', """ +DefaultEnvironment(tools=[]) +env = Environment( + tools=['default', 'yacc'], + YACC=r'%(_python_)s myyacc.py', + YACCVCGFILESUFFIX='.vcg_obsolete', + YACC_GRAPH_FILE_SUFFIX='.graph_suffix', +) +env.CXXFile(target='aaa', source='aaa.yy') +env.CXXFile(target='bbb', source='bbb.yy', YACCFLAGS='-g') +""" % locals()) + +test.write('aaa.yy', "aaa.yy\n/*yacc*/\n") +test.write('bbb.yy', "bbb.yy\n/*yacc*/\n") + +test.run(arguments='.') + +test.must_match('aaa.cc', "aaa.yy\n") +test.must_not_exist('aaa.vcg') +test.must_not_exist('aaa.graph_suffix') + +test.must_match('bbb.cc', "bbb.yy\n") +test.must_not_exist('bbb.vcg') +test.must_not_exist('bbb.vcg_obsolete') +test.must_contain('bbb.graph_suffix', "myyacc.py -g -o bbb.cc bbb.yy\n") + +test.up_to_date(arguments='.') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From dc7407bb002b20c781e1d40b6678d1df7f2818fc Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 19 May 2023 08:24:11 -0600 Subject: Fix doc typo referencing YACC_GRAPH_FILE_SUFFIX [skip appveyor] Signed-off-by: Mats Wichmann --- CHANGES.txt | 6 ++++-- SCons/Tool/yacc.xml | 15 +++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index dfdba44..f99e8ac 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,10 @@ NOTE: 4.3.0 now requires Python 3.6.0 and above. Python 3.5.x is no longer suppo RELEASE VERSION/DATE TO BE FILLED IN LATER + From William Deegan: + - Obsoleted YACCVCGFILESUFFIX, being replaced by YACC_GRAPH_FILE_SUFFIX. + If YACC_GRAPH_FILE_SUFFIX is not set, it will respect YACCVCGFILESUFFIX. + From Mats Wichmann - C scanner's dictifyCPPDEFINES routine did not understand the possible combinations of CPPDEFINES - not aware of a "name=value" string either @@ -32,8 +36,6 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER not to the source file name, to match actual current behavior (only affects if target explicitly requested with a different base name than source). Docs updated. Fixes #4326 and #4327. - Obsoleted YACCVCGFILESUFFIX, being replaced by YACC_GRAPH_FILE_SUFFIX. - If YACC_GRAPH_FILE_SUFFIX is not set, it will respect YACCVCGFILESUFFIX. - SCons test runner now uses pathlib to normalize and compare paths to test files. - Minor doc fixes: signature of Alias() now matches implementation diff --git a/SCons/Tool/yacc.xml b/SCons/Tool/yacc.xml index 3d4fa33..82725db 100644 --- a/SCons/Tool/yacc.xml +++ b/SCons/Tool/yacc.xml @@ -231,10 +231,14 @@ The default value is .hpp. -Obsoleted. Use &cv-link-ACC_GRAPH_FILE_SUFFIX;. +Obsoleted. Use &cv-link-YACC_GRAPH_FILE_SUFFIX; instead. +The value is used only if &cv-YACC_GRAPH_FILE_SUFFIX; is not set. +The default value is .gv. -Changed in version 4.X.Y +Changed in version 4.X.Y: deprecated. The default value +changed from .vcg (&bison; stopped generating +.vcg output with version 2.4, in 2006). @@ -256,13 +260,8 @@ it does not affect the actual generated filename. Various yacc tools have emitted various formats at different times. Set this to match what your parser generator produces. -The default value is .gv. - - -Changed in version 4.X.Y: the default value -changed from .vcg (&bison; stopped generating -.vcg output with version 2.4, in 2006). +New in version 4.X.Y. -- cgit v0.12 From 14a58022619c81533bcc7fe1f026dd02409235b3 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 20 Feb 2023 11:43:59 -0700 Subject: Add a copyright header to test files A lot of files that are not the main test scripts had no license/copyright headers. This change adds those. In a small number of cases, this necessitaed a change to an expected line number from a failure/exception message. Along the way, some are lightly reformatted and some add a DefaultEnvironment call. Signed-off-by: Mats Wichmann --- test/AS/fixture/myas.py | 4 + test/AS/fixture/myas_args.py | 4 + test/Actions/addpost-link-fixture/strip.py | 5 ++ test/Actions/addpost-link-fixture/test1.c | 5 ++ test/Actions/addpost-link-fixture/test_lib.c | 4 + test/Actions/append-fixture/foo.c | 4 + test/Actions/pre-post-fixture/work1/bar.c | 4 + test/Actions/pre-post-fixture/work1/foo.c | 4 + test/Actions/pre-post-fixture/work2/SConstruct | 14 +++- test/Actions/pre-post-fixture/work3/SConstruct | 8 ++ test/Actions/pre-post-fixture/work4/build.py | 5 ++ test/Actions/pre-post.py | 2 +- test/Actions/subst_shell_env-fixture/SConstruct | 5 ++ test/Actions/unicode-signature-fixture/SConstruct | 6 +- test/Batch/SConstruct_changed_sources_alwaysBuild | 8 +- test/Batch/changed_sources_main.cpp | 3 + test/CC/CC-fixture/bar.c | 4 + test/CC/CC-fixture/foo.c | 4 + test/CC/CC-fixture/mycc.py | 4 + test/CC/CCVERSION-fixture/versioned.py | 5 ++ test/CC/gcc-non-utf8-fixture/gcc-non-utf8.py | 4 + test/CXX/CXX-fixture/myc++.py | 4 + test/CacheDir/CACHEDIR_CLASS_fixture/SConstruct | 9 ++- test/CacheDir/custom_cachedir_fixture/SConstruct | 9 ++- test/CacheDir/double_cachedir_fixture/SConstruct | 8 +- .../invalid_custom_cachedir_fixture/SConstruct | 7 +- test/CacheDir/value_dependencies/SConstruct | 14 ++-- test/CompilationDatabase/fixture/SConstruct | 4 + .../fixture/SConstruct_tempfile | 4 + .../CompilationDatabase/fixture/SConstruct_variant | 4 + test/Configure/conftest_source_file/SConstruct | 6 +- test/Configure/conftest_source_file/header1.h | 6 +- test/Configure/conftest_source_file/header2.h | 6 +- test/Configure/conftest_source_file/header3.h | 6 +- test/Configure/conftest_source_file/main.c | 6 +- test/Configure/fixture/SConstruct.issue-2906 | 7 +- test/Configure/is_conftest/fixture/SConstruct | 10 ++- ...ssue-2906-useful-duplicate-configure-message.py | 9 +-- test/Configure/issue-3469/fixture/SConstruct | 1 - test/D/AllAtOnce/Image/SConstruct_template | 18 +++-- test/D/AllAtOnce/Image/amod.d | 4 + test/D/AllAtOnce/Image/bmod.d | 4 + test/D/AllAtOnce/Image/main.d | 4 + test/D/CoreScanner/Image/SConstruct_template | 8 +- test/D/CoreScanner/Image/ignored.d | 4 + test/D/CoreScanner/Image/module1.d | 4 + test/D/CoreScanner/Image/module2.d | 4 + test/D/CoreScanner/Image/p/ignored.d | 4 + test/D/CoreScanner/Image/p/submodule1.d | 4 + test/D/CoreScanner/Image/p/submodule2.d | 4 + test/D/CoreScanner/Image/test1.d | 4 + test/D/CoreScanner/Image/test2.d | 4 + test/D/HSTeoh/ArLibIssue/SConstruct_template | 8 +- .../D/HSTeoh/LibCompileOptions/SConstruct_template | 14 ++-- test/D/HSTeoh/LibCompileOptions/prog.d | 4 + test/D/HSTeoh/LinkingProblem/SConstruct_template | 13 ++-- test/D/HSTeoh/LinkingProblem/cprog.c | 4 + test/D/HSTeoh/LinkingProblem/ncurs_impl.c | 4 + test/D/HSTeoh/LinkingProblem/prog.d | 4 + .../SConstruct_template | 13 +++- .../SingleStringCannotBeMultipleOptions/cmod.c | 4 + .../SingleStringCannotBeMultipleOptions/mod1.d | 4 + .../SingleStringCannotBeMultipleOptions/proj.d | 4 + .../Image/SConstruct_template | 9 ++- .../CompileAndLinkOneStep/Image/helloWorld.d | 4 + .../Image/SConstruct_template | 10 +-- .../CompileThenLinkTwoSteps/Image/helloWorld.d | 4 + .../2939_Ariovistus/Project/SConstruct_template | 14 ++-- .../2939_Ariovistus/Project/test/test1/SConscript | 4 + .../2939_Ariovistus/Project/test/test1/stuff.cpp | 4 + .../2939_Ariovistus/Project/test/test1/stuff.h | 4 + .../2939_Ariovistus/Project/test/test1/test1.cpp | 4 + .../2939_Ariovistus/Project/test/test1/test2.d | 4 + .../2940_Ariovistus/Project/SConstruct_template | 14 ++-- .../2940_Ariovistus/Project/test/test1/SConscript | 4 + .../2940_Ariovistus/Project/test/test1/stuff.cpp | 4 + .../2940_Ariovistus/Project/test/test1/stuff.h | 4 + .../2940_Ariovistus/Project/test/test1/test1.cpp | 4 + .../2940_Ariovistus/Project/test/test1/test2.d | 4 + test/D/Issues/2994/Project/SConstruct_template | 5 +- test/D/Issues/2994/Project/main.d | 4 + test/D/MixedDAndC/Image/SConstruct | 8 +- test/D/MixedDAndC/Image/cmod.c | 4 + test/D/MixedDAndC/Image/dmod.d | 4 + test/D/MixedDAndC/Image/proj.d | 4 + test/D/SharedObjects/Image/SConstruct_template | 4 +- test/D/SharedObjects/Image/code.d | 4 + test/Decider/MD5-winonly-fixture/SConstruct | 4 + test/Dir/DriveAbsPath/SConstruct | 34 +++++--- test/Dir/PyPackageDir/image/SConstruct | 4 + test/Docbook/basedir/htmlchunked/image/SConstruct | 5 ++ .../basedir/htmlchunked/image/SConstruct.cmd | 5 ++ test/Docbook/basedir/htmlhelp/image/SConstruct | 5 ++ test/Docbook/basedir/htmlhelp/image/SConstruct.cmd | 5 ++ test/Docbook/basedir/slideshtml/image/SConstruct | 5 ++ .../basedir/slideshtml/image/SConstruct.cmd | 5 ++ test/Docbook/basedir/slideshtml/image/xsltver.py | 4 + test/Docbook/basic/epub/image/SConstruct | 5 ++ test/Docbook/basic/epub/image/SConstruct.cmd | 5 ++ test/Docbook/basic/html/image/SConstruct | 5 ++ test/Docbook/basic/html/image/SConstruct.cmd | 5 ++ test/Docbook/basic/htmlchunked/image/SConstruct | 5 ++ .../Docbook/basic/htmlchunked/image/SConstruct.cmd | 5 ++ test/Docbook/basic/htmlhelp/image/SConstruct | 5 ++ test/Docbook/basic/htmlhelp/image/SConstruct.cmd | 5 ++ test/Docbook/basic/man/image/SConstruct | 5 ++ test/Docbook/basic/man/image/SConstruct.cmd | 5 ++ test/Docbook/basic/pdf/image/SConstruct | 5 ++ test/Docbook/basic/pdf/image/SConstruct.cmd | 5 ++ test/Docbook/basic/slideshtml/image/SConstruct | 11 ++- test/Docbook/basic/slideshtml/image/SConstruct.cmd | 11 ++- test/Docbook/basic/slideshtml/image/xsltver.py | 4 + test/Docbook/basic/slidespdf/image/SConstruct | 5 ++ test/Docbook/basic/slidespdf/image/SConstruct.cmd | 5 ++ test/Docbook/basic/xinclude/image/SConstruct | 5 ++ test/Docbook/basic/xslt/image/SConstruct | 8 +- test/Docbook/basic/xsltsubdir/image/SConstruct | 5 ++ .../basic/xsltsubdir/image/subdir/SConscript | 7 +- .../Docbook/dependencies/xinclude/image/SConstruct | 5 ++ test/Docbook/rootname/htmlchunked/image/SConstruct | 5 ++ test/Docbook/rootname/htmlhelp/image/SConstruct | 5 ++ test/Docbook/rootname/slideshtml/image/SConstruct | 5 ++ test/Docbook/rootname/slideshtml/image/xsltver.py | 4 + test/File/fixture/relpath/base/SConstruct | 26 ++++--- test/Fortran/fixture/myfortran.py | 4 + test/Fortran/fixture/myfortran_flags.py | 4 + test/Install/fixture/SConstruct-multi | 4 + test/Install/multi-dir/src/SConstruct | 4 + test/Java/Java-fixture/myjar.py | 4 + test/Java/Java-fixture/myjavac.py | 4 + test/Java/Java-fixture/myrmic.py | 4 + test/Java/java_version_image/SConstruct | 28 ++++--- .../java_version_image/com/sub/bar/Example4.java | 4 + .../java_version_image/com/sub/bar/Example5.java | 4 + .../java_version_image/com/sub/bar/Example6.java | 4 + .../java_version_image/com/sub/foo/Example1.java | 4 + .../java_version_image/com/sub/foo/Example2.java | 4 + .../java_version_image/com/sub/foo/Example3.java | 4 + test/Java/java_version_image/src1/Example7.java | 4 + test/Java/java_version_image/src2/Test.java | 4 + .../java_version_image/src4/NestedExample.java | 4 + test/Java/java_version_image/src5/TestSCons.java | 4 + test/Java/java_version_image/src6/TestSCons.java | 4 + test/LEX/lex_headerfile/spaced path/SConstruct | 6 +- test/LEX/lex_headerfile/spaced path/src/SConscript | 6 +- .../applelink_image/SConstruct_CurVers_CompatVers | 46 +++++++---- test/LINK/applelink_image/SConstruct_gh2580 | 4 + test/LINK/applelink_image/foo.c | 6 +- test/Libs/bug2903/SConstruct | 20 +++-- test/Libs/bug2903/SConstruct-libs | 12 ++- test/Libs/bug2903/lib.c | 4 + test/Libs/bug2903/main.c | 4 + test/MSVC/MSVC_BATCH-spaces-targetdir.py | 10 +-- test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct | 17 ++-- test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c | 6 +- test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c | 6 +- test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c | 6 +- test/MSVC/MSVC_USE_SCRIPT_ARGS-fixture/SConstruct | 4 + test/MSVC/VSWHERE-fixture/SConstruct | 5 ++ test/MSVC/msvc_fixture/SConstruct | 6 +- test/MSVC/msvc_fixture/StdAfx.cpp | 6 +- test/MSVC/msvc_fixture/StdAfx.h | 6 +- test/MSVC/msvc_fixture/foo.cpp | 6 +- test/MSVC/msvc_fixture/resource.h | 4 + test/MSVC/msvc_fixture/test.cpp | 6 +- test/MSVC/pch_gen/fixture/SConstruct | 36 +++++---- test/MinGW/bug_2799/SConstruct | 7 +- test/MinGW/bug_2799/module.c | 4 + test/MinGW/bug_2799/shlib.c | 4 + test/Parallel/failed-build/fixture/SConstruct | 15 +++- test/Parallel/failed-build/fixture/mycopy.py | 6 +- test/Parallel/failed-build/fixture/myfail.py | 6 +- test/Parallel/failed-build/fixture/teststate.py | 6 +- test/Progress/multi_target_fixture/SConstruct | 15 ++-- test/SConscript/fixture/SConstruct | 4 + test/SConscript/must_exist_deprecation.py | 2 +- test/Scanner/Python/SConstruct | 7 +- test/Scanner/Python/script.py | 4 + test/Scanner/Python/to_be_copied/__init__.py | 6 +- test/SideEffect/Issues/3013/files/SConscript | 4 + test/SideEffect/Issues/3013/files/SConstruct | 5 ++ test/SideEffect/Issues/3013/files/test.cpp | 4 + test/Subst/fixture/SConstruct.callable_exception | 8 +- .../fixture/SConstruct-tempfile-actionlist | 16 +++- test/TEMPFILE/fixture/SConstruct.tempfiledir | 5 ++ test/TaskMaster/bug_2811/fixture_dir/SConstruct | 13 ++-- test/TaskMaster/bug_2811/fixture_dir/mycopy.py | 4 + test/YACC/YACC-fixture/SConstruct_YACC_before | 9 ++- test/YACC/YACC-fixture/myyacc.py | 4 + test/YACC/YACCFLAGS-fixture/myyacc.py | 4 + test/fixture/SConstruct-check-valid-options | 2 + test/fixture/SConstruct_test_main.py | 4 + test/fixture/echo.py | 4 + test/fixture/mycompile.py | 4 + test/fixture/mygcc.py | 4 + test/fixture/mylex.py | 4 + test/fixture/mylink.py | 4 + test/fixture/myrewrite.py | 4 + test/fixture/no_msvc/no_msvcs_sconstruct.py | 14 +++- ..._msvcs_sconstruct_msvc_query_toolset_version.py | 14 +++- .../no_msvcs_sconstruct_msvc_sdk_versions.py | 14 +++- .../no_msvcs_sconstruct_msvc_toolset_versions.py | 14 +++- test/fixture/no_msvc/no_msvcs_sconstruct_tools.py | 11 ++- .../fixture/no_msvc/no_msvcs_sconstruct_version.py | 14 ++-- test/fixture/no_msvc/no_regs_sconstruct.py | 12 ++- .../python_scanner/curdir_reference/script.py | 4 + .../from_import_simple_package_module1.py | 4 + .../from_import_simple_package_module1_as.py | 4 + .../from_import_simple_package_module1_func.py | 6 +- .../from_import_simple_package_modules_no_space.py | 4 + ...rom_import_simple_package_modules_with_space.py | 4 + .../python_scanner/from_nested1_import_multiple.py | 6 +- .../import_simple_package_module1.py | 4 + .../import_simple_package_module1_as.py | 4 + test/fixture/python_scanner/imports_nested3.py | 4 + .../python_scanner/imports_simple_package.py | 4 + .../python_scanner/imports_unknown_files.py | 6 +- .../nested2/nested3/imports_grandparent_module.py | 4 + .../nested2/nested3/imports_parent_module.py | 4 + .../nested3/imports_parent_then_submodule.py | 4 + .../python_scanner/simple_package/module1.py | 6 +- test/fixture/test_main.c | 4 + test/fixture/wrapper.py | 4 + test/fixture/wrapper_with_args.py | 4 + test/ninja/ninja-fixture/bar.c | 4 + test/ninja/ninja-fixture/foo.c | 4 + test/ninja/ninja-fixture/gen_source.c | 4 + test/ninja/ninja-fixture/test1.c | 4 + test/ninja/ninja-fixture/test2.cpp | 6 +- test/ninja/ninja-fixture/test_impl.c | 4 + test/ninja/ninja_test_sconscripts/ninja_conftest | 9 ++- .../sconstruct_control_c_ninja | 4 + .../sconstruct_default_targets | 6 +- .../sconstruct_force_scons_callback | 4 + .../sconstruct_generate_and_build | 4 + .../sconstruct_generate_and_build_cxx | 4 + .../sconstruct_generated_sources_alias | 6 +- .../sconstruct_mingw_command_generator_action | 6 +- .../sconstruct_mingw_depfile_format | 4 + .../sconstruct_ninja_command_line | 4 + .../sconstruct_ninja_determinism | 4 + .../sconstruct_no_for_sig_subst | 4 + .../sconstruct_response_file | 6 +- test/option/fixture/SConstruct__experimental | 4 + test/option/fixture/SConstruct__taskmastertrace | 4 + test/option/hash-format/SConstruct | 4 + test/option/hash-format/build.py | 6 +- .../convenience-functions/image/SConstruct | 5 ++ test/packaging/rpm/src/main.c | 4 + test/packaging/sandbox-test/SConstruct | 30 +++++--- test/textfile/fixture/SConstruct | 13 +++- test/textfile/fixture/SConstruct.2 | 13 +++- test/textfile/fixture/SConstruct.issue-3540 | 15 ++-- test/textfile/fixture/SConstruct.issue-3550 | 4 + test/textfile/fixture/SConstruct.issue-4037 | 13 ++-- .../image/Libs/tools_example/Toolpath_TestTool1.py | 5 ++ .../tools_example/Toolpath_TestTool2/__init__.py | 5 ++ .../tools_example/subdir1/Toolpath_TestTool1_1.py | 5 ++ .../subdir1/Toolpath_TestTool1_2/__init__.py | 5 ++ .../subdir1/subdir2/Toolpath_TestTool2_1.py | 5 ++ .../subdir2/Toolpath_TestTool2_2/__init__.py | 5 ++ test/toolpath/nested/image/SConstruct | 90 ++++++++++++---------- .../site_scons/site_tools/Toolpath_TestTool1.py | 5 ++ .../site_tools/Toolpath_TestTool2/__init__.py | 5 ++ .../site_tools/subdir1/Toolpath_TestTool1_1.py | 5 ++ .../subdir1/Toolpath_TestTool1_2/__init__.py | 5 ++ .../subdir1/subdir2/Toolpath_TestTool2_1.py | 5 ++ .../subdir2/Toolpath_TestTool2_2/__init__.py | 5 ++ test/toolpath/relative_import/image/SConstruct | 15 ++-- .../image/tools/TestTool1/TestTool1_1.py | 5 ++ .../tools/TestTool1/TestTool1_2/TestTool1_2_1.py | 5 ++ .../TestTool1_2/TestTool1_2_2/__init__.py | 5 ++ .../image/tools/TestTool1/TestTool1_2/__init__.py | 5 ++ .../image/tools/TestTool1/__init__.py | 5 ++ 274 files changed, 1498 insertions(+), 350 deletions(-) diff --git a/test/AS/fixture/myas.py b/test/AS/fixture/myas.py index a348ace..b3d441c 100644 --- a/test/AS/fixture/myas.py +++ b/test/AS/fixture/myas.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys diff --git a/test/AS/fixture/myas_args.py b/test/AS/fixture/myas_args.py index 7a5e6fa..0249a9e 100644 --- a/test/AS/fixture/myas_args.py +++ b/test/AS/fixture/myas_args.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys diff --git a/test/Actions/addpost-link-fixture/strip.py b/test/Actions/addpost-link-fixture/strip.py index 88242f2..ad21dbc 100644 --- a/test/Actions/addpost-link-fixture/strip.py +++ b/test/Actions/addpost-link-fixture/strip.py @@ -1,2 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys + print("strip.py: %s" % " ".join(sys.argv[1:])) diff --git a/test/Actions/addpost-link-fixture/test1.c b/test/Actions/addpost-link-fixture/test1.c index 333f5c7..585021f 100644 --- a/test/Actions/addpost-link-fixture/test1.c +++ b/test/Actions/addpost-link-fixture/test1.c @@ -1,4 +1,9 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + extern void test_lib_fn(); + int main(int argc, char **argv) { test_lib_fn(); return 0; diff --git a/test/Actions/addpost-link-fixture/test_lib.c b/test/Actions/addpost-link-fixture/test_lib.c index 0ac1076..8bb0e60 100644 --- a/test/Actions/addpost-link-fixture/test_lib.c +++ b/test/Actions/addpost-link-fixture/test_lib.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include void test_lib_fn() { diff --git a/test/Actions/append-fixture/foo.c b/test/Actions/append-fixture/foo.c index e6428b5..83ab6e1 100644 --- a/test/Actions/append-fixture/foo.c +++ b/test/Actions/append-fixture/foo.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include int main(void) diff --git a/test/Actions/pre-post-fixture/work1/bar.c b/test/Actions/pre-post-fixture/work1/bar.c index eb3fd78..1ea20c1 100644 --- a/test/Actions/pre-post-fixture/work1/bar.c +++ b/test/Actions/pre-post-fixture/work1/bar.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include int main(void) diff --git a/test/Actions/pre-post-fixture/work1/foo.c b/test/Actions/pre-post-fixture/work1/foo.c index 32f2a3e..80d2e32 100644 --- a/test/Actions/pre-post-fixture/work1/foo.c +++ b/test/Actions/pre-post-fixture/work1/foo.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include int main(void) diff --git a/test/Actions/pre-post-fixture/work2/SConstruct b/test/Actions/pre-post-fixture/work2/SConstruct index e0af0ee..347dcbe 100644 --- a/test/Actions/pre-post-fixture/work2/SConstruct +++ b/test/Actions/pre-post-fixture/work2/SConstruct @@ -1,13 +1,19 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def b(target, source, env): with open(str(target[0]), 'wb') as f: f.write((env['X'] + '\n').encode()) + +DefaultEnvironment(tools=[]) env1 = Environment(X='111', tools=[]) env2 = Environment(X='222', tools=[]) -B = Builder(action = b, env = env1, multi=1) +B = Builder(action=b, env=env1, multi=1) print("B =", B) print("B.env =", B.env) -env1.Append(BUILDERS = {'B' : B}) -env2.Append(BUILDERS = {'B' : B}) +env1.Append(BUILDERS={'B': B}) +env2.Append(BUILDERS={'B': B}) env3 = env1.Clone(X='333') print("env1 =", env1) print("env2 =", env2) @@ -15,8 +21,10 @@ print("env3 =", env3) f1 = env1.B(File('file1.out'), []) f2 = env2.B('file2.out', []) f3 = env3.B('file3.out', []) + def do_nothing(env, target, source): pass + AddPreAction(f2[0], do_nothing) AddPostAction(f3[0], do_nothing) print("f1[0].builder =", f1[0].builder) diff --git a/test/Actions/pre-post-fixture/work3/SConstruct b/test/Actions/pre-post-fixture/work3/SConstruct index e0aa257..54f537a 100644 --- a/test/Actions/pre-post-fixture/work3/SConstruct +++ b/test/Actions/pre-post-fixture/work3/SConstruct @@ -1,10 +1,18 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def pre(target, source, env): pass + def post(target, source, env): pass + def build(target, source, env): with open(str(target[0]), 'wb') as f: f.write(b'build()\n') + +DefaultEnvironment(tools=[]) env = Environment(tools=[]) AddPreAction('dir', pre) AddPostAction('dir', post) diff --git a/test/Actions/pre-post-fixture/work4/build.py b/test/Actions/pre-post-fixture/work4/build.py index 390c8b9..2758b30 100644 --- a/test/Actions/pre-post-fixture/work4/build.py +++ b/test/Actions/pre-post-fixture/work4/build.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys + with open(sys.argv[1], 'wb') as outfp: for f in sys.argv[2:]: with open(f, 'rb') as infp: diff --git a/test/Actions/pre-post.py b/test/Actions/pre-post.py index ce8cbdc..ac6a96f 100644 --- a/test/Actions/pre-post.py +++ b/test/Actions/pre-post.py @@ -43,7 +43,7 @@ test.write(['work1', 'SConstruct'], """ import os.path import stat -# DefaultEnvironment(tools=[]) +DefaultEnvironment(tools=[]) env = Environment(XXX='bar%(_exe)s') def before(env, target, source): diff --git a/test/Actions/subst_shell_env-fixture/SConstruct b/test/Actions/subst_shell_env-fixture/SConstruct index 5ba822e..f6d5dc0 100644 --- a/test/Actions/subst_shell_env-fixture/SConstruct +++ b/test/Actions/subst_shell_env-fixture/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys def custom_environment_expansion1(env, target, source, shell_env): @@ -16,6 +20,7 @@ def expand_this_generator(env, target, source, for_signature): def expand_that_generator(env, target, source, for_signature): return str(target[0]) + "_is_from_expansion" +DefaultEnvironment(tools=[]) env = Environment(tools=['textfile']) env['SHELL_ENV_GENERATORS'] = [custom_environment_expansion1, custom_environment_expansion2] diff --git a/test/Actions/unicode-signature-fixture/SConstruct b/test/Actions/unicode-signature-fixture/SConstruct index 4d466e1..95c969d 100644 --- a/test/Actions/unicode-signature-fixture/SConstruct +++ b/test/Actions/unicode-signature-fixture/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + fnode = File(u'foo.txt') def funcact(target, source, env): @@ -7,6 +11,6 @@ def funcact(target, source, env): pass return 0 +DefaultEnvironment(tools=[]) env = Environment() - env.Command(fnode, [], ["echo $TARGET", funcact]) diff --git a/test/Batch/SConstruct_changed_sources_alwaysBuild b/test/Batch/SConstruct_changed_sources_alwaysBuild index dea7908..e6ae974 100644 --- a/test/Batch/SConstruct_changed_sources_alwaysBuild +++ b/test/Batch/SConstruct_changed_sources_alwaysBuild @@ -1,8 +1,10 @@ -# Testcase for tigris bug 2622 +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +"""Testcase for tigris bug 2622""" obj = Object('changed_sources_main.cpp') AlwaysBuild(obj) - program = Program('test', source=[obj]) - Default(program) diff --git a/test/Batch/changed_sources_main.cpp b/test/Batch/changed_sources_main.cpp index 810625a..886d0bc 100644 --- a/test/Batch/changed_sources_main.cpp +++ b/test/Batch/changed_sources_main.cpp @@ -1,3 +1,6 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation #include diff --git a/test/CC/CC-fixture/bar.c b/test/CC/CC-fixture/bar.c index de1e6e5..2ebfa66 100644 --- a/test/CC/CC-fixture/bar.c +++ b/test/CC/CC-fixture/bar.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include #include diff --git a/test/CC/CC-fixture/foo.c b/test/CC/CC-fixture/foo.c index de1e6e5..2ebfa66 100644 --- a/test/CC/CC-fixture/foo.c +++ b/test/CC/CC-fixture/foo.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include #include diff --git a/test/CC/CC-fixture/mycc.py b/test/CC/CC-fixture/mycc.py index eb11c87..0a0da59 100644 --- a/test/CC/CC-fixture/mycc.py +++ b/test/CC/CC-fixture/mycc.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ Phony cc command for testing SCons. diff --git a/test/CC/CCVERSION-fixture/versioned.py b/test/CC/CCVERSION-fixture/versioned.py index 33dc574..b0f0978 100644 --- a/test/CC/CCVERSION-fixture/versioned.py +++ b/test/CC/CCVERSION-fixture/versioned.py @@ -1,5 +1,10 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import subprocess import sys + if '-dumpversion' in sys.argv: print('3.9.9') sys.exit(0) diff --git a/test/CC/gcc-non-utf8-fixture/gcc-non-utf8.py b/test/CC/gcc-non-utf8-fixture/gcc-non-utf8.py index 292e5cb..f42f957 100644 --- a/test/CC/gcc-non-utf8-fixture/gcc-non-utf8.py +++ b/test/CC/gcc-non-utf8-fixture/gcc-non-utf8.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys if __name__ == '__main__': diff --git a/test/CXX/CXX-fixture/myc++.py b/test/CXX/CXX-fixture/myc++.py index d369f61..65613c3 100644 --- a/test/CXX/CXX-fixture/myc++.py +++ b/test/CXX/CXX-fixture/myc++.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ Phony c++ command for testing SCons. diff --git a/test/CacheDir/CACHEDIR_CLASS_fixture/SConstruct b/test/CacheDir/CACHEDIR_CLASS_fixture/SConstruct index 6ec40c6..db07dc6 100644 --- a/test/CacheDir/CACHEDIR_CLASS_fixture/SConstruct +++ b/test/CacheDir/CACHEDIR_CLASS_fixture/SConstruct @@ -1,12 +1,17 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons -class CustomCacheDir(SCons.CacheDir.CacheDir): +class CustomCacheDir(SCons.CacheDir.CacheDir): @classmethod def copy_to_cache(cls, env, src, dst): print("MY_CUSTOM_CACHEDIR_CLASS") super().copy_to_cache(env, src, dst) +DefaultEnvironment(tools=[]) env = Environment(tools=[]) env['CACHEDIR_CLASS'] = CustomCacheDir env.CacheDir('cache') -env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) \ No newline at end of file +env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) diff --git a/test/CacheDir/custom_cachedir_fixture/SConstruct b/test/CacheDir/custom_cachedir_fixture/SConstruct index 6389999..8d9c478 100644 --- a/test/CacheDir/custom_cachedir_fixture/SConstruct +++ b/test/CacheDir/custom_cachedir_fixture/SConstruct @@ -1,11 +1,16 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons -class CustomCacheDir(SCons.CacheDir.CacheDir): +class CustomCacheDir(SCons.CacheDir.CacheDir): @classmethod def copy_to_cache(cls, env, src, dst): print("MY_CUSTOM_CACHEDIR_CLASS") super().copy_to_cache(env, src, dst) +DefaultEnvironment(tools=[]) env = Environment(tools=[]) env.CacheDir('cache', CustomCacheDir) -env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) \ No newline at end of file +env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) diff --git a/test/CacheDir/double_cachedir_fixture/SConstruct b/test/CacheDir/double_cachedir_fixture/SConstruct index 322e286..34c27b0 100644 --- a/test/CacheDir/double_cachedir_fixture/SConstruct +++ b/test/CacheDir/double_cachedir_fixture/SConstruct @@ -1,6 +1,10 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons -class CustomCacheDir1(SCons.CacheDir.CacheDir): +class CustomCacheDir1(SCons.CacheDir.CacheDir): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) print("INSTANCIATED %s" % str(type(self).__name__)) @@ -11,7 +15,6 @@ class CustomCacheDir1(SCons.CacheDir.CacheDir): super().copy_to_cache(env, src, dst) class CustomCacheDir2(SCons.CacheDir.CacheDir): - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) print("INSTANCIATED %s" % str(type(self).__name__)) @@ -21,6 +24,7 @@ class CustomCacheDir2(SCons.CacheDir.CacheDir): print("MY_CUSTOM_CACHEDIR_CLASS2") super().copy_to_cache(env, src, dst) +DefaultEnvironment(tools=[]) env = Environment(tools=[]) env.CacheDir('cache1', CustomCacheDir1) env.CacheDir('cache2', CustomCacheDir2) diff --git a/test/CacheDir/invalid_custom_cachedir_fixture/SConstruct b/test/CacheDir/invalid_custom_cachedir_fixture/SConstruct index ad467e0..78f1bc6 100644 --- a/test/CacheDir/invalid_custom_cachedir_fixture/SConstruct +++ b/test/CacheDir/invalid_custom_cachedir_fixture/SConstruct @@ -1,6 +1,11 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + class CustomCacheDir: pass +DefaultEnvironment(tools=[]) env = Environment(tools=[]) env.CacheDir('cache', CustomCacheDir) -env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) \ No newline at end of file +env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) diff --git a/test/CacheDir/value_dependencies/SConstruct b/test/CacheDir/value_dependencies/SConstruct index 7b7e596..55c22ff 100644 --- a/test/CacheDir/value_dependencies/SConstruct +++ b/test/CacheDir/value_dependencies/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons.Node CacheDir('cache') @@ -7,8 +11,7 @@ def b(target, source, env): pass def scan(node, env, path): - # Have the node depend on a directory, which depends on an instance of - # SCons.Node.Python.Value. + """Have the node depend on a directory, which depends on a Value node.""" sample_dir = env.fs.Dir('dir2') env.Depends(sample_dir, env.Value('c')) return [sample_dir, env.Value('d'), env.Value(b'\x03\x0F', name='name3')] @@ -16,17 +19,16 @@ def scan(node, env, path): scanner = Scanner(function=scan, node_class=SCons.Node.Node) builder = Builder(action=b, source_scanner=scanner) +DefaultEnvironment(tools=[]) env = Environment() env.Append(BUILDERS={'B': builder}) # Create a node and a directory that each depend on an instance of # SCons.Node.Python.Value. sample_dir = env.fs.Dir('dir1') -env.Depends(sample_dir, - [env.Value('a'), env.Value(b'\x01\x0F', name='name1')]) +env.Depends(sample_dir, [env.Value('a'), env.Value(b'\x01\x0F', name='name1')]) sample_file = env.fs.File('testfile') -env.Depends(sample_file, - [env.Value('b'), env.Value(b'\x02\x0F', name='name2')]) +env.Depends(sample_file, [env.Value('b'), env.Value(b'\x02\x0F', name='name2')]) env.B(target='File1.out', source=[sample_dir, sample_file]) diff --git a/test/CompilationDatabase/fixture/SConstruct b/test/CompilationDatabase/fixture/SConstruct index bd2f780..47d35fb 100644 --- a/test/CompilationDatabase/fixture/SConstruct +++ b/test/CompilationDatabase/fixture/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys DefaultEnvironment(tools=[]) diff --git a/test/CompilationDatabase/fixture/SConstruct_tempfile b/test/CompilationDatabase/fixture/SConstruct_tempfile index 6b95977..4bc5c14 100644 --- a/test/CompilationDatabase/fixture/SConstruct_tempfile +++ b/test/CompilationDatabase/fixture/SConstruct_tempfile @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys DefaultEnvironment(tools=[]) diff --git a/test/CompilationDatabase/fixture/SConstruct_variant b/test/CompilationDatabase/fixture/SConstruct_variant index ea461fb..eaf19e8 100644 --- a/test/CompilationDatabase/fixture/SConstruct_variant +++ b/test/CompilationDatabase/fixture/SConstruct_variant @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys DefaultEnvironment(tools=[]) diff --git a/test/Configure/conftest_source_file/SConstruct b/test/Configure/conftest_source_file/SConstruct index dd8d28e..521afc1 100644 --- a/test/Configure/conftest_source_file/SConstruct +++ b/test/Configure/conftest_source_file/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + DefaultEnvironment(tools=[]) env = Environment() env.Append(CPPPATH=['.']) @@ -5,4 +9,4 @@ conf1 = Configure(env) conf1.CheckHeader("header1.h") conf1.CheckHeader("header3.h") conf1.Finish() -env.Program('out', 'main.c') \ No newline at end of file +env.Program('out', 'main.c') diff --git a/test/Configure/conftest_source_file/header1.h b/test/Configure/conftest_source_file/header1.h index 85dcd68..336f921 100644 --- a/test/Configure/conftest_source_file/header1.h +++ b/test/Configure/conftest_source_file/header1.h @@ -1,2 +1,6 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #pragma once -#include "header2.h" \ No newline at end of file +#include "header2.h" diff --git a/test/Configure/conftest_source_file/header2.h b/test/Configure/conftest_source_file/header2.h index 2cf8e90..90171bd 100644 --- a/test/Configure/conftest_source_file/header2.h +++ b/test/Configure/conftest_source_file/header2.h @@ -1,2 +1,6 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #pragma once -int test_header = 1; \ No newline at end of file +int test_header = 1; diff --git a/test/Configure/conftest_source_file/header3.h b/test/Configure/conftest_source_file/header3.h index dc4359e..68d9765 100644 --- a/test/Configure/conftest_source_file/header3.h +++ b/test/Configure/conftest_source_file/header3.h @@ -1,2 +1,6 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #pragma once -int test_header = 3; \ No newline at end of file +int test_header = 3; diff --git a/test/Configure/conftest_source_file/main.c b/test/Configure/conftest_source_file/main.c index a9f9570..e6ef776 100644 --- a/test/Configure/conftest_source_file/main.c +++ b/test/Configure/conftest_source_file/main.c @@ -1,2 +1,6 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include "header1.h" -int main(){return 0;} \ No newline at end of file +int main(){return 0;} diff --git a/test/Configure/fixture/SConstruct.issue-2906 b/test/Configure/fixture/SConstruct.issue-2906 index 7763653..87a4d9e 100644 --- a/test/Configure/fixture/SConstruct.issue-2906 +++ b/test/Configure/fixture/SConstruct.issue-2906 @@ -1,5 +1,10 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +# +DefaultEnvironment(tools=[]) env = Environment() conf1 = Configure(env) env2 = Environment() # Error right here. You can't have two configure contexts in flight at the same time. -conf2 = Configure(env2) \ No newline at end of file +conf2 = Configure(env2) diff --git a/test/Configure/is_conftest/fixture/SConstruct b/test/Configure/is_conftest/fixture/SConstruct index b0d4288..5494ea5 100644 --- a/test/Configure/is_conftest/fixture/SConstruct +++ b/test/Configure/is_conftest/fixture/SConstruct @@ -1,9 +1,11 @@ -""" -Test the nodes are created as conftest nodes in configure tests. -""" +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +"""Test the nodes are created as conftest nodes in configure tests.""" import sys -DefaultEnvironment(tools=[]) +DefaultEnvironment(tools=[]) env = Environment() conf = Configure(env) diff --git a/test/Configure/issue-2906-useful-duplicate-configure-message.py b/test/Configure/issue-2906-useful-duplicate-configure-message.py index 94c55c0..8fe3f8f 100644 --- a/test/Configure/issue-2906-useful-duplicate-configure-message.py +++ b/test/Configure/issue-2906-useful-duplicate-configure-message.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify useful error message when you create a second Configure context without @@ -44,7 +43,7 @@ expected_stdout = "scons: Reading SConscript files ...\n" expected_stderr = """ scons: *** Configure() called while another Configure() exists. Please call .Finish() before creating and second Configure() context -File "%s", line 5, in \n"""%test_SConstruct_path +File "%s", line 10, in \n"""%test_SConstruct_path test.run(stderr=expected_stderr, stdout=expected_stdout, status=2) test.pass_test() diff --git a/test/Configure/issue-3469/fixture/SConstruct b/test/Configure/issue-3469/fixture/SConstruct index ae1fb30..93d91a7 100644 --- a/test/Configure/issue-3469/fixture/SConstruct +++ b/test/Configure/issue-3469/fixture/SConstruct @@ -8,7 +8,6 @@ Github issue #3469 """ DefaultEnvironment(tools=[]) - vars = Variables() vars.Add(BoolVariable('SKIP', 'Skip Middle Conf test', False)) env = Environment(variables=vars) diff --git a/test/D/AllAtOnce/Image/SConstruct_template b/test/D/AllAtOnce/Image/SConstruct_template index 89d058e..0faf715 100644 --- a/test/D/AllAtOnce/Image/SConstruct_template +++ b/test/D/AllAtOnce/Image/SConstruct_template @@ -1,13 +1,19 @@ -# -*- coding:utf-8; -*- +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation import os +DefaultEnvironment(tools=[]) environment = Environment( tools=['{}', 'link'], ) -environment.ProgramAllAtOnce('project', [ -'main.d', -'amod.d', -'bmod.d', -]) +environment.ProgramAllAtOnce( + 'project', + [ + 'main.d', + 'amod.d', + 'bmod.d', + ], +) diff --git a/test/D/AllAtOnce/Image/amod.d b/test/D/AllAtOnce/Image/amod.d index a32aa75..0da2a0e 100644 --- a/test/D/AllAtOnce/Image/amod.d +++ b/test/D/AllAtOnce/Image/amod.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import std.stdio; void print_message() { diff --git a/test/D/AllAtOnce/Image/bmod.d b/test/D/AllAtOnce/Image/bmod.d index e4c1e1b..ad99d39 100644 --- a/test/D/AllAtOnce/Image/bmod.d +++ b/test/D/AllAtOnce/Image/bmod.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + int calculate_value() { return 42; } diff --git a/test/D/AllAtOnce/Image/main.d b/test/D/AllAtOnce/Image/main.d index 8b99458..f892525 100644 --- a/test/D/AllAtOnce/Image/main.d +++ b/test/D/AllAtOnce/Image/main.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import std.stdio: writefln; import amod: print_message; import bmod: calculate_value; diff --git a/test/D/CoreScanner/Image/SConstruct_template b/test/D/CoreScanner/Image/SConstruct_template index e91343b..b67f043 100644 --- a/test/D/CoreScanner/Image/SConstruct_template +++ b/test/D/CoreScanner/Image/SConstruct_template @@ -1,8 +1,10 @@ -# -*- mode:python; coding:utf-8; -*- +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation import os -environment = Environment( - tools=['link', '{}']) +DefaultEnvironment(tools=[]) +environment = Environment(tools=['link', '{}']) environment.Program('test1.d') environment.Program('test2.d') diff --git a/test/D/CoreScanner/Image/ignored.d b/test/D/CoreScanner/Image/ignored.d index 5b54a07..bcff3b7 100644 --- a/test/D/CoreScanner/Image/ignored.d +++ b/test/D/CoreScanner/Image/ignored.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + module ignored; int something; diff --git a/test/D/CoreScanner/Image/module1.d b/test/D/CoreScanner/Image/module1.d index 487c358..1423a0a 100644 --- a/test/D/CoreScanner/Image/module1.d +++ b/test/D/CoreScanner/Image/module1.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + module module1; int something; diff --git a/test/D/CoreScanner/Image/module2.d b/test/D/CoreScanner/Image/module2.d index 198fb74..41f1aab 100644 --- a/test/D/CoreScanner/Image/module2.d +++ b/test/D/CoreScanner/Image/module2.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + module module2; int something; diff --git a/test/D/CoreScanner/Image/p/ignored.d b/test/D/CoreScanner/Image/p/ignored.d index 43d2bd8..c01e057 100644 --- a/test/D/CoreScanner/Image/p/ignored.d +++ b/test/D/CoreScanner/Image/p/ignored.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + module p.ignored; int something; diff --git a/test/D/CoreScanner/Image/p/submodule1.d b/test/D/CoreScanner/Image/p/submodule1.d index 1ec0369..c4e1be4 100644 --- a/test/D/CoreScanner/Image/p/submodule1.d +++ b/test/D/CoreScanner/Image/p/submodule1.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + module p.submodule1; int something; diff --git a/test/D/CoreScanner/Image/p/submodule2.d b/test/D/CoreScanner/Image/p/submodule2.d index 57a2825..f59116c 100644 --- a/test/D/CoreScanner/Image/p/submodule2.d +++ b/test/D/CoreScanner/Image/p/submodule2.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + module p.submodule2; int something; diff --git a/test/D/CoreScanner/Image/test1.d b/test/D/CoreScanner/Image/test1.d index d386d97..4ca6799 100644 --- a/test/D/CoreScanner/Image/test1.d +++ b/test/D/CoreScanner/Image/test1.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import module1; import module2; import module3; diff --git a/test/D/CoreScanner/Image/test2.d b/test/D/CoreScanner/Image/test2.d index f880d2f..dd43cfa 100644 --- a/test/D/CoreScanner/Image/test2.d +++ b/test/D/CoreScanner/Image/test2.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import module1, module2, diff --git a/test/D/HSTeoh/ArLibIssue/SConstruct_template b/test/D/HSTeoh/ArLibIssue/SConstruct_template index b17847a..a39c228 100644 --- a/test/D/HSTeoh/ArLibIssue/SConstruct_template +++ b/test/D/HSTeoh/ArLibIssue/SConstruct_template @@ -1,6 +1,10 @@ -env = Environment({}) +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation import os -env['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd +DefaultEnvironment(tools=[]) +env = Environment({}) +env['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd env.StaticLibrary('mylib', ['a.d', 'b.d']) diff --git a/test/D/HSTeoh/LibCompileOptions/SConstruct_template b/test/D/HSTeoh/LibCompileOptions/SConstruct_template index 1489624..b2fde06 100644 --- a/test/D/HSTeoh/LibCompileOptions/SConstruct_template +++ b/test/D/HSTeoh/LibCompileOptions/SConstruct_template @@ -1,12 +1,12 @@ -env = Environment({}) +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation import os -env['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd +DefaultEnvironment(tools=[]) +env = Environment({}) +env['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd env.Library('mylib', 'mylib.d') - -prog_env = env.Clone( - LIBS = ['mylib'], - LIBPATH = '#' - ) +prog_env = env.Clone(LIBS=['mylib'], LIBPATH='#') prog_env.Program('prog', 'prog.d') diff --git a/test/D/HSTeoh/LibCompileOptions/prog.d b/test/D/HSTeoh/LibCompileOptions/prog.d index 33c14ce..079a8df 100644 --- a/test/D/HSTeoh/LibCompileOptions/prog.d +++ b/test/D/HSTeoh/LibCompileOptions/prog.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + int main() { return 0; } diff --git a/test/D/HSTeoh/LinkingProblem/SConstruct_template b/test/D/HSTeoh/LinkingProblem/SConstruct_template index 2c53b54..993f14c 100644 --- a/test/D/HSTeoh/LinkingProblem/SConstruct_template +++ b/test/D/HSTeoh/LinkingProblem/SConstruct_template @@ -1,20 +1,17 @@ -# -*- mode:python; coding=utf-8; -*- +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation import os -environment = Environment( - tools = ['cc', '{}', 'link'], - LIBS = ['ncurses']) - +DefaultEnvironment(tools=[]) +environment = Environment(tools=['cc', '{}', 'link'], LIBS=['ncurses']) environment['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd - environment.Object('ncurs_impl.o', 'ncurs_impl.c') - environment.Program('prog', Split(""" prog.d ncurs_impl.o """)) - environment.Program('cprog', Split(""" cprog.c ncurs_impl.o diff --git a/test/D/HSTeoh/LinkingProblem/cprog.c b/test/D/HSTeoh/LinkingProblem/cprog.c index 674fd96..a70ea29 100644 --- a/test/D/HSTeoh/LinkingProblem/cprog.c +++ b/test/D/HSTeoh/LinkingProblem/cprog.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + extern void ncurs_init(); extern void ncurs_cleanup(); diff --git a/test/D/HSTeoh/LinkingProblem/ncurs_impl.c b/test/D/HSTeoh/LinkingProblem/ncurs_impl.c index 3ca6dd3..93e8276 100644 --- a/test/D/HSTeoh/LinkingProblem/ncurs_impl.c +++ b/test/D/HSTeoh/LinkingProblem/ncurs_impl.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + /* Ncurses wrappers */ #include diff --git a/test/D/HSTeoh/LinkingProblem/prog.d b/test/D/HSTeoh/LinkingProblem/prog.d index 1337210..72d4099 100644 --- a/test/D/HSTeoh/LinkingProblem/prog.d +++ b/test/D/HSTeoh/LinkingProblem/prog.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + /* * Simple D program that links to ncurses via a C wrapping file. */ diff --git a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template index 118a7b2..1c75620 100644 --- a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template +++ b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template @@ -1,12 +1,17 @@ -# -*- mode:python; coding=utf-8; -*- +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation import os +DefaultEnvironment(tools=[]) environment = Environment( tools=['link', '{}'], - # It might be thought that a single string can contain multiple options space separated. Actually this - # is deemed to be a single option, so leads to an error. - DFLAGS = '-m64 -O') + # It might be thought that a single string can contain multiple + # options space separated. Actually this is deemed to be a single option, + # so leads to an error. + DFLAGS='-m64 -O', +) environment.Program('proj', Split(""" proj.d diff --git a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/cmod.c b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/cmod.c index 41c57f3..517c7e3 100644 --- a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/cmod.c +++ b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/cmod.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + /* This is a sample C module. */ int csqr(int arg) { diff --git a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/mod1.d b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/mod1.d index 5f61802..165514b 100644 --- a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/mod1.d +++ b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/mod1.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + module mod1; import std.stdio; diff --git a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/proj.d b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/proj.d index e97f9dd..64d360a 100644 --- a/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/proj.d +++ b/test/D/HSTeoh/SingleStringCannotBeMultipleOptions/proj.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import std.stdio; import mod1; diff --git a/test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template b/test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template index e2e7439..a6a9b80 100644 --- a/test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template +++ b/test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template @@ -1,8 +1,9 @@ -# -*- mode:python; coding:utf-8; -*- +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation import os -environment = Environment( - tools=['link', '{}']) - +DefaultEnvironment(tools=[]) +environment = Environment(tools=['link', '{}']) environment.Program('helloWorld.d') diff --git a/test/D/HelloWorld/CompileAndLinkOneStep/Image/helloWorld.d b/test/D/HelloWorld/CompileAndLinkOneStep/Image/helloWorld.d index 4d95b24..e9bc225 100644 --- a/test/D/HelloWorld/CompileAndLinkOneStep/Image/helloWorld.d +++ b/test/D/HelloWorld/CompileAndLinkOneStep/Image/helloWorld.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import std.stdio; int main(immutable string[] args) { diff --git a/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template b/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template index b38a9f0..3fa6860 100644 --- a/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template +++ b/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template @@ -1,10 +1,10 @@ -# -*- mode:python; coding:utf-8; -*- +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation import os -environment = Environment( - tools=['link', '{}']) - +DefaultEnvironment(tools=[]) +environment = Environment(tools=['link', '{}']) objects = environment.Object('helloWorld.d') - environment.Program('helloWorld', objects) diff --git a/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/helloWorld.d b/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/helloWorld.d index 4d95b24..e9bc225 100644 --- a/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/helloWorld.d +++ b/test/D/HelloWorld/CompileThenLinkTwoSteps/Image/helloWorld.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import std.stdio; int main(immutable string[] args) { diff --git a/test/D/Issues/2939_Ariovistus/Project/SConstruct_template b/test/D/Issues/2939_Ariovistus/Project/SConstruct_template index c78ba96..9202c45 100644 --- a/test/D/Issues/2939_Ariovistus/Project/SConstruct_template +++ b/test/D/Issues/2939_Ariovistus/Project/SConstruct_template @@ -1,12 +1,12 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +import os from os.path import join +DefaultEnvironment(tools=[]) environment = Environment({}) - -import os environment['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd - Export('environment') - -environment.SConscript([ - join("test","test1", "SConscript"), -]); +environment.SConscript([join("test","test1", "SConscript")]); diff --git a/test/D/Issues/2939_Ariovistus/Project/test/test1/SConscript b/test/D/Issues/2939_Ariovistus/Project/test/test1/SConscript index 53a1ca0..4b0d579 100644 --- a/test/D/Issues/2939_Ariovistus/Project/test/test1/SConscript +++ b/test/D/Issues/2939_Ariovistus/Project/test/test1/SConscript @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + Import('environment') env = Environment() diff --git a/test/D/Issues/2939_Ariovistus/Project/test/test1/stuff.cpp b/test/D/Issues/2939_Ariovistus/Project/test/test1/stuff.cpp index 2970549..a19fb34 100644 --- a/test/D/Issues/2939_Ariovistus/Project/test/test1/stuff.cpp +++ b/test/D/Issues/2939_Ariovistus/Project/test/test1/stuff.cpp @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include "stuff.h" X::X() { diff --git a/test/D/Issues/2939_Ariovistus/Project/test/test1/stuff.h b/test/D/Issues/2939_Ariovistus/Project/test/test1/stuff.h index 863c330..6dc578d 100644 --- a/test/D/Issues/2939_Ariovistus/Project/test/test1/stuff.h +++ b/test/D/Issues/2939_Ariovistus/Project/test/test1/stuff.h @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + class X { public: diff --git a/test/D/Issues/2939_Ariovistus/Project/test/test1/test1.cpp b/test/D/Issues/2939_Ariovistus/Project/test/test1/test1.cpp index f4d7208..b995685 100644 --- a/test/D/Issues/2939_Ariovistus/Project/test/test1/test1.cpp +++ b/test/D/Issues/2939_Ariovistus/Project/test/test1/test1.cpp @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include "stuff.h" int main() { diff --git a/test/D/Issues/2939_Ariovistus/Project/test/test1/test2.d b/test/D/Issues/2939_Ariovistus/Project/test/test1/test2.d index 4fbfa4d..07179c1 100644 --- a/test/D/Issues/2939_Ariovistus/Project/test/test1/test2.d +++ b/test/D/Issues/2939_Ariovistus/Project/test/test1/test2.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import std.stdio; struct X { diff --git a/test/D/Issues/2940_Ariovistus/Project/SConstruct_template b/test/D/Issues/2940_Ariovistus/Project/SConstruct_template index c78ba96..00fd2b7 100644 --- a/test/D/Issues/2940_Ariovistus/Project/SConstruct_template +++ b/test/D/Issues/2940_Ariovistus/Project/SConstruct_template @@ -1,12 +1,12 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +import os from os.path import join +DefaultEnvironment(tools=[]) environment = Environment({}) - -import os environment['ENV']['HOME'] = os.environ['HOME'] # Hack for gdmd - Export('environment') - -environment.SConscript([ - join("test","test1", "SConscript"), -]); +environment.SConscript([join("test","test1", "SConscript")]) diff --git a/test/D/Issues/2940_Ariovistus/Project/test/test1/SConscript b/test/D/Issues/2940_Ariovistus/Project/test/test1/SConscript index 45e517a..00aaf14 100644 --- a/test/D/Issues/2940_Ariovistus/Project/test/test1/SConscript +++ b/test/D/Issues/2940_Ariovistus/Project/test/test1/SConscript @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + Import('environment') env = Environment() diff --git a/test/D/Issues/2940_Ariovistus/Project/test/test1/stuff.cpp b/test/D/Issues/2940_Ariovistus/Project/test/test1/stuff.cpp index 2970549..a19fb34 100644 --- a/test/D/Issues/2940_Ariovistus/Project/test/test1/stuff.cpp +++ b/test/D/Issues/2940_Ariovistus/Project/test/test1/stuff.cpp @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include "stuff.h" X::X() { diff --git a/test/D/Issues/2940_Ariovistus/Project/test/test1/stuff.h b/test/D/Issues/2940_Ariovistus/Project/test/test1/stuff.h index 863c330..6dc578d 100644 --- a/test/D/Issues/2940_Ariovistus/Project/test/test1/stuff.h +++ b/test/D/Issues/2940_Ariovistus/Project/test/test1/stuff.h @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + class X { public: diff --git a/test/D/Issues/2940_Ariovistus/Project/test/test1/test1.cpp b/test/D/Issues/2940_Ariovistus/Project/test/test1/test1.cpp index f4d7208..b995685 100644 --- a/test/D/Issues/2940_Ariovistus/Project/test/test1/test1.cpp +++ b/test/D/Issues/2940_Ariovistus/Project/test/test1/test1.cpp @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include "stuff.h" int main() { diff --git a/test/D/Issues/2940_Ariovistus/Project/test/test1/test2.d b/test/D/Issues/2940_Ariovistus/Project/test/test1/test2.d index 4fbfa4d..07179c1 100644 --- a/test/D/Issues/2940_Ariovistus/Project/test/test1/test2.d +++ b/test/D/Issues/2940_Ariovistus/Project/test/test1/test2.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import std.stdio; struct X { diff --git a/test/D/Issues/2994/Project/SConstruct_template b/test/D/Issues/2994/Project/SConstruct_template index 555b1b0..3d1bbc6 100644 --- a/test/D/Issues/2994/Project/SConstruct_template +++ b/test/D/Issues/2994/Project/SConstruct_template @@ -1,5 +1,8 @@ -# -*- mode:python; coding:utf-8; -*- +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +DefaultEnvironment(tools=[]) env=Environment({}) change = ARGUMENTS.get('change', 0) diff --git a/test/D/Issues/2994/Project/main.d b/test/D/Issues/2994/Project/main.d index f0aa23a..8bea7ff 100644 --- a/test/D/Issues/2994/Project/main.d +++ b/test/D/Issues/2994/Project/main.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + /* This program prints a hello world message to the console. */ diff --git a/test/D/MixedDAndC/Image/SConstruct b/test/D/MixedDAndC/Image/SConstruct index f24e2b3..d104e2f 100644 --- a/test/D/MixedDAndC/Image/SConstruct +++ b/test/D/MixedDAndC/Image/SConstruct @@ -1,9 +1,11 @@ -# -*- mode:python; coding:utf-8; -*- +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation import os -environment = Environment( -) +DefaultEnvironment(tools=[]) +environment = Environment() # CFLAGS=['-m64'], # DLINKFLAGS=['-m64'], # DFLAGS=['-m64', '-O']) diff --git a/test/D/MixedDAndC/Image/cmod.c b/test/D/MixedDAndC/Image/cmod.c index 31be5e9..72ace7b 100644 --- a/test/D/MixedDAndC/Image/cmod.c +++ b/test/D/MixedDAndC/Image/cmod.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + int csqr(int arg) { return arg*arg; } diff --git a/test/D/MixedDAndC/Image/dmod.d b/test/D/MixedDAndC/Image/dmod.d index c609b9c..4ab1b39 100644 --- a/test/D/MixedDAndC/Image/dmod.d +++ b/test/D/MixedDAndC/Image/dmod.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + module dmod; import std.stdio; diff --git a/test/D/MixedDAndC/Image/proj.d b/test/D/MixedDAndC/Image/proj.d index 3e0bf95..2da7057 100644 --- a/test/D/MixedDAndC/Image/proj.d +++ b/test/D/MixedDAndC/Image/proj.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + import std.stdio; import dmod; diff --git a/test/D/SharedObjects/Image/SConstruct_template b/test/D/SharedObjects/Image/SConstruct_template index 7ae1c8d..f852c09 100644 --- a/test/D/SharedObjects/Image/SConstruct_template +++ b/test/D/SharedObjects/Image/SConstruct_template @@ -1,4 +1,6 @@ -# -*- mode:python; coding:utf-8; -*- +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation # The core difference between this test and the one of SharedObjectSuffixIssue # is that here we explicitly use the relevant D tool and things work. diff --git a/test/D/SharedObjects/Image/code.d b/test/D/SharedObjects/Image/code.d index 0d9d1d7..2073b31 100644 --- a/test/D/SharedObjects/Image/code.d +++ b/test/D/SharedObjects/Image/code.d @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + int returnTheAnswer() { return 42; } diff --git a/test/Decider/MD5-winonly-fixture/SConstruct b/test/Decider/MD5-winonly-fixture/SConstruct index 9775a43..9eb66a3 100644 --- a/test/Decider/MD5-winonly-fixture/SConstruct +++ b/test/Decider/MD5-winonly-fixture/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + DefaultEnvironment(tools=[]) env=Environment() env.Decider('MD5-timestamp') diff --git a/test/Dir/DriveAbsPath/SConstruct b/test/Dir/DriveAbsPath/SConstruct index 5b63193..598723d 100644 --- a/test/Dir/DriveAbsPath/SConstruct +++ b/test/Dir/DriveAbsPath/SConstruct @@ -1,32 +1,42 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os import SCons +DefaultEnvironment(tools=[]) env = Environment() drive = os.path.splitdrive(os.getcwd())[0] drive_dir = env.fs.Dir(drive) if not isinstance(drive_dir, SCons.Node.FS.RootDir): - raise Exception('env.fs.Dir("%s") returned a %s instead of a RootDir' % - (drive, type(drive_dir))) + raise Exception( + f'env.fs.Dir("{drive}") returned a {type(drive_dir)} instead of a RootDir' + ) drive_abspath1 = drive_dir._abspath drive_abspath2 = drive_dir.abspath if drive_abspath1 != drive_abspath2: - raise Exception('Calculated _abspath %s is not the same as abspath %s' % - (drive_abspath1, drive_abspath2)) + raise Exception( + f'Calculated _abspath {drive_abspath1} is not the same as abspath {drive_abspath2}' + ) elif not os.path.exists(drive_abspath1): - raise Exception('Calculated abspath %s does not exist' % drive_abspath1) + raise Exception(f'Calculated abspath {drive_abspath1} does not exist') elif drive.rstrip(os.path.sep) != drive_abspath1.rstrip(os.path.sep): - raise Exception('Real drive %s and calculated abspath %s are not the ' - 'same' % (drive, drive_abspath1)) + raise Exception( + f'Real drive {drive} and calculated abspath {drive_abspath1} are not the same' + ) drive_path1 = drive_dir._path drive_path2 = drive_dir.path if drive_path1 != drive_path2: - raise Exception('Calculated _path %s is not the same as path %s' % - (drive_path1, drive_path2)) + raise Exception( + f'Calculated _path {drive_path1} is not the same as path {drive_path2}' + ) elif not os.path.exists(drive_path1): - raise Exception('Calculated path %s does not exist' % drive_path1) + raise Exception(f'Calculated path {drive_path1} does not exist') elif drive.rstrip(os.path.sep) != drive_path1.rstrip(os.path.sep): - raise Exception('Real drive %s and calculated abspath %s are not the ' - 'same' % (drive, drive_abs)) + raise Exception( + f'Real drive {drive} and calculated abspath {drive_abs} are not the same' + ) diff --git a/test/Dir/PyPackageDir/image/SConstruct b/test/Dir/PyPackageDir/image/SConstruct index aceb245..d09b472 100644 --- a/test/Dir/PyPackageDir/image/SConstruct +++ b/test/Dir/PyPackageDir/image/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys, os oldsyspath = sys.path diff --git a/test/Docbook/basedir/htmlchunked/image/SConstruct b/test/Docbook/basedir/htmlchunked/image/SConstruct index 0066271..87a4658 100644 --- a/test/Docbook/basedir/htmlchunked/image/SConstruct +++ b/test/Docbook/basedir/htmlchunked/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookHtmlChunked('manual', xsl='html.xsl', base_dir='output/') diff --git a/test/Docbook/basedir/htmlchunked/image/SConstruct.cmd b/test/Docbook/basedir/htmlchunked/image/SConstruct.cmd index d981b28..40dc569 100644 --- a/test/Docbook/basedir/htmlchunked/image/SConstruct.cmd +++ b/test/Docbook/basedir/htmlchunked/image/SConstruct.cmd @@ -1,2 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) env.DocbookHtmlChunked('manual', xsl='html.xsl', base_dir='output/') diff --git a/test/Docbook/basedir/htmlhelp/image/SConstruct b/test/Docbook/basedir/htmlhelp/image/SConstruct index cb2893f..3ca5e8f 100644 --- a/test/Docbook/basedir/htmlhelp/image/SConstruct +++ b/test/Docbook/basedir/htmlhelp/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookHtmlhelp('manual', xsl='htmlhelp.xsl', base_dir='output/') diff --git a/test/Docbook/basedir/htmlhelp/image/SConstruct.cmd b/test/Docbook/basedir/htmlhelp/image/SConstruct.cmd index 8c7c9ca..f76e99b 100644 --- a/test/Docbook/basedir/htmlhelp/image/SConstruct.cmd +++ b/test/Docbook/basedir/htmlhelp/image/SConstruct.cmd @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) env.DocbookHtmlhelp('manual', xsl='htmlhelp.xsl', base_dir='output/') diff --git a/test/Docbook/basedir/slideshtml/image/SConstruct b/test/Docbook/basedir/slideshtml/image/SConstruct index 2bb86f0..f9b02dd 100644 --- a/test/Docbook/basedir/slideshtml/image/SConstruct +++ b/test/Docbook/basedir/slideshtml/image/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import xsltver v = xsltver.detectXsltVersion('/usr/share/xml/docbook/stylesheet/docbook-xsl') @@ -7,6 +11,7 @@ if v >= (1, 78, 0): # Use namespace-aware input file ns_ext = 'ns' +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookSlidesHtml('virt'+ns_ext, xsl='slides.xsl', base_dir='output/') diff --git a/test/Docbook/basedir/slideshtml/image/SConstruct.cmd b/test/Docbook/basedir/slideshtml/image/SConstruct.cmd index f82444d..151e603 100644 --- a/test/Docbook/basedir/slideshtml/image/SConstruct.cmd +++ b/test/Docbook/basedir/slideshtml/image/SConstruct.cmd @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import xsltver v = xsltver.detectXsltVersion('/usr/share/xml/docbook/stylesheet/docbook-xsl') @@ -7,6 +11,7 @@ if v >= (1, 78, 0): # Use namespace-aware input file ns_ext = 'ns' +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) env.Append(DOCBOOK_XSLTPROCFLAGS=['--novalid', '--nonet']) env.DocbookSlidesHtml('virt'+ns_ext, xsl='slides.xsl', base_dir='output/') diff --git a/test/Docbook/basedir/slideshtml/image/xsltver.py b/test/Docbook/basedir/slideshtml/image/xsltver.py index c845324..e1a7074 100644 --- a/test/Docbook/basedir/slideshtml/image/xsltver.py +++ b/test/Docbook/basedir/slideshtml/image/xsltver.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os import re diff --git a/test/Docbook/basic/epub/image/SConstruct b/test/Docbook/basic/epub/image/SConstruct index 16a0699..3f4996d 100644 --- a/test/Docbook/basic/epub/image/SConstruct +++ b/test/Docbook/basic/epub/image/SConstruct @@ -1,2 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookEpub('manual') diff --git a/test/Docbook/basic/epub/image/SConstruct.cmd b/test/Docbook/basic/epub/image/SConstruct.cmd index 9b5e4cb..b86c78d 100644 --- a/test/Docbook/basic/epub/image/SConstruct.cmd +++ b/test/Docbook/basic/epub/image/SConstruct.cmd @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) DOCBOOK_XSLTPROC = ARGUMENTS.get('DOCBOOK_XSLTPROC', "") if DOCBOOK_XSLTPROC: diff --git a/test/Docbook/basic/html/image/SConstruct b/test/Docbook/basic/html/image/SConstruct index 954e639..4a9d074 100644 --- a/test/Docbook/basic/html/image/SConstruct +++ b/test/Docbook/basic/html/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookHtml('manual') diff --git a/test/Docbook/basic/html/image/SConstruct.cmd b/test/Docbook/basic/html/image/SConstruct.cmd index 3e58102..ef4eceb 100644 --- a/test/Docbook/basic/html/image/SConstruct.cmd +++ b/test/Docbook/basic/html/image/SConstruct.cmd @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) DOCBOOK_XSLTPROC = ARGUMENTS.get('DOCBOOK_XSLTPROC', "") if DOCBOOK_XSLTPROC: diff --git a/test/Docbook/basic/htmlchunked/image/SConstruct b/test/Docbook/basic/htmlchunked/image/SConstruct index 0004f8b..05a617f 100644 --- a/test/Docbook/basic/htmlchunked/image/SConstruct +++ b/test/Docbook/basic/htmlchunked/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookHtmlChunked('manual') diff --git a/test/Docbook/basic/htmlchunked/image/SConstruct.cmd b/test/Docbook/basic/htmlchunked/image/SConstruct.cmd index 8734147..765864a 100644 --- a/test/Docbook/basic/htmlchunked/image/SConstruct.cmd +++ b/test/Docbook/basic/htmlchunked/image/SConstruct.cmd @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) DOCBOOK_XSLTPROC = ARGUMENTS.get('DOCBOOK_XSLTPROC', "") if DOCBOOK_XSLTPROC: diff --git a/test/Docbook/basic/htmlhelp/image/SConstruct b/test/Docbook/basic/htmlhelp/image/SConstruct index 0c793d4..433a1c3 100644 --- a/test/Docbook/basic/htmlhelp/image/SConstruct +++ b/test/Docbook/basic/htmlhelp/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookHtmlhelp('manual') diff --git a/test/Docbook/basic/htmlhelp/image/SConstruct.cmd b/test/Docbook/basic/htmlhelp/image/SConstruct.cmd index e3e0193..854a266 100644 --- a/test/Docbook/basic/htmlhelp/image/SConstruct.cmd +++ b/test/Docbook/basic/htmlhelp/image/SConstruct.cmd @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) DOCBOOK_XSLTPROC = ARGUMENTS.get('DOCBOOK_XSLTPROC', "") if DOCBOOK_XSLTPROC: diff --git a/test/Docbook/basic/man/image/SConstruct b/test/Docbook/basic/man/image/SConstruct index ddfcfbc..2dcdb6e 100644 --- a/test/Docbook/basic/man/image/SConstruct +++ b/test/Docbook/basic/man/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookMan('refdb') diff --git a/test/Docbook/basic/man/image/SConstruct.cmd b/test/Docbook/basic/man/image/SConstruct.cmd index 122c0ce..6474f49 100644 --- a/test/Docbook/basic/man/image/SConstruct.cmd +++ b/test/Docbook/basic/man/image/SConstruct.cmd @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) DOCBOOK_XSLTPROC = ARGUMENTS.get('DOCBOOK_XSLTPROC', "") if DOCBOOK_XSLTPROC: diff --git a/test/Docbook/basic/pdf/image/SConstruct b/test/Docbook/basic/pdf/image/SConstruct index 01b2c7f..e863047 100644 --- a/test/Docbook/basic/pdf/image/SConstruct +++ b/test/Docbook/basic/pdf/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookPdf('manual') diff --git a/test/Docbook/basic/pdf/image/SConstruct.cmd b/test/Docbook/basic/pdf/image/SConstruct.cmd index db1ed18..5d70905 100644 --- a/test/Docbook/basic/pdf/image/SConstruct.cmd +++ b/test/Docbook/basic/pdf/image/SConstruct.cmd @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) DOCBOOK_XSLTPROC = ARGUMENTS.get('DOCBOOK_XSLTPROC', "") if DOCBOOK_XSLTPROC: diff --git a/test/Docbook/basic/slideshtml/image/SConstruct b/test/Docbook/basic/slideshtml/image/SConstruct index e1437da..a14f9ae 100644 --- a/test/Docbook/basic/slideshtml/image/SConstruct +++ b/test/Docbook/basic/slideshtml/image/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import xsltver v = xsltver.detectXsltVersion('/usr/share/xml/docbook/stylesheet/docbook-xsl') @@ -7,6 +11,9 @@ if v >= (1, 78, 0): # Use namespace-aware input file ns_ext = 'ns' +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) -env.DocbookSlidesHtml('virt'+ns_ext, xsl='/usr/share/xml/docbook/stylesheet/docbook-xsl/slides/xhtml/plain.xsl') - +env.DocbookSlidesHtml( + 'virt' + ns_ext, + xsl='/usr/share/xml/docbook/stylesheet/docbook-xsl/slides/xhtml/plain.xsl', +) diff --git a/test/Docbook/basic/slideshtml/image/SConstruct.cmd b/test/Docbook/basic/slideshtml/image/SConstruct.cmd index 08cbc31..2090bf0 100644 --- a/test/Docbook/basic/slideshtml/image/SConstruct.cmd +++ b/test/Docbook/basic/slideshtml/image/SConstruct.cmd @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import xsltver v = xsltver.detectXsltVersion('/usr/share/xml/docbook/stylesheet/docbook-xsl') @@ -7,7 +11,10 @@ if v >= (1, 78, 0): # Use namespace-aware input file ns_ext = 'ns' +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) env.Append(DOCBOOK_XSLTPROCFLAGS=['--novalid', '--nonet']) -env.DocbookSlidesHtml('virt'+ns_ext, xsl='/usr/share/xml/docbook/stylesheet/docbook-xsl/slides/xhtml/plain.xsl') - +env.DocbookSlidesHtml( + 'virt' + ns_ext, + xsl='/usr/share/xml/docbook/stylesheet/docbook-xsl/slides/xhtml/plain.xsl', +) diff --git a/test/Docbook/basic/slideshtml/image/xsltver.py b/test/Docbook/basic/slideshtml/image/xsltver.py index c845324..e1a7074 100644 --- a/test/Docbook/basic/slideshtml/image/xsltver.py +++ b/test/Docbook/basic/slideshtml/image/xsltver.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os import re diff --git a/test/Docbook/basic/slidespdf/image/SConstruct b/test/Docbook/basic/slidespdf/image/SConstruct index e103f02..fbe359c 100644 --- a/test/Docbook/basic/slidespdf/image/SConstruct +++ b/test/Docbook/basic/slidespdf/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookSlidesPdf('virt') diff --git a/test/Docbook/basic/slidespdf/image/SConstruct.cmd b/test/Docbook/basic/slidespdf/image/SConstruct.cmd index 2000713..18ef25b 100644 --- a/test/Docbook/basic/slidespdf/image/SConstruct.cmd +++ b/test/Docbook/basic/slidespdf/image/SConstruct.cmd @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(DOCBOOK_PREFER_XSLTPROC=1, tools=['docbook']) env.Append(DOCBOOK_XSLTPROCFLAGS=['--novalid', '--nonet']) env.DocbookSlidesPdf('virt') diff --git a/test/Docbook/basic/xinclude/image/SConstruct b/test/Docbook/basic/xinclude/image/SConstruct index 91d92e6..a571345 100644 --- a/test/Docbook/basic/xinclude/image/SConstruct +++ b/test/Docbook/basic/xinclude/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookXInclude('manual_xi.xml','manual.xml') diff --git a/test/Docbook/basic/xslt/image/SConstruct b/test/Docbook/basic/xslt/image/SConstruct index 3e8ac4a..8ae620a 100644 --- a/test/Docbook/basic/xslt/image/SConstruct +++ b/test/Docbook/basic/xslt/image/SConstruct @@ -1,9 +1,13 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) # # Create document # -env.DocbookXslt('out.xml', 'in.xml', - xsl='./to_docbook.xslt') +env.DocbookXslt('out.xml', 'in.xml', xsl='./to_docbook.xslt') diff --git a/test/Docbook/basic/xsltsubdir/image/SConstruct b/test/Docbook/basic/xsltsubdir/image/SConstruct index 4fe062a..b01da8c 100644 --- a/test/Docbook/basic/xsltsubdir/image/SConstruct +++ b/test/Docbook/basic/xsltsubdir/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) SConscript('subdir/SConscript', 'env') diff --git a/test/Docbook/basic/xsltsubdir/image/subdir/SConscript b/test/Docbook/basic/xsltsubdir/image/subdir/SConscript index ea19df5..d88eaf5 100644 --- a/test/Docbook/basic/xsltsubdir/image/subdir/SConscript +++ b/test/Docbook/basic/xsltsubdir/image/subdir/SConscript @@ -1,7 +1,10 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + Import('env') # # Create document # -env.DocbookXslt('out.xml', 'in.xml', - xsl='to_docbook.xslt') +env.DocbookXslt('out.xml', 'in.xml', xsl='to_docbook.xslt') diff --git a/test/Docbook/dependencies/xinclude/image/SConstruct b/test/Docbook/dependencies/xinclude/image/SConstruct index 91d92e6..a571345 100644 --- a/test/Docbook/dependencies/xinclude/image/SConstruct +++ b/test/Docbook/dependencies/xinclude/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookXInclude('manual_xi.xml','manual.xml') diff --git a/test/Docbook/rootname/htmlchunked/image/SConstruct b/test/Docbook/rootname/htmlchunked/image/SConstruct index 905eec1..1187960 100644 --- a/test/Docbook/rootname/htmlchunked/image/SConstruct +++ b/test/Docbook/rootname/htmlchunked/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookHtmlChunked('manual.html','manual', xsl='html.xsl') diff --git a/test/Docbook/rootname/htmlhelp/image/SConstruct b/test/Docbook/rootname/htmlhelp/image/SConstruct index 913240b..93cd473 100644 --- a/test/Docbook/rootname/htmlhelp/image/SConstruct +++ b/test/Docbook/rootname/htmlhelp/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookHtmlhelp('manual.html', 'manual', xsl='htmlhelp.xsl') diff --git a/test/Docbook/rootname/slideshtml/image/SConstruct b/test/Docbook/rootname/slideshtml/image/SConstruct index 4f1079e..2181936 100644 --- a/test/Docbook/rootname/slideshtml/image/SConstruct +++ b/test/Docbook/rootname/slideshtml/image/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import xsltver v = xsltver.detectXsltVersion('/usr/share/xml/docbook/stylesheet/docbook-xsl') @@ -7,6 +11,7 @@ if v >= (1, 78, 0): # Use namespace-aware input file ns_ext = 'ns' +DefaultEnvironment(tools=[]) env = Environment(tools=['docbook']) env.DocbookSlidesHtml('manual.html', 'virt'+ns_ext, xsl='slides.xsl') diff --git a/test/Docbook/rootname/slideshtml/image/xsltver.py b/test/Docbook/rootname/slideshtml/image/xsltver.py index c845324..e1a7074 100644 --- a/test/Docbook/rootname/slideshtml/image/xsltver.py +++ b/test/Docbook/rootname/slideshtml/image/xsltver.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os import re diff --git a/test/File/fixture/relpath/base/SConstruct b/test/File/fixture/relpath/base/SConstruct index 4bb5078..cb99226 100644 --- a/test/File/fixture/relpath/base/SConstruct +++ b/test/File/fixture/relpath/base/SConstruct @@ -1,22 +1,26 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +# # Testcase to check that .relpath works on SOURCES,TARGETS, and the singular SOURCE # This is the SConstruct for test/File/File-relpath.py -# + DefaultEnvironment(tools=[]) env = Environment(tools=[]) input_list = [ - "${TARGETS.relpath}", - "${TARGETS.abspath}", - "${SOURCES.relpath}", - "${SOURCES.abspath}", - "${SOURCE.relpath}", - "${SOURCE.abspath}", - ] + "${TARGETS.relpath}", + "${TARGETS.abspath}", + "${SOURCES.relpath}", + "${SOURCES.abspath}", + "${SOURCE.relpath}", + "${SOURCE.abspath}", +] outputs = env.subst( - input_list, + input_list, target=[File("../foo/dir"), File("build/file1")], source=[File("src/file")], ) -for i,s in zip(input_list,outputs): - print("%s=%s"%(i,s)) +for i, s in zip(input_list, outputs): + print("%s=%s" % (i, s)) diff --git a/test/Fortran/fixture/myfortran.py b/test/Fortran/fixture/myfortran.py index 6b4e5ef..2c5b580 100644 --- a/test/Fortran/fixture/myfortran.py +++ b/test/Fortran/fixture/myfortran.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import getopt import sys diff --git a/test/Fortran/fixture/myfortran_flags.py b/test/Fortran/fixture/myfortran_flags.py index 2b433ea..3ef841e 100644 --- a/test/Fortran/fixture/myfortran_flags.py +++ b/test/Fortran/fixture/myfortran_flags.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import getopt import sys diff --git a/test/Install/fixture/SConstruct-multi b/test/Install/fixture/SConstruct-multi index 94de1df..68736af 100644 --- a/test/Install/fixture/SConstruct-multi +++ b/test/Install/fixture/SConstruct-multi @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +# # first run creates a src file, makes it read-only, and installs. # second run updates src, Install should successfully replace # the previous install (read-only attr on Windows might fail it) diff --git a/test/Install/multi-dir/src/SConstruct b/test/Install/multi-dir/src/SConstruct index 44e3589..73683d3 100644 --- a/test/Install/multi-dir/src/SConstruct +++ b/test/Install/multi-dir/src/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +# # This tests for a bug where installing a sequence dirs and subdirs # outside the source tree can cause SCons to fail to create the dest # dir. diff --git a/test/Java/Java-fixture/myjar.py b/test/Java/Java-fixture/myjar.py index a47e3b0..3e17231 100644 --- a/test/Java/Java-fixture/myjar.py +++ b/test/Java/Java-fixture/myjar.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import fileinput import sys diff --git a/test/Java/Java-fixture/myjavac.py b/test/Java/Java-fixture/myjavac.py index 1c7fdea..c2a2602 100644 --- a/test/Java/Java-fixture/myjavac.py +++ b/test/Java/Java-fixture/myjavac.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys args = sys.argv[1:] diff --git a/test/Java/Java-fixture/myrmic.py b/test/Java/Java-fixture/myrmic.py index 877c1be..8934e7f 100644 --- a/test/Java/Java-fixture/myrmic.py +++ b/test/Java/Java-fixture/myrmic.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os import sys diff --git a/test/Java/java_version_image/SConstruct b/test/Java/java_version_image/SConstruct index 945c864..37e49c2 100644 --- a/test/Java/java_version_image/SConstruct +++ b/test/Java/java_version_image/SConstruct @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation AddOption('--javac_path', dest='javac_path', @@ -11,25 +14,20 @@ AddOption('--java_version', default='1.6', type='string') -path=GetOption('javac_path') +path = GetOption('javac_path') if path[0] == "'": path = path[1:-1] version = GetOption('java_version') -env = Environment(tools = ['javac'], - JAVAVERSION = version, - ) - - -env.AppendENVPath('PATH',path) +DefaultEnvironment(tools=[]) +env = Environment(tools=['javac'], JAVAVERSION=version) +env.AppendENVPath('PATH', path) # print('PATH:%s'%env['ENV']['PATH']) - - -env.Java(target = 'class1', source = 'com/sub/foo') -env.Java(target = 'class2', source = 'com/sub/bar') -env.Java(target = 'class3', source = ['src1', 'src2']) -env.Java(target = 'class4', source = ['src4']) -env.Java(target = 'class5', source = ['src5']) -env.Java(target = 'class6', source = ['src6']) +env.Java(target='class1', source='com/sub/foo') +env.Java(target='class2', source='com/sub/bar') +env.Java(target='class3', source=['src1', 'src2']) +env.Java(target='class4', source=['src4']) +env.Java(target='class5', source=['src5']) +env.Java(target='class6', source=['src6']) diff --git a/test/Java/java_version_image/com/sub/bar/Example4.java b/test/Java/java_version_image/com/sub/bar/Example4.java index 0748d54..f27b16c 100644 --- a/test/Java/java_version_image/com/sub/bar/Example4.java +++ b/test/Java/java_version_image/com/sub/bar/Example4.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + package com.sub.bar; public class Example4 diff --git a/test/Java/java_version_image/com/sub/bar/Example5.java b/test/Java/java_version_image/com/sub/bar/Example5.java index 69d2937..de6d765 100644 --- a/test/Java/java_version_image/com/sub/bar/Example5.java +++ b/test/Java/java_version_image/com/sub/bar/Example5.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + package com.other; public class Example5 diff --git a/test/Java/java_version_image/com/sub/bar/Example6.java b/test/Java/java_version_image/com/sub/bar/Example6.java index 1811b80..85166d4 100644 --- a/test/Java/java_version_image/com/sub/bar/Example6.java +++ b/test/Java/java_version_image/com/sub/bar/Example6.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + package com.sub.bar; public class Example6 diff --git a/test/Java/java_version_image/com/sub/foo/Example1.java b/test/Java/java_version_image/com/sub/foo/Example1.java index 82aac2e..1ce4f84 100644 --- a/test/Java/java_version_image/com/sub/foo/Example1.java +++ b/test/Java/java_version_image/com/sub/foo/Example1.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + package com.sub.foo; public class Example1 diff --git a/test/Java/java_version_image/com/sub/foo/Example2.java b/test/Java/java_version_image/com/sub/foo/Example2.java index 6349ac9..9c9144d 100644 --- a/test/Java/java_version_image/com/sub/foo/Example2.java +++ b/test/Java/java_version_image/com/sub/foo/Example2.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + package com.other; public class Example2 diff --git a/test/Java/java_version_image/com/sub/foo/Example3.java b/test/Java/java_version_image/com/sub/foo/Example3.java index 092f0cd..962262a 100644 --- a/test/Java/java_version_image/com/sub/foo/Example3.java +++ b/test/Java/java_version_image/com/sub/foo/Example3.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + package com.sub.foo; public class Example3 diff --git a/test/Java/java_version_image/src1/Example7.java b/test/Java/java_version_image/src1/Example7.java index 80d94f2..b8304e8 100644 --- a/test/Java/java_version_image/src1/Example7.java +++ b/test/Java/java_version_image/src1/Example7.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + public class Example7 { diff --git a/test/Java/java_version_image/src2/Test.java b/test/Java/java_version_image/src2/Test.java index 6f224b0..c6606a2 100644 --- a/test/Java/java_version_image/src2/Test.java +++ b/test/Java/java_version_image/src2/Test.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + class Empty { } diff --git a/test/Java/java_version_image/src4/NestedExample.java b/test/Java/java_version_image/src4/NestedExample.java index 531f2e9..ac4edd5 100644 --- a/test/Java/java_version_image/src4/NestedExample.java +++ b/test/Java/java_version_image/src4/NestedExample.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + // import java.util.*; public class NestedExample diff --git a/test/Java/java_version_image/src5/TestSCons.java b/test/Java/java_version_image/src5/TestSCons.java index 46572c4..d169fd3 100644 --- a/test/Java/java_version_image/src5/TestSCons.java +++ b/test/Java/java_version_image/src5/TestSCons.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + class TestSCons { public static void main(String[] args) { Foo[] fooArray = new Foo[] { new Foo() }; diff --git a/test/Java/java_version_image/src6/TestSCons.java b/test/Java/java_version_image/src6/TestSCons.java index 1aeed2f..abf2077 100644 --- a/test/Java/java_version_image/src6/TestSCons.java +++ b/test/Java/java_version_image/src6/TestSCons.java @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + class test { test() diff --git a/test/LEX/lex_headerfile/spaced path/SConstruct b/test/LEX/lex_headerfile/spaced path/SConstruct index aa4aca0..2ec0ca8 100644 --- a/test/LEX/lex_headerfile/spaced path/SConstruct +++ b/test/LEX/lex_headerfile/spaced path/SConstruct @@ -1,2 +1,6 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + DefaultEnvironment(tools=[]) -SConscript("src/SConscript") \ No newline at end of file +SConscript("src/SConscript") diff --git a/test/LEX/lex_headerfile/spaced path/src/SConscript b/test/LEX/lex_headerfile/spaced path/src/SConscript index a3f4bfd..bbfc36e 100644 --- a/test/LEX/lex_headerfile/spaced path/src/SConscript +++ b/test/LEX/lex_headerfile/spaced path/src/SConscript @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + env = Environment(tools=['lex']) def make_header_path(env, target, source, for_signature): @@ -7,4 +11,4 @@ env.Replace(LEX_HEADER_FILE_GEN=make_header_path) env.Append(LEXFLAGS=['--header-file=$LEX_HEADER_FILE_GEN']) env.CFile(target=['#gen_src/lexer.c', '#gen_src/lexer.l.h'], source='lexer.l') -env.CFile(target=['#gen_src/lexer2.c', '#gen_src/lexer2.l.h'], source='lexer2.l') \ No newline at end of file +env.CFile(target=['#gen_src/lexer2.c', '#gen_src/lexer2.l.h'], source='lexer2.l') diff --git a/test/LINK/applelink_image/SConstruct_CurVers_CompatVers b/test/LINK/applelink_image/SConstruct_CurVers_CompatVers index 4a824d3..c92a979 100644 --- a/test/LINK/applelink_image/SConstruct_CurVers_CompatVers +++ b/test/LINK/applelink_image/SConstruct_CurVers_CompatVers @@ -1,13 +1,18 @@ - +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation vars = Variables(None, ARGUMENTS) vars.Add('SHLIBVERSION', 'Set the SHLIBVERSION', 0) vars.Add('APPLELINK_CURRENT_VERSION', 'Set APPLELINK_CURRENT_VERSION', 0) vars.Add('APPLELINK_COMPATIBILITY_VERSION', 'Set APPLELINK_COMPATIBILITY_VERSION', 0) vars.Add('APPLELINK_NO_CURRENT_VERSION', 'Set APPLELINK_NO_CURRENT_VERSION', 0) -vars.Add('APPLELINK_NO_COMPATIBILITY_VERSION', 'Set APPLELINK_NO_COMPATIBILITY_VERSION', 0) +vars.Add( + 'APPLELINK_NO_COMPATIBILITY_VERSION', 'Set APPLELINK_NO_COMPATIBILITY_VERSION', 0 +) -env = Environment(variables = vars, tools=['gcc', 'applelink']) +DefaultEnvironment(tools=[]) +env = Environment(variables=vars, tools=['gcc', 'applelink']) if env['APPLELINK_NO_CURRENT_VERSION'] == '0': env['APPLELINK_NO_CURRENT_VERSION'] = 0 @@ -15,21 +20,30 @@ if env['APPLELINK_NO_CURRENT_VERSION'] == '0': if env['APPLELINK_NO_COMPATIBILITY_VERSION'] == '0': env['APPLELINK_NO_COMPATIBILITY_VERSION'] = 0 - -print("SHLIBVERSION =[%s]"%env.get('SHLIBVERSION', False)) -print("APPLELINK_CURRENT_VERSION =[%s]"%env.get('APPLELINK_CURRENT_VERSION', False)) -print("APPLELINK_COMPATIBILITY_VERSION =[%s]"%env.get('APPLELINK_COMPATIBILITY_VERSION', False)) -print("APPLELINK_NO_CURRENT_VERSION =[%s]"%env.get('APPLELINK_NO_CURRENT_VERSION', False)) -print("APPLELINK_NO_COMPATIBILITY_VERSION=[%s]"%env.get('APPLELINK_NO_COMPATIBILITY_VERSION', False)) +print( + "SHLIBVERSION =[%s]" + % env.get('SHLIBVERSION', False) +) +print( + "APPLELINK_CURRENT_VERSION =[%s]" + % env.get('APPLELINK_CURRENT_VERSION', False) +) +print( + "APPLELINK_COMPATIBILITY_VERSION =[%s]" + % env.get('APPLELINK_COMPATIBILITY_VERSION', False) +) +print( + "APPLELINK_NO_CURRENT_VERSION =[%s]" + % env.get('APPLELINK_NO_CURRENT_VERSION', False) +) +print( + "APPLELINK_NO_COMPATIBILITY_VERSION=[%s]" + % env.get('APPLELINK_NO_COMPATIBILITY_VERSION', False) +) obj = env.SharedObject('foo.c') sl = env.SharedLibrary('foo', obj) sl2 = env.SharedLibrary('foo2', obj, SONAME='libfoo.4.dynlib') lm = env.LoadableModule('fool', obj) - -env.InstallVersionedLib(target='#/install', - source=sl) - -env.InstallVersionedLib(target='#/install', - source=lm) - +env.InstallVersionedLib(target='#/install', source=sl) +env.InstallVersionedLib(target='#/install', source=lm) diff --git a/test/LINK/applelink_image/SConstruct_gh2580 b/test/LINK/applelink_image/SConstruct_gh2580 index 79fd9d5..62255fa 100644 --- a/test/LINK/applelink_image/SConstruct_gh2580 +++ b/test/LINK/applelink_image/SConstruct_gh2580 @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + DefaultEnvironment(tools=[]) env = Environment(PLATFORM='darwin') env.Object( diff --git a/test/LINK/applelink_image/foo.c b/test/LINK/applelink_image/foo.c index a441953..5a53f5e 100644 --- a/test/LINK/applelink_image/foo.c +++ b/test/LINK/applelink_image/foo.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include #include int @@ -6,4 +10,4 @@ main(int argc, char *argv[]) argv[argc++] = "--"; printf("foo.c\n"); exit (0); -} \ No newline at end of file +} diff --git a/test/Libs/bug2903/SConstruct b/test/Libs/bug2903/SConstruct index 12919ce..4f701a4 100644 --- a/test/Libs/bug2903/SConstruct +++ b/test/Libs/bug2903/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +# # SConstruct for testing but #2903. # The test changes the lib name to make sure it rebuilds # when the name changes, even if the content of the lib is the same. @@ -5,9 +9,15 @@ # when other linker options change, and not when they don't. # (This doesn't specifically test LIBPATH, but there's a test for # that already.) -env=Environment() -libname=ARGUMENTS.get('libname', 'foo') +DefaultEnvironment(tools=[]) +env = Environment() +libname = ARGUMENTS.get('libname', 'foo') env.Append(SHLINKFLAGS=' $EXTRA_SHLINKFLAGS') -shlinkflags=ARGUMENTS.get('shlinkflags', '') -env.SharedLibrary('myshared', ['main.c'], - LIBS=[libname], LIBPATH='.', EXTRA_SHLINKFLAGS=shlinkflags) +shlinkflags = ARGUMENTS.get('shlinkflags', '') +env.SharedLibrary( + 'myshared', + ['main.c'], + LIBS=[libname], + LIBPATH='.', + EXTRA_SHLINKFLAGS=shlinkflags, +) diff --git a/test/Libs/bug2903/SConstruct-libs b/test/Libs/bug2903/SConstruct-libs index 1590062..6f57e13 100644 --- a/test/Libs/bug2903/SConstruct-libs +++ b/test/Libs/bug2903/SConstruct-libs @@ -1,5 +1,11 @@ -env=Environment() +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) +env = Environment() libfoo = env.SharedLibrary('foo', 'lib.c') env.InstallAs('${SHLIBPREFIX}bar${SHLIBSUFFIX}', libfoo[0]) -if len(libfoo) > 1: # on Windows, there's an import lib (also a .exp, but we don't want that) - env.InstallAs('${LIBPREFIX}bar${LIBSUFFIX}', libfoo[1]) +if len(libfoo) > 1: + # on Windows, there's an import lib (also a .exp, but we don't want that) + env.InstallAs('${LIBPREFIX}bar${LIBSUFFIX}', libfoo[1]) diff --git a/test/Libs/bug2903/lib.c b/test/Libs/bug2903/lib.c index 65f4cd2..2425c46 100644 --- a/test/Libs/bug2903/lib.c +++ b/test/Libs/bug2903/lib.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #ifdef _WIN32 __declspec(dllexport) #endif diff --git a/test/Libs/bug2903/main.c b/test/Libs/bug2903/main.c index a4b1ecc..e44ebd5 100644 --- a/test/Libs/bug2903/main.c +++ b/test/Libs/bug2903/main.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #ifdef _WIN32 __declspec(dllexport) #endif diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir.py b/test/MSVC/MSVC_BATCH-spaces-targetdir.py index 298e10e..9b11872 100644 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir.py +++ b/test/MSVC/MSVC_BATCH-spaces-targetdir.py @@ -1,11 +1,11 @@ -import TestSCons - +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +import TestSCons test = TestSCons.TestSCons() test.skip_if_not_msvc() - - test.dir_fixture('MSVC_BATCH-spaces-targetdir') -test.run() \ No newline at end of file +test.run() diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct b/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct index da8002b..025f9ee 100644 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct +++ b/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct @@ -1,8 +1,15 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os.path -env=Environment(MSVC_BATCH=True) +DefaultEnvironment(tools=[]) +env = Environment(MSVC_BATCH=True) -td='tar ge tdir' -VariantDir(td,'src') -env.Program(os.path.join(td,'test_program'), - [os.path.join(td,a) for a in ['a.c','b.c','c.c']]) +td = 'tar ge tdir' +VariantDir(td, 'src') +env.Program( + os.path.join(td, 'test_program'), + [os.path.join(td, a) for a in ['a.c', 'b.c', 'c.c']], +) diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c index 1741de8..9164729 100644 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c +++ b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include extern void myfuncb(); @@ -12,4 +16,4 @@ int main(int argc, char *argv[]) { myfunca(); myfuncb(); myfuncc(); -} \ No newline at end of file +} diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c index e03c5d0..51e92dd 100644 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c +++ b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c @@ -1,5 +1,9 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include void myfuncb() { printf("myfuncb\n"); -} \ No newline at end of file +} diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c index 1c262d3..fe9f203 100644 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c +++ b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c @@ -1,5 +1,9 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include void myfuncc() { printf("myfuncc\n"); -} \ No newline at end of file +} diff --git a/test/MSVC/MSVC_USE_SCRIPT_ARGS-fixture/SConstruct b/test/MSVC/MSVC_USE_SCRIPT_ARGS-fixture/SConstruct index 54d140e..cbdd8aa 100644 --- a/test/MSVC/MSVC_USE_SCRIPT_ARGS-fixture/SConstruct +++ b/test/MSVC/MSVC_USE_SCRIPT_ARGS-fixture/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os if 'SCONS_CACHE_MSVC_CONFIG' in os.environ: diff --git a/test/MSVC/VSWHERE-fixture/SConstruct b/test/MSVC/VSWHERE-fixture/SConstruct index 38dfb0b..c80693e 100644 --- a/test/MSVC/VSWHERE-fixture/SConstruct +++ b/test/MSVC/VSWHERE-fixture/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os import os.path @@ -9,6 +13,7 @@ for vw_path in VSWHERE_PATHS: # Allow normal detection logic to find vswhere.exe +DefaultEnvironment(tools=[]) env1=Environment() print("VSWHERE-detect=%s" % env1['VSWHERE']) diff --git a/test/MSVC/msvc_fixture/SConstruct b/test/MSVC/msvc_fixture/SConstruct index af916dc..dd499ae 100644 --- a/test/MSVC/msvc_fixture/SConstruct +++ b/test/MSVC/msvc_fixture/SConstruct @@ -1,4 +1,8 @@ -# msvc_fixture's SConstruct +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +"""msvc_fixture's SConstruct""" DefaultEnvironment(tools=[]) # TODO: this is order-dependent (putting 'mssdk' second or third breaks), diff --git a/test/MSVC/msvc_fixture/StdAfx.cpp b/test/MSVC/msvc_fixture/StdAfx.cpp index a6a290b..caba43c 100644 --- a/test/MSVC/msvc_fixture/StdAfx.cpp +++ b/test/MSVC/msvc_fixture/StdAfx.cpp @@ -1,4 +1,8 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include "StdAfx.h" #ifndef PCHDEF this line generates an error if PCHDEF is not defined! -#endif \ No newline at end of file +#endif diff --git a/test/MSVC/msvc_fixture/StdAfx.h b/test/MSVC/msvc_fixture/StdAfx.h index a92d7df..9e0a9a1 100644 --- a/test/MSVC/msvc_fixture/StdAfx.h +++ b/test/MSVC/msvc_fixture/StdAfx.h @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include #include -#include "resource.h" \ No newline at end of file +#include "resource.h" diff --git a/test/MSVC/msvc_fixture/foo.cpp b/test/MSVC/msvc_fixture/foo.cpp index 09f15b6..6b92848 100644 --- a/test/MSVC/msvc_fixture/foo.cpp +++ b/test/MSVC/msvc_fixture/foo.cpp @@ -1 +1,5 @@ -#include "StdAfx.h" \ No newline at end of file +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + +#include "StdAfx.h" diff --git a/test/MSVC/msvc_fixture/resource.h b/test/MSVC/msvc_fixture/resource.h index 089e932..fef9b5b 100644 --- a/test/MSVC/msvc_fixture/resource.h +++ b/test/MSVC/msvc_fixture/resource.h @@ -1 +1,5 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #define IDS_TEST 2001 diff --git a/test/MSVC/msvc_fixture/test.cpp b/test/MSVC/msvc_fixture/test.cpp index 354b5f1..edb2ef5 100644 --- a/test/MSVC/msvc_fixture/test.cpp +++ b/test/MSVC/msvc_fixture/test.cpp @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include "StdAfx.h" #include "resource.h" @@ -7,4 +11,4 @@ int main(void) LoadString(GetModuleHandle(NULL), IDS_TEST, test, sizeof(test)); printf("%d %s\n", IDS_TEST, test); return 0; -} \ No newline at end of file +} diff --git a/test/MSVC/pch_gen/fixture/SConstruct b/test/MSVC/pch_gen/fixture/SConstruct index ab63cd6..2d91925 100644 --- a/test/MSVC/pch_gen/fixture/SConstruct +++ b/test/MSVC/pch_gen/fixture/SConstruct @@ -1,43 +1,45 @@ -# pch_gen fixture's SConstruct +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +"""pch_gen fixture's SConstruct""" DefaultEnvironment(tools=[]) # TODO: this is order-dependent (putting 'mssdk' second or third breaks), # and ideally we shouldn't need to specify the tools= list anyway. - -VariantDir('output1','src') -VariantDir('output2','src') - +VariantDir('output1', 'src') +VariantDir('output2', 'src') # Add flag to cause pch_gen to return empty string # This will enable testing that PCH if subst'd yields empty string will stop # PCH from being enabled. vars = Variables(None, ARGUMENTS) -vars.AddVariables(BoolVariable("DISABLE_PCH", help="Disable PCH functionality", default=False)) - +vars.AddVariables( + BoolVariable("DISABLE_PCH", help="Disable PCH functionality", default=False) +) env = Environment(variables=vars, tools=["mssdk", "msvc", "mslink"]) env.Append(CCFLAGS="/DPCHDEF") env["PDB"] = File("output1/test.pdb") env["PCHSTOP"] = "StdAfx.h" - def pch_gen(env, target, source, for_signature): if env['DISABLE_PCH']: return "" else: return "StdAfx-1.pch" - env["PCH"] = pch_gen env.PCH("output1/StdAfx-1.pch", "output1/StdAfx.cpp") -env.Program("output1/test", ["output1/test.cpp", env.RES("output1/test.rc")], LIBS=["user32"]) +env.Program( + "output1/test", + ["output1/test.cpp", env.RES("output1/test.rc")], + LIBS=["user32"], +) env.Object("output1/fast", "output1/foo.cpp") env.Object("output1/slow", "output1/foo.cpp", PCH=0) - - - env2 = env.Clone() def pch_gen2(env, target, source, for_signature): @@ -45,9 +47,13 @@ def pch_gen2(env, target, source, for_signature): return "" else: return env.get('PCH_NODE') + env2["PDB"] = File("output2/test.pdb") env2["PCHSTOP"] = "StdAfx.h" env2["PCH"] = pch_gen2 env2['PCH_NODE'] = env2.PCH("output2/StdAfx-1.pch", "output2/StdAfx.cpp")[0] -env2.Program("output2/test", ["output2/test.cpp", env.RES("output2/test.rc")], LIBS=["user32"]) - +env2.Program( + "output2/test", + ["output2/test.cpp", env.RES("output2/test.rc")], + LIBS=["user32"], +) diff --git a/test/MinGW/bug_2799/SConstruct b/test/MinGW/bug_2799/SConstruct index f22cacc..00606ee 100644 --- a/test/MinGW/bug_2799/SConstruct +++ b/test/MinGW/bug_2799/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment( tools=['mingw'], SHCCCOMSTR='SHCC $TARGET', @@ -8,7 +13,5 @@ env = Environment( SHLIBPREFIX='lib', LDMODULESUFFIX='.so', ) - env.SharedLibrary('testlib', 'shlib.c') - env.LoadableModule('testmodule', 'module.c') diff --git a/test/MinGW/bug_2799/module.c b/test/MinGW/bug_2799/module.c index 3cf5ace..31703f0 100644 --- a/test/MinGW/bug_2799/module.c +++ b/test/MinGW/bug_2799/module.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + extern void bar(void) { } diff --git a/test/MinGW/bug_2799/shlib.c b/test/MinGW/bug_2799/shlib.c index efe6b3f..f942e9f 100644 --- a/test/MinGW/bug_2799/shlib.c +++ b/test/MinGW/bug_2799/shlib.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + extern int foo(void) { return 0; diff --git a/test/Parallel/failed-build/fixture/SConstruct b/test/Parallel/failed-build/fixture/SConstruct index 21109fe..6236aa6 100644 --- a/test/Parallel/failed-build/fixture/SConstruct +++ b/test/Parallel/failed-build/fixture/SConstruct @@ -1,12 +1,19 @@ -import sys +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os +import random +import sys import threading -import random +from teststate import server_thread + PORT = random.randint(10000, 60000) sys.path.append(os.getcwd()) -from teststate import server_thread + +DefaultEnvironment(tools=[]) # this thread will setup a sever for the different tasks to talk to # and act as a manager of IPC and the different tasks progressing @@ -21,4 +28,4 @@ env = Environment(BUILDERS={'MyCopy' : MyCopy, 'Fail' : Fail}) env.Fail(target='f3', source='f3.in') env.MyCopy(target='f4', source='f4.in') env.MyCopy(target='f5', source='f5.in') -env.MyCopy(target='f6', source='f6.in') \ No newline at end of file +env.MyCopy(target='f6', source='f6.in') diff --git a/test/Parallel/failed-build/fixture/mycopy.py b/test/Parallel/failed-build/fixture/mycopy.py index 97c8e88..3826d87 100644 --- a/test/Parallel/failed-build/fixture/mycopy.py +++ b/test/Parallel/failed-build/fixture/mycopy.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os import sys import time @@ -32,4 +36,4 @@ if count >= WAIT: sys.exit(99) conn.close() -sys.exit(0) \ No newline at end of file +sys.exit(0) diff --git a/test/Parallel/failed-build/fixture/myfail.py b/test/Parallel/failed-build/fixture/myfail.py index bd54d44..4c6a8ab 100644 --- a/test/Parallel/failed-build/fixture/myfail.py +++ b/test/Parallel/failed-build/fixture/myfail.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os import sys import time @@ -28,4 +32,4 @@ if count >= WAIT: conn.request("GET", "/?set_myfail_done=1&pid=" + str(os.getpid())) conn.close() -sys.exit(1) \ No newline at end of file +sys.exit(1) diff --git a/test/Parallel/failed-build/fixture/teststate.py b/test/Parallel/failed-build/fixture/teststate.py index d02957e..8499720 100644 --- a/test/Parallel/failed-build/fixture/teststate.py +++ b/test/Parallel/failed-build/fixture/teststate.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import http.server import socketserver import time @@ -87,4 +91,4 @@ def server_thread(PORT): return httpd = socketserver.TCPServer(("127.0.0.1", PORT), S) - httpd.serve_forever() \ No newline at end of file + httpd.serve_forever() diff --git a/test/Progress/multi_target_fixture/SConstruct b/test/Progress/multi_target_fixture/SConstruct index 5a16f05..9a5ed11 100644 --- a/test/Progress/multi_target_fixture/SConstruct +++ b/test/Progress/multi_target_fixture/SConstruct @@ -1,15 +1,20 @@ -import SCons +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +import SCons class ProgressTest: - def __call__(self, node): if node.get_state() == SCons.Node.executing: print(node) - +DefaultEnvironment(tools=[]) env = Environment(tools=[]) -env.Command(target=['out1.txt', 'out2.txt'], source=['in.txt'], action=Action( - 'echo $SOURCE > ${TARGETS[0]};echo $SOURCE > ${TARGETS[1]}', None)) +env.Command( + target=['out1.txt', 'out2.txt'], + source=['in.txt'], + action=Action('echo $SOURCE > ${TARGETS[0]};echo $SOURCE > ${TARGETS[1]}', None), +) Progress(ProgressTest()) diff --git a/test/SConscript/fixture/SConstruct b/test/SConscript/fixture/SConstruct index a955efc..aec868e 100644 --- a/test/SConscript/fixture/SConstruct +++ b/test/SConscript/fixture/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons from SCons.Warnings import _warningOut import sys diff --git a/test/SConscript/must_exist_deprecation.py b/test/SConscript/must_exist_deprecation.py index eaa0c42..4c1db12 100644 --- a/test/SConscript/must_exist_deprecation.py +++ b/test/SConscript/must_exist_deprecation.py @@ -44,7 +44,7 @@ warnmsg = """ scons: warning: Calling missing SConscript without error is deprecated. Transition by adding must_exist=False to SConscript calls. Missing SConscript '{}' -""".format(missing) + test.python_file_line(SConstruct_path, 14) +""".format(missing) + test.python_file_line(SConstruct_path, 18) expect_stderr = warnmsg test.run(arguments=".", stderr=expect_stderr) diff --git a/test/Scanner/Python/SConstruct b/test/Scanner/Python/SConstruct index 988cf60..6a3fd05 100644 --- a/test/Scanner/Python/SConstruct +++ b/test/Scanner/Python/SConstruct @@ -1,5 +1,10 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys +DefaultEnvironment(tools=[]) env = Environment(tools=['python']) # Copy each file individually instead of copying the dir. This has the benefit @@ -13,4 +18,4 @@ for srcNode in srcDir.glob('*'): # Don't set a dependency on the copy actions on purpose. Scanner should find # the dependencies automatically. -env.Command('a.out', 'script.py', '$PYTHON $SOURCE $TARGET', PYTHON=sys.executable) \ No newline at end of file +env.Command('a.out', 'script.py', '$PYTHON $SOURCE $TARGET', PYTHON=sys.executable) diff --git a/test/Scanner/Python/script.py b/test/Scanner/Python/script.py index 105a575..e51ec41 100644 --- a/test/Scanner/Python/script.py +++ b/test/Scanner/Python/script.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import package1 # noqa: F401 import package2 # noqa: F401 import sys diff --git a/test/Scanner/Python/to_be_copied/__init__.py b/test/Scanner/Python/to_be_copied/__init__.py index 3c1c05b..bd9464c 100644 --- a/test/Scanner/Python/to_be_copied/__init__.py +++ b/test/Scanner/Python/to_be_copied/__init__.py @@ -1 +1,5 @@ -from . import helper # noqa: F401 \ No newline at end of file +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +from . import helper # noqa: F401 diff --git a/test/SideEffect/Issues/3013/files/SConscript b/test/SideEffect/Issues/3013/files/SConscript index 27da7bb..53cfcdc 100644 --- a/test/SideEffect/Issues/3013/files/SConscript +++ b/test/SideEffect/Issues/3013/files/SConscript @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + Import('env') primary = env.make_file('output', 'test.cpp') diff --git a/test/SideEffect/Issues/3013/files/SConstruct b/test/SideEffect/Issues/3013/files/SConstruct index d01a4b7..9294cb0 100644 --- a/test/SideEffect/Issues/3013/files/SConstruct +++ b/test/SideEffect/Issues/3013/files/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment() def make_file(target, source, env): diff --git a/test/SideEffect/Issues/3013/files/test.cpp b/test/SideEffect/Issues/3013/files/test.cpp index 27424b0..94e2cad 100644 --- a/test/SideEffect/Issues/3013/files/test.cpp +++ b/test/SideEffect/Issues/3013/files/test.cpp @@ -1,2 +1,6 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + void some_function() {} diff --git a/test/Subst/fixture/SConstruct.callable_exception b/test/Subst/fixture/SConstruct.callable_exception index 3f1b337..1c1b952 100644 --- a/test/Subst/fixture/SConstruct.callable_exception +++ b/test/Subst/fixture/SConstruct.callable_exception @@ -1,11 +1,17 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + class TestCallable(object): def __init__(self, thing, makePathsRelative = True, debug = False): pass + def __call__(self, target, source, env, for_signature): raise TypeError("User callable exception") +DefaultEnvironment(tools=[]) env = Environment() env["TESTCLASS"] = TestCallable env["CCCOM"] = "$CC $_CCCOMCOM $CCFLAGS -o ${TESTCLASS('$TARGET')} -c ${TESTCLASS('$SOURCES')}" -env.Program(target='test_main', source='test_main.c') \ No newline at end of file +env.Program(target='test_main', source='test_main.c') diff --git a/test/TEMPFILE/fixture/SConstruct-tempfile-actionlist b/test/TEMPFILE/fixture/SConstruct-tempfile-actionlist index 07b6345..8d2069b 100644 --- a/test/TEMPFILE/fixture/SConstruct-tempfile-actionlist +++ b/test/TEMPFILE/fixture/SConstruct-tempfile-actionlist @@ -1,6 +1,14 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + DefaultEnvironment(tools=[]) -env = Environment(tools=[], - BUILDCOM=['${TEMPFILE("xxx.py -otempfile $SOURCE")}', - '${TEMPFILE("yyy.py -o$TARGET tempfile")}'], - MAXLINELENGTH=1) +env = Environment( + tools=[], + BUILDCOM=[ + '${TEMPFILE("xxx.py -otempfile $SOURCE")}', + '${TEMPFILE("yyy.py -o$TARGET tempfile")}', + ], + MAXLINELENGTH=1, +) env.Command('file.output', 'file.input', '$BUILDCOM') diff --git a/test/TEMPFILE/fixture/SConstruct.tempfiledir b/test/TEMPFILE/fixture/SConstruct.tempfiledir index ea26c27..0e45b7f 100644 --- a/test/TEMPFILE/fixture/SConstruct.tempfiledir +++ b/test/TEMPFILE/fixture/SConstruct.tempfiledir @@ -1,7 +1,12 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os my_temp_dir = os.path.join(os.getcwd(), 'my_temp_files') +DefaultEnvironment(tools=[]) env = Environment( BUILDCOM='${TEMPFILE("xxx.py $TARGET $SOURCES")}', MAXLINELENGTH=16, diff --git a/test/TaskMaster/bug_2811/fixture_dir/SConstruct b/test/TaskMaster/bug_2811/fixture_dir/SConstruct index d453368..1f8c364 100644 --- a/test/TaskMaster/bug_2811/fixture_dir/SConstruct +++ b/test/TaskMaster/bug_2811/fixture_dir/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ This issue requires the following. 1. Generated source file which outputs 2 (or more) files @@ -29,17 +33,12 @@ def _dwo_emitter(target, source, env): return (targets, source) build_string = '$MYCOPY $SOURCE $TARGET' - - bld = Builder(action=build_string) +DefaultEnvironment(tools=[]) env = Environment(BUILDERS={'Foo': bld}, MYCOPY="%s mycopy.py"%sys.executable) - env['SHCCCOM'] = '$MYCOPY $SOURCE $TARGET && $MYCOPY $SOURCE ${TARGETS[1]}' - env['SHCCCOMSTR'] = env['SHCCCOM'] - - suffixes = ['.c'] for object_builder in SCons.Tool.createObjBuilders(env): @@ -63,4 +62,4 @@ env.Foo('b','b.in') # seems like processing is always alphabetical.. -# code: language=python insertSpaces=4 tabSize=4 \ No newline at end of file +# code: language=python insertSpaces=4 tabSize=4 diff --git a/test/TaskMaster/bug_2811/fixture_dir/mycopy.py b/test/TaskMaster/bug_2811/fixture_dir/mycopy.py index c1a57f5..3e4f7c0 100644 --- a/test/TaskMaster/bug_2811/fixture_dir/mycopy.py +++ b/test/TaskMaster/bug_2811/fixture_dir/mycopy.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys import shutil diff --git a/test/YACC/YACC-fixture/SConstruct_YACC_before b/test/YACC/YACC-fixture/SConstruct_YACC_before index 94f7adf..78ca5db 100644 --- a/test/YACC/YACC-fixture/SConstruct_YACC_before +++ b/test/YACC/YACC-fixture/SConstruct_YACC_before @@ -1,4 +1,9 @@ -env=Environment(tools=[]) -env2=env.Clone(YACC="SOMETHING_DUMB") +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) +env = Environment(tools=[]) +env2 = env.Clone(YACC="SOMETHING_DUMB") env2.Tool('yacc') env2.CFile('aaa.y') diff --git a/test/YACC/YACC-fixture/myyacc.py b/test/YACC/YACC-fixture/myyacc.py index 77f80ea..5027122 100644 --- a/test/YACC/YACC-fixture/myyacc.py +++ b/test/YACC/YACC-fixture/myyacc.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import getopt import sys diff --git a/test/YACC/YACCFLAGS-fixture/myyacc.py b/test/YACC/YACCFLAGS-fixture/myyacc.py index 3bc1375..6558f07 100644 --- a/test/YACC/YACCFLAGS-fixture/myyacc.py +++ b/test/YACC/YACCFLAGS-fixture/myyacc.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import getopt import sys from pathlib import Path diff --git a/test/fixture/SConstruct-check-valid-options b/test/fixture/SConstruct-check-valid-options index 53bdf89..9e7c990 100644 --- a/test/fixture/SConstruct-check-valid-options +++ b/test/fixture/SConstruct-check-valid-options @@ -5,6 +5,8 @@ import sys from SCons.Script.SConsOptions import SConsOptionParser, SConsBadOptionError +DefaultEnvironment(tools=[]) + AddOption( '--testing', help='Test arg', diff --git a/test/fixture/SConstruct_test_main.py b/test/fixture/SConstruct_test_main.py index 8d2d2b0..aa4284d 100644 --- a/test/fixture/SConstruct_test_main.py +++ b/test/fixture/SConstruct_test_main.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + DefaultEnvironment(tools=[]) env = Environment() env.Program('main.exe', ['main.c']) diff --git a/test/fixture/echo.py b/test/fixture/echo.py index a13f2ca..3f685c2 100755 --- a/test/fixture/echo.py +++ b/test/fixture/echo.py @@ -1,2 +1,6 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys print(sys.argv) diff --git a/test/fixture/mycompile.py b/test/fixture/mycompile.py index 15a1c6f..d858f6a 100644 --- a/test/fixture/mycompile.py +++ b/test/fixture/mycompile.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ Phony compiler for testing SCons. diff --git a/test/fixture/mygcc.py b/test/fixture/mygcc.py index 91ca386..146e596 100644 --- a/test/fixture/mygcc.py +++ b/test/fixture/mygcc.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ Phony compiler for testing SCons. diff --git a/test/fixture/mylex.py b/test/fixture/mylex.py index b5e94b1..9c9417e 100644 --- a/test/fixture/mylex.py +++ b/test/fixture/mylex.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ Phony lex for testing SCons. diff --git a/test/fixture/mylink.py b/test/fixture/mylink.py index f462655..abe22ae 100644 --- a/test/fixture/mylink.py +++ b/test/fixture/mylink.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ Phony linker for testing SCons. diff --git a/test/fixture/myrewrite.py b/test/fixture/myrewrite.py index eb83cac..f331558 100644 --- a/test/fixture/myrewrite.py +++ b/test/fixture/myrewrite.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + r""" Phony tool to modify a file in place for testing SCons. diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct.py b/test/fixture/no_msvc/no_msvcs_sconstruct.py index 18366d8..1aed9ec 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct.py @@ -1,15 +1,21 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons import SCons.Tool.MSCommon +DefaultEnvironment(tools=[]) + def DummyVsWhere(msvc_version, env): # not testing versions with vswhere, so return none return None for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: - SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key]=[(SCons.Util.HKEY_LOCAL_MACHINE, r'')] + SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key] = [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'') + ] SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere - env = SCons.Environment.Environment() - -print('MSVC_VERSION='+str(env.get('MSVC_VERSION'))) \ No newline at end of file +print('MSVC_VERSION=' + str(env.get('MSVC_VERSION'))) diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_query_toolset_version.py b/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_query_toolset_version.py index 8e3c65f..fc5558b 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_query_toolset_version.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_query_toolset_version.py @@ -1,15 +1,21 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons import SCons.Tool.MSCommon +DefaultEnvironment(tools=[]) + def DummyVsWhere(msvc_version, env): # not testing versions with vswhere, so return none return None for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: - SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key]=[(SCons.Util.HKEY_LOCAL_MACHINE, r'')] + SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key] = [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'') + ] SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere - msvc_version, msvc_toolset_version = SCons.Tool.MSCommon.msvc_query_version_toolset() - -print('msvc_version={}, msvc_toolset_version={}'.format(repr(msvc_version), repr(msvc_toolset_version))) \ No newline at end of file +print(f'msvc_version={msvc_version!r}, msvc_toolset_version={msvc_toolset_version!r}') diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_sdk_versions.py b/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_sdk_versions.py index 7953ce6..6e7562d 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_sdk_versions.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_sdk_versions.py @@ -1,15 +1,21 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons import SCons.Tool.MSCommon +DefaultEnvironment(tools=[]) + def DummyVsWhere(msvc_version, env): # not testing versions with vswhere, so return none return None for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: - SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key]=[(SCons.Util.HKEY_LOCAL_MACHINE, r'')] + SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key] = [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'') + ] SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere - sdk_version_list = SCons.Tool.MSCommon.msvc_sdk_versions() - -print('sdk_version_list='+repr(sdk_version_list)) +print('sdk_version_list=' + repr(sdk_version_list)) diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_toolset_versions.py b/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_toolset_versions.py index fd209fd..c2208cd 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_toolset_versions.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct_msvc_toolset_versions.py @@ -1,15 +1,21 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons import SCons.Tool.MSCommon +DefaultEnvironment(tools=[]) + def DummyVsWhere(msvc_version, env): # not testing versions with vswhere, so return none return None for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: - SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key]=[(SCons.Util.HKEY_LOCAL_MACHINE, r'')] + SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key] = [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'') + ] SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere - toolset_version_list = SCons.Tool.MSCommon.msvc_toolset_versions() - -print('toolset_version_list='+repr(toolset_version_list)) +print('toolset_version_list=' + repr(toolset_version_list)) diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py b/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py index 9aa924b..2f2f07a 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py @@ -1,14 +1,21 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons import SCons.Tool.MSCommon +DefaultEnvironment(tools=[]) + def DummyVsWhere(msvc_version, env): # not testing versions with vswhere, so return none return None for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: - SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key]=[(SCons.Util.HKEY_LOCAL_MACHINE, r'')] + SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key] = [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'') + ] SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere - env = SCons.Environment.Environment(tools=['myignoredefaultmsvctool']) diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct_version.py b/test/fixture/no_msvc/no_msvcs_sconstruct_version.py index b586d6c..bd81688 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct_version.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct_version.py @@ -1,19 +1,21 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons import SCons.Tool.MSCommon +DefaultEnvironment(tools=[]) def DummyVsWhere(msvc_version, env): # not testing versions with vswhere, so return none return None - for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: - SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key]=[(SCons.Util.HKEY_LOCAL_MACHINE, r'')] + SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key] = [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'') + ] SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere - SCons.Tool.MSCommon.msvc_set_notfound_policy('error') - env = SCons.Environment.Environment(MSVC_VERSION='14.3') - - diff --git a/test/fixture/no_msvc/no_regs_sconstruct.py b/test/fixture/no_msvc/no_regs_sconstruct.py index 3eeca94..9dcc7a8 100644 --- a/test/fixture/no_msvc/no_regs_sconstruct.py +++ b/test/fixture/no_msvc/no_regs_sconstruct.py @@ -1,7 +1,15 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons import SCons.Tool.MSCommon +DefaultEnvironment(tools=[]) + for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: - SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key]=[(SCons.Util.HKEY_LOCAL_MACHINE, r'')] + SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key] = [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'') + ] -env = SCons.Environment.Environment() \ No newline at end of file +env = SCons.Environment.Environment() diff --git a/test/fixture/python_scanner/curdir_reference/script.py b/test/fixture/python_scanner/curdir_reference/script.py index d533863..280e41a 100644 --- a/test/fixture/python_scanner/curdir_reference/script.py +++ b/test/fixture/python_scanner/curdir_reference/script.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from . import helper diff --git a/test/fixture/python_scanner/from_import_simple_package_module1.py b/test/fixture/python_scanner/from_import_simple_package_module1.py index dcc86de..ab03709 100644 --- a/test/fixture/python_scanner/from_import_simple_package_module1.py +++ b/test/fixture/python_scanner/from_import_simple_package_module1.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from simple_package import module1 diff --git a/test/fixture/python_scanner/from_import_simple_package_module1_as.py b/test/fixture/python_scanner/from_import_simple_package_module1_as.py index 51061c6..ee97737 100644 --- a/test/fixture/python_scanner/from_import_simple_package_module1_as.py +++ b/test/fixture/python_scanner/from_import_simple_package_module1_as.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from simple_package import module1 as m1 diff --git a/test/fixture/python_scanner/from_import_simple_package_module1_func.py b/test/fixture/python_scanner/from_import_simple_package_module1_func.py index e9877fb..5ee6920 100644 --- a/test/fixture/python_scanner/from_import_simple_package_module1_func.py +++ b/test/fixture/python_scanner/from_import_simple_package_module1_func.py @@ -1 +1,5 @@ -from simple_package.module1 import somefunc # noqa: F401 \ No newline at end of file +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +from simple_package.module1 import somefunc # noqa: F401 diff --git a/test/fixture/python_scanner/from_import_simple_package_modules_no_space.py b/test/fixture/python_scanner/from_import_simple_package_modules_no_space.py index 17b82f8..5560dc8 100644 --- a/test/fixture/python_scanner/from_import_simple_package_modules_no_space.py +++ b/test/fixture/python_scanner/from_import_simple_package_modules_no_space.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from simple_package import module1,module2 diff --git a/test/fixture/python_scanner/from_import_simple_package_modules_with_space.py b/test/fixture/python_scanner/from_import_simple_package_modules_with_space.py index 169e6f7..7c13d22 100644 --- a/test/fixture/python_scanner/from_import_simple_package_modules_with_space.py +++ b/test/fixture/python_scanner/from_import_simple_package_modules_with_space.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from simple_package import module1, module2 diff --git a/test/fixture/python_scanner/from_nested1_import_multiple.py b/test/fixture/python_scanner/from_nested1_import_multiple.py index 2cdd47f..0a75bd8 100644 --- a/test/fixture/python_scanner/from_nested1_import_multiple.py +++ b/test/fixture/python_scanner/from_nested1_import_multiple.py @@ -1 +1,5 @@ -from nested1 import module, nested2 # noqa: F401 \ No newline at end of file +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +from nested1 import module, nested2 # noqa: F401 diff --git a/test/fixture/python_scanner/import_simple_package_module1.py b/test/fixture/python_scanner/import_simple_package_module1.py index bd85010..1bd2fca 100644 --- a/test/fixture/python_scanner/import_simple_package_module1.py +++ b/test/fixture/python_scanner/import_simple_package_module1.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import simple_package.module1 diff --git a/test/fixture/python_scanner/import_simple_package_module1_as.py b/test/fixture/python_scanner/import_simple_package_module1_as.py index a706672..25da8a9 100644 --- a/test/fixture/python_scanner/import_simple_package_module1_as.py +++ b/test/fixture/python_scanner/import_simple_package_module1_as.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import simple_package.module1 as m1 diff --git a/test/fixture/python_scanner/imports_nested3.py b/test/fixture/python_scanner/imports_nested3.py index c2929d0..4929cbd 100644 --- a/test/fixture/python_scanner/imports_nested3.py +++ b/test/fixture/python_scanner/imports_nested3.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import nested1.nested2.nested3 diff --git a/test/fixture/python_scanner/imports_simple_package.py b/test/fixture/python_scanner/imports_simple_package.py index d974128..059dd6e 100644 --- a/test/fixture/python_scanner/imports_simple_package.py +++ b/test/fixture/python_scanner/imports_simple_package.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import simple_package diff --git a/test/fixture/python_scanner/imports_unknown_files.py b/test/fixture/python_scanner/imports_unknown_files.py index 5582e7b..0bfc401 100644 --- a/test/fixture/python_scanner/imports_unknown_files.py +++ b/test/fixture/python_scanner/imports_unknown_files.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import doesntexist # noqa: F401 import notthere.something # noqa: F401 -from notthere import a, few, things # noqa: F401 \ No newline at end of file +from notthere import a, few, things # noqa: F401 diff --git a/test/fixture/python_scanner/nested1/nested2/nested3/imports_grandparent_module.py b/test/fixture/python_scanner/nested1/nested2/nested3/imports_grandparent_module.py index 06bb7f5..e952aef 100644 --- a/test/fixture/python_scanner/nested1/nested2/nested3/imports_grandparent_module.py +++ b/test/fixture/python_scanner/nested1/nested2/nested3/imports_grandparent_module.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from ... import module diff --git a/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_module.py b/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_module.py index be10279..9701e4d 100644 --- a/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_module.py +++ b/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_module.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from .. import module diff --git a/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_then_submodule.py b/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_then_submodule.py index 39f1a1a..cc629c0 100644 --- a/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_then_submodule.py +++ b/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_then_submodule.py @@ -1 +1,5 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from ...nested2a import module diff --git a/test/fixture/python_scanner/simple_package/module1.py b/test/fixture/python_scanner/simple_package/module1.py index 6880c47..1991088 100644 --- a/test/fixture/python_scanner/simple_package/module1.py +++ b/test/fixture/python_scanner/simple_package/module1.py @@ -1,2 +1,6 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def somefunc(): - return \ No newline at end of file + return diff --git a/test/fixture/test_main.c b/test/fixture/test_main.c index adbe919..e81a58b 100644 --- a/test/fixture/test_main.c +++ b/test/fixture/test_main.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + int main( int argc, char* argv[] ) { return 0; diff --git a/test/fixture/wrapper.py b/test/fixture/wrapper.py index c266cfa..05cea02 100644 --- a/test/fixture/wrapper.py +++ b/test/fixture/wrapper.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ Command wrapper, for testing SCons. diff --git a/test/fixture/wrapper_with_args.py b/test/fixture/wrapper_with_args.py index 769aea4..6621077 100644 --- a/test/fixture/wrapper_with_args.py +++ b/test/fixture/wrapper_with_args.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ Command wrapper taking arguments, for testing SCons. diff --git a/test/ninja/ninja-fixture/bar.c b/test/ninja/ninja-fixture/bar.c index 15b2ecc..cc7b901 100644 --- a/test/ninja/ninja-fixture/bar.c +++ b/test/ninja/ninja-fixture/bar.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include #include diff --git a/test/ninja/ninja-fixture/foo.c b/test/ninja/ninja-fixture/foo.c index ba35c68..8389085 100644 --- a/test/ninja/ninja-fixture/foo.c +++ b/test/ninja/ninja-fixture/foo.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include #include diff --git a/test/ninja/ninja-fixture/gen_source.c b/test/ninja/ninja-fixture/gen_source.c index 38ac3fe..dffaecc 100644 --- a/test/ninja/ninja-fixture/gen_source.c +++ b/test/ninja/ninja-fixture/gen_source.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include #include diff --git a/test/ninja/ninja-fixture/test1.c b/test/ninja/ninja-fixture/test1.c index 678461f..f2c28f7 100644 --- a/test/ninja/ninja-fixture/test1.c +++ b/test/ninja/ninja-fixture/test1.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include #include diff --git a/test/ninja/ninja-fixture/test2.cpp b/test/ninja/ninja-fixture/test2.cpp index 69b54c9..504956e 100644 --- a/test/ninja/ninja-fixture/test2.cpp +++ b/test/ninja/ninja-fixture/test2.cpp @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include "test2.hpp" int @@ -13,4 +17,4 @@ int Foo::print_function() { std::cout << "print_function"; return 0; -} \ No newline at end of file +} diff --git a/test/ninja/ninja-fixture/test_impl.c b/test/ninja/ninja-fixture/test_impl.c index ac3fd88..5f12306 100644 --- a/test/ninja/ninja-fixture/test_impl.c +++ b/test/ninja/ninja-fixture/test_impl.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + #include #include diff --git a/test/ninja/ninja_test_sconscripts/ninja_conftest b/test/ninja/ninja_test_sconscripts/ninja_conftest index 993972a..7549880 100644 --- a/test/ninja/ninja_test_sconscripts/ninja_conftest +++ b/test/ninja/ninja_test_sconscripts/ninja_conftest @@ -1,10 +1,13 @@ -SetOption('experimental','ninja') -DefaultEnvironment(tools=[]) +# MIT License +# +# Copyright The SCons Foundation import sys -env = Environment() +SetOption('experimental','ninja') +DefaultEnvironment(tools=[]) +env = Environment() conf = Configure(env) env.Tool('ninja') diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_control_c_ninja b/test/ninja/ninja_test_sconscripts/sconstruct_control_c_ninja index 34d7872..7fdcf29 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_control_c_ninja +++ b/test/ninja/ninja_test_sconscripts/sconstruct_control_c_ninja @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import os import signal diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_default_targets b/test/ninja/ninja_test_sconscripts/sconstruct_default_targets index 8963270..1a92be3 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_default_targets +++ b/test/ninja/ninja_test_sconscripts/sconstruct_default_targets @@ -1,12 +1,14 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons SetOption('experimental','ninja') DefaultEnvironment(tools=[]) env = Environment(tools=[]) - env.Tool('ninja') - env.Command('out1.txt', 'foo.c', 'echo test > $TARGET' ) out2_node = env.Command('out2.txt', 'foo.c', 'echo test > $TARGET', NINJA_FORCE_SCONS_BUILD=True) alias = env.Alias('def', out2_node) diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_force_scons_callback b/test/ninja/ninja_test_sconscripts/sconstruct_force_scons_callback index ef3562b..75a6dae 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_force_scons_callback +++ b/test/ninja/ninja_test_sconscripts/sconstruct_force_scons_callback @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + SetOption("experimental", "ninja") DefaultEnvironment(tools=[]) diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_generate_and_build b/test/ninja/ninja_test_sconscripts/sconstruct_generate_and_build index 81a4366..9769e15 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_generate_and_build +++ b/test/ninja/ninja_test_sconscripts/sconstruct_generate_and_build @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + SetOption('experimental','ninja') DefaultEnvironment(tools=[]) diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_generate_and_build_cxx b/test/ninja/ninja_test_sconscripts/sconstruct_generate_and_build_cxx index f7137df..c306b21 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_generate_and_build_cxx +++ b/test/ninja/ninja_test_sconscripts/sconstruct_generate_and_build_cxx @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + SetOption('experimental','ninja') DefaultEnvironment(tools=[]) env = Environment() diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_generated_sources_alias b/test/ninja/ninja_test_sconscripts/sconstruct_generated_sources_alias index 3661bcc..d8fcf09 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_generated_sources_alias +++ b/test/ninja/ninja_test_sconscripts/sconstruct_generated_sources_alias @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons SetOption('experimental','ninja') @@ -38,4 +42,4 @@ my_gen_alias, env.Textfile('generated_header2.c', [ 'int func2(){return func1();}' ]) -env.Program(target='gen_source', source=['gen_source.c', 'generated_header2.c']) \ No newline at end of file +env.Program(target='gen_source', source=['gen_source.c', 'generated_header2.c']) diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_mingw_command_generator_action b/test/ninja/ninja_test_sconscripts/sconstruct_mingw_command_generator_action index e3fcfe2..475fca7 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_mingw_command_generator_action +++ b/test/ninja/ninja_test_sconscripts/sconstruct_mingw_command_generator_action @@ -1,7 +1,11 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + SetOption('experimental','ninja') DefaultEnvironment(tools=[]) env = Environment(tools=['mingw']) env.Tool('ninja') dll = env.SharedLibrary(target='test_impl', source='test_impl.c') -env.Program(target='test', source='test1.c', LIBS=[dll]) \ No newline at end of file +env.Program(target='test', source='test1.c', LIBS=[dll]) diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_mingw_depfile_format b/test/ninja/ninja_test_sconscripts/sconstruct_mingw_depfile_format index b765db5..4a48ca6 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_mingw_depfile_format +++ b/test/ninja/ninja_test_sconscripts/sconstruct_mingw_depfile_format @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + SetOption('experimental','ninja') DefaultEnvironment(tools=[]) diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_ninja_command_line b/test/ninja/ninja_test_sconscripts/sconstruct_ninja_command_line index 4967912..ffd0d03 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_ninja_command_line +++ b/test/ninja/ninja_test_sconscripts/sconstruct_ninja_command_line @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + SetOption('experimental','ninja') DefaultEnvironment(tools=[]) diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_ninja_determinism b/test/ninja/ninja_test_sconscripts/sconstruct_ninja_determinism index 3d3eecb..a7982d4 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_ninja_determinism +++ b/test/ninja/ninja_test_sconscripts/sconstruct_ninja_determinism @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import random SetOption('experimental', 'ninja') diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_no_for_sig_subst b/test/ninja/ninja_test_sconscripts/sconstruct_no_for_sig_subst index 69f72b6..dda8d0d 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_no_for_sig_subst +++ b/test/ninja/ninja_test_sconscripts/sconstruct_no_for_sig_subst @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import SCons SetOption('experimental','ninja') diff --git a/test/ninja/ninja_test_sconscripts/sconstruct_response_file b/test/ninja/ninja_test_sconscripts/sconstruct_response_file index 6b7eb5d..c384054 100644 --- a/test/ninja/ninja_test_sconscripts/sconstruct_response_file +++ b/test/ninja/ninja_test_sconscripts/sconstruct_response_file @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + SetOption('experimental','ninja') DefaultEnvironment(tools=[]) @@ -12,4 +16,4 @@ env.Program(target='foo', source='foo.c', OBJSUFFIX=env['OBJSUFFIX'] + "1") env2 = env.Clone() env2.Append(CPPPATH='very/long/and/very/fake/path/for/testing') -env2.Program(target='foo2', source='foo.c', OBJSUFFIX=env['OBJSUFFIX'] + "2") \ No newline at end of file +env2.Program(target='foo2', source='foo.c', OBJSUFFIX=env['OBJSUFFIX'] + "2") diff --git a/test/option/fixture/SConstruct__experimental b/test/option/fixture/SConstruct__experimental index 2348b9a..d1e8fc7 100644 --- a/test/option/fixture/SConstruct__experimental +++ b/test/option/fixture/SConstruct__experimental @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from SCons.Script.SConsOptions import experimental_features print("All Features=%s" % ','.join(sorted(experimental_features))) diff --git a/test/option/fixture/SConstruct__taskmastertrace b/test/option/fixture/SConstruct__taskmastertrace index 91e8c91..eedd6fb 100644 --- a/test/option/fixture/SConstruct__taskmastertrace +++ b/test/option/fixture/SConstruct__taskmastertrace @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +# DefaultEnvironment(tools=[]) env = Environment(tools=[]) diff --git a/test/option/hash-format/SConstruct b/test/option/hash-format/SConstruct index de76e1b..44cab5a 100644 --- a/test/option/hash-format/SConstruct +++ b/test/option/hash-format/SConstruct @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import atexit import sys diff --git a/test/option/hash-format/build.py b/test/option/hash-format/build.py index 6b6baad..1d14042 100644 --- a/test/option/hash-format/build.py +++ b/test/option/hash-format/build.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys with open(sys.argv[1], 'wb') as f, open(sys.argv[2], 'rb') as infp: - f.write(infp.read()) \ No newline at end of file + f.write(infp.read()) diff --git a/test/packaging/convenience-functions/image/SConstruct b/test/packaging/convenience-functions/image/SConstruct index a424fd9..e11bff5 100644 --- a/test/packaging/convenience-functions/image/SConstruct +++ b/test/packaging/convenience-functions/image/SConstruct @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['default', 'packaging']) prog = env.Install( 'bin/', ["f1", "f2"] ) env.File( "f3" ) diff --git a/test/packaging/rpm/src/main.c b/test/packaging/rpm/src/main.c index 49e8969..cff3239 100644 --- a/test/packaging/rpm/src/main.c +++ b/test/packaging/rpm/src/main.c @@ -1,3 +1,7 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + int main( int argc, char* argv[] ) { diff --git a/test/packaging/sandbox-test/SConstruct b/test/packaging/sandbox-test/SConstruct index f44a471..c286d80 100644 --- a/test/packaging/sandbox-test/SConstruct +++ b/test/packaging/sandbox-test/SConstruct @@ -1,19 +1,27 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation from glob import glob -src_files = glob( 'src/*.c' ) -include_files = glob( 'src/*.h' ) +src_files = glob('src/*.c') +include_files = glob('src/*.h') -SharedLibrary( 'foobar', src_files ) +SharedLibrary('foobar', src_files) +DefaultEnvironment(tools=[]) env = Environment(tools=['default', 'packaging']) -env.Package( NAME = 'libfoobar', - VERSION = '1.2.3', - PACKAGETYPE = 'targz', - source = src_files + include_files ) +env.Package( + NAME='libfoobar', + VERSION='1.2.3', + PACKAGETYPE='targz', + source=src_files + include_files, +) -env.Package( NAME = 'libfoobar', - VERSION = '1.2.3', - PACKAGETYPE = 'zip', - source = src_files + include_files ) +env.Package( + NAME='libfoobar', + VERSION='1.2.3', + PACKAGETYPE='zip', + source=src_files + include_files, +) diff --git a/test/textfile/fixture/SConstruct b/test/textfile/fixture/SConstruct index b246687..8c3dc3b 100644 --- a/test/textfile/fixture/SConstruct +++ b/test/textfile/fixture/SConstruct @@ -1,5 +1,8 @@ -DefaultEnvironment(tools=[]) +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation +DefaultEnvironment(tools=[]) env = Environment(tools=['textfile']) data0 = ['Goethe', 'Schiller'] data = ['lalala', 42, data0, 'tanteratei', @@ -11,9 +14,11 @@ env.Textfile('foo1a.txt', data + ['']) env.Textfile('foo2a.txt', data + [''], LINESEPARATOR='|*') issue_4021_textfile = r'..\..\..\@HINT_PATH@\Datalogics.PDFL.dll' -env.Textfile('issue-4021.txt', issue_4021_textfile, - SUBST_DICT={'@HINT_PATH@': r'NETCore\bin\$$(Platform)\$$(Configuration)'}) - +env.Textfile( + 'issue-4021.txt', + issue_4021_textfile, + SUBST_DICT={'@HINT_PATH@': r'NETCore\bin\$$(Platform)\$$(Configuration)'}, +) # recreate the list with the data wrapped in Value() data0 = list(map(Value, data0)) data = list(map(Value, data)) diff --git a/test/textfile/fixture/SConstruct.2 b/test/textfile/fixture/SConstruct.2 index b7e63a1..6b5f02e 100644 --- a/test/textfile/fixture/SConstruct.2 +++ b/test/textfile/fixture/SConstruct.2 @@ -1,9 +1,14 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + DefaultEnvironment(tools=[]) -textlist = ['This line has no substitutions', - 'This line has @subst@ substitutions', - 'This line has %subst% substitutions', - ] +textlist = [ + 'This line has no substitutions', + 'This line has @subst@ substitutions', + 'This line has %subst% substitutions', +] sub1 = {'@subst@': 'most'} sub2 = {'%subst%': 'many'} diff --git a/test/textfile/fixture/SConstruct.issue-3540 b/test/textfile/fixture/SConstruct.issue-3540 index 021689a..04cccca 100644 --- a/test/textfile/fixture/SConstruct.issue-3540 +++ b/test/textfile/fixture/SConstruct.issue-3540 @@ -1,17 +1,16 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + """ Test for GH Issue 3540 textfile()'s action is not sensitive to changes in TEXTFILESUFFIX (rather was sensitive to SUBSTFILESUFFIX) - """ -DefaultEnvironment(tools=[]) - text_file_suffix = ARGUMENTS.get('text_file_suffix', 'DEFAULTSUFFIX') - -env = Environment(tools=['textfile'], - TEXTFILESUFFIX=text_file_suffix) - +DefaultEnvironment(tools=[]) +env = Environment(tools=['textfile'], TEXTFILESUFFIX=text_file_suffix) env['FOO_PATH'] = "test-value-1" foo = env.Substfile( @@ -19,5 +18,5 @@ foo = env.Substfile( source="substfile.in", SUBST_DICT={ "@foo_path@": "$FOO_PATH", - } + }, ) diff --git a/test/textfile/fixture/SConstruct.issue-3550 b/test/textfile/fixture/SConstruct.issue-3550 index 0239ade..b2708d4 100644 --- a/test/textfile/fixture/SConstruct.issue-3550 +++ b/test/textfile/fixture/SConstruct.issue-3550 @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + DefaultEnvironment(tools=[]) env = Environment(tools=['textfile']) diff --git a/test/textfile/fixture/SConstruct.issue-4037 b/test/textfile/fixture/SConstruct.issue-4037 index d5c8f96..44cc3ff 100644 --- a/test/textfile/fixture/SConstruct.issue-4037 +++ b/test/textfile/fixture/SConstruct.issue-4037 @@ -1,3 +1,8 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment() def generator(source, target, env, for_signature): @@ -9,10 +14,6 @@ env['GENERATOR'] = generator env.Textfile( target="target", - source=[ - "@generated@", - ], - SUBST_DICT={ - '@generated@' : '$GENERATOR', - }, + source=["@generated@"], + SUBST_DICT={'@generated@' : '$GENERATOR'}, ) diff --git a/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool1.py b/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool1.py index 1c024e1..670c942 100644 --- a/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool1.py +++ b/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool1.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool1'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/__init__.py b/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/__init__.py index 225b9aa..1a8d052 100644 --- a/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/__init__.py +++ b/test/toolpath/nested/image/Libs/tools_example/Toolpath_TestTool2/__init__.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool2'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_1.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_1.py index c266f89..96e681b 100644 --- a/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_1.py +++ b/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_1.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool1_1'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/__init__.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/__init__.py index f203260..e34618d 100644 --- a/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/__init__.py +++ b/test/toolpath/nested/image/Libs/tools_example/subdir1/Toolpath_TestTool1_2/__init__.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool1_2'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_1.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_1.py index b1b47a2..047ae78 100644 --- a/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_1.py +++ b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_1.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool2_1'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py index 407df86..d99e6c5 100644 --- a/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py +++ b/test/toolpath/nested/image/Libs/tools_example/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool2_2'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/SConstruct b/test/toolpath/nested/image/SConstruct index 7fac870..89f1041 100644 --- a/test/toolpath/nested/image/SConstruct +++ b/test/toolpath/nested/image/SConstruct @@ -1,39 +1,47 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys, os -toollist = ['Toolpath_TestTool1', - 'Toolpath_TestTool2', - 'subdir1.Toolpath_TestTool1_1', - 'subdir1.Toolpath_TestTool1_2', - 'subdir1.subdir2.Toolpath_TestTool2_1', - 'subdir1.subdir2.Toolpath_TestTool2_2', - ] +DefaultEnvironment(tools=[]) + +toollist = [ + 'Toolpath_TestTool1', + 'Toolpath_TestTool2', + 'subdir1.Toolpath_TestTool1_1', + 'subdir1.Toolpath_TestTool1_2', + 'subdir1.subdir2.Toolpath_TestTool2_1', + 'subdir1.subdir2.Toolpath_TestTool2_2', +] print('Test where tools are located under site_scons/site_tools') env1 = Environment(tools=toollist) -print("env1['Toolpath_TestTool1'] = %s"%env1.get('Toolpath_TestTool1')) -print("env1['Toolpath_TestTool2'] = %s"%env1.get('Toolpath_TestTool2')) -print("env1['Toolpath_TestTool1_1'] = %s"%env1.get('Toolpath_TestTool1_1')) -print("env1['Toolpath_TestTool1_2'] = %s"%env1.get('Toolpath_TestTool1_2')) -print("env1['Toolpath_TestTool2_1'] = %s"%env1.get('Toolpath_TestTool2_1')) -print("env1['Toolpath_TestTool2_2'] = %s"%env1.get('Toolpath_TestTool2_2')) +print("env1['Toolpath_TestTool1'] = %s" % env1.get('Toolpath_TestTool1')) +print("env1['Toolpath_TestTool2'] = %s" % env1.get('Toolpath_TestTool2')) +print("env1['Toolpath_TestTool1_1'] = %s" % env1.get('Toolpath_TestTool1_1')) +print("env1['Toolpath_TestTool1_2'] = %s" % env1.get('Toolpath_TestTool1_2')) +print("env1['Toolpath_TestTool2_1'] = %s" % env1.get('Toolpath_TestTool2_1')) +print("env1['Toolpath_TestTool2_2'] = %s" % env1.get('Toolpath_TestTool2_2')) print('Test where toolpath is set in the env constructor') env2 = Environment(tools=toollist, toolpath=['Libs/tools_example']) -print("env2['Toolpath_TestTool1'] = %s"%env2.get('Toolpath_TestTool1')) -print("env2['Toolpath_TestTool2'] = %s"%env2.get('Toolpath_TestTool2')) -print("env2['Toolpath_TestTool1_1'] = %s"%env2.get('Toolpath_TestTool1_1')) -print("env2['Toolpath_TestTool1_2'] = %s"%env2.get('Toolpath_TestTool1_2')) -print("env2['Toolpath_TestTool2_1'] = %s"%env2.get('Toolpath_TestTool2_1')) -print("env2['Toolpath_TestTool2_2'] = %s"%env2.get('Toolpath_TestTool2_2')) +print("env2['Toolpath_TestTool1'] = %s" % env2.get('Toolpath_TestTool1')) +print("env2['Toolpath_TestTool2'] = %s" % env2.get('Toolpath_TestTool2')) +print("env2['Toolpath_TestTool1_1'] = %s" % env2.get('Toolpath_TestTool1_1')) +print("env2['Toolpath_TestTool1_2'] = %s" % env2.get('Toolpath_TestTool1_2')) +print("env2['Toolpath_TestTool2_1'] = %s" % env2.get('Toolpath_TestTool2_1')) +print("env2['Toolpath_TestTool2_2'] = %s" % env2.get('Toolpath_TestTool2_2')) print('Test a Clone') base = Environment(tools=[], toolpath=['Libs/tools_example']) derived = base.Clone(tools=['subdir1.Toolpath_TestTool1_1']) -print("derived['Toolpath_TestTool1_1'] = %s"%derived.get('Toolpath_TestTool1_1')) - - +print("derived['Toolpath_TestTool1_1'] = %s" % derived.get('Toolpath_TestTool1_1')) print('Test using syspath as the toolpath') -print('Lets pretend that tools_example within Libs is actually a module installed via pip') +print( + 'Lets pretend that tools_example within Libs ' + 'is actually a module installed via pip' +) oldsyspath = sys.path dir_path = Dir('.').srcnode().abspath dir_path = os.path.join(dir_path, 'Libs') @@ -43,27 +51,29 @@ searchpaths = [] for item in sys.path: if os.path.isdir(item): searchpaths.append(item) -toollist = ['tools_example.Toolpath_TestTool1', - 'tools_example.Toolpath_TestTool2', - 'tools_example.subdir1.Toolpath_TestTool1_1', - 'tools_example.subdir1.Toolpath_TestTool1_2', - 'tools_example.subdir1.subdir2.Toolpath_TestTool2_1', - 'tools_example.subdir1.subdir2.Toolpath_TestTool2_2', - ] +toollist = [ + 'tools_example.Toolpath_TestTool1', + 'tools_example.Toolpath_TestTool2', + 'tools_example.subdir1.Toolpath_TestTool1_1', + 'tools_example.subdir1.Toolpath_TestTool1_2', + 'tools_example.subdir1.subdir2.Toolpath_TestTool2_1', + 'tools_example.subdir1.subdir2.Toolpath_TestTool2_2', +] env3 = Environment(tools=toollist, toolpath=searchpaths) -print("env3['Toolpath_TestTool1'] = %s"%env3.get('Toolpath_TestTool1')) -print("env3['Toolpath_TestTool2'] = %s"%env3.get('Toolpath_TestTool2')) -print("env3['Toolpath_TestTool1_1'] = %s"%env3.get('Toolpath_TestTool1_1')) -print("env3['Toolpath_TestTool1_2'] = %s"%env3.get('Toolpath_TestTool1_2')) -print("env3['Toolpath_TestTool2_1'] = %s"%env3.get('Toolpath_TestTool2_1')) -print("env3['Toolpath_TestTool2_2'] = %s"%env3.get('Toolpath_TestTool2_2')) - +print("env3['Toolpath_TestTool1'] = %s" % env3.get('Toolpath_TestTool1')) +print("env3['Toolpath_TestTool2'] = %s" % env3.get('Toolpath_TestTool2')) +print("env3['Toolpath_TestTool1_1'] = %s" % env3.get('Toolpath_TestTool1_1')) +print("env3['Toolpath_TestTool1_2'] = %s" % env3.get('Toolpath_TestTool1_2')) +print("env3['Toolpath_TestTool2_1'] = %s" % env3.get('Toolpath_TestTool2_1')) +print("env3['Toolpath_TestTool2_2'] = %s" % env3.get('Toolpath_TestTool2_2')) print('Test using PyPackageDir') toollist = ['Toolpath_TestTool2_1', 'Toolpath_TestTool2_2'] -env4 = Environment(tools = toollist, toolpath = [PyPackageDir('tools_example.subdir1.subdir2')]) -print("env4['Toolpath_TestTool2_1'] = %s"%env4.get('Toolpath_TestTool2_1')) -print("env4['Toolpath_TestTool2_2'] = %s"%env4.get('Toolpath_TestTool2_2')) +env4 = Environment( + tools=toollist, toolpath=[PyPackageDir('tools_example.subdir1.subdir2')] +) +print("env4['Toolpath_TestTool2_1'] = %s" % env4.get('Toolpath_TestTool2_1')) +print("env4['Toolpath_TestTool2_2'] = %s" % env4.get('Toolpath_TestTool2_2')) sys.path = oldsyspath diff --git a/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool1.py b/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool1.py index 1c024e1..670c942 100644 --- a/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool1.py +++ b/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool1.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool1'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/__init__.py b/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/__init__.py index 225b9aa..1a8d052 100644 --- a/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/__init__.py +++ b/test/toolpath/nested/image/site_scons/site_tools/Toolpath_TestTool2/__init__.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool2'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_1.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_1.py index c266f89..96e681b 100644 --- a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_1.py +++ b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_1.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool1_1'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/__init__.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/__init__.py index f203260..e34618d 100644 --- a/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/__init__.py +++ b/test/toolpath/nested/image/site_scons/site_tools/subdir1/Toolpath_TestTool1_2/__init__.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool1_2'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_1.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_1.py index b1b47a2..047ae78 100644 --- a/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_1.py +++ b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_1.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool2_1'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py index 407df86..d99e6c5 100644 --- a/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py +++ b/test/toolpath/nested/image/site_scons/site_tools/subdir1/subdir2/Toolpath_TestTool2_2/__init__.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['Toolpath_TestTool2_2'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/relative_import/image/SConstruct b/test/toolpath/relative_import/image/SConstruct index cf607d1..0f720e8 100644 --- a/test/toolpath/relative_import/image/SConstruct +++ b/test/toolpath/relative_import/image/SConstruct @@ -1,10 +1,15 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +DefaultEnvironment(tools=[]) env = Environment(tools=['TestTool1', 'TestTool1.TestTool1_2'], toolpath=['tools']) # Test a relative import within the root of the tools directory -print("env['TestTool1'] = %s"%env.get('TestTool1')) -print("env['TestTool1_1'] = %s"%env.get('TestTool1_1')) +print("env['TestTool1'] = %s" % env.get('TestTool1')) +print("env['TestTool1_1'] = %s" % env.get('TestTool1_1')) # Test a relative import within a sub dir -print("env['TestTool1_2'] = %s"%env.get('TestTool1_2')) -print("env['TestTool1_2_1'] = %s"%env.get('TestTool1_2_1')) -print("env['TestTool1_2_2'] = %s"%env.get('TestTool1_2_2')) +print("env['TestTool1_2'] = %s" % env.get('TestTool1_2')) +print("env['TestTool1_2_1'] = %s" % env.get('TestTool1_2_1')) +print("env['TestTool1_2_2'] = %s" % env.get('TestTool1_2_2')) diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_1.py b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_1.py index 584d353..0c11a8c 100644 --- a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_1.py +++ b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_1.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['TestTool1_1'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_1.py b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_1.py index 62d754b..100c05f 100644 --- a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_1.py +++ b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_1.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['TestTool1_2_1'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/__init__.py b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/__init__.py index 12c6018..ba65226 100644 --- a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/__init__.py +++ b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/TestTool1_2_2/__init__.py @@ -1,4 +1,9 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + def generate(env): env['TestTool1_2_2'] = 1 + def exists(env): return 1 diff --git a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/__init__.py b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/__init__.py index 58fdc93..74b05b3 100644 --- a/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/__init__.py +++ b/test/toolpath/relative_import/image/tools/TestTool1/TestTool1_2/__init__.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from . import TestTool1_2_1 from . import TestTool1_2_2 @@ -5,6 +9,7 @@ def generate(env): env['TestTool1_2'] = 1 TestTool1_2_1.generate(env) TestTool1_2_2.generate(env) + def exists(env): TestTool1_2_1.exists(env) TestTool1_2_2.exists(env) diff --git a/test/toolpath/relative_import/image/tools/TestTool1/__init__.py b/test/toolpath/relative_import/image/tools/TestTool1/__init__.py index c479560..8a7f81b 100644 --- a/test/toolpath/relative_import/image/tools/TestTool1/__init__.py +++ b/test/toolpath/relative_import/image/tools/TestTool1/__init__.py @@ -1,9 +1,14 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + from . import TestTool1_1 def generate(env): env['TestTool1'] = 1 # Include another tool within the same directory TestTool1_1.generate(env) + def exists(env): TestTool1_1.exists(env) return 1 -- cgit v0.12 From a28f56e5dd9b6ae384e50eb47ce35333d8ee5e91 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 22 May 2023 12:22:28 -0600 Subject: Changes for Python 3.12 support With Python 3.12 now in feature freeze, we can do a "final update" to sweep up issues. - new bytecodes for ActionTests.py - adapt to changes to pathlib module in runtest.py (PosixPath no longer converts slashes if given a Windows-style path). Neither of these are "user visible", only on the testing side, so no doc impacts. Signed-off-by: Mats Wichmann --- CHANGES.txt | 7 ++ SCons/ActionTests.py | 237 ++++++++++++++++++++++++--------------------------- runtest.py | 10 ++- 3 files changed, 125 insertions(+), 129 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6e8e677..2e37f0c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -32,6 +32,13 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER that if arg was a list, a ListAction was *always* returned; mention default Decider and sort the names of available decider functions, and add a version marking. Minor fiddling with Alias.py docstrings. + - Python 3.12 support: new bytecodes for ActionTests.py, adapt to + changes to pathlib module in runtest.py (PosixPath no longer + converts slashes if given a Windows-style path). Also switch to + using `subTest` in `ActionTests`, so that we can see all 21 fails + due to bytecode changes (previously testcases aborted on the first + assert fail so we only saw seven), and use unittest asserts to + simplify complex printing stanzas. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/ActionTests.py b/SCons/ActionTests.py index 2e6204e..533a007 100644 --- a/SCons/ActionTests.py +++ b/SCons/ActionTests.py @@ -1367,7 +1367,7 @@ class CommandActionTestCase(unittest.TestCase): class SpecialEnvironment(Environment): def WhereIs(self, prog): return prog - + class fs: def File(name): return name @@ -1541,7 +1541,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): (3, 9): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'), (3, 10): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'), (3, 11): bytearray(b'0, 0, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()'), - (3, 12): bytearray(b'0, 0, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()'), + (3, 12): bytearray(b'0, 0, 0, 0,(),(),(\x97\x00y\x00),(),()'), } meth_matches = [ @@ -1557,15 +1557,15 @@ class CommandGeneratorActionTestCase(unittest.TestCase): env = Environment(XYZ='foo') - a = self.factory(f_global) - c = a.get_contents(target=[], source=[], env=env) - assert c == func_matches[sys.version_info[:2]], f"Got\n{c!r}\nExpected\n" + repr( - func_matches[sys.version_info[:2]]) + with self.subTest(): + a = self.factory(f_global) + c = a.get_contents(target=[], source=[], env=env) + self.assertEqual(c, func_matches[sys.version_info[:2]]) - a = self.factory(f_local) - c = a.get_contents(target=[], source=[], env=env) - assert c == func_matches[sys.version_info[:2]], f"Got\n{c!r}\nExpected\n" + repr( - func_matches[sys.version_info[:2]]) + with self.subTest(): + a = self.factory(f_local) + c = a.get_contents(target=[], source=[], env=env) + self.assertEqual(c, func_matches[sys.version_info[:2]]) def f_global2(target, source, env, for_signature): return SCons.Action.Action(GlobalFunc, varlist=['XYZ']) @@ -1575,13 +1575,15 @@ class CommandGeneratorActionTestCase(unittest.TestCase): matches_foo = func_matches[sys.version_info[:2]] + b'foo' - a = self.factory(f_global2) - c = a.get_contents(target=[], source=[], env=env) - assert c in matches_foo, repr(c) + with self.subTest(): + a = self.factory(f_global2) + c = a.get_contents(target=[], source=[], env=env) + self.assertIn(c, matches_foo) - a = self.factory(f_local2) - c = a.get_contents(target=[], source=[], env=env) - assert c in matches_foo, repr(c) + with self.subTest(): + a = self.factory(f_local2) + c = a.get_contents(target=[], source=[], env=env) + self.assertIn(c, matches_foo) class FunctionActionTestCase(unittest.TestCase): @@ -1720,7 +1722,7 @@ class FunctionActionTestCase(unittest.TestCase): (3, 9): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'), (3, 10): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'), (3, 11): bytearray(b'0, 0, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()'), - (3, 12): bytearray(b'0, 0, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()'), + (3, 12): bytearray(b'0, 0, 0, 0,(),(),(\x97\x00y\x00),(),()'), } @@ -1732,66 +1734,62 @@ class FunctionActionTestCase(unittest.TestCase): (3, 9): bytearray(b'1, 1, 0, 0,(),(),(d\x00S\x00),(),()'), (3, 10): bytearray(b'1, 1, 0, 0,(),(),(d\x00S\x00),(),()'), (3, 11): bytearray(b'1, 1, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()'), - (3, 12): bytearray(b'1, 1, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()'), + (3, 12): bytearray(b'1, 1, 0, 0,(),(),(\x97\x00y\x00),(),()'), } def factory(act, **kw): return SCons.Action.FunctionAction(act, kw) - a = factory(GlobalFunc) - c = a.get_contents(target=[], source=[], env=Environment()) - assert ( - c == func_matches[sys.version_info[:2]] - ), f"Got\n{c!r}\nExpected one of \n" + repr(func_matches[sys.version_info[:2]]) + with self.subTest(): + a = factory(GlobalFunc) + c = a.get_contents(target=[], source=[], env=Environment()) + self.assertEqual(c, func_matches[sys.version_info[:2]]) - a = factory(LocalFunc) - c = a.get_contents(target=[], source=[], env=Environment()) - assert ( - c == func_matches[sys.version_info[:2]] - ), f"Got\n{c!r}\nExpected one of \n" + repr(func_matches[sys.version_info[:2]]) + with self.subTest(): + a = factory(LocalFunc) + c = a.get_contents(target=[], source=[], env=Environment()) + self.assertEqual(c, func_matches[sys.version_info[:2]]) matches_foo = func_matches[sys.version_info[:2]] + b'foo' - a = factory(GlobalFunc, varlist=['XYZ']) - c = a.get_contents(target=[], source=[], env=Environment()) - assert ( - c == func_matches[sys.version_info[:2]] - ), f"Got\n{c!r}\nExpected one of \n" + repr(func_matches[sys.version_info[:2]]) - # assert c in func_matches, repr(c) + with self.subTest(): + a = factory(GlobalFunc, varlist=['XYZ']) + c = a.get_contents(target=[], source=[], env=Environment()) + self.assertEqual(c, func_matches[sys.version_info[:2]]) - c = a.get_contents(target=[], source=[], env=Environment(XYZ='foo')) - assert c == matches_foo, repr(c) + with self.subTest(): + c = a.get_contents(target=[], source=[], env=Environment(XYZ='foo')) + self.assertEqual(c, matches_foo) ##TODO: is this set of tests still needed? # Make sure a bare string varlist works - a = factory(GlobalFunc, varlist='XYZ') - c = a.get_contents(target=[], source=[], env=Environment()) - # assert c in func_matches, repr(c) - assert ( - c == func_matches[sys.version_info[:2]] - ), f"Got\n{c!r}\nExpected one of \n" + repr(func_matches[sys.version_info[:2]]) + with self.subTest(): + a = factory(GlobalFunc, varlist='XYZ') + c = a.get_contents(target=[], source=[], env=Environment()) + self.assertEqual(c, func_matches[sys.version_info[:2]]) - c = a.get_contents(target=[], source=[], env=Environment(XYZ='foo')) - assert c in matches_foo, repr(c) + with self.subTest(): + c = a.get_contents(target=[], source=[], env=Environment(XYZ='foo')) + self.assertIn(c, matches_foo) class Foo: def get_contents(self, target, source, env) -> bytes: return b'xyzzy' - a = factory(Foo()) - c = a.get_contents(target=[], source=[], env=Environment()) - assert c == b'xyzzy', repr(c) + with self.subTest(): + a = factory(Foo()) + c = a.get_contents(target=[], source=[], env=Environment()) + self.assertEqual(c, b'xyzzy') class LocalClass: def LocalMethod(self) -> None: pass - lc = LocalClass() - a = factory(lc.LocalMethod) - c = a.get_contents(target=[], source=[], env=Environment()) - assert ( - c == meth_matches[sys.version_info[:2]] - ), f"Got\n{c!r}\nExpected one of \n" + repr(meth_matches[sys.version_info[:2]]) + with self.subTest(): + lc = LocalClass() + a = factory(lc.LocalMethod) + c = a.get_contents(target=[], source=[], env=Environment()) + self.assertEqual(c, meth_matches[sys.version_info[:2]]) def test_strfunction(self) -> None: """Test the FunctionAction.strfunction() method.""" @@ -1977,7 +1975,7 @@ class LazyActionTestCase(unittest.TestCase): (3, 9): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'), (3, 10): bytearray(b'0, 0, 0, 0,(),(),(d\x00S\x00),(),()'), (3, 11): bytearray(b'0, 0, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()'), - (3, 12): bytearray(b'0, 0, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()'), + (3, 12): bytearray(b'0, 0, 0, 0,(),(),(\x97\x00y\x00),(),()'), } meth_matches = [ @@ -1990,31 +1988,28 @@ class LazyActionTestCase(unittest.TestCase): a = SCons.Action.Action("${FOO}") - env = Environment(FOO=factory(GlobalFunc)) - c = a.get_contents(target=[], source=[], env=env) - # assert c in func_matches, "Got\n"+repr(c)+"\nExpected one of \n"+"\n".join([repr(f) for f in func_matches]) - assert ( - c == func_matches[sys.version_info[:2]] - ), f"Got\n{c!r}\nExpected one of \n" + repr(func_matches[sys.version_info[:2]]) + with self.subTest(): + env = Environment(FOO=factory(GlobalFunc)) + c = a.get_contents(target=[], source=[], env=env) + self.assertEqual(c, func_matches[sys.version_info[:2]]) - env = Environment(FOO=factory(LocalFunc)) - c = a.get_contents(target=[], source=[], env=env) - assert ( - c == func_matches[sys.version_info[:2]] - ), f"Got\n{c!r}\nExpected one of \n" + repr(func_matches[sys.version_info[:2]]) + with self.subTest(): + env = Environment(FOO=factory(LocalFunc)) + c = a.get_contents(target=[], source=[], env=env) + self.assertEqual(c, func_matches[sys.version_info[:2]]) # matches_foo = [x + b"foo" for x in func_matches] matches_foo = func_matches[sys.version_info[:2]] + b'foo' - env = Environment(FOO=factory(GlobalFunc, varlist=['XYZ'])) - c = a.get_contents(target=[], source=[], env=env) - assert ( - c == func_matches[sys.version_info[:2]] - ), f"Got\n{c!r}\nExpected one of \n" + repr(func_matches[sys.version_info[:2]]) + with self.subTest(): + env = Environment(FOO=factory(GlobalFunc, varlist=['XYZ'])) + c = a.get_contents(target=[], source=[], env=env) + self.assertEqual(c, func_matches[sys.version_info[:2]]) - env['XYZ'] = 'foo' - c = a.get_contents(target=[], source=[], env=env) - assert c in matches_foo, repr(c) + with self.subTest(): + env['XYZ'] = 'foo' + c = a.get_contents(target=[], source=[], env=env) + self.assertIn(c, matches_foo) class ActionCallerTestCase(unittest.TestCase): @@ -2043,55 +2038,48 @@ class ActionCallerTestCase(unittest.TestCase): (3, 9): b'd\x00S\x00', (3, 10): b'd\x00S\x00', (3, 11): b'\x97\x00d\x00S\x00', - (3, 12): b'\x97\x00d\x00S\x00', + (3, 12): b'\x97\x00y\x00', } - af = SCons.Action.ActionFactory(GlobalFunc, strfunc) - ac = SCons.Action.ActionCaller(af, [], {}) - c = ac.get_contents([], [], Environment()) - assert c == matches[sys.version_info[:2]], ( - f"Got\n{c!r}\nExpected one of \n" - + repr(matches[sys.version_info[:2]]) - ) + with self.subTest(): + af = SCons.Action.ActionFactory(GlobalFunc, strfunc) + ac = SCons.Action.ActionCaller(af, [], {}) + c = ac.get_contents([], [], Environment()) + self.assertEqual(c, matches[sys.version_info[:2]]) - af = SCons.Action.ActionFactory(LocalFunc, strfunc) - ac = SCons.Action.ActionCaller(af, [], {}) - c = ac.get_contents([], [], Environment()) - assert c == matches[sys.version_info[:2]], ( - f"Got\n{c!r}\nExpected one of \n" - + repr(matches[sys.version_info[:2]]) - ) + with self.subTest(): + af = SCons.Action.ActionFactory(LocalFunc, strfunc) + ac = SCons.Action.ActionCaller(af, [], {}) + c = ac.get_contents([], [], Environment()) + self.assertEqual(c, matches[sys.version_info[:2]]) class LocalActFunc: def __call__(self) -> None: pass - af = SCons.Action.ActionFactory(GlobalActFunc(), strfunc) - ac = SCons.Action.ActionCaller(af, [], {}) - c = ac.get_contents([], [], Environment()) - assert c == matches[sys.version_info[:2]], ( - f"Got\n{c!r}\nExpected one of \n" - + repr(matches[sys.version_info[:2]]) - ) + with self.subTest(): + af = SCons.Action.ActionFactory(GlobalActFunc(), strfunc) + ac = SCons.Action.ActionCaller(af, [], {}) + c = ac.get_contents([], [], Environment()) + self.assertEqual(c, matches[sys.version_info[:2]]) - af = SCons.Action.ActionFactory(LocalActFunc(), strfunc) - ac = SCons.Action.ActionCaller(af, [], {}) - c = ac.get_contents([], [], Environment()) - assert c == matches[sys.version_info[:2]], ( - f"Got\n{c!r}\nExpected one of \n" - + repr(matches[sys.version_info[:2]]) - ) + with self.subTest(): + af = SCons.Action.ActionFactory(LocalActFunc(), strfunc) + ac = SCons.Action.ActionCaller(af, [], {}) + c = ac.get_contents([], [], Environment()) + self.assertEqual(c, matches[sys.version_info[:2]]) matches = [ b"", b"", ] - af = SCons.Action.ActionFactory(str, strfunc) - ac = SCons.Action.ActionCaller(af, [], {}) - c = ac.get_contents([], [], Environment()) - assert c in ("", "", ""), repr(c) - # ^^ class str for python3 + with self.subTest(): + af = SCons.Action.ActionFactory(str, strfunc) + ac = SCons.Action.ActionCaller(af, [], {}) + c = ac.get_contents([], [], Environment()) + self.assertIn(c, ("", "", "")) + # ^^ class str for python3 def test___call__(self) -> None: """Test calling an ActionCaller""" @@ -2244,24 +2232,23 @@ class ObjectContentsTestCase(unittest.TestCase): # Since the python bytecode has per version differences, # we need different expected results per version + # Note unlike the others, this result is a tuple, use assertIn expected = { - (3, 5): (bytearray(b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()')), - (3, 6): (bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()')), - (3, 7): (bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()')), - (3, 8): (bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()')), - (3, 9): (bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()')), - (3, 10): ( + (3, 5): (bytearray(b'3, 3, 0, 0,(),(),(|\x00\x00S),(),()'),), + (3, 6): (bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()'),), + (3, 7): (bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()'),), + (3, 8): (bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()'),), + (3, 9): (bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()'),), + (3, 10): ( # 3.10.1, 3.10.2 bytearray(b'3, 3, 0, 0,(N.),(),(|\x00S\x00),(),()'), bytearray(b'3, 3, 0, 0,(),(),(|\x00S\x00),(),()'), - ), # 3.10.1, 3.10.2 - (3, 11): bytearray(b'3, 3, 0, 0,(),(),(\x97\x00|\x00S\x00),(),()'), - (3, 12): bytearray(b'3, 3, 0, 0,(),(),(\x97\x00|\x00S\x00),(),()'), + ), + (3, 11): (bytearray(b'3, 3, 0, 0,(),(),(\x97\x00|\x00S\x00),(),()'),), + (3, 12): (bytearray(b'3, 3, 0, 0,(),(),(\x97\x00|\x00S\x00),(),()'),), } c = SCons.Action._function_contents(func1) - assert c in expected[sys.version_info[:2]], f"Got\n{c!r}\nExpected\n" + repr( - expected[sys.version_info[:2]] - ) + self.assertIn(c, expected[sys.version_info[:2]]) def test_object_contents(self) -> None: """Test that Action._object_contents works""" @@ -2297,13 +2284,11 @@ class ObjectContentsTestCase(unittest.TestCase): b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(\x97\x00d\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x02|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x00S\x00),(),(),2, 2, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()}}{{{a=a,b=b}}}" ), (3, 12): bytearray( - b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(\x97\x00d\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x02|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00d\x00S\x00),(),(),2, 2, 0, 0,(),(),(\x97\x00d\x00S\x00),(),()}}{{{a=a,b=b}}}" + b"{TestClass:__main__}[[[(, ()), [(, (,))]]]]{{1, 1, 0, 0,(a,b),(a,b),(\x97\x00d\x01|\x00_\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x02|\x00_\x01\x00\x00\x00\x00\x00\x00\x00\x00y\x00),(),(),2, 2, 0, 0,(),(),(\x97\x00y\x00),(),()}}{{{a=a,b=b}}}" ), } - assert c == expected[sys.version_info[:2]], f"Got\n{c!r}\nExpected\n" + repr( - expected[sys.version_info[:2]] - ) + self.assertEqual(c, expected[sys.version_info[:2]]) def test_code_contents(self) -> None: """Test that Action._code_contents works""" @@ -2335,13 +2320,11 @@ class ObjectContentsTestCase(unittest.TestCase): b'0, 0, 0, 0,(Hello, World!),(print),(\x97\x00\x02\x00e\x00d\x00\xa6\x01\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00d\x01S\x00)' ), (3, 12): bytearray( - b'0, 0, 0, 0,(Hello, World!),(print),(\x97\x00\x02\x00e\x00d\x00\xab\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00d\x01S\x00)' + b'0, 0, 0, 0,(Hello, World!),(print),(\x97\x00\x02\x00e\x00d\x00\xab\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00y\x01)' ), } - assert c == expected[sys.version_info[:2]], f"Got\n{c!r}\nExpected\n" + repr( - expected[sys.version_info[:2]] - ) + self.assertEqual(c, expected[sys.version_info[:2]]) def test_uncaught_exception_bubbles(self): """Test that _subproc bubbles uncaught exceptions""" diff --git a/runtest.py b/runtest.py index 46cdc7b..07d9f33 100755 --- a/runtest.py +++ b/runtest.py @@ -592,7 +592,10 @@ def scanlist(testfile): # backward slashes, first create the object as a PureWindowsPath which # accepts either, then use that to make a Path object to use for # comparisons like "file in scanned_list". - return [Path(PureWindowsPath(t)) for t in tests if t] + if sys.platform == 'win32': + return [Path(t) for t in tests if t] + else: + return [Path(PureWindowsPath(t).as_posix()) for t in tests if t] def find_unit_tests(directory): @@ -641,7 +644,10 @@ else: if args.all: # -a flag testpaths = [Path('SCons'), Path('test')] elif args.testlist: # paths given on cmdline - testpaths = [Path(PureWindowsPath(t)) for t in args.testlist] + if sys.platform == 'win32': + testpaths = [Path(t) for t in args.testlist] + else: + testpaths = [Path(PureWindowsPath(t).as_posix()) for t in args.testlist] for path in testpaths: # Clean up path removing leading ./ or .\ -- cgit v0.12 From ddbcf3c686e7e16f2b57b3b5e3676371b728a964 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 22 May 2023 09:04:51 -0600 Subject: Drop unused environment methods Drop three unused methods from the Environment Base class: get_src_sig_type and get_tgt_sig_type, as well as "private" _changed_source which no longer was mapped to any decider. These were orphaned when the long-deprecated Source Signatures and Target Signatures were removed in #9c4e6c7a3 - missing this change. Signed-off-by: Mats Wichmann --- CHANGES.txt | 6 ++++++ RELEASE.txt | 6 ++++-- SCons/Environment.py | 25 ------------------------- 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6e8e677..625ff95 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -32,6 +32,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER that if arg was a list, a ListAction was *always* returned; mention default Decider and sort the names of available decider functions, and add a version marking. Minor fiddling with Alias.py docstrings. + - Added copyright headers to files in test/ that didn't have them. + - Drop three unused methods from the Environment Base class: + get_src_sig_type and get_tgt_sig_type, as well as "private" + _changed_source. These were orphaned when the long-deprecated + Source Signatures and Target Signatures were removed, these were + missed at that time. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index 5cef731..abaef36 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -26,8 +26,10 @@ DEPRECATED FUNCTIONALITY CHANGED/ENHANCED EXISTING FUNCTIONALITY --------------------------------------- -- List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug +- Three unused non-public methods of the Environment Base class + were dropped: get_src_sig_type, get_tgt_sig_type, _changed_source. + These were unused remnants of the previously removed SourceSignatures + and TargetSignatures features (dropped in 3.1.2). FIXES ----- diff --git a/SCons/Environment.py b/SCons/Environment.py index b074af7..2f1dcaf 100644 --- a/SCons/Environment.py +++ b/SCons/Environment.py @@ -1399,23 +1399,6 @@ class Base(SubstitutionEnvironment): if k not in self._dict: self._dict[k] = v - - def get_src_sig_type(self): - try: - return self.src_sig_type - except AttributeError: - t = SCons.Defaults.DefaultEnvironment().src_sig_type - self.src_sig_type = t - return t - - def get_tgt_sig_type(self): - try: - return self.tgt_sig_type - except AttributeError: - t = SCons.Defaults.DefaultEnvironment().tgt_sig_type - self.tgt_sig_type = t - return t - ####################################################################### # Public methods for manipulating an Environment. These begin with # upper-case letters. The essential characteristic of methods in @@ -1627,14 +1610,6 @@ class Base(SubstitutionEnvironment): def _changed_content(self, dependency, target, prev_ni, repo_node=None): return dependency.changed_content(target, prev_ni, repo_node) - def _changed_source(self, dependency, target, prev_ni, repo_node=None): - target_env = dependency.get_build_env() - type = target_env.get_tgt_sig_type() - if type == 'source': - return target_env.decide_source(dependency, target, prev_ni, repo_node) - else: - return target_env.decide_target(dependency, target, prev_ni, repo_node) - def _changed_timestamp_then_content(self, dependency, target, prev_ni, repo_node=None): return dependency.changed_timestamp_then_content(target, prev_ni, repo_node) -- cgit v0.12 From a910451a1f5e729e24ede5bfccbab032b6d4a5a6 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 22 May 2023 14:03:08 -0600 Subject: Drop dead code from unit tests Remove dead code: some mocked classes in unit tests had methods which have been removed from the Node class they're mocking, there's no need to shadow those any more as there are no callers. The methods are depends_on (base functionality removed in 2005 ) and is_pseudeo_derived (base functionality removed in 2006). Signed-off-by: Mats Wichmann --- CHANGES.txt | 6 ++++++ SCons/SConfTests.py | 2 -- SCons/Taskmaster/TaskmasterTests.py | 9 --------- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6e8e677..569c5a0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -32,6 +32,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER that if arg was a list, a ListAction was *always* returned; mention default Decider and sort the names of available decider functions, and add a version marking. Minor fiddling with Alias.py docstrings. + - Remove dead code: some mocked classes in unit tests had methods + which have been removed from the Node class they're mocking, + there's no need to shadow those any more as there are no callers. + The methods are depends_on (base functionality removed in 2005) + and is_pseudeo_derived (base functionality removed in 2006). There + may well be more! RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/SConfTests.py b/SCons/SConfTests.py index e8e0fc7..96ba926 100644 --- a/SCons/SConfTests.py +++ b/SCons/SConfTests.py @@ -199,8 +199,6 @@ class SConfTestCase(unittest.TestCase): self.state = state def alter_targets(self): return [], None - def depends_on(self, nodes): - return None def postprocess(self) -> None: pass def clear(self) -> None: diff --git a/SCons/Taskmaster/TaskmasterTests.py b/SCons/Taskmaster/TaskmasterTests.py index 32959fb..83b7ea9 100644 --- a/SCons/Taskmaster/TaskmasterTests.py +++ b/SCons/Taskmaster/TaskmasterTests.py @@ -197,18 +197,9 @@ class Node: def store_bsig(self) -> None: pass - def is_pseudo_derived(self) -> None: - pass - def is_up_to_date(self): return self._current_val - def depends_on(self, nodes) -> int: - for node in nodes: - if node in self.kids: - return 1 - return 0 - def __str__(self) -> str: return self.name -- cgit v0.12 From cb7ac753a67d3481ecdf0c09f540b6550b7013e1 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 22 May 2023 17:05:49 -0700 Subject: [ci skip] Fixed typo --- SCons/Script/Main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index a1ce5df..947e555 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -76,7 +76,7 @@ KNOWN_SCONSTRUCT_NAMES = [ 'sconstruct.py', ] -# list of names regognized by debugger as "SConscript files" (inc. SConstruct) +# list of names recognized by debugger as "SConscript files" (inc. SConstruct) # files suffixed .py always work so don't need to be in this list. KNOWN_SCONSCRIPTS = [ "SConstruct", -- cgit v0.12 From 0904d5bfe683195ad2a5d99ccd6fbe4a0f132183 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 27 May 2023 11:54:38 -0600 Subject: Tweak test MSVC/MSVC_BATCH-spaces-targetdir.py Test did not have an ending test.pass_test(), so it was not actually *recorded* as a pass, though it was passing. Renamed fixture dir. Signed-off-by: Mats Wichmann --- CHANGES.txt | 5 +++++ test/MSVC/MSVC_BATCH-spaces-fixture/SConstruct | 15 +++++++++++++++ test/MSVC/MSVC_BATCH-spaces-fixture/sconstest.skip | 0 test/MSVC/MSVC_BATCH-spaces-fixture/src/a.c | 19 +++++++++++++++++++ test/MSVC/MSVC_BATCH-spaces-fixture/src/b.c | 9 +++++++++ test/MSVC/MSVC_BATCH-spaces-fixture/src/c.c | 9 +++++++++ test/MSVC/MSVC_BATCH-spaces-targetdir.py | 13 +++++++++++-- test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct | 15 --------------- test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c | 19 ------------------- test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c | 9 --------- test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c | 9 --------- 11 files changed, 68 insertions(+), 54 deletions(-) create mode 100644 test/MSVC/MSVC_BATCH-spaces-fixture/SConstruct create mode 100644 test/MSVC/MSVC_BATCH-spaces-fixture/sconstest.skip create mode 100644 test/MSVC/MSVC_BATCH-spaces-fixture/src/a.c create mode 100644 test/MSVC/MSVC_BATCH-spaces-fixture/src/b.c create mode 100644 test/MSVC/MSVC_BATCH-spaces-fixture/src/c.c delete mode 100644 test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct delete mode 100644 test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c delete mode 100644 test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c delete mode 100644 test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c diff --git a/CHANGES.txt b/CHANGES.txt index 56f9d1b..2584583 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -59,6 +59,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER The methods are depends_on (base functionality removed in 2005) and is_pseudeo_derived (base functionality removed in 2006). There may well be more! + - Added pass_test() call to test/MSVC/MSVC_BATCH-spaces-targetdir.py. + It looked it was missing a more detailed check, but it should be + sufficient just to check the build worked. Renamed the fixture + dir to follow naming convention in test/MSVC overall, and added + a sconstest.skip file, also to follow convention. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/test/MSVC/MSVC_BATCH-spaces-fixture/SConstruct b/test/MSVC/MSVC_BATCH-spaces-fixture/SConstruct new file mode 100644 index 0000000..025f9ee --- /dev/null +++ b/test/MSVC/MSVC_BATCH-spaces-fixture/SConstruct @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + +import os.path + +DefaultEnvironment(tools=[]) +env = Environment(MSVC_BATCH=True) + +td = 'tar ge tdir' +VariantDir(td, 'src') +env.Program( + os.path.join(td, 'test_program'), + [os.path.join(td, a) for a in ['a.c', 'b.c', 'c.c']], +) diff --git a/test/MSVC/MSVC_BATCH-spaces-fixture/sconstest.skip b/test/MSVC/MSVC_BATCH-spaces-fixture/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/MSVC/MSVC_BATCH-spaces-fixture/src/a.c b/test/MSVC/MSVC_BATCH-spaces-fixture/src/a.c new file mode 100644 index 0000000..9164729 --- /dev/null +++ b/test/MSVC/MSVC_BATCH-spaces-fixture/src/a.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + +#include + +extern void myfuncb(); +extern void myfuncc(); + + +void myfunca() { + printf("myfunca\n"); +} + +int main(int argc, char *argv[]) { + myfunca(); + myfuncb(); + myfuncc(); +} diff --git a/test/MSVC/MSVC_BATCH-spaces-fixture/src/b.c b/test/MSVC/MSVC_BATCH-spaces-fixture/src/b.c new file mode 100644 index 0000000..51e92dd --- /dev/null +++ b/test/MSVC/MSVC_BATCH-spaces-fixture/src/b.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + +#include + +void myfuncb() { + printf("myfuncb\n"); +} diff --git a/test/MSVC/MSVC_BATCH-spaces-fixture/src/c.c b/test/MSVC/MSVC_BATCH-spaces-fixture/src/c.c new file mode 100644 index 0000000..fe9f203 --- /dev/null +++ b/test/MSVC/MSVC_BATCH-spaces-fixture/src/c.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +// +// Copyright The SCons Foundation + +#include + +void myfuncc() { + printf("myfuncc\n"); +} diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir.py b/test/MSVC/MSVC_BATCH-spaces-targetdir.py index 9b11872..98cde3f 100644 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir.py +++ b/test/MSVC/MSVC_BATCH-spaces-targetdir.py @@ -2,10 +2,19 @@ # # Copyright The SCons Foundation +"""Test that spaces in the target dir name doesn't break MSVC_BATCH.""" + import TestSCons test = TestSCons.TestSCons() test.skip_if_not_msvc() -test.dir_fixture('MSVC_BATCH-spaces-targetdir') -test.run() +test.dir_fixture('MSVC_BATCH-spaces-fixture') +test.run(stderr=None) # it's enough that the build didn't fail +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4 diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct b/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct deleted file mode 100644 index 025f9ee..0000000 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir/SConstruct +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: MIT -# -# Copyright The SCons Foundation - -import os.path - -DefaultEnvironment(tools=[]) -env = Environment(MSVC_BATCH=True) - -td = 'tar ge tdir' -VariantDir(td, 'src') -env.Program( - os.path.join(td, 'test_program'), - [os.path.join(td, a) for a in ['a.c', 'b.c', 'c.c']], -) diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c deleted file mode 100644 index 9164729..0000000 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/a.c +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright The SCons Foundation - -#include - -extern void myfuncb(); -extern void myfuncc(); - - -void myfunca() { - printf("myfunca\n"); -} - -int main(int argc, char *argv[]) { - myfunca(); - myfuncb(); - myfuncc(); -} diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c deleted file mode 100644 index 51e92dd..0000000 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/b.c +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright The SCons Foundation - -#include - -void myfuncb() { - printf("myfuncb\n"); -} diff --git a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c b/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c deleted file mode 100644 index fe9f203..0000000 --- a/test/MSVC/MSVC_BATCH-spaces-targetdir/src/c.c +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// Copyright The SCons Foundation - -#include - -void myfuncc() { - printf("myfuncc\n"); -} -- cgit v0.12 From c7920c9ebf0031dd2c7664ea5cc128af51e64167 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 4 Jun 2023 15:39:36 -0700 Subject: Initial support for writing --debug=time, count into a JSON file --- SCons/Debug.py | 1 + SCons/Script/Main.py | 6 +++++- SCons/Util/stats.py | 38 ++++++++++++++++++++++++++++++++------ SCons/__init__.py | 6 +++--- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/SCons/Debug.py b/SCons/Debug.py index fa07743..ea359f6 100644 --- a/SCons/Debug.py +++ b/SCons/Debug.py @@ -196,6 +196,7 @@ TimeStampDefault = False StartTime = time.perf_counter() PreviousTime = StartTime + def Trace(msg, tracefile=None, mode='w', tstamp=False): """Write a trace message. diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index ec34c12..572a2e7 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -62,7 +62,7 @@ import SCons.Taskmaster import SCons.Util import SCons.Warnings import SCons.Script.Interactive -from SCons.Util.stats import COUNT_STATS, MEMORY_STATS, ENABLE_JSON, WriteJsonFile +from SCons.Util.stats import COUNT_STATS, MEMORY_STATS, TIME_STATS, ENABLE_JSON, WriteJsonFile from SCons import __version__ as SConsVersion @@ -208,6 +208,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): "Command execution end timestamp: %s: %f\n" % (str(self.node), finish_time) ) + TIME_STATS.add_command(str(self.node), (finish_time - start_time)) sys.stdout.write( "Command execution time: %s: %f seconds\n" % (str(self.node), (finish_time - start_time)) @@ -646,6 +647,7 @@ def _set_debug_values(options): options.tree_printers.append(TreePrinter(status=True)) if "time" in debug_values: print_time = True + TIME_STATS.enable(sys.stdout) if "action-timestamps" in debug_values: print_time = True print_action_timestamps = True @@ -1419,6 +1421,8 @@ def main(): print("Total SConscript file execution time: %f seconds"%sconscript_time) print("Total SCons execution time: %f seconds"%scons_time) print("Total command execution time: %f seconds"%ct) + TIME_STATS.total_times(total_time, sconscript_time, scons_time, ct) + if SCons.Util.stats.ENABLE_JSON: WriteJsonFile() diff --git a/SCons/Util/stats.py b/SCons/Util/stats.py index ccad165..177f363 100644 --- a/SCons/Util/stats.py +++ b/SCons/Util/stats.py @@ -51,11 +51,6 @@ def AddStatType(name, stat_object): ALL_STATS[name] = stat_object -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: class Stats: def __init__(self): self.stats = [] @@ -126,8 +121,29 @@ class MemStats(Stats): self.outfp.write(fmt % (label, stats)) +class TimeStats(Stats): + def __init__(self): + super().__init__() + self.totals = {} + self.commands = {} # we get order from insertion order, and can address individual via dict + + def total_times(self, build_time, sconscript_time, scons_exec_time, command_exec_time): + self.totals = { + 'build_time': build_time, + 'sconscript_time': sconscript_time, + 'scons_exec_time': scons_exec_time, + 'command_exec_time': command_exec_time + } + + def add_command(self, command, command_time): + if command in self.commands: + print("Duplicate command %s" % command) + self.commands[command] = command_time + + COUNT_STATS = CountStats() MEMORY_STATS = MemStats() +TIME_STATS = TimeStats() def WriteJsonFile(): @@ -150,7 +166,17 @@ def WriteJsonFile(): m = json_structure['Memory'] for label, stats in zip(MEMORY_STATS.labels, MEMORY_STATS.stats): - m[label] =stats + m[label] = stats + + if TIME_STATS.enabled: + json_structure['Time'] = {'Commands': TIME_STATS.commands, + 'Totals': TIME_STATS.totals} with open("scons_stats.json", 'w') as sf: sf.write(json.dumps(json_structure)) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/SCons/__init__.py b/SCons/__init__.py index 9804f4f..f0f241d 100644 --- a/SCons/__init__.py +++ b/SCons/__init__.py @@ -1,9 +1,9 @@ __version__="4.5.2" __copyright__="Copyright (c) 2001 - 2023 The SCons Foundation" __developer__="bdbaddog" -__date__="Sat, 22 Apr 2023 16:48:09 -0700" +__date__="Sun, 04 Jun 2023 15:36:48 -0700" __buildsys__="M1Dog2021" -__revision__="176711bd1fde814e9c441ae44132eb600063ec7a" -__build__="176711bd1fde814e9c441ae44132eb600063ec7a" +__revision__="b3744e8862927899e3d0ebcb41297f9b4c142c63" +__build__="b3744e8862927899e3d0ebcb41297f9b4c142c63" # make sure compatibility is always in place import SCons.compat # noqa \ No newline at end of file -- cgit v0.12 From 071b019942366375884eb0301cc37289e6101849 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 4 Jun 2023 16:36:45 -0700 Subject: Added build info to json, added --debug=json to docs --- SCons/Script/Main.py | 2 +- SCons/Util/stats.py | 39 +++++++++++++++++++++++++++++++++------ doc/man/scons.xml | 13 +++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 572a2e7..46b6e6a 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -208,7 +208,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): "Command execution end timestamp: %s: %f\n" % (str(self.node), finish_time) ) - TIME_STATS.add_command(str(self.node), (finish_time - start_time)) + TIME_STATS.add_command(str(self.node), start_time, finish_time) sys.stdout.write( "Command execution time: %s: %f seconds\n" % (str(self.node), (finish_time - start_time)) diff --git a/SCons/Util/stats.py b/SCons/Util/stats.py index 177f363..5a05f1c 100644 --- a/SCons/Util/stats.py +++ b/SCons/Util/stats.py @@ -33,13 +33,16 @@ There are basically two types of stats. though it might be useful to query during a run. """ +import os import json +import sys +from datetime import datetime import SCons.Debug ALL_STATS = {} ENABLE_JSON = False - +JSON_OUTPUT_FILE = 'scons_stats.json' def AddStatType(name, stat_object): """ @@ -135,10 +138,12 @@ class TimeStats(Stats): 'command_exec_time': command_exec_time } - def add_command(self, command, command_time): + def add_command(self, command, start_time, finish_time): if command in self.commands: print("Duplicate command %s" % command) - self.commands[command] = command_time + self.commands[command] = {'start': start_time, + 'end' : finish_time, + 'duration': finish_time - start_time} COUNT_STATS = CountStats() @@ -148,8 +153,12 @@ TIME_STATS = TimeStats() def WriteJsonFile(): """ - + Actually write the JSON file with debug information. + Depending which of : count, time, action-timestamps,memory their information will be written. """ + + from SCons.Script import BUILD_TARGETS, COMMAND_LINE_TARGETS, ARGUMENTS, ARGLIST + print("DUMPING JSON FILE") json_structure = {} if COUNT_STATS.enabled: @@ -172,8 +181,26 @@ def WriteJsonFile(): json_structure['Time'] = {'Commands': TIME_STATS.commands, 'Totals': TIME_STATS.totals} - with open("scons_stats.json", 'w') as sf: - sf.write(json.dumps(json_structure)) + # Now add information about this build to the JSON file + json_structure['Build_Info'] = { + 'BUILD_TARGETS' : [str(t) for t in BUILD_TARGETS], + 'ARGUMENTS' : [str(a) for a in ARGUMENTS], + 'ARGLIST' : [ str(al) for al in ARGLIST], + 'COMMAND_LINE_TARGETS' : [ str(clt) for clt in COMMAND_LINE_TARGETS], + 'ARGV' : sys.argv, + 'TIME' : datetime.now().isoformat(), + 'HOST' : os.uname().nodename, + 'PYTHON_VERSION' : { + 'major' : sys.version_info.major, + 'minor' : sys.version_info.minor, + 'micro' : sys.version_info.micro, + 'releaselevel' : sys.version_info.releaselevel, + 'serial' : sys.version_info.serial, + } + } + + with open(JSON_OUTPUT_FILE, 'w') as sf: + sf.write(json.dumps(json_structure, indent=4)) # Local Variables: # tab-width:4 diff --git a/doc/man/scons.xml b/doc/man/scons.xml index e79a267..0625efa 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -929,6 +929,19 @@ $ scons --debug=includes foo.o + + json + +Write info for any of the following debug options if they are enabled: memory, + count, time, action-timestamps + + +$ scons --debug=memory,json foo.o + + + + + memoizer -- cgit v0.12 From 1960eaffb7089069e645a648f13d1ffda93f4d28 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 4 Jun 2023 18:09:49 -0700 Subject: Added test, CHANGES/RELEASE text. Fixturized SConstruct from test/option/debug-count.py, and used that in test/option/debug-json.py --- CHANGES.txt | 5 ++ RELEASE.txt | 3 ++ SCons/Script/Main.py | 1 - SCons/Util/stats.py | 2 +- test/option/debug-count.py | 16 ++---- test/option/debug-json.py | 82 ++++++++++++++++++++++++++++++ test/option/fixture/SConstruct_debug_count | 6 +++ 7 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 test/option/debug-json.py create mode 100644 test/option/fixture/SConstruct_debug_count diff --git a/CHANGES.txt b/CHANGES.txt index 2584583..b9f0c49 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,11 @@ NOTE: 4.3.0 now requires Python 3.6.0 and above. Python 3.5.x is no longer suppo RELEASE VERSION/DATE TO BE FILLED IN LATER + From William Deegan + - The --debug flag now has a 'json' option which will write information + generated by --debug={count, memory, time, action-timestamps} and about + the build. + From Mats Wichmann - C scanner's dictifyCPPDEFINES routine did not understand the possible combinations of CPPDEFINES - not aware of a "name=value" string either diff --git a/RELEASE.txt b/RELEASE.txt index e71e2b6..f7566fb 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -34,6 +34,9 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY were dropped: get_src_sig_type, get_tgt_sig_type, _changed_source. These were unused remnants of the previously removed SourceSignatures and TargetSignatures features (dropped in 3.1.2). +- The --debug flag now has a 'json' option which will write information + generated by --debug={count, memory, time, action-timestamps} and about + the build. FIXES ----- diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 05a45b5..73070b2 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -1506,7 +1506,6 @@ def main() -> None: if SCons.Util.stats.ENABLE_JSON: WriteJsonFile() - TIME_STATS.total_times(total_time, sconscript_time, scons_time, ct) if SCons.Util.stats.ENABLE_JSON: diff --git a/SCons/Util/stats.py b/SCons/Util/stats.py index 5a05f1c..c407871 100644 --- a/SCons/Util/stats.py +++ b/SCons/Util/stats.py @@ -159,7 +159,7 @@ def WriteJsonFile(): from SCons.Script import BUILD_TARGETS, COMMAND_LINE_TARGETS, ARGUMENTS, ARGLIST - print("DUMPING JSON FILE") + # print("DUMPING JSON FILE") json_structure = {} if COUNT_STATS.enabled: json_structure['Object counts'] = {} diff --git a/test/option/debug-count.py b/test/option/debug-count.py index cf46feb..dd252fc 100644 --- a/test/option/debug-count.py +++ b/test/option/debug-count.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -25,8 +27,6 @@ Test that the --debug=count option works. """ -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - import re import sys @@ -34,15 +34,7 @@ import TestSCons test = TestSCons.TestSCons() - -test.write('SConstruct', """ -DefaultEnvironment(tools=[]) -def cat(target, source, env): - with open(str(target[0]), 'wb') as f, open(str(source[0]), 'rb') as infp: - f.write(infp.read()) -env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))}) -env.Cat('file.out', 'file.in') -""") +test.file_fixture('fixture/SConstruct_debug_count', 'SConstruct') test.write('file.in', "file.in\n") diff --git a/test/option/debug-json.py b/test/option/debug-json.py new file mode 100644 index 0000000..283b67d --- /dev/null +++ b/test/option/debug-json.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +Test that the --debug=json option works. +""" + +import json +import re +import sys + +import TestSCons + +test = TestSCons.TestSCons() + +test.file_fixture('fixture/SConstruct_debug_count', 'SConstruct') +test.write('file.in', "file.in\n") + + +# Just check that object counts for some representative classes +# show up in the output. + +def find_object_count(s, stdout): + re_string = r'\d+ +\d+ %s' % re.escape(s) + return re.search(re_string, stdout) + + +objects = [ + 'Action.CommandAction', + 'Builder.BuilderBase', + 'Environment.Base', + 'Executor.Executor', + 'Node.FS.File', + 'Node.FS.Base', + 'Node.Node', +] + +test.run(arguments='--debug=count,json') +test.must_exist('scons_stats.json') +with open('scons_stats.json') as jf: + stats_info = json.load(jf) + if 'Build_Info' not in stats_info: + test.fail_test(message='No Build_Info in json') + if 'Object counts' not in stats_info: + test.fail_test(message='No "Object counts" in json') + + for o in objects: + if o not in stats_info['Object counts']: + test.fail_test(message=f"Object counts missing {o}") + + if stats_info['Build_Info']['PYTHON_VERSION']['major'] != sys.version_info.major: + test.fail_test(message=f"Build Info PYTHON_VERSION incorrect") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/fixture/SConstruct_debug_count b/test/option/fixture/SConstruct_debug_count new file mode 100644 index 0000000..be55d35 --- /dev/null +++ b/test/option/fixture/SConstruct_debug_count @@ -0,0 +1,6 @@ +DefaultEnvironment(tools=[]) +def cat(target, source, env): + with open(str(target[0]), 'wb') as f, open(str(source[0]), 'rb') as infp: + f.write(infp.read()) +env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))}) +env.Cat('file.out', 'file.in') -- cgit v0.12 From 8d2a4b55744150f151448a361f46e4c928db458b Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 5 Jun 2023 10:21:59 -0700 Subject: Added test for --debug=json. Implemented DebugOptions(json). Create containing directory, and issue UserError if the directory is not creatable.. --- CHANGES.txt | 2 +- SCons/Script/Main.py | 24 ++++++++++++++---- SCons/Script/__init__.py | 1 + SCons/Util/stats.py | 5 +++- test/option/debug-json.py | 39 ++++++++++++++++++++---------- test/option/fixture/SConstruct_debug_count | 4 +++ 6 files changed, 55 insertions(+), 20 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index b9f0c49..edac6d2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,7 +13,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - The --debug flag now has a 'json' option which will write information generated by --debug={count, memory, time, action-timestamps} and about the build. - + From Mats Wichmann - C scanner's dictifyCPPDEFINES routine did not understand the possible combinations of CPPDEFINES - not aware of a "name=value" string either diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 73070b2..d4b83b0 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -59,7 +59,7 @@ import SCons.Taskmaster import SCons.Util import SCons.Warnings import SCons.Script.Interactive -from SCons.Util.stats import COUNT_STATS, MEMORY_STATS, TIME_STATS, ENABLE_JSON, WriteJsonFile +from SCons.Util.stats import COUNT_STATS, MEMORY_STATS, TIME_STATS, ENABLE_JSON, WriteJsonFile, JSON_OUTPUT_FILE from SCons import __version__ as SConsVersion @@ -519,6 +519,24 @@ def GetOption(name): def SetOption(name, value): return OptionsParser.values.set_option(name, value) +def DebugOptions(json=None): + """ + API to allow specifying options to SCons debug logic + Currently only json is supported which changes the + json file written by --debug=json from the default + """ + if json is not None: + json_node = SCons.Defaults.DefaultEnvironment().arg2nodes(json) + SCons.Util.stats.JSON_OUTPUT_FILE = json_node[0].get_abspath() + # Check if parent dir to JSON_OUTPUT_FILE exists + json_dir = os.path.dirname(SCons.Util.stats.JSON_OUTPUT_FILE) + try: + if not os.path.isdir(json_dir): + os.makedirs(json_dir, exist_ok=True) + except (FileNotFoundError, OSError) as e: + raise SCons.Errors.UserError(f"Unable to create directory for JSON debug output file: {SCons.Util.stats.JSON_OUTPUT_FILE}") + + def ValidateOptions(throw_exception: bool=False) -> None: """Validate options passed to SCons on the command line. @@ -1507,10 +1525,6 @@ def main() -> None: if SCons.Util.stats.ENABLE_JSON: WriteJsonFile() - - if SCons.Util.stats.ENABLE_JSON: - WriteJsonFile() - sys.exit(exit_status) # Local Variables: diff --git a/SCons/Script/__init__.py b/SCons/Script/__init__.py index c8666c4..e398ecf 100644 --- a/SCons/Script/__init__.py +++ b/SCons/Script/__init__.py @@ -110,6 +110,7 @@ SetOption = Main.SetOption ValidateOptions = Main.ValidateOptions Progress = Main.Progress GetBuildFailures = Main.GetBuildFailures +DebugOptions = Main.DebugOptions #keep_going_on_error = Main.keep_going_on_error #print_dtree = Main.print_dtree diff --git a/SCons/Util/stats.py b/SCons/Util/stats.py index c407871..911910b 100644 --- a/SCons/Util/stats.py +++ b/SCons/Util/stats.py @@ -151,6 +151,7 @@ MEMORY_STATS = MemStats() TIME_STATS = TimeStats() + def WriteJsonFile(): """ Actually write the JSON file with debug information. @@ -159,7 +160,7 @@ def WriteJsonFile(): from SCons.Script import BUILD_TARGETS, COMMAND_LINE_TARGETS, ARGUMENTS, ARGLIST - # print("DUMPING JSON FILE") + print(f"DUMPING JSON FILE: {JSON_OUTPUT_FILE}") json_structure = {} if COUNT_STATS.enabled: json_structure['Object counts'] = {} @@ -199,6 +200,8 @@ def WriteJsonFile(): } } + + with open(JSON_OUTPUT_FILE, 'w') as sf: sf.write(json.dumps(json_structure, indent=4)) diff --git a/test/option/debug-json.py b/test/option/debug-json.py index 283b67d..f3e6e0f 100644 --- a/test/option/debug-json.py +++ b/test/option/debug-json.py @@ -46,6 +46,22 @@ def find_object_count(s, stdout): re_string = r'\d+ +\d+ %s' % re.escape(s) return re.search(re_string, stdout) +def check_json_file(filename): + with open(filename,'r') as jf: + stats_info = json.load(jf) + if 'Build_Info' not in stats_info: + test.fail_test(message='No Build_Info in json') + if 'Object counts' not in stats_info: + test.fail_test(message='No "Object counts" in json') + + for o in objects: + if o not in stats_info['Object counts']: + test.fail_test(message=f"Object counts missing {o}") + + if stats_info['Build_Info']['PYTHON_VERSION'][ + 'major'] != sys.version_info.major: + test.fail_test(message=f"Build Info PYTHON_VERSION incorrect") + objects = [ 'Action.CommandAction', @@ -59,19 +75,16 @@ objects = [ test.run(arguments='--debug=count,json') test.must_exist('scons_stats.json') -with open('scons_stats.json') as jf: - stats_info = json.load(jf) - if 'Build_Info' not in stats_info: - test.fail_test(message='No Build_Info in json') - if 'Object counts' not in stats_info: - test.fail_test(message='No "Object counts" in json') - - for o in objects: - if o not in stats_info['Object counts']: - test.fail_test(message=f"Object counts missing {o}") - - if stats_info['Build_Info']['PYTHON_VERSION']['major'] != sys.version_info.major: - test.fail_test(message=f"Build Info PYTHON_VERSION incorrect") +check_json_file('scons_stats.json') + +test.run(arguments='--debug=count,json JSON=build/output/stats.json') +test.must_exist('build/output/stats.json') +check_json_file('build/output/stats.json') + +test.run(arguments='--debug=count,json JSON=/cant/write/here/dumb.json', status=2, stderr=None) +test.must_not_exist('/cant/write/here/dumb.json') +test.pass_test('scons: *** Unable to create directory for JSON debug output file:' in test.stderr()) + test.pass_test() diff --git a/test/option/fixture/SConstruct_debug_count b/test/option/fixture/SConstruct_debug_count index be55d35..332815b 100644 --- a/test/option/fixture/SConstruct_debug_count +++ b/test/option/fixture/SConstruct_debug_count @@ -1,3 +1,7 @@ +if ARGUMENTS.get('JSON',False): + DebugOptions(json=ARGUMENTS.get('JSON')) + + DefaultEnvironment(tools=[]) def cat(target, source, env): with open(str(target[0]), 'wb') as f, open(str(source[0]), 'rb') as infp: -- cgit v0.12 From 0467f15ea25a719fa45ee86d74a1b1657a357105 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 5 Jun 2023 10:43:47 -0700 Subject: Added docs --- SCons/Script/Main.xml | 17 ++ SCons/Util/stats.py | 2 +- doc/generated/examples/caching_ex-random_1.xml | 2 +- doc/generated/examples/troubleshoot_explain1_3.xml | 2 +- .../examples/troubleshoot_stacktrace_2.xml | 3 +- doc/generated/functions.gen | 269 +++++++++++++-------- doc/generated/functions.mod | 4 + doc/man/scons.xml | 4 +- 8 files changed, 193 insertions(+), 110 deletions(-) diff --git a/SCons/Script/Main.xml b/SCons/Script/Main.xml index 379d534..9248668 100644 --- a/SCons/Script/Main.xml +++ b/SCons/Script/Main.xml @@ -183,6 +183,23 @@ Future versions of &SCons; will likely forbid such usage. + + +([json]) + + + +Allows setting options for SCons debug options. Currently the only supported value is + json which sets the path to the json file created when + --debug=json is set. + + +DebugOptions(json='#/build/output/scons_stats.json') + + + + + () diff --git a/SCons/Util/stats.py b/SCons/Util/stats.py index 911910b..58fa5dd 100644 --- a/SCons/Util/stats.py +++ b/SCons/Util/stats.py @@ -160,7 +160,7 @@ def WriteJsonFile(): from SCons.Script import BUILD_TARGETS, COMMAND_LINE_TARGETS, ARGUMENTS, ARGLIST - print(f"DUMPING JSON FILE: {JSON_OUTPUT_FILE}") + # print(f"DUMPING JSON FILE: {JSON_OUTPUT_FILE}") json_structure = {} if COUNT_STATS.enabled: json_structure['Object counts'] = {} diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 4773380..422f37d 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,7 +1,7 @@ % scons -Q -cc -o f1.o -c f1.c cc -o f4.o -c f4.c cc -o f2.o -c f2.c +cc -o f1.o -c f1.c cc -o f5.o -c f5.c cc -o f3.o -c f3.c cc -o prog f1.o f2.o f3.o f4.o f5.o diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml index e658d89..a0aec9f 100644 --- a/doc/generated/examples/troubleshoot_explain1_3.xml +++ b/doc/generated/examples/troubleshoot_explain1_3.xml @@ -2,5 +2,5 @@ cp file.in file.oout scons: warning: Cannot find target file.out after building -File "/Users/bdbaddog/devel/scons/git/as_scons/scripts/scons.py", line 97, in <module> +File "/Users/bdbaddog/devel/scons/git/scons-2/scripts/scons.py", line 97, in <module> diff --git a/doc/generated/examples/troubleshoot_stacktrace_2.xml b/doc/generated/examples/troubleshoot_stacktrace_2.xml index 79234f2..668e67f 100644 --- a/doc/generated/examples/troubleshoot_stacktrace_2.xml +++ b/doc/generated/examples/troubleshoot_stacktrace_2.xml @@ -3,8 +3,9 @@ scons: *** [prog.o] Source `prog.c' not found, needed by target `prog.o'. scons: internal stack trace: File "SCons/Taskmaster/Job.py", line 219, in start task.prepare() - File "SCons/Script/Main.py", line 180, in prepare + File "SCons/Script/Main.py", line 201, in prepare return SCons.Taskmaster.OutOfDateTask.prepare(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "SCons/Taskmaster/__init__.py", line 195, in prepare executor.prepare() File "SCons/Executor.py", line 418, in prepare diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen index 5a74fc6..90d263d 100644 --- a/doc/generated/functions.gen +++ b/doc/generated/functions.gen @@ -248,9 +248,9 @@ to be performed after the specified target has been built. -The specified action(s) may be +action may be an Action object, or anything that -can be converted into an Action object +can be converted into an Action object. See the manpage section "Action Objects" for a complete explanation. @@ -261,6 +261,13 @@ the action may be called multiple times, once after each action that generates one or more targets in the list. + + +foo = Program('foo.c') +# remove execute permission from binary: +AddPostAction(foo, Chmod('$TARGET', "a-x")) + + @@ -273,9 +280,9 @@ to be performed before the specified target is built. -The specified action(s) may be +action may be an Action object, or anything that -can be converted into an Action object +can be converted into an Action object. See the manpage section "Action Objects" for a complete explanation. @@ -318,20 +325,34 @@ file into an object file. - Alias(alias, [targets, [action]]) - env.Alias(alias, [targets, [action]]) + Alias(alias, [source, [action]]) + env.Alias(alias, [source, [action]]) -Creates one or more phony targets that -expand to one or more other targets. -An optional +Creates a phony target (or targets) that +can be used as references to zero or more other targets, +as specified by the optional source +parameter. +alias and +source +may each be a string or Node object, +or a list of strings or Node objects; +if Nodes are used for +alias +they must be Alias nodes. +The optional action -(command) -or list of actions -can be specified that will be executed +parameter specifies an action or list of actions +that will be executed whenever the any of the alias targets are out-of-date. -Returns the Node object representing the alias, -which exists outside of any file system. -This Node object, or the alias name, + + + +Returns a list of Alias Node objects representing the alias(es), +which exist outside of any physical file system. + + + +The alias name, or an Alias Node object, may be used as a dependency of any other target, including another alias. &f-Alias; @@ -519,7 +540,7 @@ giving an easy way to enter multiple macros in one addition. Use an = to specify a valued macro. -A tuple is treated as a valued macro. +A tuple is treated as a valued macro. Use the value None if the macro should not have a value. It is an error to supply more than two elements in such a tuple. @@ -1117,13 +1138,25 @@ so you normally don't need to create directories by hand. Configure(env, [custom_tests, conf_dir, log_file, config_h]) env.Configure([custom_tests, conf_dir, log_file, config_h]) -Creates a Configure object for integrated -functionality similar to GNU autoconf. +Creates a &Configure; object for integrated +functionality similar to GNU autoconf. See the manpage section "Configure Contexts" for a complete explanation of the arguments and behavior. + + DebugOptions([json]) + +Allows setting options for SCons debug options. Currently the only supported value is + json which sets the path to the json file created when + --debug=json is set. + + +DebugOptions(json='#/build/output/scons_stats.json') + + + Decider(function) env.Decider(function) @@ -1141,50 +1174,24 @@ that will be applied: -"timestamp-newer" - - -Specifies that a target shall be considered out of date and rebuilt -if the dependency's timestamp is newer than the target file's timestamp. -This is the behavior of the classic Make utility, -and -make -can be used a synonym for -timestamp-newer. - - - - -"timestamp-match" - - -Specifies that a target shall be considered out of date and rebuilt -if the dependency's timestamp is different than the -timestamp recorded the last time the target was built. -This provides behavior very similar to the classic Make utility -(in particular, files are not opened up so that their -contents can be checksummed) -except that the target will also be rebuilt if a -dependency file has been restored to a version with an -earlier -timestamp, such as can happen when restoring files from backup archives. - - - - "content" Specifies that a target shall be considered out of date and rebuilt if the dependency's content has changed since the last time the target was built, -as determined be performing an checksum -on the dependency's contents +as determined by performing a checksum +on the dependency's contents using the selected hash function, and comparing it to the checksum recorded the last time the target was built. -MD5 -can be used as a synonym for -content, but it is deprecated. +content is the default decider. + + +Changed in version 4.1: +The decider was renamed to content +since the hash function is now selectable. +The former name, MD5, +can still be used as a synonym, but is deprecated. @@ -1215,9 +1222,44 @@ that runs a build, updates a file, and runs the build again, all within a single second. -MD5-timestamp -can be used as a synonym for -content-timestamp, but it is deprecated. + + +Changed in version 4.1: +The decider was renamed to content-timestamp +since the hash function is now selectable. +The former name, MD5-timestamp, +can still be used as a synonym, but is deprecated. + + + + +"timestamp-newer" + + +Specifies that a target shall be considered out of date and rebuilt +if the dependency's timestamp is newer than the target file's timestamp. +This is the behavior of the classic Make utility, +and +make +can be used a synonym for +timestamp-newer. + + + + +"timestamp-match" + + +Specifies that a target shall be considered out of date and rebuilt +if the dependency's timestamp is different than the +timestamp recorded the last time the target was built. +This provides behavior very similar to the classic Make utility +(in particular, files are not opened up so that their +contents can be checksummed) +except that the target will also be rebuilt if a +dependency file has been restored to a version with an +earlier +timestamp, such as can happen when restoring files from backup archives. @@ -3973,7 +4015,7 @@ Sets &scons; option variable name to value. These options are all also settable via command-line options but the variable name -may differ from the command-line option name - +may differ from the command-line option name - see the table for correspondences. A value set via command-line option will take precedence over one set with &f-SetOption;, which @@ -4481,57 +4523,74 @@ gltool(env) # adds 'opengl' to the TOOLS variable ValidateOptions([throw_exception=False]) - Check that all the options specified on the command line are either defined by SCons itself - or defined by calls to &f-link-AddOption;. - - - This function should only be called after the last &f-link-AddOption; call in your &SConscript; - logic. - - - Be aware that some tools call &f-link-AddOption;, if you are getting error messages for arguments - that they add, you will need to ensure that you load those tools before you call &f-ValidateOptions;. - - - If there are any command line options not defined, calling this function will cause SCons to issue an - error message and then exit with an error exit - status. - If the optional throw_exception is True, &f-ValidateOptions; will raise a - SConsBadOptionError - exception. This would allow the calling - &SConscript; logic can catch that exception and handle invalid options itself. - - - - Example: - - - + Check that all the options specified on the command line are either + &SCons; built-in options or defined via calls to &f-link-AddOption;. + &SCons; will eventually fail on unknown options anyway, but calling + this function allows the build to "fail fast" before executing + expensive logic later in the build. + + + + This function should only be called after the last &f-AddOption; + call in your &SConscript; logic. + Be aware that some tools call &f-AddOption;, if you are getting + error messages for arguments that they add, you will need to ensure + that those tools are loaded before calling &f-ValidateOptions;. + + + + If there are any unknown command line options, &f-ValidateOptions; + prints an error message and exits with an error exit status. + If the optional throw_exception argument is + True (default is False), + a SConsBadOptionError is raised, + giving an opportunity for the &SConscript; logic to catch that + exception and handle invalid options appropriately. Note that + this exception name needs to be imported (see the example below). + + + + A common build problem is typos (or thinkos) - a user enters an option + that is just a little off the expected value, or perhaps a different + word with a similar meaning. It may be useful to abort the build + before going too far down the wrong path. For example: + + + +$ scons --compilers=mingw # the correct flag is --compiler + + + + Here &SCons; could go off and run a bunch of configure steps with + the default value of --compiler, since the + incorrect command line did not actually supply a value to it, + costing developer time to track down why the configure logic + made the "wrong" choices. This example shows catching this: + + + +from SCons.Script.SConsOptions import SConsBadOptionError + +AddOption( + '--compiler', + dest='compiler', + action='store', + default='gcc', + type='string', +) + +# ... other SConscript logic ... + try: ValidateOptions(throw_exception=True) except SConsBadOptionError as e: - print("Parser is SConsOptionParser:%s" % (isinstance(e.parser, SConsOptionParser))) - print("Message is :%s" % e.opt_str) + print(f"ValidateOptions detects a fail: ", e.opt_str) Exit(3) - - - - This function is useful to force SCons to fail fast before you execute any expensive logic later in your - build logic. - For example if you specify build options via any flags, a simple typo could yield the incorrect build - option throughout your entire build. - - -scons --compilers=mingw (the correct flag is --compiler) - - - Could cause SCons to run configure steps with the incorrect compiler. Costing developer time trying to - track down why the configure logic failed with a compiler which should work. - - - New in version 4.5.0 - - + + + New in version 4.5.0 + + Value(value, [built_value], [name]) diff --git a/doc/generated/functions.mod b/doc/generated/functions.mod index 34424a5..7273aab 100644 --- a/doc/generated/functions.mod +++ b/doc/generated/functions.mod @@ -25,6 +25,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. Clone"> Command"> Configure"> +DebugOptions"> Decider"> Default"> DefaultEnvironment"> @@ -106,6 +107,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. env.Clone"> env.Command"> env.Configure"> +env.DebugOptions"> env.Decider"> env.Default"> env.DefaultEnvironment"> @@ -193,6 +195,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. Clone"> Command"> Configure"> +DebugOptions"> Decider"> Default"> DefaultEnvironment"> @@ -274,6 +277,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. env.Clone"> env.Command"> env.Configure"> +env.DebugOptions"> env.Decider"> env.Default"> env.DefaultEnvironment"> diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 7579ce2..dd70c21 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -932,8 +932,10 @@ $ scons --debug=includes foo.o json -Write info for any of the following debug options if they are enabled: memory, +Write info to a JSON file for any of the following debug options if they are enabled: memory, count, time, action-timestamps + The default output file is in the top level directory named scons_stats.json + The file name/path can be modified by using DebugOptions(json='path/to/file.json') $ scons --debug=memory,json foo.o -- cgit v0.12 From a8016c61cdac9e73c77f83143cd7aa3118330cef Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 6 Jun 2023 10:42:35 -0700 Subject: Skip checking for exception when writing to unwritable dir in test. Change logic which get's nodename to work on all platforms (was failing on windows) --- SCons/Script/Main.py | 4 +++- SCons/Util/stats.py | 8 ++++---- test/option/debug-json.py | 9 ++++++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index d4b83b0..68a8183 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -533,7 +533,9 @@ def DebugOptions(json=None): try: if not os.path.isdir(json_dir): os.makedirs(json_dir, exist_ok=True) - except (FileNotFoundError, OSError) as e: + # Now try to open file and see if you can.. + open(SCons.Util.stats.JSON_OUTPUT_FILE,'w') + except OSError as e: raise SCons.Errors.UserError(f"Unable to create directory for JSON debug output file: {SCons.Util.stats.JSON_OUTPUT_FILE}") diff --git a/SCons/Util/stats.py b/SCons/Util/stats.py index 58fa5dd..d2f2574 100644 --- a/SCons/Util/stats.py +++ b/SCons/Util/stats.py @@ -33,7 +33,7 @@ There are basically two types of stats. though it might be useful to query during a run. """ -import os +import platform import json import sys from datetime import datetime @@ -190,7 +190,7 @@ def WriteJsonFile(): 'COMMAND_LINE_TARGETS' : [ str(clt) for clt in COMMAND_LINE_TARGETS], 'ARGV' : sys.argv, 'TIME' : datetime.now().isoformat(), - 'HOST' : os.uname().nodename, + 'HOST' : platform.node(), 'PYTHON_VERSION' : { 'major' : sys.version_info.major, 'minor' : sys.version_info.minor, @@ -201,9 +201,9 @@ def WriteJsonFile(): } - with open(JSON_OUTPUT_FILE, 'w') as sf: - sf.write(json.dumps(json_structure, indent=4)) + sf.write(json.dumps(json_structure, indent=4)) + # Local Variables: # tab-width:4 diff --git a/test/option/debug-json.py b/test/option/debug-json.py index f3e6e0f..867f3c2 100644 --- a/test/option/debug-json.py +++ b/test/option/debug-json.py @@ -32,6 +32,7 @@ import re import sys import TestSCons +from TestCmd import IS_WINDOWS test = TestSCons.TestSCons() @@ -81,9 +82,11 @@ test.run(arguments='--debug=count,json JSON=build/output/stats.json') test.must_exist('build/output/stats.json') check_json_file('build/output/stats.json') -test.run(arguments='--debug=count,json JSON=/cant/write/here/dumb.json', status=2, stderr=None) -test.must_not_exist('/cant/write/here/dumb.json') -test.pass_test('scons: *** Unable to create directory for JSON debug output file:' in test.stderr()) +# TODO: Not sure how to do this in a reasonable way on windows, so just skip for now +if not IS_WINDOWS: + test.run(arguments='--debug=count,json JSON=/cant/write/here/dumb.json', status=2, stderr=None) + test.must_not_exist('/cant/write/here/dumb.json') + test.pass_test('scons: *** Unable to create directory for JSON debug output file:' in test.stderr()) test.pass_test() -- cgit v0.12 From d0605a2fb9da48068c37440f6826b31d23a6805a Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 6 Jun 2023 07:26:31 -0600 Subject: Maint: turn ActionBase into abstract class Align some function sigs that were missing a kwarg. Sorted the imports. Signed-off-by: Mats Wichmann --- CHANGES.txt | 4 ++++ SCons/Action.py | 64 +++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 2584583..78cbadf 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -64,6 +64,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER sufficient just to check the build worked. Renamed the fixture dir to follow naming convention in test/MSVC overall, and added a sconstest.skip file, also to follow convention. + - Class ActionBase is now an abstract base class to more accurately + reflect its usage. Derived _ActionAction inherits the ABC, so it + now declares (actually raises NotImplementedError) two methods it + doesn't use so it can be instantiated by unittests and others. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Action.py b/SCons/Action.py index fcc6f3f..8748985 100644 --- a/SCons/Action.py +++ b/SCons/Action.py @@ -100,21 +100,22 @@ way for wrapping up the functions. """ +import inspect import os import pickle import re -import sys import subprocess -from subprocess import DEVNULL -import inspect +import sys +from abc import ABC, abstractmethod from collections import OrderedDict +from subprocess import DEVNULL +from typing import Union import SCons.Debug -import SCons.Util -from SCons.Debug import logInstanceCreation import SCons.Errors -import SCons.Util import SCons.Subst +import SCons.Util +from SCons.Debug import logInstanceCreation # we use these a lot, so try to optimize them from SCons.Util import is_String, is_List @@ -441,7 +442,7 @@ def _do_create_action(act, kw): This handles the fact that passing lists to :func:`Action` itself has different semantics than passing lists as elements of lists. The former will create a :class:`ListAction`, the latter will create a - :class:`CommandAction by converting the inner list elements to strings. + :class:`CommandAction` by converting the inner list elements to strings. """ if isinstance(act, ActionBase): return act @@ -518,11 +519,26 @@ def Action(act, *args, **kw): return _do_create_action(act, kw) -class ActionBase: +class ActionBase(ABC): """Base class for all types of action objects that can be held by other objects (Builders, Executors, etc.) This provides the common methods for manipulating and combining those actions.""" + @abstractmethod + def __call__( + self, + target, + source, + env, + exitstatfunc=_null, + presub=_null, + show=_null, + execute=_null, + chdir=_null, + executor=None, + ): + raise NotImplementedError + def __eq__(self, other): return self.__dict__ == other @@ -534,6 +550,14 @@ class ActionBase: def genstring(self, target, source, env): return str(self) + @abstractmethod + def get_presig(self, target, source, env, executor=None): + raise NotImplementedError + + @abstractmethod + def get_implicit_deps(self, target, source, env, executor=None): + raise NotImplementedError + def get_contents(self, target, source, env): result = self.get_presig(target, source, env) @@ -722,6 +746,16 @@ class _ActionAction(ActionBase): return stat + # Stub these two only so _ActionAction can be instantiated. It's really + # an ABC like parent ActionBase, but things reach in and use it. It's + # not just unittests or we could fix it up with a concrete subclass there. + + def get_presig(self, target, source, env, executor=None): + raise NotImplementedError + + def get_implicit_deps(self, target, source, env, executor=None): + raise NotImplementedError + def _string_from_cmd_list(cmd_list): """Takes a list of command line arguments and returns a pretty @@ -1223,10 +1257,14 @@ class LazyAction(CommandGeneratorAction, CommandAction): c = self.get_parent_class(env) return c.__call__(self, target, source, env, *args, **kw) - def get_presig(self, target, source, env): + def get_presig(self, target, source, env, executor=None): c = self.get_parent_class(env) return c.get_presig(self, target, source, env) + def get_implicit_deps(self, target, source, env, executor=None): + c = self.get_parent_class(env) + return c.get_implicit_deps(self, target, source, env) + def get_varlist(self, target, source, env, executor=None): c = self.get_parent_class(env) return c.get_varlist(self, target, source, env, executor) @@ -1345,14 +1383,14 @@ class FunctionAction(_ActionAction): # more information about this issue. del exc_info - def get_presig(self, target, source, env): + def get_presig(self, target, source, env, executor=None): """Return the signature contents of this callable action.""" try: return self.gc(target, source, env) except AttributeError: return self.funccontents - def get_implicit_deps(self, target, source, env): + def get_implicit_deps(self, target, source, env, executor=None): return [] class ListAction(ActionBase): @@ -1379,7 +1417,7 @@ class ListAction(ActionBase): return SCons.Util.flatten_sequence( [a.presub_lines(env) for a in self.list]) - def get_presig(self, target, source, env): + def get_presig(self, target, source, env, executor=None): """Return the signature contents of this action list. Simple concatenation of the signatures of the elements. @@ -1398,7 +1436,7 @@ class ListAction(ActionBase): return stat return 0 - def get_implicit_deps(self, target, source, env): + def get_implicit_deps(self, target, source, env, executor=None): result = [] for act in self.list: result.extend(act.get_implicit_deps(target, source, env)) -- cgit v0.12 From 5a1e170535202eae20aea6423ac5aaa78fa54efd Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 20 Jan 2023 10:45:25 -0700 Subject: Minor scanner tweaks Marked a couple of scanner methods that don't use "self" as @staticmethod for consistency. Signed-off-by: Mats Wichmann --- CHANGES.txt | 1 + SCons/Scanner/D.py | 3 ++- SCons/Scanner/JavaTests.py | 4 ++-- SCons/Scanner/LaTeX.py | 3 ++- SCons/Scanner/__init__.py | 6 ++++-- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 2584583..f9e6cb1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -64,6 +64,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER sufficient just to check the build worked. Renamed the fixture dir to follow naming convention in test/MSVC overall, and added a sconstest.skip file, also to follow convention. + - Marked some scanner methods as @staticmethod. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Scanner/D.py b/SCons/Scanner/D.py index f4366df..9bc608f 100644 --- a/SCons/Scanner/D.py +++ b/SCons/Scanner/D.py @@ -43,7 +43,8 @@ class D(Classic): regex=r'(?:import\s+)([\w\s=,.]+)(?:\s*:[\s\w,=]+)?(?:;)', ) - def find_include(self, include, source_dir, path): + @staticmethod + def find_include(include, source_dir, path): # translate dots (package separators) to slashes inc = include.replace('.', '/') diff --git a/SCons/Scanner/JavaTests.py b/SCons/Scanner/JavaTests.py index cf4ca83..38a4bdb 100644 --- a/SCons/Scanner/JavaTests.py +++ b/SCons/Scanner/JavaTests.py @@ -54,8 +54,8 @@ for fname in subfiles: test.write(fname.split('/'), "\n") class DummyEnvironment(collections.UserDict): - def __init__(self,**kw) -> None: - collections.UserDict.__init__(self) + def __init__(self, **kw) -> None: + super().__init__() self.data.update(kw) self.fs = SCons.Node.FS.FS(test.workpath('')) self['ENV'] = {} diff --git a/SCons/Scanner/LaTeX.py b/SCons/Scanner/LaTeX.py index 6abe736..4412aee 100644 --- a/SCons/Scanner/LaTeX.py +++ b/SCons/Scanner/LaTeX.py @@ -289,7 +289,8 @@ class LaTeX(ScannerBase): return [filename+e for e in self.graphics_extensions] return [filename] - def sort_key(self, include): + @staticmethod + def sort_key(include): return SCons.Node.FS._my_normcase(str(include)) def find_include(self, include, source_dir, path): diff --git a/SCons/Scanner/__init__.py b/SCons/Scanner/__init__.py index c8c2732..61ba8a9 100644 --- a/SCons/Scanner/__init__.py +++ b/SCons/Scanner/__init__.py @@ -415,7 +415,8 @@ class ClassicCPP(Classic): to the constructor must return the leading bracket in group 0, and the contained filename in group 1. """ - def find_include(self, include, source_dir, path): + @staticmethod + def find_include(include, source_dir, path): include = list(map(SCons.Util.to_str, include)) if include[0] == '"': paths = (source_dir,) + tuple(path) @@ -426,7 +427,8 @@ class ClassicCPP(Classic): i = SCons.Util.silent_intern(include[1]) return n, i - def sort_key(self, include): + @staticmethod + def sort_key(include): return SCons.Node.FS._my_normcase(' '.join(include)) # Local Variables: -- cgit v0.12 From eb440a02930e3aff35b6dcc85462a4035e764aee Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 8 Jun 2023 07:51:50 -0700 Subject: [ci skip] Add blurb to RELEASE.txt --- RELEASE.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RELEASE.txt b/RELEASE.txt index e71e2b6..865ae30 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -72,7 +72,10 @@ DEVELOPMENT to test files, which allows test lists, exclude lists, and tests on the command line to "not care" about the OS convention for pathname separators. - +- Class ActionBase is now an abstract base class to more accurately + reflect its usage. Derived _ActionAction inherits the ABC, so it + now declares (actually raises NotImplementedError) two methods it + doesn't use so it can be instantiated by unittests and others. Thanks to the following contributors listed below for their contributions to this release. ========================================================================================== -- cgit v0.12 From c8e8cae80d894b5e7971ae3bef1e6acebfccb201 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 8 Jun 2023 10:07:25 -0700 Subject: Address mwichmann's comments on PR. pep8 naming, abstract base class Stats, quiet some linting warnings where the use is intentional --- SCons/Script/Main.py | 18 ++++++++++-------- SCons/Util/stats.py | 21 ++++++++++++--------- doc/man/scons.xml | 6 +++--- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 68a8183..861f57a 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -59,7 +59,7 @@ import SCons.Taskmaster import SCons.Util import SCons.Warnings import SCons.Script.Interactive -from SCons.Util.stats import COUNT_STATS, MEMORY_STATS, TIME_STATS, ENABLE_JSON, WriteJsonFile, JSON_OUTPUT_FILE +from SCons.Util.stats import COUNT_STATS, MEMORY_STATS, TIME_STATS, ENABLE_JSON, write_scons_stats_file, JSON_OUTPUT_FILE from SCons import __version__ as SConsVersion @@ -534,7 +534,8 @@ def DebugOptions(json=None): if not os.path.isdir(json_dir): os.makedirs(json_dir, exist_ok=True) # Now try to open file and see if you can.. - open(SCons.Util.stats.JSON_OUTPUT_FILE,'w') + with open(SCons.Util.stats.JSON_OUTPUT_FILE,'w') as js: + pass except OSError as e: raise SCons.Errors.UserError(f"Unable to create directory for JSON debug output file: {SCons.Util.stats.JSON_OUTPUT_FILE}") @@ -669,8 +670,10 @@ def _SConstruct_exists( return sfile return None + def _set_debug_values(options) -> None: - global print_memoizer, print_objects, print_stacktrace, print_time, print_action_timestamps + global print_memoizer, print_objects, print_stacktrace, print_time, \ + print_action_timestamps, ENABLE_JSON debug_values = options.debug @@ -720,9 +723,7 @@ def _set_debug_values(options) -> None: if "duplicate" in debug_values: SCons.Node.print_duplicate = True if "json" in debug_values: - SCons.Util.stats.ENABLE_JSON = True - if "json" in debug_values: - SCons.Util.stats.ENABLE_JSON = True + ENABLE_JSON = True def _create_path(plist): path = '.' @@ -1431,6 +1432,7 @@ def main() -> None: global OptionsParser global exit_status global first_command_start + global ENABLE_JSON # Check up front for a Python version we do not support. We # delay the check for deprecated Python versions until later, @@ -1524,8 +1526,8 @@ def main() -> None: TIME_STATS.total_times(total_time, sconscript_time, scons_time, ct) - if SCons.Util.stats.ENABLE_JSON: - WriteJsonFile() + if ENABLE_JSON: + write_scons_stats_file() sys.exit(exit_status) diff --git a/SCons/Util/stats.py b/SCons/Util/stats.py index d2f2574..3223c86 100644 --- a/SCons/Util/stats.py +++ b/SCons/Util/stats.py @@ -33,6 +33,8 @@ There are basically two types of stats. though it might be useful to query during a run. """ +from abc import ABC + import platform import json import sys @@ -40,21 +42,21 @@ from datetime import datetime import SCons.Debug -ALL_STATS = {} +all_stats = {} ENABLE_JSON = False JSON_OUTPUT_FILE = 'scons_stats.json' -def AddStatType(name, stat_object): +def add_stat_type(name, stat_object): """ Add a statistic type to the global collection """ - if name in ALL_STATS: + if name in all_stats: raise UserWarning(f'Stat type {name} already exists') else: - ALL_STATS[name] = stat_object + all_stats[name] = stat_object -class Stats: +class Stats(ABC): def __init__(self): self.stats = [] self.labels = [] @@ -151,14 +153,15 @@ MEMORY_STATS = MemStats() TIME_STATS = TimeStats() - -def WriteJsonFile(): +def write_scons_stats_file(): """ Actually write the JSON file with debug information. Depending which of : count, time, action-timestamps,memory their information will be written. """ - from SCons.Script import BUILD_TARGETS, COMMAND_LINE_TARGETS, ARGUMENTS, ARGLIST + # Have to import where used to avoid import loop + from SCons.Script import BUILD_TARGETS, COMMAND_LINE_TARGETS, ARGUMENTS, \ + ARGLIST # [import-outside-toplevel] # print(f"DUMPING JSON FILE: {JSON_OUTPUT_FILE}") json_structure = {} @@ -202,7 +205,7 @@ def WriteJsonFile(): with open(JSON_OUTPUT_FILE, 'w') as sf: - sf.write(json.dumps(json_structure, indent=4)) + sf.write(json.dumps(json_structure, indent=4)) # Local Variables: diff --git a/doc/man/scons.xml b/doc/man/scons.xml index dd70c21..80d16c0 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -932,10 +932,10 @@ $ scons --debug=includes foo.o json -Write info to a JSON file for any of the following debug options if they are enabled: memory, + Write info to a JSON file for any of the following debug options if they are enabled: memory, count, time, action-timestamps - The default output file is in the top level directory named scons_stats.json - The file name/path can be modified by using DebugOptions(json='path/to/file.json') + The default output file is scons_stats.json + The file name/path can be modified by using &f-link-DebugOptions; for example DebugOptions(json='path/to/file.json') $ scons --debug=memory,json foo.o -- cgit v0.12 From 68594e090d543e9698b1c60d34b236dbc95bc6bf Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 8 Jun 2023 19:42:01 -0700 Subject: refeactor module variables to be lower case per mwichmann's review --- SCons/Script/Main.py | 34 +++++++++++++++++----------------- SCons/Util/stats.py | 22 +++++++++++----------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 861f57a..c9cd486 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -59,7 +59,7 @@ import SCons.Taskmaster import SCons.Util import SCons.Warnings import SCons.Script.Interactive -from SCons.Util.stats import COUNT_STATS, MEMORY_STATS, TIME_STATS, ENABLE_JSON, write_scons_stats_file, JSON_OUTPUT_FILE +from SCons.Util.stats import count_stats, memory_stats, time_stats, ENABLE_JSON, write_scons_stats_file, JSON_OUTPUT_FILE from SCons import __version__ as SConsVersion @@ -229,7 +229,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): "Command execution end timestamp: %s: %f\n" % (str(self.node), finish_time) ) - TIME_STATS.add_command(str(self.node), start_time, finish_time) + time_stats.add_command(str(self.node), start_time, finish_time) sys.stdout.write( "Command execution time: %s: %f seconds\n" % (str(self.node), (finish_time - start_time)) @@ -685,7 +685,7 @@ def _set_debug_values(options) -> None: enable_count = False if __debug__: enable_count = True if enable_count: - COUNT_STATS.enable(sys.stdout) + count_stats.enable(sys.stdout) SCons.Debug.track_instances = True else: msg = "--debug=count is not supported when running SCons\n" + \ @@ -699,7 +699,7 @@ def _set_debug_values(options) -> None: options.debug_includes = "includes" in debug_values print_memoizer = "memoizer" in debug_values if "memory" in debug_values: - MEMORY_STATS.enable(sys.stdout) + memory_stats.enable(sys.stdout) print_objects = ("objects" in debug_values) if print_objects: SCons.Debug.track_instances = True @@ -711,8 +711,8 @@ def _set_debug_values(options) -> None: options.tree_printers.append(TreePrinter(status=True)) if "time" in debug_values: print_time = True - TIME_STATS.enable(sys.stdout) - TIME_STATS.enable(sys.stdout) + time_stats.enable(sys.stdout) + time_stats.enable(sys.stdout) if "action-timestamps" in debug_values: print_time = True print_action_timestamps = True @@ -1056,8 +1056,8 @@ def _main(parser): if not hasattr(sys.stderr, 'isatty') or not sys.stderr.isatty(): sys.stderr = SCons.Util.Unbuffered(sys.stderr) - MEMORY_STATS.append('before reading SConscript files:') - COUNT_STATS.append(('pre-', 'read')) + memory_stats.append('before reading SConscript files:') + count_stats.append(('pre-', 'read')) # And here's where we (finally) read the SConscript files. @@ -1083,8 +1083,8 @@ def _main(parser): progress_display("scons: done reading SConscript files.") - MEMORY_STATS.append('after reading SConscript files:') - COUNT_STATS.append(('post-', 'read')) + memory_stats.append('after reading SConscript files:') + count_stats.append(('post-', 'read')) # Re-{enable,disable} warnings in case they disabled some in # the SConscript file. @@ -1336,8 +1336,8 @@ def _build_targets(fs, options, targets, target_top): if msg: SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg) - MEMORY_STATS.append('before building targets:') - COUNT_STATS.append(('pre-', 'build')) + memory_stats.append('before building targets:') + count_stats.append(('pre-', 'build')) def jobs_postfunc( jobs=jobs, @@ -1365,8 +1365,8 @@ def _build_targets(fs, options, targets, target_top): progress_display("scons: " + opening_message) jobs.run(postfunc = jobs_postfunc) - MEMORY_STATS.append('after building targets:') - COUNT_STATS.append(('post-', 'build')) + memory_stats.append('after building targets:') + count_stats.append(('post-', 'build')) return nodes @@ -1492,8 +1492,8 @@ def main() -> None: SCons.Script._SConscript.SConscript_exception() sys.exit(2) - MEMORY_STATS.print_stats() - COUNT_STATS.print_stats() + memory_stats.print_stats() + count_stats.print_stats() if print_objects: SCons.Debug.listLoggedInstances('*') @@ -1523,7 +1523,7 @@ def main() -> None: print("Total SConscript file execution time: %f seconds"%sconscript_time) print("Total SCons execution time: %f seconds"%scons_time) print("Total command execution time: %f seconds"%ct) - TIME_STATS.total_times(total_time, sconscript_time, scons_time, ct) + time_stats.total_times(total_time, sconscript_time, scons_time, ct) if ENABLE_JSON: diff --git a/SCons/Util/stats.py b/SCons/Util/stats.py index 3223c86..22135e3 100644 --- a/SCons/Util/stats.py +++ b/SCons/Util/stats.py @@ -148,9 +148,9 @@ class TimeStats(Stats): 'duration': finish_time - start_time} -COUNT_STATS = CountStats() -MEMORY_STATS = MemStats() -TIME_STATS = TimeStats() +count_stats = CountStats() +memory_stats = MemStats() +time_stats = TimeStats() def write_scons_stats_file(): @@ -165,25 +165,25 @@ def write_scons_stats_file(): # print(f"DUMPING JSON FILE: {JSON_OUTPUT_FILE}") json_structure = {} - if COUNT_STATS.enabled: + if count_stats.enabled: json_structure['Object counts'] = {} oc = json_structure['Object counts'] - for c in COUNT_STATS.stats_table: + for c in count_stats.stats_table: oc[c] = {} - for l, v in zip(COUNT_STATS.labels, COUNT_STATS.stats_table[c]): + for l, v in zip(count_stats.labels, count_stats.stats_table[c]): oc[c][''.join(l)] = v - if MEMORY_STATS.enabled: + if memory_stats.enabled: json_structure['Memory'] = {} m = json_structure['Memory'] - for label, stats in zip(MEMORY_STATS.labels, MEMORY_STATS.stats): + for label, stats in zip(memory_stats.labels, memory_stats.stats): m[label] = stats - if TIME_STATS.enabled: - json_structure['Time'] = {'Commands': TIME_STATS.commands, - 'Totals': TIME_STATS.totals} + if time_stats.enabled: + json_structure['Time'] = {'Commands': time_stats.commands, + 'Totals': time_stats.totals} # Now add information about this build to the JSON file json_structure['Build_Info'] = { -- cgit v0.12 From cb4d8c9016441047758c8b1f0c0f9ef945d48873 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 23 May 2023 10:08:09 -0600 Subject: Followon to PR #4348: more bool fixes Manually fixed up some things related to bool, e.g. simple functions which just did "return 1" were interpreted by the tool as returning int, when bool was really the intent. Functions/methods named like "is*", "has*", "exists", "rexists" (and others) are now pretty consistently marked as returning bool. A couple of minor alignments of branched definitions, and a couple of docstring adjustments made. If Tools which had old heading style were touched, they got the new style. Signed-off-by: Mats Wichmann --- CHANGES.txt | 5 +++ RELEASE.txt | 1 + SCons/ActionTests.py | 6 +-- SCons/Builder.py | 6 +-- SCons/BuilderTests.py | 6 +-- SCons/CacheDir.py | 7 +++- SCons/Debug.py | 4 +- SCons/Defaults.py | 4 +- SCons/Environment.py | 20 ++++------ SCons/ExecutorTests.py | 6 +-- SCons/Node/Alias.py | 8 ++-- SCons/Node/FS.py | 76 ++++++++++++++++++------------------- SCons/Node/NodeTests.py | 7 ++-- SCons/Node/Python.py | 4 +- SCons/Node/__init__.py | 63 +++++++++++++++--------------- SCons/SConf.py | 13 ++++--- SCons/SConfTests.py | 12 +++--- SCons/Scanner/JavaTests.py | 4 +- SCons/Scanner/ProgTests.py | 8 ++-- SCons/Scanner/ScannerTests.py | 45 +++++++++++----------- SCons/Subst.py | 16 ++++---- SCons/SubstTests.py | 41 ++++++++++---------- SCons/Taskmaster/TaskmasterTests.py | 22 +++++------ SCons/Tool/DCommon.py | 8 ++-- SCons/Tool/JavaCommon.py | 4 +- SCons/Tool/MSCommon/MSVC/Util.py | 6 +-- SCons/Tool/MSCommon/common.py | 7 ++-- SCons/Tool/cxx.py | 28 +++++++------- SCons/Tool/cyglink.py | 4 +- SCons/Tool/default.py | 25 +++++------- SCons/Tool/docbook/__init__.py | 27 ++++++------- SCons/Tool/dvi.py | 18 ++++----- SCons/Tool/filesystem.py | 24 +++++------- SCons/Tool/install.py | 4 +- SCons/Tool/javac.py | 10 ++--- SCons/Tool/linkCommon/__init__.py | 2 +- SCons/Tool/msvsTests.py | 27 +++++++------ SCons/Tool/ninja/Utils.py | 6 +-- SCons/Tool/packaging/__init__.py | 4 +- SCons/Tool/packaging/msi.py | 25 ++++++------ SCons/Tool/packaging/rpm.py | 14 ++----- SCons/Tool/pdf.py | 23 +++++------ SCons/Tool/rmic.py | 25 +++++------- SCons/Tool/textfile.py | 45 ++++++++++------------ SCons/UtilTests.py | 36 +++++++++--------- SCons/cppTests.py | 2 +- 46 files changed, 358 insertions(+), 400 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d292d84..fc51163 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -24,6 +24,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER add missed versionadded indicator. - Added some typing annotations generated by a tool, to eliminate manual work in future on things which are safe for the tool to produce. + Then manually fixed up some things related to bool that the tool did + not handly idealls. For example, simple functions which just did + "return 1" were interpreted by the tool as returning int, when bool + was really the intent. Functions/methods named like "is_*", "has_*", + "exists" are now pretty consistently marked as "-> bool". - Simplify some code due to pylint observation: "C2801: Unnecessarily calls dunder method __call__. Invoke instance directly." - Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1. diff --git a/RELEASE.txt b/RELEASE.txt index bd4be6b..bb0ca0f 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -79,6 +79,7 @@ DEVELOPMENT reflect its usage. Derived _ActionAction inherits the ABC, so it now declares (actually raises NotImplementedError) two methods it doesn't use so it can be instantiated by unittests and others. +- Added more type annotations to internal routines. Thanks to the following contributors listed below for their contributions to this release. ========================================================================================== diff --git a/SCons/ActionTests.py b/SCons/ActionTests.py index 533a007..07fa297 100644 --- a/SCons/ActionTests.py +++ b/SCons/ActionTests.py @@ -109,7 +109,7 @@ class CmdStringHolder: self.data = str(cmd) self.literal = literal - def is_literal(self): + def is_literal(self) -> bool: return self.literal def escape(self, escape_func): @@ -1265,8 +1265,8 @@ class CommandActionTestCase(unittest.TestCase): def escape(self, escape_func): return escape_func(self.data) - def is_literal(self) -> int: - return 1 + def is_literal(self) -> bool: + return True a = SCons.Action.CommandAction(["xyzzy"]) e = Environment(SPAWN=func) diff --git a/SCons/Builder.py b/SCons/Builder.py index bdedc3a..a11524e 100644 --- a/SCons/Builder.py +++ b/SCons/Builder.py @@ -385,10 +385,10 @@ class BuilderBase: emitter = None, multi: int = 0, env = None, - single_source: int = 0, + single_source: bool = False, name = None, chdir = _null, - is_explicit: int = 1, + is_explicit: bool = True, src_builder = None, ensure_suffix: bool = False, **overrides) -> None: @@ -889,7 +889,7 @@ class CompositeBuilder(SCons.Util.Proxy): self.cmdgen.add_action(suffix, action) self.set_src_suffix(self.cmdgen.src_suffixes()) -def is_a_Builder(obj): +def is_a_Builder(obj) -> bool: """"Returns True if the specified obj is one of our Builder classes. The test is complicated a bit by the fact that CompositeBuilder diff --git a/SCons/BuilderTests.py b/SCons/BuilderTests.py index 3ba5285..379d18b 100644 --- a/SCons/BuilderTests.py +++ b/SCons/BuilderTests.py @@ -170,15 +170,15 @@ class MyNode_without_target_from_source: return self.builder is not None def set_explicit(self, is_explicit) -> None: self.is_explicit = is_explicit - def has_explicit_builder(self): + def has_explicit_builder(self) -> bool: return self.is_explicit - def env_set(self, env, safe: int=0) -> None: + def env_set(self, env, safe: bool=False) -> None: self.env = env def add_source(self, source) -> None: self.sources.extend(source) def scanner_key(self): return self.name - def is_derived(self): + def is_derived(self) -> bool: return self.has_builder() def generate_build_env(self, env): return env diff --git a/SCons/CacheDir.py b/SCons/CacheDir.py index 12f1d54..a063849 100644 --- a/SCons/CacheDir.py +++ b/SCons/CacheDir.py @@ -67,7 +67,7 @@ def CacheRetrieveFunc(target, source, env) -> int: fs.chmod(t.get_internal_path(), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) return 0 -def CacheRetrieveString(target, source, env): +def CacheRetrieveString(target, source, env) -> None: t = target[0] fs = t.fs cd = env.get_CacheDir() @@ -271,7 +271,10 @@ class CacheDir: return cachedir, os.path.join(cachedir, sig) def retrieve(self, node) -> bool: - """ + """Retrieve a node from cache. + + Returns True if a successful retrieval resulted. + This method is called from multiple threads in a parallel build, so only do thread safe stuff here. Do thread unsafe stuff in built(). diff --git a/SCons/Debug.py b/SCons/Debug.py index 000ebd5..615eb4f 100644 --- a/SCons/Debug.py +++ b/SCons/Debug.py @@ -92,7 +92,7 @@ def dumpLoggedInstances(classes, file=sys.stdout) -> None: if sys.platform[:5] == "linux": # Linux doesn't actually support memory usage stats from getrusage(). - def memory(): + def memory() -> int: with open('/proc/self/stat') as f: mstr = f.read() mstr = mstr.split()[22] @@ -111,7 +111,7 @@ else: def memory() -> int: return 0 else: - def memory(): + def memory() -> int: res = resource.getrusage(resource.RUSAGE_SELF) return res[4] diff --git a/SCons/Defaults.py b/SCons/Defaults.py index 15041a5..39fdd5b 100644 --- a/SCons/Defaults.py +++ b/SCons/Defaults.py @@ -95,7 +95,7 @@ def DefaultEnvironment(*args, **kw): # going into a shared library are, in fact, shared. def StaticObjectEmitter(target, source, env): for tgt in target: - tgt.attributes.shared = None + tgt.attributes.shared = False return target, source @@ -112,7 +112,7 @@ def SharedFlagChecker(source, target, env): try: shared = src.attributes.shared except AttributeError: - shared = None + shared = False if not shared: raise SCons.Errors.UserError( "Source file: %s is static and is not compatible with shared target: %s" % (src, target[0])) diff --git a/SCons/Environment.py b/SCons/Environment.py index 2f1dcaf..4e5601e 100644 --- a/SCons/Environment.py +++ b/SCons/Environment.py @@ -507,17 +507,13 @@ class BuilderDict(UserDict): self.__setitem__(i, v) - _is_valid_var = re.compile(r'[_a-zA-Z]\w*$') -def is_valid_construction_var(varstr): - """Return if the specified string is a legitimate construction - variable. - """ +def is_valid_construction_var(varstr) -> bool: + """Return True if *varstr* is a legitimate construction variable.""" return _is_valid_var.match(varstr) - class SubstitutionEnvironment: """Base class for different flavors of construction environments. @@ -1602,21 +1598,21 @@ class Base(SubstitutionEnvironment): if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.EnvironmentClone') return clone - def _changed_build(self, dependency, target, prev_ni, repo_node=None): + def _changed_build(self, dependency, target, prev_ni, repo_node=None) -> bool: if dependency.changed_state(target, prev_ni, repo_node): - return 1 + return True return self.decide_source(dependency, target, prev_ni, repo_node) - def _changed_content(self, dependency, target, prev_ni, repo_node=None): + def _changed_content(self, dependency, target, prev_ni, repo_node=None) -> bool: return dependency.changed_content(target, prev_ni, repo_node) - def _changed_timestamp_then_content(self, dependency, target, prev_ni, repo_node=None): + def _changed_timestamp_then_content(self, dependency, target, prev_ni, repo_node=None) -> bool: return dependency.changed_timestamp_then_content(target, prev_ni, repo_node) - def _changed_timestamp_newer(self, dependency, target, prev_ni, repo_node=None): + def _changed_timestamp_newer(self, dependency, target, prev_ni, repo_node=None) -> bool: return dependency.changed_timestamp_newer(target, prev_ni, repo_node) - def _changed_timestamp_match(self, dependency, target, prev_ni, repo_node=None): + def _changed_timestamp_match(self, dependency, target, prev_ni, repo_node=None) -> bool: return dependency.changed_timestamp_match(target, prev_ni, repo_node) def Decider(self, function): diff --git a/SCons/ExecutorTests.py b/SCons/ExecutorTests.py index 24df8e7..7e5df14 100644 --- a/SCons/ExecutorTests.py +++ b/SCons/ExecutorTests.py @@ -49,7 +49,7 @@ class MyAction: return ' '.join(['GENSTRING'] + list(map(str, self.actions)) + target + source) def get_contents(self, target, source, env): return b' '.join( - [SCons.Util.to_bytes(aa) for aa in self.actions] + + [SCons.Util.to_bytes(aa) for aa in self.actions] + [SCons.Util.to_bytes(tt) for tt in target] + [SCons.Util.to_bytes(ss) for ss in source] ) @@ -99,7 +99,7 @@ class MyNode: def disambiguate(self): return self - def is_up_to_date(self): + def is_up_to_date(self) -> bool: return self.up_to_date class MyScanner: @@ -264,7 +264,7 @@ class ExecutorTestCase(unittest.TestCase): be = x.get_build_env() assert be['e'] == 1, be['e'] - + x.cleanup() x.env = MyEnvironment(eee=1) diff --git a/SCons/Node/Alias.py b/SCons/Node/Alias.py index 55c4795..f36a4ec 100644 --- a/SCons/Node/Alias.py +++ b/SCons/Node/Alias.py @@ -87,7 +87,7 @@ class AliasNodeInfo(SCons.Node.NodeInfoBase): for key, value in state.items(): if key not in ('__weakref__',): setattr(self, key, value) - + class AliasBuildInfo(SCons.Node.BuildInfoBase): __slots__ = () @@ -103,7 +103,7 @@ class Alias(SCons.Node.Node): self.name = name self.changed_since_last_build = 1 self.store_info = 0 - + def str_for_display(self): return '"' + self.__str__() + '"' @@ -116,11 +116,11 @@ class Alias(SCons.Node.Node): really_build = SCons.Node.Node.build is_up_to_date = SCons.Node.Node.children_are_up_to_date - def is_under(self, dir) -> int: + def is_under(self, dir) -> bool: # Make Alias nodes get built regardless of # what directory scons was run from. Alias nodes # are outside the filesystem: - return 1 + return True def get_contents(self): """The contents of an alias is the concatenation diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py index 58b8a5c..e6255c4 100644 --- a/SCons/Node/FS.py +++ b/SCons/Node/FS.py @@ -762,30 +762,30 @@ class Base(SCons.Node.Node): else: return None - def isdir(self): + def isdir(self) -> bool: st = self.stat() return st is not None and stat.S_ISDIR(st.st_mode) - def isfile(self): + def isfile(self) -> bool: st = self.stat() return st is not None and stat.S_ISREG(st.st_mode) if hasattr(os, 'symlink'): - def islink(self): + def islink(self) -> bool: st = self.lstat() return st is not None and stat.S_ISLNK(st.st_mode) else: def islink(self) -> bool: return False # no symlinks - def is_under(self, dir): + def is_under(self, dir) -> bool: if self is dir: - return 1 + return True else: return self.dir.is_under(dir) def set_local(self) -> None: - self._local = 1 + self._local = True def srcnode(self): """If this node is in a build path, return the node @@ -1144,10 +1144,10 @@ class LocalFS: def getsize(self, path): return os.path.getsize(path) - def isdir(self, path): + def isdir(self, path) -> bool: return os.path.isdir(path) - def isfile(self, path): + def isfile(self, path) -> bool: return os.path.isfile(path) def link(self, src, dst): @@ -1185,7 +1185,7 @@ class LocalFS: if hasattr(os, 'symlink'): - def islink(self, path): + def islink(self, path) -> bool: return os.path.islink(path) else: @@ -1914,16 +1914,15 @@ class Dir(Base): def do_duplicate(self, src) -> None: pass - def is_up_to_date(self) -> int: - """If any child is not up-to-date, then this directory isn't, - either.""" + def is_up_to_date(self) -> bool: + """If any child is not up-to-date, then this directory isn't, either.""" if self.builder is not MkdirBuilder and not self.exists(): - return 0 + return False up_to_date = SCons.Node.up_to_date for kid in self.children(): if kid.get_state() > up_to_date: - return 0 - return 1 + return False + return True def rdir(self): if not self.exists(): @@ -2474,11 +2473,8 @@ class RootDir(Dir): def entry_tpath(self, name): return self._tpath + name - def is_under(self, dir) -> int: - if self is dir: - return 1 - else: - return 0 + def is_under(self, dir) -> bool: + return True if self is dir else False def up(self): return None @@ -2713,7 +2709,7 @@ class File(Base): """Turn a file system node into a File object.""" self.scanner_paths = {} if not hasattr(self, '_local'): - self._local = 0 + self._local = False if not hasattr(self, 'released_target_info'): self.released_target_info = False @@ -3018,19 +3014,19 @@ class File(Base): if self.exists(): self.get_build_env().get_CacheDir().push(self) - def retrieve_from_cache(self): + def retrieve_from_cache(self) -> bool: """Try to retrieve the node's content from a cache This method is called from multiple threads in a parallel build, so only do thread safe stuff here. Do thread unsafe stuff in built(). - Returns true if the node was successfully retrieved. + Returns True if the node was successfully retrieved. """ if self.nocache: - return None + return False if not self.is_derived(): - return None + return False return self.get_build_env().get_CacheDir().retrieve(self) def visited(self) -> None: @@ -3310,7 +3306,7 @@ class File(Base): self.scanner_paths = None - def changed(self, node=None, allowcache: bool=False): + def changed(self, node=None, allowcache: bool=False) -> bool: """ Returns if the node is up-to-date with respect to the BuildInfo stored last time it was built. @@ -3332,14 +3328,14 @@ class File(Base): self._memo['changed'] = has_changed return has_changed - def changed_content(self, target, prev_ni, repo_node=None): + def changed_content(self, target, prev_ni, repo_node=None) -> bool: cur_csig = self.get_csig() try: return cur_csig != prev_ni.csig except AttributeError: - return 1 + return True - def changed_state(self, target, prev_ni, repo_node=None): + def changed_state(self, target, prev_ni, repo_node=None) -> bool: return self.state != SCons.Node.up_to_date @@ -3466,7 +3462,7 @@ class File(Base): return df - def changed_timestamp_then_content(self, target, prev_ni, node=None): + def changed_timestamp_then_content(self, target, prev_ni, node=None) -> bool: """ Used when decider for file is Timestamp-MD5 @@ -3527,13 +3523,13 @@ class File(Base): return False return self.changed_content(target, new_prev_ni) - def changed_timestamp_newer(self, target, prev_ni, repo_node=None): + def changed_timestamp_newer(self, target, prev_ni, repo_node=None) -> bool: try: return self.get_timestamp() > target.get_timestamp() except AttributeError: - return 1 + return True - def changed_timestamp_match(self, target, prev_ni, repo_node=None): + def changed_timestamp_match(self, target, prev_ni, repo_node=None) -> bool: """ Return True if the timestamps don't match or if there is no previous timestamp :param target: @@ -3543,13 +3539,13 @@ class File(Base): try: return self.get_timestamp() != prev_ni.timestamp except AttributeError: - return 1 + return True - def is_up_to_date(self): - """Check for whether the Node is current - In all cases self is the target we're checking to see if it's up to date - """ + def is_up_to_date(self) -> bool: + """Check for whether the Node is current. + In all cases self is the target we're checking to see if it's up to date + """ T = 0 if T: Trace('is_up_to_date(%s):' % self) if not self.exists(): @@ -3570,10 +3566,10 @@ class File(Base): raise e SCons.Node.store_info_map[self.store_info](self) if T: Trace(' 1\n') - return 1 + return True self.changed() if T: Trace(' None\n') - return None + return False else: r = self.changed() if T: Trace(' self.exists(): %s\n' % r) diff --git a/SCons/Node/NodeTests.py b/SCons/Node/NodeTests.py index e7c9e9a..42fae01 100644 --- a/SCons/Node/NodeTests.py +++ b/SCons/Node/NodeTests.py @@ -137,7 +137,7 @@ class Environment: return [] class Builder: - def __init__(self, env=None, is_explicit: int=1) -> None: + def __init__(self, env=None, is_explicit: bool=True) -> None: if env is None: env = Environment() self.env = env self.overrides = {} @@ -542,10 +542,9 @@ class NodeTestCase(unittest.TestCase): assert m is None, m def test_is_up_to_date(self) -> None: - """Test the default is_up_to_date() method - """ + """Test the default is_up_to_date() method.""" node = SCons.Node.Node() - assert node.is_up_to_date() is None + assert not node.is_up_to_date() def test_children_are_up_to_date(self) -> None: """Test the children_are_up_to_date() method used by subclasses diff --git a/SCons/Node/Python.py b/SCons/Node/Python.py index 008787a..2f285b4 100644 --- a/SCons/Node/Python.py +++ b/SCons/Node/Python.py @@ -117,11 +117,11 @@ class Value(SCons.Node.Node): is_up_to_date = SCons.Node.Node.children_are_up_to_date - def is_under(self, dir) -> int: + def is_under(self, dir) -> bool: # Make Value nodes get built regardless of # what directory scons was run from. Value nodes # are outside the filesystem: - return 1 + return True def write(self, built_value) -> None: """Set the value of the node.""" diff --git a/SCons/Node/__init__.py b/SCons/Node/__init__.py index 81ff2ff..9a8398f 100644 --- a/SCons/Node/__init__.py +++ b/SCons/Node/__init__.py @@ -109,7 +109,7 @@ interactive = False def is_derived_none(node): raise NotImplementedError -def is_derived_node(node): +def is_derived_node(node) -> bool: """ Returns true if this node is derived (i.e. built). """ @@ -118,16 +118,16 @@ def is_derived_node(node): _is_derived_map = {0 : is_derived_none, 1 : is_derived_node} -def exists_none(node): +def exists_none(node) -> bool: raise NotImplementedError -def exists_always(node) -> int: - return 1 +def exists_always(node) -> bool: + return True def exists_base(node) -> bool: return node.stat() is not None -def exists_entry(node): +def exists_entry(node) -> bool: """Return if the Entry exists. Check the file system to see what we should turn into first. Assume a file if there's no directory.""" @@ -135,7 +135,7 @@ def exists_entry(node): return _exists_map[node._func_exists](node) -def exists_file(node): +def exists_file(node) -> bool: # Duplicate from source path if we are set up to do this. if node.duplicate and not node.is_derived() and not node.linked: src = node.srcnode() @@ -245,7 +245,7 @@ _target_from_source_map = {0 : target_from_source_none, # # First, the single decider functions # -def changed_since_last_build_node(node, target, prev_ni, repo_node=None): +def changed_since_last_build_node(node, target, prev_ni, repo_node=None) -> bool: """ Must be overridden in a specific subclass to return True if this @@ -266,37 +266,37 @@ def changed_since_last_build_node(node, target, prev_ni, repo_node=None): raise NotImplementedError -def changed_since_last_build_alias(node, target, prev_ni, repo_node=None): +def changed_since_last_build_alias(node, target, prev_ni, repo_node=None) -> bool: cur_csig = node.get_csig() try: return cur_csig != prev_ni.csig except AttributeError: - return 1 + return True -def changed_since_last_build_entry(node, target, prev_ni, repo_node=None): +def changed_since_last_build_entry(node, target, prev_ni, repo_node=None) -> bool: node.disambiguate() return _decider_map[node.changed_since_last_build](node, target, prev_ni, repo_node) -def changed_since_last_build_state_changed(node, target, prev_ni, repo_node=None): +def changed_since_last_build_state_changed(node, target, prev_ni, repo_node=None) -> bool: return node.state != SCons.Node.up_to_date -def decide_source(node, target, prev_ni, repo_node=None): +def decide_source(node, target, prev_ni, repo_node=None) -> bool: return target.get_build_env().decide_source(node, target, prev_ni, repo_node) -def decide_target(node, target, prev_ni, repo_node=None): +def decide_target(node, target, prev_ni, repo_node=None) -> bool: return target.get_build_env().decide_target(node, target, prev_ni, repo_node) -def changed_since_last_build_python(node, target, prev_ni, repo_node=None): +def changed_since_last_build_python(node, target, prev_ni, repo_node=None) -> bool: cur_csig = node.get_csig() try: return cur_csig != prev_ni.csig except AttributeError: - return 1 + return True # @@ -681,7 +681,7 @@ class Node(object, metaclass=NoSlotsPyPy): """ pass - def retrieve_from_cache(self) -> int: + def retrieve_from_cache(self) -> bool: """Try to retrieve the node's content from a cache This method is called from multiple threads in a parallel build, @@ -690,7 +690,7 @@ class Node(object, metaclass=NoSlotsPyPy): Returns true if the node was successfully retrieved. """ - return 0 + return False # # Taskmaster interface subsystem @@ -757,7 +757,7 @@ class Node(object, metaclass=NoSlotsPyPy): e.node = self raise - def built(self): + def built(self) -> None: """Called just after this node is successfully built.""" # Clear the implicit dependency caches of any Nodes @@ -783,7 +783,6 @@ class Node(object, metaclass=NoSlotsPyPy): except AttributeError: pass - self.clear() if self.pseudo: @@ -900,8 +899,8 @@ class Node(object, metaclass=NoSlotsPyPy): def set_explicit(self, is_explicit) -> None: self.is_explicit = is_explicit - def has_explicit_builder(self): - """Return whether this Node has an explicit builder + def has_explicit_builder(self) -> bool: + """Return whether this Node has an explicit builder. This allows an internal Builder created by SCons to be marked non-explicit, so that it can be overridden by an explicit @@ -910,8 +909,8 @@ class Node(object, metaclass=NoSlotsPyPy): try: return self.is_explicit except AttributeError: - self.is_explicit = None - return self.is_explicit + self.is_explicit = False + return False def get_builder(self, default_builder=None): """Return the set builder, or a specified default value""" @@ -922,7 +921,7 @@ class Node(object, metaclass=NoSlotsPyPy): multiple_side_effect_has_builder = has_builder - def is_derived(self): + def is_derived(self) -> bool: """ Returns true if this node is derived (i.e. built). @@ -1119,7 +1118,7 @@ class Node(object, metaclass=NoSlotsPyPy): """ return scanner.select(self) - def env_set(self, env, safe: int=0) -> None: + def env_set(self, env, safe: bool=False) -> None: if safe and self.env: return self.env = env @@ -1250,7 +1249,7 @@ class Node(object, metaclass=NoSlotsPyPy): """Set the Node's always_build value.""" self.always_build = always_build - def exists(self): + def exists(self) -> bool: """Does this node exists?""" return _exists_map[self._func_exists](self) @@ -1512,12 +1511,12 @@ class Node(object, metaclass=NoSlotsPyPy): return result - def is_up_to_date(self): + def is_up_to_date(self) -> bool: """Default check for whether the Node is current: unknown Node subtypes are always out of date, so they will always get built.""" - return None + return False - def children_are_up_to_date(self): + def children_are_up_to_date(self) -> bool: """Alternate check for whether the Node is current: If all of our children were up-to-date, then this Node was up-to-date, too. @@ -1526,7 +1525,7 @@ class Node(object, metaclass=NoSlotsPyPy): # Allow the children to calculate their signatures. self.binfo = self.get_binfo() if self.always_build: - return None + return False state = 0 for kid in self.children(None): s = kid.get_state() @@ -1534,10 +1533,10 @@ class Node(object, metaclass=NoSlotsPyPy): state = s return (state == 0 or state == SCons.Node.up_to_date) - def is_literal(self) -> int: + def is_literal(self) -> bool: """Always pass the string representation of a Node to the command interpreter literally.""" - return 1 + return True def render_include_tree(self): """ diff --git a/SCons/SConf.py b/SCons/SConf.py index 128644f..e522c8b 100644 --- a/SCons/SConf.py +++ b/SCons/SConf.py @@ -39,6 +39,7 @@ import os import re import sys import traceback +from typing import Tuple import SCons.Action import SCons.Builder @@ -265,12 +266,12 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): sys.excepthook(*self.exc_info()) return SCons.Taskmaster.Task.failed(self) - def collect_node_states(self): + def collect_node_states(self) -> Tuple[bool, bool, bool]: # returns (is_up_to_date, cached_error, cachable) - # where is_up_to_date is 1, if the node(s) are up_to_date - # cached_error is 1, if the node(s) are up_to_date, but the - # build will fail - # cachable is 0, if some nodes are not in our cache + # where is_up_to_date is True if the node(s) are up_to_date + # cached_error is True if the node(s) are up_to_date, but the + # build will fail + # cachable is False if some nodes are not in our cache T = 0 changed = False cached_error = False @@ -311,7 +312,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): if cache_mode == CACHE and not cachable: raise ConfigureCacheError(self.targets[0]) elif cache_mode == FORCE: - is_up_to_date = 0 + is_up_to_date = False if cached_error and is_up_to_date: self.display("Building \"%s\" failed in a previous run and all " diff --git a/SCons/SConfTests.py b/SCons/SConfTests.py index 96ba926..2903ba6 100644 --- a/SCons/SConfTests.py +++ b/SCons/SConfTests.py @@ -185,8 +185,8 @@ class SConfTestCase(unittest.TestCase): self.attributes = Attrs() def disambiguate(self): return self - def has_builder(self) -> int: - return 1 + def has_builder(self) -> bool: + return True def add_pre_action(self, *actions) -> None: pass def add_post_action(self, *actions) -> None: @@ -203,14 +203,14 @@ class SConfTestCase(unittest.TestCase): pass def clear(self) -> None: pass - def is_up_to_date(self): - return None + def is_up_to_date(self) -> bool: + return False def prepare(self) -> None: pass def push_to_cache(self) -> None: pass - def retrieve_from_cache(self) -> int: - return 0 + def retrieve_from_cache(self) -> bool: + return False def build(self, **kw) -> None: return def built(self) -> None: diff --git a/SCons/Scanner/JavaTests.py b/SCons/Scanner/JavaTests.py index 38a4bdb..0a3c759 100644 --- a/SCons/Scanner/JavaTests.py +++ b/SCons/Scanner/JavaTests.py @@ -96,8 +96,8 @@ class DummyNode: def __init__(self, name) -> None: self.name = name - def rexists(self) -> int: - return 1 + def rexists(self) -> bool: + return True def __str__(self) -> str: return self.name diff --git a/SCons/Scanner/ProgTests.py b/SCons/Scanner/ProgTests.py index 2798ab6..37eb48a 100644 --- a/SCons/Scanner/ProgTests.py +++ b/SCons/Scanner/ProgTests.py @@ -89,11 +89,11 @@ class DummyEnvironment: class DummyNode: def __init__(self, name) -> None: self.name = name - def rexists(self) -> int: - return 1 + def rexists(self) -> bool: + return True def __str__(self) -> str: return self.name - + def deps_match(deps, libs): deps=sorted(map(str, deps)) libs.sort() @@ -195,7 +195,7 @@ class ProgramScannerTestCase7(unittest.TestCase): class ProgramScannerTestCase8(unittest.TestCase): def runTest(self) -> None: - + n1 = DummyNode('n1') env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], LIBS=[n1], diff --git a/SCons/Scanner/ScannerTests.py b/SCons/Scanner/ScannerTests.py index 1fbbb62..a777ba5 100644 --- a/SCons/Scanner/ScannerTests.py +++ b/SCons/Scanner/ScannerTests.py @@ -124,8 +124,8 @@ class ScannerBaseTestCase(unittest.TestCase): self.key = key def scanner_key(self): return self.key - def rexists(self) -> int: - return 1 + def rexists(self) -> bool: + return True def func(self, filename, env, target, *args): self.filename = filename @@ -343,13 +343,14 @@ class ScannerBaseTestCase(unittest.TestCase): assert s == 'xyzzy', s class SelectorTestCase(unittest.TestCase): + class skey_node: def __init__(self, key) -> None: self.key = key def scanner_key(self): return self.key - def rexists(self) -> int: - return 1 + def rexists(self) -> bool: + return True def test___init__(self) -> None: """Test creation of Scanner.Selector object""" @@ -407,28 +408,28 @@ class CurrentTestCase(unittest.TestCase): self.called_has_builder = None self.called_is_up_to_date = None self.func_called = None - def rexists(self) -> int: - return 1 + def rexists(self) -> bool: + return True class HasNoBuilder(MyNode): - def has_builder(self): - self.called_has_builder = 1 - return None + def has_builder(self) -> bool: + self.called_has_builder = True + return False class IsNotCurrent(MyNode): - def has_builder(self) -> int: - self.called_has_builder = 1 - return 1 - def is_up_to_date(self): - self.called_is_up_to_date = 1 - return None + def has_builder(self) -> bool: + self.called_has_builder = True + return True + def is_up_to_date(self) -> bool: + self.called_is_up_to_date = True + return False class IsCurrent(MyNode): - def has_builder(self) -> int: - self.called_has_builder = 1 - return 1 - def is_up_to_date(self) -> int: - self.called_is_up_to_date = 1 - return 1 + def has_builder(self) -> bool: + self.called_has_builder = True + return True + def is_up_to_date(self) -> bool: + self.called_is_up_to_date = True + return True def func(node, env, path): - node.func_called = 1 + node.func_called = True return [] env = DummyEnvironment() s = Current(func) diff --git a/SCons/Subst.py b/SCons/Subst.py index 8e6d22e..4046ca6 100644 --- a/SCons/Subst.py +++ b/SCons/Subst.py @@ -71,8 +71,8 @@ class Literal: def for_signature(self): return self.lstr - def is_literal(self) -> int: - return 1 + def is_literal(self) -> bool: + return True def __eq__(self, other): if not isinstance(other, Literal): @@ -113,8 +113,8 @@ class SpecialAttrWrapper: def for_signature(self): return self.forsig - def is_literal(self) -> int: - return 1 + def is_literal(self) -> bool: + return True def quote_spaces(arg): """Generic function for putting double quotes around any string that @@ -135,7 +135,7 @@ class CmdStringHolder(collections.UserString): super().__init__(cmd) self.literal = literal - def is_literal(self): + def is_literal(self) -> bool: return self.literal def escape(self, escape_func, quote_func=quote_spaces): @@ -417,7 +417,7 @@ class StringSubber: return list(map(func, s)) elif callable(s): - # SCons has the unusual Null class where any __getattr__ call returns it's self, + # SCons has the unusual Null class where any __getattr__ call returns it's self, # which does not work the signature module, and the Null class returns an empty # string if called on, so we make an exception in this condition for Null class # Also allow callables where the only non default valued args match the expected defaults @@ -594,7 +594,7 @@ class ListSubber(collections.UserList): self.substitute(a, lvars, 1) self.next_word() elif callable(s): - # SCons has the unusual Null class where any __getattr__ call returns it's self, + # SCons has the unusual Null class where any __getattr__ call returns it's self, # which does not work the signature module, and the Null class returns an empty # string if called on, so we make an exception in this condition for Null class # Also allow callables where the only non default valued args match the expected defaults @@ -894,7 +894,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv The companion scons_subst() function (above) handles basic substitutions within strings, so see that function instead if that's what you're looking for. - """ + """ if conv is None: conv = _strconv[mode] diff --git a/SCons/SubstTests.py b/SCons/SubstTests.py index dead458..12929c6 100644 --- a/SCons/SubstTests.py +++ b/SCons/SubstTests.py @@ -40,8 +40,8 @@ class DummyNode: self.name = os.path.normpath(name) def __str__(self) -> str: return self.name - def is_literal(self) -> int: - return 1 + def is_literal(self) -> bool: + return True def rfile(self): return self def get_subst_proxy(self): @@ -136,8 +136,8 @@ class SubstTestCase(unittest.TestCase): self.literal = literal def __str__(self) -> str: return self.literal - def is_literal(self) -> int: - return 1 + def is_literal(self) -> bool: + return True class TestCallable: def __init__(self, value) -> None: @@ -1200,24 +1200,25 @@ class quote_spaces_TestCase(unittest.TestCase): def __init__(self, name, children=[]) -> None: self.children = children self.name = name + def __str__(self) -> str: return self.name - def exists(self) -> int: - return 1 - def rexists(self) -> int: - return 1 - def has_builder(self) -> int: - return 1 - def has_explicit_builder(self) -> int: - return 1 - def side_effect(self) -> int: - return 1 - def precious(self) -> int: - return 1 - def always_build(self) -> int: - return 1 - def current(self) -> int: - return 1 + def exists(self) -> bool: + return True + def rexists(self) -> bool: + return True + def has_builder(self) -> bool: + return True + def has_explicit_builder(self) -> bool: + return True + def side_effect(self) -> bool: + return True + def precious(self) -> bool: + return True + def always_build(self) -> bool: + return True + def current(self) -> bool: + return True class LiteralTestCase(unittest.TestCase): def test_Literal(self) -> None: diff --git a/SCons/Taskmaster/TaskmasterTests.py b/SCons/Taskmaster/TaskmasterTests.py index 83b7ea9..0dd91f1 100644 --- a/SCons/Taskmaster/TaskmasterTests.py +++ b/SCons/Taskmaster/TaskmasterTests.py @@ -43,8 +43,8 @@ class Node: self.name = name self.kids = kids self.scans = scans - self.cached = 0 - self.scanned = 0 + self.cached = False + self.scanned = False self.scanner = None self.targets = [self] self.prerequisites = None @@ -61,7 +61,7 @@ class Node: self.ref_count = 0 self.waiting_parents = set() self.waiting_s_e = set() - self.side_effect = 0 + self.side_effect = False self.side_effects = [] self.alttargets = [] self.postprocessed = None @@ -75,7 +75,7 @@ class Node: def push_to_cache(self) -> None: pass - def retrieve_from_cache(self): + def retrieve_from_cache(self) -> bool: global cache_text if self.cached: cache_text.append(self.name + " retrieved") @@ -147,7 +147,7 @@ class Node: def has_builder(self) -> bool: return self.builder is not None - def is_derived(self): + def is_derived(self) -> bool: return self.has_builder or self.side_effect def alter_targets(self): @@ -160,7 +160,7 @@ class Node: def children(self): if not self.scanned: self.scan() - self.scanned = 1 + self.scanned = True return self.kids def scan(self) -> None: @@ -197,7 +197,7 @@ class Node: def store_bsig(self) -> None: pass - def is_up_to_date(self): + def is_up_to_date(self) -> bool: return self._current_val def __str__(self) -> str: @@ -447,7 +447,7 @@ class TaskmasterTestCase(unittest.TestCase): n3 = Node("n3") n4 = Node("n4", [n1, n2, n3]) n5 = Node("n5", [n4]) - n3.side_effect = 1 + n3.side_effect = True n1.side_effects = n2.side_effects = n3.side_effects = [n4] tm = SCons.Taskmaster.Taskmaster([n1, n2, n3, n4, n5]) t = tm.next_task() @@ -1001,7 +1001,7 @@ class TaskmasterTestCase(unittest.TestCase): cache_text = [] n5 = Node("n5") n6 = Node("n6") - n6.cached = 1 + n6.cached = True tm = SCons.Taskmaster.Taskmaster([n5]) t = tm.next_task() # This next line is moderately bogus. We're just reaching @@ -1019,8 +1019,8 @@ class TaskmasterTestCase(unittest.TestCase): cache_text = [] n7 = Node("n7") n8 = Node("n8") - n7.cached = 1 - n8.cached = 1 + n7.cached = True + n8.cached = True tm = SCons.Taskmaster.Taskmaster([n7]) t = tm.next_task() # This next line is moderately bogus. We're just reaching diff --git a/SCons/Tool/DCommon.py b/SCons/Tool/DCommon.py index a4f976d..7bdf6f5 100644 --- a/SCons/Tool/DCommon.py +++ b/SCons/Tool/DCommon.py @@ -32,15 +32,15 @@ Coded by Russel Winder (russel@winder.org.uk) import os.path -def isD(env, source) -> int: +def isD(env, source) -> bool: if not source: - return 0 + return False for s in source: if s.sources: ext = os.path.splitext(str(s.sources[0]))[1] if ext == '.d': - return 1 - return 0 + return True + return False def addDPATHToEnv(env, executable) -> None: diff --git a/SCons/Tool/JavaCommon.py b/SCons/Tool/JavaCommon.py index 96000d0..4a5a7c5 100644 --- a/SCons/Tool/JavaCommon.py +++ b/SCons/Tool/JavaCommon.py @@ -471,7 +471,7 @@ else: # Java-file parsing takes too long (although it shouldn't relative # to how long the Java compiler itself seems to take...). - def parse_java_file(fn): + def parse_java_file(fn, version=default_java_version): """ "Parse" a .java file. This actually just splits the file name, so the assumption here @@ -511,7 +511,7 @@ def get_java_install_dirs(platform, version=None) -> List[str]: extracts the next-to-last component, then trims it further if it had a complex name, like 'java-1.8.0-openjdk-1.8.0.312-1', to try and put it on a common footing with the more common style, - which looks like 'jdk-11.0.2'. + which looks like 'jdk-11.0.2'. This is certainly fragile, and if someone has a 9.0 it won't sort right since this will still be alphabetic, BUT 9.0 was diff --git a/SCons/Tool/MSCommon/MSVC/Util.py b/SCons/Tool/MSCommon/MSVC/Util.py index 4b487da..f0e47e2 100644 --- a/SCons/Tool/MSCommon/MSVC/Util.py +++ b/SCons/Tool/MSCommon/MSVC/Util.py @@ -157,21 +157,21 @@ def get_msvc_version_prefix(version): # toolset version query utilities -def is_toolset_full(toolset_version): +def is_toolset_full(toolset_version) -> bool: rval = False if toolset_version: if re_toolset_full.match(toolset_version): rval = True return rval -def is_toolset_140(toolset_version): +def is_toolset_140(toolset_version) -> bool: rval = False if toolset_version: if re_toolset_140.match(toolset_version): rval = True return rval -def is_toolset_sxs(toolset_version): +def is_toolset_sxs(toolset_version) -> bool: rval = False if toolset_version: if re_toolset_sxs.match(toolset_version): diff --git a/SCons/Tool/MSCommon/common.py b/SCons/Tool/MSCommon/common.py index 185ccdf..0cadc10 100644 --- a/SCons/Tool/MSCommon/common.py +++ b/SCons/Tool/MSCommon/common.py @@ -161,7 +161,7 @@ def write_script_env_cache(cache) -> None: _is_win64 = None -def is_win64(): +def is_win64() -> bool: """Return true if running on windows 64 bits. Works whether python itself runs in 64 bits or 32 bits.""" @@ -196,9 +196,8 @@ def read_reg(value, hkroot=SCons.Util.HKEY_LOCAL_MACHINE): return SCons.Util.RegGetValue(hkroot, value)[0] -def has_reg(value): - """Return True if the given key exists in HKEY_LOCAL_MACHINE, False - otherwise.""" +def has_reg(value) -> bool: + """Return True if the given key exists in HKEY_LOCAL_MACHINE.""" try: SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, value) ret = True diff --git a/SCons/Tool/cxx.py b/SCons/Tool/cxx.py index bf4bcce..2cf3299 100644 --- a/SCons/Tool/cxx.py +++ b/SCons/Tool/cxx.py @@ -1,12 +1,6 @@ -"""SCons.Tool.c++ - -Tool-specific initialization for generic Posix C++ compilers. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. -""" - +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -26,7 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# + +"""Tool-specific initialization for generic Posix C++ compilers. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import os.path @@ -39,16 +39,16 @@ CXXSuffixes = ['.cpp', '.cc', '.cxx', '.c++', '.C++', '.mm'] if SCons.Util.case_sensitive_suffixes('.c', '.C'): CXXSuffixes.append('.C') -def iscplusplus(source) -> int: +def iscplusplus(source) -> bool: if not source: # Source might be None for unusual cases like SConf. - return 0 + return False for s in source: if s.sources: ext = os.path.splitext(str(s.sources[0]))[1] if ext in CXXSuffixes: - return 1 - return 0 + return True + return False def generate(env) -> None: """ diff --git a/SCons/Tool/cyglink.py b/SCons/Tool/cyglink.py index 0d1eb51..0925a3d 100644 --- a/SCons/Tool/cyglink.py +++ b/SCons/Tool/cyglink.py @@ -31,7 +31,7 @@ def cyglink_lib_emitter(target, source, env, **kw): import_lib = env.subst('$%s_IMPLIBNAME' % var_prefix, target=target, source=source) import_lib_target = env.fs.File(import_lib) - import_lib_target.attributes.shared = 1 + import_lib_target.attributes.shared = True target.append(import_lib_target) if verbose: @@ -41,7 +41,7 @@ def cyglink_lib_emitter(target, source, env, **kw): for tgt in target: if is_String(tgt): tgt = env.File(tgt) - tgt.attributes.shared = 1 + tgt.attributes.shared = True return target, source diff --git a/SCons/Tool/default.py b/SCons/Tool/default.py index 4b386e2..3ceefb1 100644 --- a/SCons/Tool/default.py +++ b/SCons/Tool/default.py @@ -1,15 +1,6 @@ -"""SCons.Tool.default - -Initialization with a default tool list. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,9 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Initialization with a default tool list. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import SCons.Tool @@ -40,8 +35,8 @@ def generate(env) -> None: for t in SCons.Tool.tool_list(env['PLATFORM'], env): SCons.Tool.Tool(t)(env) -def exists(env) -> int: - return 1 +def exists(env) -> bool: + return True # Local Variables: # tab-width:4 diff --git a/SCons/Tool/docbook/__init__.py b/SCons/Tool/docbook/__init__.py index 3af1bdb..54f1883 100644 --- a/SCons/Tool/docbook/__init__.py +++ b/SCons/Tool/docbook/__init__.py @@ -1,16 +1,6 @@ - -"""SCons.Tool.docbook - -Tool-specific initialization for Docbook. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# + +"""Tool-specific initialization for Docbook. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import os import glob @@ -43,7 +39,6 @@ import SCons.Script import SCons.Tool import SCons.Util - __debug_tool_location = False # Get full path to this script scriptpath = os.path.dirname(os.path.realpath(__file__)) @@ -839,5 +834,5 @@ def generate(env) -> None: env.AddMethod(DocbookXslt, "DocbookXslt") -def exists(env) -> int: - return 1 +def exists(env) -> bool: + return True diff --git a/SCons/Tool/dvi.py b/SCons/Tool/dvi.py index a395d2b..044f62c 100644 --- a/SCons/Tool/dvi.py +++ b/SCons/Tool/dvi.py @@ -1,11 +1,6 @@ -"""SCons.Tool.dvi - -Common DVI Builder definition for various other Tool modules that use it. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -25,9 +20,10 @@ Common DVI Builder definition for various other Tool modules that use it. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +""" +Common DVI Builder definition for various other Tool modules that use it. +""" import SCons.Builder import SCons.Tool @@ -52,10 +48,10 @@ def generate(env) -> None: env['BUILDERS']['DVI'] = DVIBuilder -def exists(env) -> int: +def exists(env) -> bool: # This only puts a skeleton Builder in place, so if someone # references this Tool directly, it's always "available." - return 1 + return True # Local Variables: # tab-width:4 diff --git a/SCons/Tool/filesystem.py b/SCons/Tool/filesystem.py index 9a977b5..d90f240 100644 --- a/SCons/Tool/filesystem.py +++ b/SCons/Tool/filesystem.py @@ -1,14 +1,6 @@ -"""SCons.Tool.filesystem - -Tool-specific initialization for the filesystem tools. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -28,9 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for the filesystem tools. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import SCons from SCons.Tool.install import copyFunc @@ -88,8 +84,8 @@ def generate(env) -> None: env['COPYSTR'] = 'Copy file(s): "$SOURCES" to "$TARGETS"' -def exists(env) -> int: - return 1 +def exists(env) -> bool: + return True # Local Variables: # tab-width:4 diff --git a/SCons/Tool/install.py b/SCons/Tool/install.py index 54fc090..5c98fb3 100644 --- a/SCons/Tool/install.py +++ b/SCons/Tool/install.py @@ -500,8 +500,8 @@ def generate(env) -> None: except KeyError: env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib -def exists(env) -> int: - return 1 +def exists(env) -> bool: + return True # Local Variables: # tab-width:4 diff --git a/SCons/Tool/javac.py b/SCons/Tool/javac.py index 6353924..a805937 100644 --- a/SCons/Tool/javac.py +++ b/SCons/Tool/javac.py @@ -21,17 +21,13 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -"""SCons.Tool.javac - -Tool-specific initialization for javac. +"""Tool-specific initialization for javac. There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() selection method. - """ - import os import os.path from collections import OrderedDict @@ -242,8 +238,8 @@ def generate(env) -> None: env['_JAVACCOM'] = '$JAVAC $JAVACFLAGS $_JAVABOOTCLASSPATH $_JAVAPROCESSORPATH $_JAVACLASSPATH -d ${TARGET.attributes.java_classdir} $_JAVASOURCEPATH $SOURCES' env['JAVACCOM'] = "${TEMPFILE('$_JAVACCOM','$JAVACCOMSTR')}" -def exists(env) -> int: - return 1 +def exists(env) -> bool: + return True # Local Variables: # tab-width:4 diff --git a/SCons/Tool/linkCommon/__init__.py b/SCons/Tool/linkCommon/__init__.py index b8d7610..f0cf4fc 100644 --- a/SCons/Tool/linkCommon/__init__.py +++ b/SCons/Tool/linkCommon/__init__.py @@ -165,6 +165,6 @@ def lib_emitter(target, source, env, **kw): for tgt in target: if SCons.Util.is_String(tgt): tgt = env.File(tgt) - tgt.attributes.shared = 1 + tgt.attributes.shared = True return target, source diff --git a/SCons/Tool/msvsTests.py b/SCons/Tool/msvsTests.py index 9c369d1..dd708d0 100644 --- a/SCons/Tool/msvsTests.py +++ b/SCons/Tool/msvsTests.py @@ -1,5 +1,6 @@ +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -19,8 +20,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import sys @@ -577,8 +576,8 @@ def DummyQueryValue(key, value): # print "Query Value",key.name+"\\"+value,"=>",rv return rv -def DummyExists(path) -> int: - return 1 +def DummyExists(path) -> bool: + return True def DummyVsWhere(msvc_version, env): # not testing versions with vswhere, so return none @@ -642,12 +641,12 @@ class msvsTestCase(unittest.TestCase): assert not v1 or str(v1[0]) == self.highest_version, \ (v1, self.highest_version) assert len(v1) == self.number_of_versions, v1 - + def test_config_generation(self) -> None: """Test _DSPGenerator.__init__(...)""" if not self.highest_version : return - + # Initialize 'static' variables version_num, suite = msvs_parse_version(self.highest_version) if version_num >= 10.0: @@ -663,16 +662,16 @@ class msvsTestCase(unittest.TestCase): # Avoid any race conditions between the test cases when we test # actually writing the files. dspfile = 'test%s%s' % (hash(self), suffix) - + str_function_test = str(function_test.__init__) source = 'test.cpp' - + # Create the cmdargs test list list_variant = ['Debug|Win32','Release|Win32', 'Debug|x64', 'Release|x64'] - list_cmdargs = ['debug=True target_arch=32', + list_cmdargs = ['debug=True target_arch=32', 'debug=False target_arch=32', - 'debug=True target_arch=x64', + 'debug=True target_arch=x64', 'debug=False target_arch=x64'] list_cppdefines = [['_A', '_B', 'C'], ['_B', '_C_'], ['D'], []] list_cpppaths = [[r'C:\test1'], [r'C:\test1;C:\test2'], @@ -775,15 +774,15 @@ class msvsTestCase(unittest.TestCase): class _DummyEnv(DummyEnv): def subst(self, string, *args, **kwargs): return string - + env = _DummyEnv(param_dict) env['MSVSSCONSCRIPT'] = '' env['MSVS_VERSION'] = self.highest_version env['MSVSBUILDTARGET'] = 'target' - + # Call function to test genDSP = function_test(dspfile, source, env) - + # Check expected result self.assertListEqual(list(genDSP.configs.keys()), list(expected_configs.keys())) for key, v in genDSP.configs.items(): diff --git a/SCons/Tool/ninja/Utils.py b/SCons/Tool/ninja/Utils.py index eb09daf..7c85f62 100644 --- a/SCons/Tool/ninja/Utils.py +++ b/SCons/Tool/ninja/Utils.py @@ -59,11 +59,11 @@ def ninja_add_command_line_options() -> None: action="store_true", default=False, help='Allow scons to skip regeneration of the ninja file and restarting of the daemon. ' + - 'Care should be taken in cases where Glob is in use or SCons generated files are used in ' + + 'Care should be taken in cases where Glob is in use or SCons generated files are used in ' + 'command lines.') -def is_valid_dependent_node(node): +def is_valid_dependent_node(node) -> bool: """ Return True if node is not an alias or is an alias that has children @@ -76,7 +76,7 @@ def is_valid_dependent_node(node): are valid implicit dependencies. """ if isinstance(node, SCons.Node.Alias.Alias): - return node.children() + return bool(node.children()) return not node.get_env().get("NINJA_SKIP") diff --git a/SCons/Tool/packaging/__init__.py b/SCons/Tool/packaging/__init__.py index c8e530d..ea2f429 100644 --- a/SCons/Tool/packaging/__init__.py +++ b/SCons/Tool/packaging/__init__.py @@ -218,8 +218,8 @@ def generate(env) -> None: env['BUILDERS']['Tag'] = Tag -def exists(env) -> int: - return 1 +def exists(env) -> bool: + return True def options(opts) -> None: diff --git a/SCons/Tool/packaging/msi.py b/SCons/Tool/packaging/msi.py index a0bed8f..6746db8 100644 --- a/SCons/Tool/packaging/msi.py +++ b/SCons/Tool/packaging/msi.py @@ -1,11 +1,7 @@ -"""SCons.Tool.packaging.msi - -The msi packager. -""" - +# MIT License +# +# Copyright The SCons Foundation # -# __COPYRIGHT__ -# # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including @@ -25,7 +21,7 @@ The msi packager. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""The msi packager.""" import os import SCons @@ -78,9 +74,8 @@ def convert_to_id(s, id_set): return id_set[id][s] -def is_dos_short_file_name(file): - """ Examine if the given file is in the 8.3 form. - """ +def is_dos_short_file_name(file) -> bool: + """Examine if the given file is in the 8.3 form.""" fname, ext = os.path.splitext(file) proper_ext = len(ext) == 0 or (2 <= len(ext) <= 4) # the ext contains the dot proper_fname = file.isupper() and len(fname) <= 8 @@ -88,9 +83,11 @@ def is_dos_short_file_name(file): return proper_ext and proper_fname def gen_dos_short_file_name(file, filename_set): - """ See http://support.microsoft.com/default.aspx?scid=kb;en-us;Q142982 + """Return a filename in the 8.3 form. + + See http://support.microsoft.com/default.aspx?scid=kb;en-us;Q142982 - These are no complete 8.3 dos short names. The ~ char is missing and + These are no complete 8.3 dos short names. The ~ char is missing and replaced with one character from the filename. WiX warns about such filenames, since a collision might occur. Google for "CNDL1014" for more information. @@ -298,7 +295,7 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, for d in dir_parts[:]: already_created = [c for c in Directory.childNodes if c.nodeName == 'Directory' - and c.attributes['LongName'].value == escape(d)] + and c.attributes['LongName'].value == escape(d)] if already_created: Directory = already_created[0] diff --git a/SCons/Tool/packaging/rpm.py b/SCons/Tool/packaging/rpm.py index a0c3172..03633db 100644 --- a/SCons/Tool/packaging/rpm.py +++ b/SCons/Tool/packaging/rpm.py @@ -1,10 +1,6 @@ -"""SCons.Tool.Packaging.rpm - -The rpm packager. -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -25,12 +21,10 @@ The rpm packager. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - +"""The rpm packager.""" import SCons.Builder import SCons.Tool.rpmutils - from SCons.Environment import OverrideEnvironment from SCons.Tool.packaging import stripinstallbuilder, src_targz from SCons.Errors import UserError @@ -324,7 +318,7 @@ class SimpleTagCompiler: def compile(self, values): """ Compiles the tagset and returns a str containing the result """ - def is_international(tag): + def is_international(tag) -> bool: return tag.endswith('_') def get_country_code(tag): diff --git a/SCons/Tool/pdf.py b/SCons/Tool/pdf.py index ddaaa8a..74b2449 100644 --- a/SCons/Tool/pdf.py +++ b/SCons/Tool/pdf.py @@ -1,12 +1,6 @@ -"""SCons.Tool.pdf - -Common PDF Builder definition for various other Tool modules that use it. -Add an explicit action to run epstopdf to convert .eps files to .pdf - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -26,9 +20,12 @@ Add an explicit action to run epstopdf to convert .eps files to .pdf # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Common PDF Builder definition. + +This is for various other Tool modules that use it. +Add an explicit action to run epstopdf to convert .eps files to .pdf +""" import SCons.Builder import SCons.Tool @@ -55,7 +52,7 @@ def generate(env) -> None: env['PDFPREFIX'] = '' env['PDFSUFFIX'] = '.pdf' -# put the epstopdf builder in this routine so we can add it after +# put the epstopdf builder in this routine so we can add it after # the pdftex builder so that one is the default for no source suffix def generate2(env) -> None: bld = env['BUILDERS']['PDF'] @@ -66,10 +63,10 @@ def generate2(env) -> None: env['EPSTOPDFFLAGS'] = SCons.Util.CLVar('') env['EPSTOPDFCOM'] = '$EPSTOPDF $EPSTOPDFFLAGS ${SOURCE} --outfile=${TARGET}' -def exists(env) -> int: +def exists(env) -> bool: # This only puts a skeleton Builder in place, so if someone # references this Tool directly, it's always "available." - return 1 + return True # Local Variables: # tab-width:4 diff --git a/SCons/Tool/rmic.py b/SCons/Tool/rmic.py index 8523397..a5d8063 100644 --- a/SCons/Tool/rmic.py +++ b/SCons/Tool/rmic.py @@ -1,15 +1,6 @@ -"""SCons.Tool.rmic - -Tool-specific initialization for rmic. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,9 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for rmic. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import os.path @@ -123,14 +118,14 @@ def generate(env) -> None: env['RMICCOM'] = '$RMIC $RMICFLAGS -d ${TARGET.attributes.java_lookupdir} -classpath ${SOURCE.attributes.java_classdir} ${SOURCES.attributes.java_classname}' env['JAVACLASSSUFFIX'] = '.class' -def exists(env) -> int: +def exists(env) -> bool: # As reported by Jan Nijtmans in issue #2730, the simple # return env.Detect('rmic') # doesn't always work during initialization. For now, we # stop trying to detect an executable (analogous to the # javac Builder). # TODO: Come up with a proper detect() routine...and enable it. - return 1 + return True # Local Variables: # tab-width:4 diff --git a/SCons/Tool/textfile.py b/SCons/Tool/textfile.py index 9d98644..f79f808 100644 --- a/SCons/Tool/textfile.py +++ b/SCons/Tool/textfile.py @@ -21,31 +21,28 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" -Textfile/Substfile builder for SCons. - - Create file 'target' which typically is a textfile. The 'source' - may be any combination of strings, Nodes, or lists of same. A - 'linesep' will be put between any part written and defaults to - os.linesep. - - The only difference between the Textfile builder and the Substfile - builder is that strings are converted to Value() nodes for the - former and File() nodes for the latter. To insert files in the - former or strings in the latter, wrap them in a File() or Value(), - respectively. - - The values of SUBST_DICT first have any construction variables - expanded (its keys are not expanded). If a value of SUBST_DICT is - a python callable function, it is called and the result is expanded - as the value. Values are substituted in a "random" order; if any - substitution could be further expanded by another substitution, it - is unpredictable whether the expansion will occur. +"""Textfile/Substfile builder for SCons. + +Create file 'target' which typically is a textfile. The 'source' +may be any combination of strings, Nodes, or lists of same. A +'linesep' will be put between any part written and defaults to +os.linesep. + +The only difference between the Textfile builder and the Substfile +builder is that strings are converted to Value() nodes for the +former and File() nodes for the latter. To insert files in the +former or strings in the latter, wrap them in a File() or Value(), +respectively. + +The values of SUBST_DICT first have any construction variables +expanded (its keys are not expanded). If a value of SUBST_DICT is +a python callable function, it is called and the result is expanded +as the value. Values are substituted in a "random" order; if any +substitution could be further expanded by another substitution, it +is unpredictable whether the expansion will occur. """ import SCons - - from SCons.Node import Node from SCons.Node.Python import Value from SCons.Util import is_String, is_Sequence, is_Dict, to_bytes @@ -192,8 +189,8 @@ def generate(env) -> None: env['FILE_ENCODING'] = env.get('FILE_ENCODING', 'utf-8') -def exists(env) -> int: - return 1 +def exists(env) -> bool: + return True # Local Variables: # tab-width:4 diff --git a/SCons/UtilTests.py b/SCons/UtilTests.py index 860724e..54cb658 100644 --- a/SCons/UtilTests.py +++ b/SCons/UtilTests.py @@ -119,32 +119,32 @@ class UtilTestCase(unittest.TestCase): def __str__(self) -> str: return self.name - def exists(self) -> int: - return 1 + def exists(self) -> bool: + return True - def rexists(self) -> int: - return 1 + def rexists(self) -> bool: + return True - def has_builder(self) -> int: - return 1 + def has_builder(self) -> bool: + return True - def has_explicit_builder(self) -> int: - return 1 + def has_explicit_builder(self) -> bool: + return True - def side_effect(self) -> int: - return 1 + def side_effect(self) -> bool: + return True - def precious(self) -> int: - return 1 + def precious(self) -> bool: + return True - def always_build(self) -> int: - return 1 + def always_build(self) -> bool: + return True - def is_up_to_date(self) -> int: - return 1 + def is_up_to_date(self) -> bool: + return True - def noclean(self) -> int: - return 1 + def noclean(self) -> bool: + return True def tree_case_1(self): """Fixture for the render_tree() and print_tree() tests.""" diff --git a/SCons/cppTests.py b/SCons/cppTests.py index 5f00d50..85f01b7 100644 --- a/SCons/cppTests.py +++ b/SCons/cppTests.py @@ -26,7 +26,7 @@ import unittest import TestUnit -import cpp +import SCons.cpp as cpp basic_input = """ -- cgit v0.12 From f2f997b6907e2f5bcf1c8553a5532b54aa6bdc71 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 18 Jun 2023 15:53:33 -0700 Subject: [ci skip] Fixed typo in CHANGES.txt --- CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index fc51163..57089dc 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -25,7 +25,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Added some typing annotations generated by a tool, to eliminate manual work in future on things which are safe for the tool to produce. Then manually fixed up some things related to bool that the tool did - not handly idealls. For example, simple functions which just did + not handly ideally. For example, simple functions which just did "return 1" were interpreted by the tool as returning int, when bool was really the intent. Functions/methods named like "is_*", "has_*", "exists" are now pretty consistently marked as "-> bool". -- cgit v0.12 From 34552173661b13419cec50628604ad37b19856f2 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 18 Jun 2023 16:06:35 -0700 Subject: [ci skip] Added info on byacc difference to CHANGES.txt --- CHANGES.txt | 9 +++++---- RELEASE.txt | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 6276443..9bd0fbe 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -80,10 +80,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER --defines and --graph being called without option-argument as being synonyms for -d (first two) and -g. -H also recognized as a synonym for -d. Default value for $YACC_GRAPH_FILE_SUFFIX changed to '.gv' - to match current bison default (since bison 3.8). The graph file name - (-g) is now generated relative to the requested target file name, - not to the source file name, to match actual current behavior (only - affects if target explicitly requested with a different base name + to match current bison default (since bison 3.8). Set this variable + to '.dot' if using byacc. The graph file name (-g) is now generated + relative to the requested target file name, not to the source file + name, to match actual current behavior (only affects if target + explicitly requested with a different base name than source). Docs updated. Fixes #4326 and #4327. diff --git a/RELEASE.txt b/RELEASE.txt index 45a5f4b..ee27081 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -44,7 +44,7 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY for -d (first two) and -g. -H also recognized as a synonym for -d. Default value for $YACC_GRAPH_FILE_SUFFIX changed to '.gv' to match current bison default (since bison 3.8). Set this variable to '.dot' - if using byacc. + if using byacc. Fixes #4326 and #4327. FIXES ----- -- cgit v0.12 From 2d14859378bc9f099f115e3e816eaebebf29dd77 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 6 Jun 2023 06:46:56 -0600 Subject: maintenance: update/cleanup dblite module Signed-off-by: Mats Wichmann --- CHANGES.txt | 1 + RELEASE.txt | 1 + SCons/SConsign.py | 26 ++------ SCons/dblite.py | 190 +++++++++++++++++++++++++++++++++++------------------- 4 files changed, 132 insertions(+), 86 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 30218d3..a4d12a2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -91,6 +91,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER name, to match actual current behavior (only affects if target explicitly requested with a different base name than source). Docs updated. Fixes #4326 and #4327. + - Cleanud up dblite module (checker warnings, etc.). RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index ff15b25..a9132c4 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -88,6 +88,7 @@ DEVELOPMENT now declares (actually raises NotImplementedError) two methods it doesn't use so it can be instantiated by unittests and others. - Added more type annotations to internal routines. +- Cleanud up dblite module (checker warnings, etc.). Thanks to the following contributors listed below for their contributions to this release. ========================================================================================== diff --git a/SCons/SConsign.py b/SCons/SConsign.py index 860d40b..5d57af5 100644 --- a/SCons/SConsign.py +++ b/SCons/SConsign.py @@ -23,7 +23,7 @@ """Operations on signature database files (.sconsign). """ -import SCons.compat +import SCons.compat # pylint: disable=wrong-import-order import os import pickle @@ -69,11 +69,10 @@ def current_sconsign_filename(): # eg .sconsign_sha1, etc. if hash_format is None and current_hash_algorithm == 'md5': return ".sconsign" - else: - return ".sconsign_" + current_hash_algorithm + return ".sconsign_" + current_hash_algorithm def Get_DataBase(dir): - global DataBase, DB_Module, DB_Name + global DB_Name if DB_Name is None: DB_Name = current_sconsign_filename() @@ -117,8 +116,6 @@ normcase = os.path.normcase def write() -> None: - global sig_files - if print_time(): start_time = time.perf_counter() @@ -284,7 +281,6 @@ class DB(Base): self.set_entry = self.do_not_set_entry self.store_info = self.do_not_store_info - global sig_files sig_files.append(self) def write(self, sync: int=1) -> None: @@ -316,9 +312,7 @@ class DB(Base): class Dir(Base): def __init__(self, fp=None, dir=None) -> None: - """ - fp - file pointer to read entries from - """ + """fp - file pointer to read entries from.""" super().__init__() if not fp: @@ -335,13 +329,9 @@ class Dir(Base): class DirFile(Dir): - """ - Encapsulates reading and writing a per-directory .sconsign file. - """ + """Encapsulates reading and writing a per-directory .sconsign file.""" def __init__(self, dir) -> None: - """ - dir - the directory for the file - """ + """dir - the directory for the file.""" self.dir = dir self.sconsign = os.path.join(dir.get_internal_path(), current_sconsign_filename()) @@ -364,12 +354,10 @@ class DirFile(Dir): except AttributeError: pass - global sig_files sig_files.append(self) def write(self, sync: int=1) -> None: - """ - Write the .sconsign file to disk. + """Write the .sconsign file to disk. Try to write to a temporary file first, and rename it if we succeed. If we can't write to the temporary file, it's diff --git a/SCons/dblite.py b/SCons/dblite.py index dd05f66..e50b7f9 100644 --- a/SCons/dblite.py +++ b/SCons/dblite.py @@ -24,8 +24,13 @@ """ dblite.py module contributed by Ralf W. Grosse-Kunstleve. Extended for Unicode by Steven Knight. + +This is a very simple-minded "database" used for saved signature +information, with an interface modeled on the Python dbm database +interface module. """ +import io import os import pickle import shutil @@ -45,41 +50,59 @@ def corruption_warning(filename) -> None: """ print("Warning: Discarding corrupt database:", filename) -DBLITE_SUFFIX = '.dblite' -TMP_SUFFIX = '.tmp' +DBLITE_SUFFIX = ".dblite" +TMP_SUFFIX = ".tmp" -class dblite: - """ - Squirrel away references to the functions in various modules - that we'll use when our __del__() method calls our sync() method - during shutdown. We might get destroyed when Python is in the midst - of tearing down the different modules we import in an essentially - arbitrary order, and some of the various modules's global attributes - may already be wiped out from under us. - See the discussion at: - http://mail.python.org/pipermail/python-bugs-list/2003-March/016877.html +class _Dblite: + """Lightweight signature database class. + + Behaves like a dict when in memory, loads from a pickled disk + file on open and writes back out to it on close. + + Open the database file using a path derived from *file_base_name*. + The optional *flag* argument can be: + +---------+---------------------------------------------------+ + | Value | Meaning | + +=========+===================================================+ + | ``'r'`` | Open existing database for reading only (default) | + +---------+---------------------------------------------------+ + | ``'w'`` | Open existing database for reading and writing | + +---------+---------------------------------------------------+ + | ``'c'`` | Open database for reading and writing, creating | + | | it if it doesn't exist | + +---------+---------------------------------------------------+ + | ``'n'`` | Always create a new, empty database, open for | + | | reading and writing | + +---------+---------------------------------------------------+ + + The optional *mode* argument is the POSIX mode of the file, used only + when the database has to be created. It defaults to octal ``0o666``. """ - _open = open + # Because open() is defined at module level, overwriting builtin open + # in the scope of this module, we use io.open to avoid ambiguity. + _open = staticmethod(io.open) + + # we need to squirrel away references to functions from various modules + # that we'll use when sync() is called: this may happen at Python + # teardown time (we call it from our __del__), and the global module + # references themselves may already have been rebound to None. _pickle_dump = staticmethod(pickle.dump) _pickle_protocol = PICKLE_PROTOCOL - try: - _os_chown = os.chown + _os_chown = staticmethod(os.chown) except AttributeError: _os_chown = None - _os_replace = os.replace - _os_chmod = os.chmod - _shutil_copyfile = shutil.copyfile - _time_time = time.time + _os_replace = staticmethod(os.replace) + _os_chmod = staticmethod(os.chmod) + _shutil_copyfile = staticmethod(shutil.copyfile) + _time_time = staticmethod(time.time) - def __init__(self, file_base_name, flag, mode) -> None: - assert flag in (None, "r", "w", "c", "n") - if flag is None: - flag = "r" + def __init__(self, file_base_name, flag='r', mode=0o666) -> None: + assert flag in ("r", "w", "c", "n") base, ext = os.path.splitext(file_base_name) if ext == DBLITE_SUFFIX: @@ -95,7 +118,7 @@ class dblite: self._dict = {} self._needs_sync = False - if self._os_chown is not None and (os.geteuid() == 0 or os.getuid() == 0): + if self._os_chown is not None and 0 in (os.geteuid(), os.getegid()): # running as root; chown back to current owner/group when done try: statinfo = os.stat(self._file_name) @@ -111,30 +134,47 @@ class dblite: self._chgrp_to = -1 # don't chgrp if self._flag == "n": - with self._open(self._file_name, "wb", self._mode): - pass # just make sure it exists + with io.open(self._file_name, "wb", opener=self.opener): + return # just make sure it exists else: + # We only need the disk file to slurp in the data. Updates are + # handled on close, db is mainained only in memory until then. try: - f = self._open(self._file_name, "rb") - except IOError as e: + with io.open(self._file_name, "rb") as f: + p = f.read() + except OSError as e: + # an error for file not to exist, unless flag is create if self._flag != "c": raise e - with self._open(self._file_name, "wb", self._mode): - pass # just make sure it exists - else: - p = f.read() - f.close() - if len(p) > 0: - try: - self._dict = pickle.loads(p, encoding='bytes') - except (pickle.UnpicklingError, EOFError, KeyError): - # Note how we catch KeyErrors too here, which might happen - # when we don't have cPickle available (default pickle - # throws it). - if IGNORE_CORRUPT_DBFILES: - corruption_warning(self._file_name) - else: - raise + with io.open(self._file_name, "wb", opener=self.opener): + return # just make sure it exists + if len(p) > 0: + try: + self._dict = pickle.loads(p, encoding='bytes') + except ( + pickle.UnpicklingError, + # Python3 docs: + # Note that other exceptions may also be raised during + # unpickling, including (but not necessarily limited to) + # AttributeError, EOFError, ImportError, and IndexError. + AttributeError, + EOFError, + ImportError, + IndexError, + ): + if IGNORE_CORRUPT_DBFILES: + corruption_warning(self._file_name) + else: + raise + + def opener(self, path, flags): + """Database open helper when creation may be needed. + + The high-level Python open() function cannot specify a file mode + for creation. Using this as the opener with the saved mode lets + us do that. + """ + return os.open(path, flags, mode=self._mode) def close(self) -> None: if self._needs_sync: @@ -144,8 +184,15 @@ class dblite: self.close() def sync(self) -> None: + """Flush the database to disk. + + This routine *must* succeed, since the in-memory and on-disk + copies are out of sync as soon as we do anything that changes + the in-memory version. Thus, to be cautious, flush to a + temporary file and then move it over with some error handling. + """ self._check_writable() - with self._open(self._tmp_name, "wb", self._mode) as f: + with self._open(self._tmp_name, "wb", opener=self.opener) as f: self._pickle_dump(self._dict, f, self._pickle_protocol) try: @@ -162,7 +209,9 @@ class dblite: pass self._os_replace(self._tmp_name, self._file_name) - if self._os_chown is not None and self._chown_to > 0: # don't chown to root or -1 + if ( + self._os_chown is not None and self._chown_to > 0 + ): # don't chown to root or -1 try: self._os_chown(self._file_name, self._chown_to, self._chgrp_to) except OSError: @@ -171,13 +220,12 @@ class dblite: self._needs_sync = False if KEEP_ALL_FILES: self._shutil_copyfile( - self._file_name, - self._file_name + "_" + str(int(self._time_time())) + self._file_name, f"{self._file_name}_{int(self._time_time())}" ) def _check_writable(self): if self._flag == "r": - raise IOError("Read-only database: %s" % self._file_name) + raise OSError(f"Read-only database: {self._file_name}") def __getitem__(self, key): return self._dict[key] @@ -186,29 +234,37 @@ class dblite: self._check_writable() if not isinstance(key, str): - raise TypeError("key `%s' must be a string but is %s" % (key, type(key))) + raise TypeError(f"key `{key}' must be a string but is {type(key)}") if not isinstance(value, bytes): - raise TypeError("value `%s' must be a bytes but is %s" % (value, type(value))) + raise TypeError(f"value `{value}' must be bytes but is {type(value)}") self._dict[key] = value self._needs_sync = True + def __delitem__(self, key): + del self._dict[key] + def keys(self): - return list(self._dict.keys()) + return self._dict.keys() + + def items(self): + return self._dict.items() + + def values(self): + return self._dict.values() + + __iter__ = keys def __contains__(self, key) -> bool: return key in self._dict - def __iter__(self): - return iter(self._dict) - def __len__(self) -> int: return len(self._dict) -def open(file, flag=None, mode: int=0o666): - return dblite(file, flag, mode) +def open(file, flag="r", mode: int = 0o666): # pylint: disable=redefined-builtin + return _Dblite(file, flag, mode) def _exercise(): @@ -225,13 +281,13 @@ def _exercise(): assert db["bar"] == b"foo" db.sync() - db = open("tmp", "r") + db = open("tmp") assert len(db) == 2, len(db) assert db["foo"] == b"bar" assert db["bar"] == b"foo" try: db.sync() - except IOError as e: + except OSError as e: assert str(e) == "Read-only database: tmp.dblite" else: raise RuntimeError("IOError expected.") @@ -250,21 +306,21 @@ def _exercise(): try: db["list"] = [1, 2] except TypeError as e: - assert str(e) == "value `[1, 2]' must be a bytes but is ", str(e) + assert str(e) == "value `[1, 2]' must be bytes but is ", str(e) else: raise RuntimeError("TypeError exception expected") - db = open("tmp", "r") + db = open("tmp") assert len(db) == 3, len(db) db = open("tmp", "n") assert len(db) == 0, len(db) - dblite._open("tmp.dblite", "w") + _Dblite._open("tmp.dblite", "w") - db = open("tmp", "r") - dblite._open("tmp.dblite", "w").write("x") + db = open("tmp") + _Dblite._open("tmp.dblite", "w").write("x") try: - db = open("tmp", "r") + db = open("tmp") except pickle.UnpicklingError: pass else: @@ -272,12 +328,12 @@ def _exercise(): global IGNORE_CORRUPT_DBFILES IGNORE_CORRUPT_DBFILES = True - db = open("tmp", "r") + db = open("tmp") assert len(db) == 0, len(db) os.unlink("tmp.dblite") try: db = open("tmp", "w") - except IOError as e: + except OSError as e: assert str(e) == "[Errno 2] No such file or directory: 'tmp.dblite'", str(e) else: raise RuntimeError("IOError expected.") -- cgit v0.12 From 9e116a99b7cd8fc4284400a38de9bc23ee63905a Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 19 Jun 2023 17:12:22 -0700 Subject: [ci skip] fixed typo in CHANGES.txt/RELEASE.txt --- CHANGES.txt | 2 +- RELEASE.txt | 4 ++-- SCons/SConsign.py | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index a4d12a2..702b4ff 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -91,7 +91,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER name, to match actual current behavior (only affects if target explicitly requested with a different base name than source). Docs updated. Fixes #4326 and #4327. - - Cleanud up dblite module (checker warnings, etc.). + - Cleaned up dblite module (checker warnings, etc.). RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index a9132c4..331872e 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -88,10 +88,10 @@ DEVELOPMENT now declares (actually raises NotImplementedError) two methods it doesn't use so it can be instantiated by unittests and others. - Added more type annotations to internal routines. -- Cleanud up dblite module (checker warnings, etc.). +- Cleaned up dblite module (checker warnings, etc.). Thanks to the following contributors listed below for their contributions to this release. ========================================================================================== .. code-block:: text - git shortlog --no-merges -ns 4.0.1..HEAD + git shortlog --no-merges -ns 4.5.2..HEAD diff --git a/SCons/SConsign.py b/SCons/SConsign.py index 5d57af5..3d56304 100644 --- a/SCons/SConsign.py +++ b/SCons/SConsign.py @@ -112,6 +112,7 @@ def Reset() -> None: sig_files = [] DB_sync_list = [] + normcase = os.path.normcase -- cgit v0.12